diff --git a/Cargo.lock b/Cargo.lock index cd74f589f07..84a668b5188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4335,8 +4335,11 @@ dependencies = [ name = "rustc_smir" version = "0.0.0" dependencies = [ + "rustc_driver", "rustc_hir", + "rustc_interface", "rustc_middle", + "rustc_session", "rustc_span", "rustc_target", "scoped-tls", diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 3081dcfa2b7..ec2da39398b 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -480,7 +480,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.0.sess.span_fatal(span, err.to_string()) } else { - span_bug!(span, "failed to get layout for `{}`: {}", ty, err) + self.0.sess.span_fatal(span, format!("failed to get layout for `{}`: {}", ty, err)) } } } diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 88dcafa7370..dcebd92a61c 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{ BaseTypeMethods, MiscMethods, }; +use rustc_codegen_ssa::errors as ssa_errors; use rustc_data_structures::base_n; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::span_bug; @@ -479,7 +480,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.sess().emit_fatal(respan(span, err.into_diagnostic())) } else { - span_bug!(span, "failed to get layout for `{}`: {}", ty, err) + self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err }) } } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 24fd5bbf8c5..8e8290279ab 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -10,6 +10,7 @@ use crate::value::Value; use cstr::cstr; use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh}; +use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n; use rustc_data_structures::fx::FxHashMap; @@ -1000,7 +1001,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() }) } else { - span_bug!(span, "failed to get layout for `{ty}`: {err:?}") + self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err }) } } } diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index b6c70c62249..3dc83f50b21 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -35,6 +35,8 @@ codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error} codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error} +codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err} + codegen_ssa_failed_to_write = failed to write {$path}: {$error} codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index b7d8b9b45bf..41602321ded 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -7,6 +7,7 @@ use rustc_errors::{ IntoDiagnosticArg, }; use rustc_macros::Diagnostic; +use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::Ty; use rustc_span::{Span, Symbol}; use rustc_type_ir::FloatTy; @@ -1030,6 +1031,15 @@ pub struct TargetFeatureSafeTrait { pub def: Span, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_failed_to_get_layout)] +pub struct FailedToGetLayout<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, + pub err: LayoutError<'tcx>, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_error_creating_remark_dir)] pub struct ErrorCreatingRemarkDir { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index c930537d4ae..67aef0a7c43 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -195,8 +195,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef let ty_b = field.ty(tcx, args_b); if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) { - if layout.is_zst() && layout.align.abi.bytes() == 1 { - // ignore ZST fields with alignment of 1 byte + if layout.is_1zst() { + // ignore 1-ZST fields return false; } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 1ba746eddeb..fc4c29eb36d 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -804,7 +804,7 @@ pub(crate) fn nonnull_optimization_guaranteed<'tcx>( tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed) } -/// `repr(transparent)` structs can have a single non-ZST field, this function returns that +/// `repr(transparent)` structs can have a single non-1-ZST field, this function returns that /// field. pub fn transparent_newtype_field<'a, 'tcx>( tcx: TyCtxt<'tcx>, @@ -813,8 +813,8 @@ pub fn transparent_newtype_field<'a, 'tcx>( let param_env = tcx.param_env(variant.def_id); variant.fields.iter().find(|field| { let field_ty = tcx.type_of(field.did).instantiate_identity(); - let is_zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_zst()); - !is_zst + let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst()); + !is_1zst }) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index e362b3477c9..9a0e72d7b64 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -4,7 +4,9 @@ use crate::query::TyCtxtAt; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, ConstKind, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_error_messages::DiagnosticMessage; -use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; +use rustc_errors::{ + DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg, +}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; @@ -265,6 +267,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { } } +impl<'tcx> IntoDiagnosticArg for LayoutError<'tcx> { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + self.to_string().into_diagnostic_arg() + } +} + #[derive(Clone, Copy)] pub struct LayoutCx<'tcx, C> { pub tcx: C, diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 80d4e7ed02f..21ec904e43c 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -9,6 +9,9 @@ rustc_hir = { path = "../rustc_hir", optional = true } rustc_middle = { path = "../rustc_middle", optional = true } rustc_span = { path = "../rustc_span", optional = true } rustc_target = { path = "../rustc_target", optional = true } +rustc_driver = { path = "../rustc_driver", optional = true } +rustc_interface = { path = "../rustc_interface", optional = true} +rustc_session = {path = "../rustc_session", optional = true} tracing = "0.1" scoped-tls = "1.0" @@ -18,4 +21,7 @@ default = [ "rustc_middle", "rustc_span", "rustc_target", + "rustc_driver", + "rustc_interface", + "rustc_session", ] diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index ebacb7cce83..5334a75dc06 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -4,13 +4,18 @@ //! until stable MIR is complete. use std::fmt::Debug; +use std::ops::Index; use std::string::ToString; +use crate::rustc_internal; use crate::{ rustc_smir::Tables, stable_mir::{self, with}, }; +use rustc_driver::{Callbacks, Compilation, RunCompiler}; +use rustc_interface::{interface, Queries}; use rustc_middle::ty::TyCtxt; +use rustc_session::EarlyErrorHandler; pub use rustc_span::def_id::{CrateNum, DefId}; fn with_tables(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R { @@ -20,7 +25,7 @@ fn with_tables(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R { } pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { - with_tables(|t| t.item_def_id(item)) + with_tables(|t| t[item.0]) } pub fn crate_item(did: DefId) -> stable_mir::CrateItem { @@ -67,23 +72,16 @@ pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef { with_tables(|t| t.impl_def(did)) } +impl<'tcx> Index for Tables<'tcx> { + type Output = DefId; + + #[inline(always)] + fn index(&self, index: stable_mir::DefId) -> &Self::Output { + &self.def_ids[index.0] + } +} + impl<'tcx> Tables<'tcx> { - pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId { - self.def_ids[item.0] - } - - pub fn trait_def_id(&self, trait_def: &stable_mir::ty::TraitDef) -> DefId { - self.def_ids[trait_def.0] - } - - pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId { - self.def_ids[impl_def.0] - } - - pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId { - self.def_ids[generic_def.0] - } - pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem { stable_mir::CrateItem(self.create_def_id(did)) } @@ -140,12 +138,12 @@ impl<'tcx> Tables<'tcx> { // FIXME: this becomes inefficient when we have too many ids for (i, &d) in self.def_ids.iter().enumerate() { if d == did { - return i; + return stable_mir::DefId(i); } } let id = self.def_ids.len(); self.def_ids.push(did); - id + stable_mir::DefId(id) } } @@ -163,3 +161,40 @@ pub type Opaque = impl Debug + ToString + Clone; pub(crate) fn opaque(value: &T) -> Opaque { format!("{value:?}") } + +pub struct StableMir { + args: Vec, + callback: fn(TyCtxt<'_>), +} + +impl StableMir { + /// Creates a new `StableMir` instance, with given test_function and arguments. + pub fn new(args: Vec, callback: fn(TyCtxt<'_>)) -> Self { + StableMir { args, callback } + } + + /// Runs the compiler against given target and tests it with `test_function` + pub fn run(&mut self) { + rustc_driver::catch_fatal_errors(|| { + RunCompiler::new(&self.args.clone(), self).run().unwrap(); + }) + .unwrap(); + } +} + +impl Callbacks for StableMir { + /// Called after analysis. Return value instructs the compiler whether to + /// continue the compilation afterwards (defaults to `Compilation::Continue`) + fn after_analysis<'tcx>( + &mut self, + _handler: &EarlyErrorHandler, + _compiler: &interface::Compiler, + queries: &'tcx Queries<'tcx>, + ) -> Compilation { + queries.global_ctxt().unwrap().enter(|tcx| { + rustc_internal::run(tcx, || (self.callback)(tcx)); + }); + // No need to keep going. + Compilation::Stop + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 925d4a3bdd8..7877c91c2cf 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -10,8 +10,8 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; use crate::stable_mir::ty::{ - allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy, - Movability, RigidTy, TyKind, UintTy, + allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, + TyKind, UintTy, }; use crate::stable_mir::{self, Context}; use rustc_hir as hir; @@ -54,7 +54,7 @@ impl<'tcx> Context for Tables<'tcx> { } fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl { - let def_id = self.trait_def_id(trait_def); + let def_id = self[trait_def.0]; let trait_def = self.tcx.trait_def(def_id); trait_def.stable(self) } @@ -68,13 +68,13 @@ impl<'tcx> Context for Tables<'tcx> { } fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait { - let def_id = self.impl_trait_def_id(impl_def); + let def_id = self[impl_def.0]; let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap(); impl_trait.stable(self) } fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body { - let def_id = self.item_def_id(item); + let def_id = self[item.0]; let mir = self.tcx.optimized_mir(def_id); stable_mir::mir::Body { blocks: mir @@ -102,19 +102,16 @@ impl<'tcx> Context for Tables<'tcx> { ty.stable(self) } - fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics { - let def_id = self.generic_def_id(generic_def); - let generic_def = self.tcx.generics_of(def_id); - generic_def.stable(self) + fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics { + let def_id = self[def_id]; + let generics = self.tcx.generics_of(def_id); + generics.stable(self) } - fn predicates_of( - &mut self, - trait_def: &stable_mir::ty::TraitDef, - ) -> stable_mir::GenericPredicates { - let trait_def_id = self.trait_def_id(trait_def); - let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(trait_def_id); - stable_mir::GenericPredicates { + fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { + let def_id = self[def_id]; + let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id); + stable_mir::ty::GenericPredicates { parent: parent.map(|did| self.trait_def(did)), predicates: predicates .iter() diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 44938eaa035..1b834628175 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -13,11 +13,10 @@ use std::cell::Cell; -use crate::rustc_smir::Tables; - use self::ty::{ - GenericDef, Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind, + GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, }; +use crate::rustc_smir::Tables; pub mod mir; pub mod ty; @@ -29,7 +28,8 @@ pub type Symbol = String; pub type CrateNum = usize; /// A unique identification number for each item accessible for the current compilation unit. -pub type DefId = usize; +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct DefId(pub(crate) usize); /// A list of crate items. pub type CrateItems = Vec; @@ -40,12 +40,6 @@ pub type TraitDecls = Vec; /// A list of impl trait decls. pub type ImplTraitDecls = Vec; -/// A list of predicates. -pub struct GenericPredicates { - pub parent: Option, - pub predicates: Vec<(PredicateKind, Span)>, -} - /// Holds information about a crate. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Crate { @@ -109,14 +103,6 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { with(|cx| cx.trait_impl(trait_impl)) } -pub fn generics_of(generic_def: &GenericDef) -> Generics { - with(|cx| cx.generics_of(generic_def)) -} - -pub fn predicates_of(trait_def: &TraitDef) -> GenericPredicates { - with(|cx| cx.predicates_of(trait_def)) -} - pub trait Context { fn entry_fn(&mut self) -> Option; /// Retrieve all items of the local crate that have a MIR associated with them. @@ -126,8 +112,8 @@ pub trait Context { fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl; fn all_trait_impls(&mut self) -> ImplTraitDecls; fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait; - fn generics_of(&mut self, generic_def: &GenericDef) -> Generics; - fn predicates_of(&mut self, trait_def: &TraitDef) -> GenericPredicates; + fn generics_of(&mut self, def_id: DefId) -> Generics; + fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates; /// Get information about the local crate. fn local_crate(&self) -> Crate; /// Retrieve a list of all external crates. diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 5929823b1bb..fce5375f848 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -120,27 +120,9 @@ pub struct GenericDef(pub(crate) DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ConstDef(pub(crate) DefId); -impl TraitDef { - pub fn trait_decl(&self) -> TraitDecl { - with(|cx| cx.trait_decl(self)) - } -} - #[derive(Clone, PartialEq, Eq, Debug)] pub struct ImplDef(pub(crate) DefId); -impl ImplDef { - pub fn trait_impl(&self) -> ImplTrait { - with(|cx| cx.trait_impl(self)) - } -} - -impl GenericDef { - pub fn generics_of(&self) -> Generics { - with(|tcx| tcx.generics_of(self)) - } -} - #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec); @@ -463,6 +445,16 @@ pub struct TraitDecl { pub deny_explicit_impl: bool, } +impl TraitDecl { + pub fn generics_of(&self) -> Generics { + with(|cx| cx.generics_of(self.def_id.0)) + } + + pub fn predicates_of(&self) -> GenericPredicates { + with(|cx| cx.predicates_of(self.def_id.0)) + } +} + pub type ImplTrait = EarlyBinder; #[derive(Clone, Debug)] @@ -499,8 +491,8 @@ pub struct GenericParamDef { } pub struct GenericPredicates { - pub parent: Option, - pub predicates: Vec, + pub parent: Option, + pub predicates: Vec<(PredicateKind, Span)>, } #[derive(Clone, Debug)] diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index a03da41652c..802391f1aad 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -592,13 +592,13 @@ fn make_thin_self_ptr<'tcx>( for i in 0..fat_pointer_layout.fields.count() { let field_layout = fat_pointer_layout.field(cx, i); - if !field_layout.is_zst() { + if !field_layout.is_1zst() { fat_pointer_layout = field_layout; continue 'descend_newtypes; } } - bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); + bug!("receiver has no non-1-ZST fields {:?}", fat_pointer_layout); } fat_pointer_layout.ty diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 6b4273c03e4..ed7b3496894 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -192,7 +192,7 @@ fn layout_of_uncached<'tcx>( let metadata_layout = cx.layout_of(metadata_ty)?; // If the metadata is a 1-zst, then the pointer is thin. - if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 { + if metadata_layout.is_1zst() { return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr))); } diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f882a31de5a..d72543c7e02 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -263,7 +263,7 @@ flavor. Valid options are: * `lld-link`: use the LLVM `lld` executable with the [`-flavor link` flag][lld-flavor] for Microsoft's `link.exe`. -[lld-flavor]: https://lld.llvm.org/Driver.html +[lld-flavor]: https://releases.llvm.org/12.0.0/tools/lld/docs/Driver.html ## linker-plugin-lto diff --git a/tests/debuginfo/regression-bad-location-list-67992.rs b/tests/debuginfo/regression-bad-location-list-67992.rs new file mode 100644 index 00000000000..cc7c4a0d71a --- /dev/null +++ b/tests/debuginfo/regression-bad-location-list-67992.rs @@ -0,0 +1,31 @@ +// compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// gdb-command:print a +// gdb-check:$1 = regression_bad_location_list_67992::Foo {x: [0 ]} + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-command:print a +// lldbg-check:(regression_bad_location_list_67992::Foo) $0 = [...] +// lldbr-check:(regression_bad_location_list_67992::Foo) a = [...] + +const ARRAY_SIZE: usize = 1024; + +struct Foo { + x: [u64; ARRAY_SIZE], +} + +fn foo(a: Foo, i: usize) -> u64 { + a.x[i] // #break +} + +fn main() { + println!("Hello, world!"); + + println!("{}", foo(Foo { x: [0; ARRAY_SIZE] }, 42)); +} diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index f55d7d599f1..00dce3e004e 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -9,18 +9,12 @@ #![feature(rustc_private)] #![feature(assert_matches)] -extern crate rustc_driver; extern crate rustc_hir; -extern crate rustc_interface; extern crate rustc_middle; -extern crate rustc_session; extern crate rustc_smir; -use rustc_driver::{Callbacks, Compilation, RunCompiler}; use rustc_hir::def::DefKind; -use rustc_interface::{interface, Queries}; use rustc_middle::ty::TyCtxt; -use rustc_session::EarlyErrorHandler; use rustc_smir::{rustc_internal, stable_mir}; use std::assert_matches::assert_matches; use std::io::Write; @@ -130,8 +124,8 @@ fn get_item<'a>( /// This test will generate and analyze a dummy crate using the stable mir. /// For that, it will first write the dummy crate into a file. -/// It will invoke the compiler using a custom Callback implementation, which will -/// invoke Stable MIR APIs after the compiler has finished its analysis. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. fn main() { let path = "input.rs"; generate_input(&path).unwrap(); @@ -142,29 +136,7 @@ fn main() { CRATE_NAME.to_string(), path.to_string(), ]; - rustc_driver::catch_fatal_errors(|| { - RunCompiler::new(&args, &mut SMirCalls {}).run().unwrap(); - }) - .unwrap(); -} - -struct SMirCalls {} - -impl Callbacks for SMirCalls { - /// Called after analysis. Return value instructs the compiler whether to - /// continue the compilation afterwards (defaults to `Compilation::Continue`) - fn after_analysis<'tcx>( - &mut self, - _handler: &EarlyErrorHandler, - _compiler: &interface::Compiler, - queries: &'tcx Queries<'tcx>, - ) -> Compilation { - queries.global_ctxt().unwrap().enter(|tcx| { - rustc_smir::rustc_internal::run(tcx, || test_stable_mir(tcx)); - }); - // No need to keep going. - Compilation::Stop - } + rustc_internal::StableMir::new(args, test_stable_mir).run(); } fn generate_input(path: &str) -> std::io::Result<()> { diff --git a/tests/ui/layout/layout-cycle.rs b/tests/ui/layout/layout-cycle.rs new file mode 100644 index 00000000000..85685058e49 --- /dev/null +++ b/tests/ui/layout/layout-cycle.rs @@ -0,0 +1,31 @@ +// build-fail +//~^ ERROR: a cycle occurred during layout computation +//~| ERROR: cycle detected when computing layout of + +// Issue #111176 -- ensure that we do not emit ICE on layout cycles + +use std::mem; + +pub struct S { + pub f: ::I, +} + +pub trait Tr { + type I: Tr; +} + +impl Tr for S { + type I = S>; +} + +impl Tr for () { + type I = (); +} + +fn foo() -> usize { + mem::size_of::>() +} + +fn main() { + println!("{}", foo::>()); +} diff --git a/tests/ui/layout/layout-cycle.stderr b/tests/ui/layout/layout-cycle.stderr new file mode 100644 index 00000000000..a3cdb7edcc2 --- /dev/null +++ b/tests/ui/layout/layout-cycle.stderr @@ -0,0 +1,11 @@ +error[E0391]: cycle detected when computing layout of `S>` + | + = note: ...which requires computing layout of ` as Tr>::I`... + = note: ...which again requires computing layout of `S>`, completing the cycle + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: failed to get layout for S>: a cycle occurred during layout computation + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0391`.