diff options
101 files changed, 466 insertions, 525 deletions
diff --git a/Cargo.lock b/Cargo.lock index e67fe08feec..014e14e5399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3245,6 +3245,7 @@ dependencies = [ "rustc_driver", "rustc_driver_impl", "rustc_smir", + "stable_mir", ] [[package]] @@ -4409,7 +4410,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "scoped-tls", + "stable_mir", "tracing", ] @@ -4947,6 +4948,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] +name = "stable_mir" +version = "0.1.0-preview" +dependencies = [ + "scoped-tls", + "tracing", +] + +[[package]] name = "stacker" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 41003ad83f3..dcb165f9fdb 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -13,6 +13,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } # Make sure rustc_smir ends up in the sysroot, because this # crate is intended to be used by stable MIR consumers, which are not in-tree rustc_smir = { path = "../rustc_smir" } +stable_mir = { path = "../stable_mir" } [dependencies.jemalloc-sys] version = "0.5.0" diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5b172b863ab..85ab5e7223b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1664,7 +1664,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lifetime.ident, )); - // Now make an arg that we can use for the substs of the opaque tykind. + // Now make an arg that we can use for the generic params of the opaque tykind. let id = self.next_node_id(); let lifetime_arg = self.new_named_lifetime_with_res(id, lifetime.ident, res); let duplicated_lifetime_def_id = self.local_def_id(duplicated_lifetime_node_id); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 30b47d076e2..55d581b3ab1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -27,7 +27,7 @@ pub(crate) struct RegionName { /// This helps to print the right kinds of diagnostics. #[derive(Debug, Clone)] pub(crate) enum RegionNameSource { - /// A bound (not free) region that was substituted at the def site (not an HRTB). + /// A bound (not free) region that was instantiated at the def site (not an HRTB). NamedEarlyBoundRegion(Span), /// A free region that the user has a name (`'a`) for. NamedFreeRegion(Span), @@ -516,7 +516,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // be the same as those of the ADT. // FIXME: We should be able to do something similar to // match_adt_and_segment in this case. - Res::Def(DefKind::TyAlias { .. }, _) => (), + Res::Def(DefKind::TyAlias, _) => (), _ => { if let Some(last_segment) = path.segments.last() { if let Some(highlight) = self.match_adt_and_segment( @@ -619,7 +619,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // programs, so we need to use delay_span_bug here. See #82126. self.infcx.tcx.sess.delay_span_bug( hir_arg.span(), - format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"), + format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"), ); } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 1049e7a8bbe..852935676b6 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2250,7 +2250,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { // Query canonicalization can create local superuniverses (for example in - // `InferCtx::query_response_substitution_guess`), but they don't have an associated + // `InferCtx::query_response_instantiation_guess`), but they don't have an associated // `UniverseInfo` explaining why they were created. // This can cause ICEs if these causes are accessed in diagnostics, for example in issue // #114907 where this happens via liveness and dropck outlives results. diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index aa750dd0169..9b952f3fe36 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1007,7 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } pub(super) fn register_predefined_opaques_in_new_solver(&mut self) { - // OK to use the identity substitutions for each opaque type key, since + // OK to use the identity arguments for each opaque type key, since // we remap opaques from HIR typeck back to their definition params. let opaques: Vec<_> = self .infcx diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index e00299bad66..af437f36b9f 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -639,10 +639,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { }; let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); - let subst_mapping = - iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var())); + let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var())); - UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static } + UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static } } fn compute_inputs_and_output( diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs index f782671fe36..03912b18ea5 100755 --- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs +++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs @@ -100,9 +100,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { stack = &stack[..index + ENCODE_METADATA.len()]; } - const SUBST_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions"; - if let Some(index) = stack.find(SUBST_AND_NORMALIZE_ERASING_REGIONS) { - stack = &stack[..index + SUBST_AND_NORMALIZE_ERASING_REGIONS.len()]; + const INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::instantiate_and_normalize_erasing_regions"; + if let Some(index) = stack.find(INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS) { + stack = &stack[..index + INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS.len()]; } const NORMALIZE_ERASING_LATE_BOUND_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::normalize_erasing_late_bound_regions"; diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index ec2da39398b..359b430b4e5 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -359,7 +359,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { where T: TypeFoldable<TyCtxt<'tcx>> + Copy, { - self.instance.subst_mir_and_normalize_erasing_regions( + self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, ty::ParamEnv::reveal_all(), ty::EarlyBinder::bind(value), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 5ca2942ac4e..aff764f0224 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -90,7 +90,7 @@ fn make_mir_scope<'ll, 'tcx>( Some((callee, _)) => { // FIXME(eddyb) this would be `self.monomorphize(&callee)` // if this is moved to `rustc_codegen_ssa::mir::debuginfo`. - let callee = cx.tcx.subst_and_normalize_erasing_regions( + let callee = cx.tcx.instantiate_and_normalize_erasing_regions( instance.args, ty::ParamEnv::reveal_all(), ty::EarlyBinder::bind(callee), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index c862acdc7de..30cc9ea9b82 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) { // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { - let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions( + let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions( instance.args, ty::ParamEnv::reveal_all(), cx.tcx.type_of(impl_def_id), diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 1e905a7c78e..a61018f9870 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { T: Copy + TypeFoldable<TyCtxt<'tcx>>, { debug!("monomorphize: self.instance={:?}", self.instance); - self.instance.subst_mir_and_normalize_erasing_regions( + self.instance.instantiate_mir_and_normalize_erasing_regions( self.cx.tcx(), ty::ParamEnv::reveal_all(), ty::EarlyBinder::bind(value), diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 9205acc527e..0ab2b7ecd9c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -135,15 +135,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { assert_eq!(alloc_align, layout.align.abi); let read_scalar = |start, size, s: abi::Scalar, ty| { - let val = alloc - .0 - .read_scalar( - bx, - alloc_range(start, size), - /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)), - ) - .unwrap(); - bx.scalar_to_backend(val, s, ty) + match alloc.0.read_scalar( + bx, + alloc_range(start, size), + /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)), + ) { + Ok(val) => bx.scalar_to_backend(val, s, ty), + Err(_) => bx.const_poison(ty), + } }; // It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point. @@ -156,7 +155,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => { let size = s.size(bx); assert_eq!(size, layout.size, "abi::Scalar size does not match layout size"); - let val = read_scalar(Size::ZERO, size, s, bx.type_ptr()); + let val = read_scalar(offset, size, s, bx.backend_type(layout)); OperandRef { val: OperandValue::Immediate(val), layout } } Abi::ScalarPair( @@ -164,10 +163,10 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { b @ abi::Scalar::Initialized { .. }, ) => { let (a_size, b_size) = (a.size(bx), b.size(bx)); - let b_offset = a_size.align_to(b.align(bx).abi); + let b_offset = (offset + a_size).align_to(b.align(bx).abi); assert!(b_offset.bytes() > 0); let a_val = read_scalar( - Size::ZERO, + offset, a_size, a, bx.scalar_pair_element_backend_type(layout, 0, true), diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 7c743a21d93..94a5cc67d31 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -569,7 +569,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> Result<T, ErrorHandled> { frame .instance - .try_subst_mir_and_normalize_erasing_regions( + .try_instantiate_mir_and_normalize_erasing_regions( *self.tcx, self.param_env, ty::EarlyBinder::bind(value), diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index b3319442388..eb639ded70f 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -4,7 +4,7 @@ use rustc_middle::ty::{ }; use std::ops::ControlFlow; -/// Checks whether a type contains generic parameters which require substitution. +/// Checks whether a type contains generic parameters which must be instantiated. /// /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization /// types may be "concrete enough" even though they still contain generic parameters in @@ -43,7 +43,8 @@ where .try_into() .expect("more generic parameters than can fit into a `u32`"); // Only recurse when generic parameters in fns, closures and generators - // are used and require substitution. + // are used and have to be instantiated. + // // Just in case there are closures or generators within this subst, // recurse. if unused_params.is_used(index) && subst.has_param() { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 2f5f2ad6534..0d8733070a4 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -558,8 +558,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { } } -/// A faster version of the validation pass that only checks those things which may break when apply -/// generic substitutions. +/// A faster version of the validation pass that only checks those things which may break when +/// instantiating any generic parameters. pub fn validate_types<'tcx>( tcx: TyCtxt<'tcx>, mir_phase: MirPhase, diff --git a/compiler/rustc_error_codes/src/error_codes/E0038.md b/compiler/rustc_error_codes/src/error_codes/E0038.md index 584b78554ef..8f8eabb1519 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0038.md +++ b/compiler/rustc_error_codes/src/error_codes/E0038.md @@ -162,14 +162,13 @@ fn foo<T>(x: T) { ``` The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any -other type substitution is different. Hence the compiler generates the +other instantiation is different. Hence the compiler generates the implementation on-demand. If you call `foo()` with a `bool` parameter, the compiler will only generate code for `foo::<bool>()`. When we have additional type parameters, the number of monomorphized implementations the compiler generates does not grow drastically, since the compiler will only generate an -implementation if the function is called with unparameterized substitutions -(i.e., substitutions where none of the substituted types are themselves -parameterized). +implementation if the function is called with fully concrete arguments +(i.e., arguments which do not contain any generic parameters). However, with trait objects we have to make a table containing _every_ object that implements the trait. Now, if it has type parameters, we need to add diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 64271309664..3a4eb90f7f9 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -61,9 +61,7 @@ pub enum DefKind { Variant, Trait, /// Type alias: `type Foo = Bar;` - TyAlias { - lazy: bool, - }, + TyAlias, /// Type from an `extern` block. ForeignTy, /// Trait alias: `trait IntIterator = Iterator<Item = i32>;` @@ -143,7 +141,7 @@ impl DefKind { DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", DefKind::OpaqueTy => "opaque type", - DefKind::TyAlias { .. } => "type alias", + DefKind::TyAlias => "type alias", DefKind::TraitAlias => "trait alias", DefKind::AssocTy => "associated type", DefKind::Union => "union", @@ -199,7 +197,7 @@ impl DefKind { | DefKind::Variant | DefKind::Trait | DefKind::OpaqueTy - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy @@ -250,7 +248,7 @@ impl DefKind { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 644c4d8265d..0d65ddb5642 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -101,7 +101,7 @@ impl Target { DefKind::Mod => Target::Mod, DefKind::ForeignMod => Target::ForeignMod, DefKind::GlobalAsm => Target::GlobalAsm, - DefKind::TyAlias { .. } => Target::TyAlias, + DefKind::TyAlias => Target::TyAlias, DefKind::OpaqueTy => Target::OpaqueTy, DefKind::Enum => Target::Enum, DefKind::Struct => Target::Struct, diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index ba152cd48de..21611e9c586 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -427,7 +427,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { let bound_vars = tcx.late_bound_vars(binding.hir_id); ty::Binder::bind_with_vars(subst_output, bound_vars) } else { - // Include substitutions for generic parameters of associated types + // Append the generic arguments of the associated type to the `trait_ref`. candidate.map_bound(|trait_ref| { let ident = Ident::new(assoc_item.name, binding.item_name.span); let item_segment = hir::PathSegment { diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 1372cc896be..e3621ef933a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -139,22 +139,22 @@ fn generic_arg_mismatch_err( err.emit() } -/// Creates the relevant generic argument substitutions +/// Creates the relevant generic arguments /// corresponding to a set of generic parameters. This is a /// rather complex function. Let us try to explain the role /// of each of its parameters: /// -/// To start, we are given the `def_id` of the thing we are -/// creating the substitutions for, and a partial set of -/// substitutions `parent_args`. In general, the substitutions -/// for an item begin with substitutions for all the "parents" of +/// To start, we are given the `def_id` of the thing whose generic +/// parameters we are instantiating, and a partial set of +/// arguments `parent_args`. In general, the generic arguments +/// for an item begin with arguments for all the "parents" of /// that item -- e.g., for a method it might include the /// parameters from the impl. /// /// Therefore, the method begins by walking down these parents, /// starting with the outermost parent and proceed inwards until /// it reaches `def_id`. For each parent `P`, it will check `parent_args` -/// first to see if the parent's substitutions are listed in there. If so, +/// first to see if the parent's arguments are listed in there. If so, /// we can append those and move on. Otherwise, it invokes the /// three callback functions: /// @@ -188,7 +188,7 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>( stack.push((def_id, parent_defs)); } - // We manually build up the substitution, rather than using convenience + // We manually build up the generic arguments, rather than using convenience // methods in `subst.rs`, so that we can iterate over the arguments and // parameters in lock-step linearly, instead of trying to match each pair. let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count); @@ -196,7 +196,8 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>( while let Some((def_id, defs)) = stack.pop() { let mut params = defs.params.iter().peekable(); - // If we have already computed substitutions for parents, we can use those directly. + // If we have already computed the generic arguments for parents, + // we can use those directly. while let Some(¶m) = params.peek() { if let Some(&kind) = parent_args.get(param.index as usize) { args.push(kind); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 106cd223d30..56b1fd36973 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -289,7 +289,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`, - /// returns an appropriate set of substitutions for this particular reference to `I`. + /// returns an appropriate set of generic arguments for this particular reference to `I`. pub fn ast_path_args_for_ty( &self, span: Span, @@ -315,7 +315,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// Given the type/lifetime/const arguments provided to some path (along with /// an implicit `Self`, if this is a trait reference), returns the complete - /// set of substitutions. This may involve applying defaulted type parameters. + /// set of generic arguments. This may involve applying defaulted type parameters. /// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`. /// /// Example: @@ -909,23 +909,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let args = self.ast_path_args_for_ty(span, did, item_segment); - if let DefKind::TyAlias { lazy: true } = tcx.def_kind(did) { + if let DefKind::TyAlias = tcx.def_kind(did) + && tcx.type_alias_is_lazy(did) + { // Type aliases defined in crates that have the // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will // then actually instantiate the where bounds of. let alias_ty = tcx.mk_alias_ty(did, args); Ty::new_alias(tcx, ty::Weak, alias_ty) } else { - let ty = tcx.at(span).type_of(did); - if ty.skip_binder().has_opaque_types() { - // Type aliases referring to types that contain opaque types (but aren't just directly - // referencing a single opaque type) get encoded as a type alias that normalization will - // then actually instantiate the where bounds of. - let alias_ty = tcx.mk_alias_ty(did, args); - Ty::new_alias(tcx, ty::Weak, alias_ty) - } else { - ty.instantiate(tcx, args) - } + tcx.at(span).type_of(did).instantiate(tcx, args) } } @@ -2164,7 +2157,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::Def( DefKind::Enum - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::Struct | DefKind::Union | DefKind::ForeignTy, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 564206f9e4b..eb1f48d23ff 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -640,7 +640,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { check_opaque(tcx, id); } } - DefKind::TyAlias { .. } => { + DefKind::TyAlias => { let pty_ty = tcx.type_of(id.owner_id).instantiate_identity(); let generics = tcx.generics_of(id.owner_id); check_type_params_are_used(tcx, &generics, pty_ty); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 00a684f2963..b7b162ce27b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -246,9 +246,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { // `ForeignItem`s are handled separately. hir::ItemKind::ForeignMod { .. } => {} hir::ItemKind::TyAlias(hir_ty, ast_generics) => { - if tcx.features().lazy_type_alias - || tcx.type_of(item.owner_id).skip_binder().has_opaque_types() - { + if tcx.type_alias_is_lazy(item.owner_id) { // Bounds of lazy type aliases and of eager ones that contain opaque types are respected. // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`. check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow); @@ -1711,10 +1709,8 @@ fn check_variances_for_type_defn<'tcx>( } } ItemKind::TyAlias(..) => { - let ty = tcx.type_of(item.owner_id).instantiate_identity(); - - if tcx.features().lazy_type_alias || ty.has_opaque_types() { - if ty.references_error() { + if tcx.type_alias_is_lazy(item.owner_id) { + if tcx.type_of(item.owner_id).skip_binder().references_error() { return; } } else { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 01e40c62a8b..cd37221ae6f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -58,6 +58,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { type_of: type_of::type_of, type_of_opaque: type_of::type_of_opaque, + type_alias_is_lazy: type_of::type_alias_is_lazy, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, generics_of: generics_of::generics_of, diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index d9207f2de52..eb4466449a0 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1519,7 +1519,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { DefKind::Struct | DefKind::Union | DefKind::Enum - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::Trait, def_id, ) if depth == 0 => Some(def_id), @@ -2029,7 +2029,7 @@ fn is_late_bound_map( hir::TyKind::Path(hir::QPath::Resolved( None, - hir::Path { res: Res::Def(DefKind::TyAlias { .. }, alias_def), segments, span }, + hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span }, )) => { // See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider // args to be unconstrained. diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index d12337687e2..ae62119b182 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -623,3 +623,25 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) { .emit(); } } + +pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { + use hir::intravisit::Visitor; + if tcx.features().lazy_type_alias { + return true; + } + struct HasTait { + has_type_alias_impl_trait: bool, + } + impl<'tcx> Visitor<'tcx> for HasTait { + fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { + if let hir::TyKind::OpaqueDef(..) = t.kind { + self.has_type_alias_impl_trait = true; + } else { + hir::intravisit::walk_ty(self, t); + } + } + } + let mut has_tait = HasTait { has_type_alias_impl_trait: false }; + has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0); + has_tait.has_type_alias_impl_trait +} diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 9aac7160f2e..61d9c989e2f 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -6,7 +6,7 @@ use hir::def_id::{DefId, LocalDefId}; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; use super::terms::VarianceTerm::*; @@ -78,9 +78,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>( } } DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id), - DefKind::TyAlias { lazy } - if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() => - { + DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => { constraint_cx.build_constraints_for_item(def_id) } _ => {} @@ -110,8 +108,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // The type as returned by `type_of` is the underlying type and generally not a weak projection. // Therefore we need to check the `DefKind` first. - if let DefKind::TyAlias { lazy } = tcx.def_kind(def_id) - && (lazy || ty.has_opaque_types()) + if let DefKind::TyAlias = tcx.def_kind(def_id) + && tcx.type_alias_is_lazy(def_id) { self.add_constraints_from_ty(current_item, ty, self.covariant); return; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index d69d7ff904a..85e0000ab47 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt}; -use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable}; use std::ops::ControlFlow; /// Defines the `TermsContext` basically houses an arena where we can @@ -56,9 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { let crate_map = tcx.crate_variances(()); return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]); } - DefKind::TyAlias { lazy } - if lazy || tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() => - { + DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => { // These are inferred. let crate_map = tcx.crate_variances(()); return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]); diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs index 1a8ec5f0853..275df24956c 100644 --- a/compiler/rustc_hir_analysis/src/variance/terms.rs +++ b/compiler/rustc_hir_analysis/src/variance/terms.rs @@ -12,7 +12,7 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, LocalDefIdMap}; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, TyCtxt}; use std::fmt; use self::VarianceTerm::*; @@ -97,9 +97,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>( } } DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id), - DefKind::TyAlias { lazy } - if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() => - { + DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => { terms_cx.add_inferreds_for_item(def_id) } _ => {} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 37ea94d821e..c0332a48be3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1370,10 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => bug!("unexpected type: {:?}", ty.normalized), }, - Res::Def( - DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy, - _, - ) + Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() { Some(adt) if !adt.is_enum() => { diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 7fb1dc2347e..337d12b2d51 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -464,7 +464,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { // Opaque types can't have field projections, but we can instead convert // the current place in-place (heh) to the hidden type, and then apply all // follow up projections on that. - if node_ty != place_ty && place_ty.has_opaque_types() { + if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) { projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); } projections.push(Projection { kind, ty }); @@ -557,10 +557,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id)) } Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _) - | Res::Def( - DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy, - _, - ) + | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) | Res::SelfCtor(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index bcaa4091c3a..a9029a8cec0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -918,7 +918,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { // // See the `need_type_info/issue-103053.rs` test for // a example. - if !matches!(path.res, Res::Def(DefKind::TyAlias { .. }, _)) => { + if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => { if let Some(ty) = self.opt_node_type(expr.hir_id) && let ty::Adt(_, args) = ty.kind() { @@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { ) => { if tcx.res_generics_def_id(path.res) != Some(def.did()) { match path.res { - Res::Def(DefKind::TyAlias { .. }, _) => { + Res::Def(DefKind::TyAlias, _) => { // FIXME: Ideally we should support this. For that // we have to map back from the self type to the // type alias though. That's difficult. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 4f6b79d9aee..536f78a73ed 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1454,13 +1454,13 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return }; - if cx.tcx.features().lazy_type_alias { - // Bounds of lazy type aliases are respected. + // Bounds of lazy type aliases and TAITs are respected. + if cx.tcx.type_alias_is_lazy(item.owner_id) { return; } let ty = cx.tcx.type_of(item.owner_id).skip_binder(); - if ty.has_opaque_types() || ty.has_inherent_projections() { + if ty.has_inherent_projections() { // Bounds of type aliases that contain opaque types or inherent projections are respected. // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X = Type::Inherent;`. return; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index b56fe375849..f27eee0d79a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -210,6 +210,7 @@ provide! { tcx, def_id, other, cdata, inferred_outlives_of => { table_defaulted_array } super_predicates_of => { table } type_of => { table } + type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) } variances_of => { table } fn_sig => { table } codegen_fn_attrs => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 7506fc1bb05..a4ba943275e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -31,7 +31,6 @@ use rustc_middle::query::Providers; use rustc_middle::traits::specialization_graph; use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; -use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, AssocItemContainer, SymbolName, Ty, TyCtxt}; use rustc_middle::util::common::to_readable_str; use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; @@ -827,7 +826,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy @@ -862,7 +861,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy @@ -903,7 +902,7 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool { | DefKind::Variant | DefKind::Trait | DefKind::Impl { .. } => true, - DefKind::TyAlias { .. } + DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy @@ -938,7 +937,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy @@ -982,7 +981,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool { | DefKind::Const | DefKind::Fn | DefKind::ForeignMod - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::Enum | DefKind::Union @@ -1092,9 +1091,7 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def | DefKind::Closure | DefKind::Generator | DefKind::ExternCrate => false, - DefKind::TyAlias { lazy } => { - lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() - } + DefKind::TyAlias => tcx.type_alias_is_lazy(def_id), } } @@ -1105,7 +1102,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy @@ -1145,7 +1142,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::Fn | DefKind::Const | DefKind::Static(..) - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::Impl { .. } | DefKind::AssocFn @@ -1205,7 +1202,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool { | DefKind::Const | DefKind::Static(..) | DefKind::Ctor(..) - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::ForeignTy | DefKind::Impl { .. } @@ -1246,7 +1243,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool { | DefKind::AssocConst | DefKind::AnonConst | DefKind::Static(..) - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::Impl { of_trait: false } | DefKind::ForeignTy @@ -1279,7 +1276,7 @@ fn should_encode_const(def_kind: DefKind) -> bool { | DefKind::Field | DefKind::Fn | DefKind::Static(..) - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::ForeignTy | DefKind::Impl { .. } @@ -1451,6 +1448,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Macro(_) = def_kind { self.encode_info_for_macro(local_id); } + if let DefKind::TyAlias = def_kind { + self.tables + .type_alias_is_lazy + .set(def_id.index, self.tcx.type_alias_is_lazy(def_id)); + } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); self.tables diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 09b2a1a0cb2..42764af52c4 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -383,6 +383,7 @@ define_tables! { is_intrinsic: Table<DefIndex, bool>, is_macro_rules: Table<DefIndex, bool>, is_type_alias_impl_trait: Table<DefIndex, bool>, + type_alias_is_lazy: Table<DefIndex, bool>, attr_flags: Table<DefIndex, AttrFlags>, def_path_hashes: Table<DefIndex, DefPathHash>, explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index d105dab4814..bb1320942b0 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -145,8 +145,7 @@ fixed_size_enum! { ( Enum ) ( Variant ) ( Trait ) - ( TyAlias { lazy: false } ) - ( TyAlias { lazy: true } ) + ( TyAlias ) ( ForeignTy ) ( TraitAlias ) ( AssocTy ) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 3491c487f3e..4af2d83e9c7 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -196,9 +196,7 @@ impl<'hir> Map<'hir> { ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind), ItemKind::Mod(..) => DefKind::Mod, ItemKind::OpaqueTy(..) => DefKind::OpaqueTy, - ItemKind::TyAlias(..) => { - DefKind::TyAlias { lazy: self.tcx.features().lazy_type_alias } - } + ItemKind::TyAlias(..) => DefKind::TyAlias, ItemKind::Enum(..) => DefKind::Enum, ItemKind::Struct(..) => DefKind::Struct, ItemKind::Union(..) => DefKind::Union, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5986a8b1cd8..340c5a769db 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -229,7 +229,7 @@ rustc_queries! { action = { use rustc_hir::def::DefKind; match tcx.def_kind(key) { - DefKind::TyAlias { .. } => "expanding type alias", + DefKind::TyAlias => "expanding type alias", DefKind::TraitAlias => "expanding trait alias", _ => "computing type of", } @@ -251,6 +251,14 @@ rustc_queries! { } } + query type_alias_is_lazy(key: DefId) -> bool { + desc { |tcx| + "computing whether `{path}` is a lazy type alias", + path = tcx.def_path_str(key), + } + separate_provide_extern + } + query collect_return_position_impl_trait_in_trait_tys(key: DefId) -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 219927f5ab4..f50969dd967 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -448,7 +448,7 @@ impl<'tcx> AdtDef<'tcx> { Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid), Res::Def(DefKind::Struct, _) | Res::Def(DefKind::Union, _) - | Res::Def(DefKind::TyAlias { .. }, _) + | Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssocTy, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a7dd6dc737d..c06b8b2dfa0 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1114,7 +1114,7 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) && let hir::TyKind::Path(hir::QPath::Resolved( None, - hir::Path { res: hir::def::Res::Def(DefKind::TyAlias { .. }, def_id), .. }, )) = hir_output.kind + hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind && let Some(local_id) = def_id.as_local() && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics() diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index e7ebb985ca4..f03813a459b 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -493,7 +493,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> { Alias(Opaque, AliasTy { def_id, .. }) => { let parent = self.tcx.parent(def_id); let parent_ty = self.tcx.type_of(parent).instantiate_identity(); - if let DefKind::TyAlias { .. } | DefKind::AssocTy = self.tcx.def_kind(parent) + if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent) && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind() && parent_opaque_def_id == def_id { @@ -577,7 +577,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> { Alias(Opaque, AliasTy { def_id, .. }) => { let parent = self.tcx.parent(def_id); let parent_ty = self.tcx.type_of(parent).instantiate_identity(); - if let hir::def::DefKind::TyAlias { .. } | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent) + if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent) && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind() && parent_opaque_def_id == def_id { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 2b75f6c4e8f..0b0a708e42b 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -118,7 +118,7 @@ impl<'tcx> Instance<'tcx> { /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.subst_and_normalize_erasing_regions(self.args, param_env, ty) + tcx.instantiate_and_normalize_erasing_regions(self.args, param_env, ty) } /// Finds a crate that contains a monomorphization of this instance that @@ -580,7 +580,7 @@ impl<'tcx> Instance<'tcx> { self.def.has_polymorphic_mir_body().then_some(self.args) } - pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T + pub fn instantiate_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T where T: TypeFoldable<TyCtxt<'tcx>> + Copy, { @@ -593,7 +593,7 @@ impl<'tcx> Instance<'tcx> { } #[inline(always)] - pub fn subst_mir_and_normalize_erasing_regions<T>( + pub fn instantiate_mir_and_normalize_erasing_regions<T>( &self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -603,14 +603,14 @@ impl<'tcx> Instance<'tcx> { T: TypeFoldable<TyCtxt<'tcx>> + Clone, { if let Some(args) = self.args_for_mir_body() { - tcx.subst_and_normalize_erasing_regions(args, param_env, v) + tcx.instantiate_and_normalize_erasing_regions(args, param_env, v) } else { tcx.normalize_erasing_regions(param_env, v.skip_binder()) } } #[inline(always)] - pub fn try_subst_mir_and_normalize_erasing_regions<T>( + pub fn try_instantiate_mir_and_normalize_erasing_regions<T>( &self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -620,7 +620,7 @@ impl<'tcx> Instance<'tcx> { T: TypeFoldable<TyCtxt<'tcx>> + Clone, { if let Some(args) = self.args_for_mir_body() { - tcx.try_subst_and_normalize_erasing_regions(args, param_env, v) + tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v) } else { tcx.try_normalize_erasing_regions(param_env, v.skip_binder()) } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 2415d50b278..fd125af2074 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -134,8 +134,9 @@ impl<'tcx> TyCtxt<'tcx> { /// in-scope substitutions and then normalizing any associated /// types. /// Panics if normalization fails. In case normalization might fail - /// use `try_subst_and_normalize_erasing_regions` instead. - pub fn subst_and_normalize_erasing_regions<T>( + /// use `try_instantiate_and_normalize_erasing_regions` instead. + #[instrument(level = "debug", skip(self))] + pub fn instantiate_and_normalize_erasing_regions<T>( self, param_args: GenericArgsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -144,22 +145,16 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<TyCtxt<'tcx>>, { - debug!( - "subst_and_normalize_erasing_regions(\ - param_args={:?}, \ - value={:?}, \ - param_env={:?})", - param_args, value, param_env, - ); let substituted = value.instantiate(self, param_args); self.normalize_erasing_regions(param_env, substituted) } /// Monomorphizes a type from the AST by first applying the /// in-scope substitutions and then trying to normalize any associated - /// types. Contrary to `subst_and_normalize_erasing_regions` this does + /// types. Contrary to `instantiate_and_normalize_erasing_regions` this does /// not assume that normalization succeeds. - pub fn try_subst_and_normalize_erasing_regions<T>( + #[instrument(level = "debug", skip(self))] + pub fn try_instantiate_and_normalize_erasing_regions<T>( self, param_args: GenericArgsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -168,13 +163,6 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<TyCtxt<'tcx>>, { - debug!( - "subst_and_normalize_erasing_regions(\ - param_args={:?}, \ - value={:?}, \ - param_env={:?})", - param_args, value, param_env, - ); let substituted = value.instantiate(self, param_args); self.try_normalize_erasing_regions(param_env, substituted) } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 99dc0b2607e..2d7350387ca 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -360,7 +360,7 @@ pub trait PrettyPrinter<'tcx>: self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?; self.write_str("::")?; } else if let DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Trait - | DefKind::TyAlias { .. } | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind + | DefKind::TyAlias | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind { } else { // If not covered above, like for example items out of `impl` blocks, fallback. @@ -766,7 +766,7 @@ pub trait PrettyPrinter<'tcx>: let parent = self.tcx().parent(def_id); match self.tcx().def_kind(parent) { - DefKind::TyAlias { .. } | DefKind::AssocTy => { + DefKind::TyAlias | DefKind::AssocTy => { // NOTE: I know we should check for NO_QUERIES here, but it's alright. // `type_of` on a type alias or assoc type should never cause a cycle. if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) = @@ -2998,7 +2998,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N match child.res { def::Res::Def(DefKind::AssocTy, _) => {} - def::Res::Def(DefKind::TyAlias { .. }, _) => {} + def::Res::Def(DefKind::TyAlias, _) => {} def::Res::Def(defkind, def_id) => { if let Some(ns) = defkind.ns() { collect_fn(&child.ident, ns, def_id); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c823c4c2b57..1e57392e0e7 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1223,7 +1223,7 @@ impl<'tcx> AliasTy<'tcx> { DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent, DefKind::AssocTy => ty::Projection, DefKind::OpaqueTy => ty::Opaque, - DefKind::TyAlias { .. } => ty::Weak, + DefKind::TyAlias => ty::Weak, kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), } } @@ -1959,7 +1959,7 @@ impl<'tcx> Ty<'tcx> { (kind, tcx.def_kind(alias_ty.def_id)), (ty::Opaque, DefKind::OpaqueTy) | (ty::Projection | ty::Inherent, DefKind::AssocTy) - | (ty::Weak, DefKind::TyAlias { .. }) + | (ty::Weak, DefKind::TyAlias) ); Ty::new(tcx, Alias(kind, alias_ty)) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 0dda7cd83be..31b52677b27 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -156,7 +156,7 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::Enum | DefKind::Trait | DefKind::OpaqueTy - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index dec06363380..578d8e7a975 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -217,7 +217,7 @@ fn find_item_ty_spans( match ty.kind { hir::TyKind::Path(hir::QPath::Resolved(_, path)) => { if let Res::Def(kind, def_id) = path.res - && !matches!(kind, DefKind::TyAlias { .. }) { + && !matches!(kind, DefKind::TyAlias) { let check_params = def_id.as_local().map_or(true, |def_id| { if def_id == needle { spans.push(ty.span); diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index f1f75c26717..fe47a1cd78c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -439,7 +439,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { DefKind::Struct | DefKind::Ctor(CtorOf::Struct, ..) | DefKind::Union - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::AssocTy, _, ) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 1d9c89477cb..ebd61f8ad95 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -193,7 +193,7 @@ impl<'tcx> Inliner<'tcx> { return Err("optimization fuel exhausted"); } - let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions( + let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions( self.tcx, self.param_env, ty::EarlyBinder::bind(callee_body.clone()), @@ -481,9 +481,10 @@ impl<'tcx> Inliner<'tcx> { work_list.push(target); // If the place doesn't actually need dropping, treat it like a regular goto. - let ty = callsite - .callee - .subst_mir(self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty)); + let ty = callsite.callee.instantiate_mir( + self.tcx, + ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty), + ); if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind { work_list.push(unwind); } @@ -650,7 +651,7 @@ impl<'tcx> Inliner<'tcx> { // Copy only unevaluated constants from the callee_body into the caller_body. // Although we are only pushing `ConstKind::Unevaluated` consts to // `required_consts`, here we may not only have `ConstKind::Unevaluated` - // because we are calling `subst_and_normalize_erasing_regions`. + // because we are calling `instantiate_and_normalize_erasing_regions`. caller_body.required_consts.extend( callee_body.required_consts.iter().copied().filter(|&ct| match ct.const_ { Const::Ty(_) => { @@ -811,9 +812,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { match terminator.kind { TerminatorKind::Drop { ref place, unwind, .. } => { // If the place doesn't actually need dropping, treat it like a regular goto. - let ty = self - .instance - .subst_mir(tcx, ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty)); + let ty = self.instance.instantiate_mir( + tcx, + ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty), + ); if ty.needs_drop(tcx, self.param_env) { self.cost += CALL_PENALTY; if let UnwindAction::Cleanup(_) = unwind { @@ -824,7 +826,8 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } } TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => { - let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty())); + let fn_ty = + self.instance.instantiate_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty())); self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) { // Don't give intrinsics the extra penalty for calls INSTR_COST diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 822634129fc..d30e0bad813 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -44,7 +44,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( ) -> bool { trace!(%caller); for &(callee, args) in tcx.mir_inliner_callees(caller.def) { - let Ok(args) = caller.try_subst_mir_and_normalize_erasing_regions( + let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions( tcx, param_env, ty::EarlyBinder::bind(args), diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index b7a51cfd619..2795cf15702 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -29,6 +29,7 @@ use crate::MirPass; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_index::bit_set::BitSet; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; @@ -345,24 +346,22 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let basic_blocks = body.basic_blocks.as_mut(); let source_scopes = &body.source_scopes; - let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); - let mut used_blocks = 0; - for alive_index in reachable.iter() { - let alive_index = alive_index.index(); - replacements[alive_index] = BasicBlock::new(used_blocks); - if alive_index != used_blocks { - // Swap the next alive block data with the current available slot. Since - // alive_index is non-decreasing this is a valid operation. - basic_blocks.raw.swap(alive_index, used_blocks); - } - used_blocks += 1; - } - if tcx.sess.instrument_coverage() { - save_unreachable_coverage(basic_blocks, source_scopes, used_blocks); + save_unreachable_coverage(basic_blocks, source_scopes, &reachable); } - basic_blocks.raw.truncate(used_blocks); + let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); + let mut orig_index = 0; + let mut used_index = 0; + basic_blocks.raw.retain(|_| { + let keep = reachable.contains(BasicBlock::new(orig_index)); + if keep { + replacements[orig_index] = BasicBlock::new(used_index); + used_index += 1; + } + orig_index += 1; + keep + }); for block in basic_blocks { for target in block.terminator_mut().successors_mut() { @@ -404,11 +403,12 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn save_unreachable_coverage( basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'_>>, source_scopes: &IndexSlice<SourceScope, SourceScopeData<'_>>, - first_dead_block: usize, + reachable: &BitSet<BasicBlock>, ) { // Identify instances that still have some live coverage counters left. let mut live = FxHashSet::default(); - for basic_block in &basic_blocks.raw[0..first_dead_block] { + for bb in reachable.iter() { + let basic_block = &basic_blocks[bb]; for statement in &basic_block.statements { let StatementKind::Coverage(coverage) = &statement.kind else { continue }; let CoverageKind::Counter { .. } = coverage.kind else { continue }; @@ -417,7 +417,8 @@ fn save_unreachable_coverage( } } - for block in &mut basic_blocks.raw[..first_dead_block] { + for bb in reachable.iter() { + let block = &mut basic_blocks[bb]; for statement in &mut block.statements { let StatementKind::Coverage(_) = &statement.kind else { continue }; let instance = statement.source_info.scope.inlined_instance(source_scopes); @@ -433,7 +434,11 @@ fn save_unreachable_coverage( // Retain coverage for instances that still have some live counters left. let mut retained_coverage = Vec::new(); - for dead_block in &basic_blocks.raw[first_dead_block..] { + for dead_block in basic_blocks.indices() { + if reachable.contains(dead_block) { + continue; + } + let dead_block = &basic_blocks[dead_block]; for statement in &dead_block.statements { let StatementKind::Coverage(coverage) = &statement.kind else { continue }; let Some(code_region) = &coverage.code_region else { continue }; diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index bd1724bf842..0b9311a20ef 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -13,7 +13,11 @@ pub struct UnreachablePropagation; impl MirPass<'_> for UnreachablePropagation { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { // Enable only under -Zmir-opt-level=2 as this can make programs less debuggable. - sess.mir_opt_level() >= 2 + + // FIXME(#116171) Coverage gets confused by MIR passes that can remove all + // coverage statements from an instrumented function. This pass can be + // re-enabled when coverage codegen is robust against that happening. + sess.mir_opt_level() >= 2 && !sess.instrument_coverage() } fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 4afa4e597f7..1a9f0e8352e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -606,7 +606,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { T: TypeFoldable<TyCtxt<'tcx>>, { debug!("monomorphize: self.instance={:?}", self.instance); - self.instance.subst_mir_and_normalize_erasing_regions( + self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, ty::ParamEnv::reveal_all(), ty::EarlyBinder::bind(value), diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index c993e64477b..1d8cbe0e21b 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -647,7 +647,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( // parameters, but the self-type of their impl block do will fail to normalize. if !tcx.sess.opts.unstable_opts.polymorphize || !instance.has_param() { // This is a method within an impl, find out what the self-type is: - let impl_self_ty = tcx.subst_and_normalize_erasing_regions( + let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions( instance.args, ty::ParamEnv::reveal_all(), tcx.type_of(impl_def_id), diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 0e85f35fc1b..6c206a6bac8 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -143,7 +143,7 @@ fn mark_used_by_default_parameters<'tcx>( | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index a3433d3d13d..e25c5c9f27c 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -26,12 +26,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In let ClosureSizeProfileData { before_feature_tys, after_feature_tys } = typeck_results.closure_size_eval[&closure_def_id]; - let before_feature_tys = tcx.subst_and_normalize_erasing_regions( + let before_feature_tys = tcx.instantiate_and_normalize_erasing_regions( closure_instance.args, param_env, ty::EarlyBinder::bind(before_feature_tys), ); - let after_feature_tys = tcx.subst_and_normalize_erasing_regions( + let after_feature_tys = tcx.instantiate_and_normalize_erasing_regions( closure_instance.args, param_env, ty::EarlyBinder::bind(after_feature_tys), diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 9e4d960af14..153c39977bb 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -21,7 +21,7 @@ pub fn test_abi(tcx: TyCtxt<'_>) { DefKind::Fn | DefKind::AssocFn => { dump_abi_of_fn_item(tcx, id, attr); } - DefKind::TyAlias { .. } => { + DefKind::TyAlias => { dump_abi_of_fn_type(tcx, id, attr); } _ => { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d1c3bcf3839..493daf314ce 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -96,7 +96,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn handle_res(&mut self, res: Res) { match res { - Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias { .. }, def_id) => { + Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, def_id) => { self.check_def_id(def_id); } _ if self.in_pat => {} @@ -923,7 +923,7 @@ impl<'tcx> DeadVisitor<'tcx> { | DefKind::Fn | DefKind::Static(_) | DefKind::Const - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::Enum | DefKind::Union | DefKind::ForeignTy => self.warn_dead_code(def_id, "used"), diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index e3a63f2e004..e195f9ab6da 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -23,7 +23,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) { for id in tcx.hir_crate_items(()).definitions() { for attr in tcx.get_attrs(id, sym::rustc_layout) { match tcx.def_kind(id) { - DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union => { + DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union => { dump_layout_of(tcx, id, attr); } _ => { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 2e71ac8d7dc..ab85f680fcf 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -588,7 +588,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { self.update(def_id, macro_ev, Level::Reachable); match def_kind { // No type privacy, so can be directly marked as reachable. - DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias { .. } => { + DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => { if vis.is_accessible_from(module, self.tcx) { self.update(def_id, macro_ev, Level::Reachable); } @@ -1637,8 +1637,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { let def_kind = tcx.def_kind(def_id); match def_kind { - DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias { .. } => { - if let DefKind::TyAlias { .. } = def_kind { + DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => { + if let DefKind::TyAlias = def_kind { self.check_unnameable(def_id, effective_vis); } self.check(def_id, item_visibility, effective_vis).generics().predicates().ty(); diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 2e9ebde296c..f2c1f84fccc 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -580,9 +580,7 @@ pub(crate) fn report_cycle<'a>( }); } - let alias = if stack - .iter() - .all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias { .. }))) + let alias = if stack.iter().all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias))) { Some(crate::error::Alias::Ty) } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2c36c83ae72..a18109574fe 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -698,10 +698,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { // These items live in the type namespace. ItemKind::TyAlias(..) => { - let res = Res::Def( - DefKind::TyAlias { lazy: self.r.tcx.features().lazy_type_alias }, - def_id, - ); + let res = Res::Def(DefKind::TyAlias, def_id); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } @@ -950,7 +947,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { DefKind::Struct | DefKind::Union | DefKind::Variant - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::OpaqueTy | DefKind::TraitAlias diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 01f9f060594..c3c43346ed8 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -474,7 +474,7 @@ impl<'a> PathSource<'a> { | DefKind::Enum | DefKind::Trait | DefKind::TraitAlias - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::AssocTy | DefKind::TyParam | DefKind::OpaqueTy @@ -513,7 +513,7 @@ impl<'a> PathSource<'a> { DefKind::Struct | DefKind::Union | DefKind::Variant - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::AssocTy, _, ) | Res::SelfTyParam { .. } @@ -1766,7 +1766,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) | Res::Def(DefKind::Enum, def_id) - | Res::Def(DefKind::TyAlias { .. }, def_id) + | Res::Def(DefKind::TyAlias, def_id) | Res::Def(DefKind::Trait, def_id) if i + 1 == proj_start => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 06a08f29a1e..64440a6c04e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1429,7 +1429,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => { err.span_label(span, fallback_label.to_string()); } - (Res::Def(DefKind::TyAlias { .. }, def_id), PathSource::Trait(_)) => { + (Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => { err.span_label(span, "type aliases cannot be used as traits"); if self.r.tcx.sess.is_nightly_build() { let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \ @@ -1598,7 +1598,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { err.span_label(span, fallback_label.to_string()); err.note("can't use `Self` as a constructor, you must use the implemented struct"); } - (Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, _), _) if ns == ValueNS => { + (Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => { err.note("can't use a type alias as a constructor"); } _ => return false, diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 21ec904e43c..4c29f743708 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,24 +4,14 @@ version = "0.0.0" edition = "2021" [dependencies] -# Use optional dependencies for rustc_* in order to support building this crate separately. -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} +rustc_hir = { path = "../rustc_hir" } +rustc_middle = { path = "../rustc_middle" } +rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } +rustc_driver = { path = "../rustc_driver" } +rustc_interface = { path = "../rustc_interface" } +rustc_session = {path = "../rustc_session" } tracing = "0.1" -scoped-tls = "1.0" +stable_mir = {path = "../stable_mir" } [features] -default = [ - "rustc_hir", - "rustc_middle", - "rustc_span", - "rustc_target", - "rustc_driver", - "rustc_interface", - "rustc_session", -] diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 8cb533c8d67..b6c36678db5 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -10,26 +10,12 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] -#![cfg_attr(not(feature = "default"), feature(rustc_private))] +#![feature(rustc_private)] #![feature(ptr_metadata)] #![feature(type_alias_impl_trait)] // Used to define opaque types. #![feature(intra_doc_pointers)] -// Declare extern rustc_* crates to enable building this crate separately from the compiler. -#[cfg(not(feature = "default"))] -extern crate rustc_hir; -#[cfg(not(feature = "default"))] -extern crate rustc_middle; -#[cfg(not(feature = "default"))] -extern crate rustc_span; -#[cfg(not(feature = "default"))] -extern crate rustc_target; - pub mod rustc_internal; -pub mod stable_mir; // Make this module private for now since external users should not call these directly. mod rustc_smir; - -#[macro_use] -extern crate scoped_tls; diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 10ee5af86c6..441aafd1257 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,75 +3,17 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use std::fmt::Debug; use std::ops::{ControlFlow, Index}; use crate::rustc_internal; -use crate::stable_mir::CompilerError; -use crate::{ - rustc_smir::Tables, - stable_mir::{self, with}, -}; +use crate::rustc_smir::Tables; use rustc_driver::{Callbacks, Compilation, RunCompiler}; use rustc_interface::{interface, Queries}; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::TyCtxt; pub use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Span; - -fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R { - let mut ret = None; - with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t)))); - ret.unwrap() -} - -pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { - with_tables(|t| t[item.0]) -} - -pub fn crate_item(did: DefId) -> stable_mir::CrateItem { - with_tables(|t| t.crate_item(did)) -} - -pub fn adt_def(did: DefId) -> stable_mir::ty::AdtDef { - with_tables(|t| t.adt_def(did)) -} - -pub fn foreign_def(did: DefId) -> stable_mir::ty::ForeignDef { - with_tables(|t| t.foreign_def(did)) -} - -pub fn fn_def(did: DefId) -> stable_mir::ty::FnDef { - with_tables(|t| t.fn_def(did)) -} - -pub fn closure_def(did: DefId) -> stable_mir::ty::ClosureDef { - with_tables(|t| t.closure_def(did)) -} - -pub fn generator_def(did: DefId) -> stable_mir::ty::GeneratorDef { - with_tables(|t| t.generator_def(did)) -} - -pub fn alias_def(did: DefId) -> stable_mir::ty::AliasDef { - with_tables(|t| t.alias_def(did)) -} - -pub fn param_def(did: DefId) -> stable_mir::ty::ParamDef { - with_tables(|t| t.param_def(did)) -} - -pub fn br_named_def(did: DefId) -> stable_mir::ty::BrNamedDef { - with_tables(|t| t.br_named_def(did)) -} - -pub fn trait_def(did: DefId) -> stable_mir::ty::TraitDef { - with_tables(|t| t.trait_def(did)) -} - -pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef { - with_tables(|t| t.impl_def(did)) -} +use stable_mir::CompilerError; impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> { type Output = DefId; @@ -82,6 +24,15 @@ impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> { } } +impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> { + type Output = Span; + + #[inline(always)] + fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { + &self.spans[index.0] + } +} + impl<'tcx> Tables<'tcx> { pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem { stable_mir::CrateItem(self.create_def_id(did)) @@ -178,32 +129,12 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { } pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { - crate::stable_mir::run( + stable_mir::run( Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] }, f, ); } -/// A type that provides internal information but that can still be used for debug purpose. -#[derive(Clone)] -pub struct Opaque(String); - -impl std::fmt::Display for Opaque { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl std::fmt::Debug for Opaque { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } -} - -pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque { - Opaque(format!("{value:?}")) -} - pub struct StableMir<B = (), C = ()> where B: Send, diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index d8766cf8ce2..63a2a145069 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -3,11 +3,9 @@ use rustc_middle::mir::{ ConstValue, }; -use crate::{ - rustc_smir::{Stable, Tables}, - stable_mir::mir::Mutability, - stable_mir::ty::{Allocation, ProvenanceMap}, -}; +use crate::rustc_smir::{Stable, Tables}; +use stable_mir::mir::Mutability; +use stable_mir::ty::{Allocation, ProvenanceMap}; /// Creates new empty `Allocation` from given `Align`. fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index b575445c4d5..5ff17613b4e 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,19 +7,16 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::rustc_internal::{self, opaque}; -use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{ - FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy, -}; -use crate::stable_mir::{self, CompilerError, Context}; +use hir::def::DefKind; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc_span::ErrorGuaranteed; use rustc_target::abi::FieldIdx; +use stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; +use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy}; +use stable_mir::{self, opaque, Context}; use tracing::debug; mod alloc; @@ -44,6 +41,14 @@ impl<'tcx> Context for Tables<'tcx> { self.tcx.def_path_str(self[def_id]) } + fn print_span(&self, span: stable_mir::ty::Span) -> String { + self.tcx.sess.source_map().span_to_diagnostic_string(self[span]) + } + + fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind { + self.tcx.def_kind(self[def_id]).stable(self) + } + fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span { self.tcx.def_span(self[def_id]).stable(self) } @@ -104,11 +109,7 @@ impl<'tcx> Context for Tables<'tcx> { } } - fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) { - f(self) - } - - fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind { + fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind { self.types[ty.0].clone().stable(self) } @@ -276,7 +277,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { place.stable(tables), ), ThreadLocalRef(def_id) => { - stable_mir::mir::Rvalue::ThreadLocalRef(rustc_internal::crate_item(*def_id)) + stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id)) } AddressOf(mutability, place) => { stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables)) @@ -739,7 +740,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple, mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => { stable_mir::mir::AggregateKind::Adt( - rustc_internal::adt_def(*def_id), + tables.adt_def(*def_id), var_idx.index(), generic_arg.stable(tables), user_ty_index.map(|idx| idx.index()), @@ -748,13 +749,13 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { } mir::AggregateKind::Closure(def_id, generic_arg) => { stable_mir::mir::AggregateKind::Closure( - rustc_internal::closure_def(*def_id), + tables.closure_def(*def_id), generic_arg.stable(tables), ) } mir::AggregateKind::Generator(def_id, generic_arg, movability) => { stable_mir::mir::AggregateKind::Generator( - rustc_internal::generator_def(*def_id), + tables.generator_def(*def_id), generic_arg.stable(tables), movability.stable(tables), ) @@ -964,13 +965,13 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { impl<'tcx> Stable<'tcx> for ty::BoundTyKind { type T = stable_mir::ty::BoundTyKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::BoundTyKind; match self { ty::BoundTyKind::Anon => BoundTyKind::Anon, ty::BoundTyKind::Param(def_id, symbol) => { - BoundTyKind::Param(rustc_internal::param_def(*def_id), symbol.to_string()) + BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string()) } } } @@ -979,13 +980,13 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind { impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { type T = stable_mir::ty::BoundRegionKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::BoundRegionKind; match self { ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon, ty::BoundRegionKind::BrNamed(def_id, symbol) => { - BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string()) + BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string()) } ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv, } @@ -1072,12 +1073,10 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))), ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))), ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt( - rustc_internal::adt_def(adt_def.did()), + tables.adt_def(adt_def.did()), generic_args.stable(tables), )), - ty::Foreign(def_id) => { - TyKind::RigidTy(RigidTy::Foreign(rustc_internal::foreign_def(*def_id))) - } + ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))), ty::Str => TyKind::RigidTy(RigidTy::Str), ty::Array(ty, constant) => { TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables))) @@ -1091,10 +1090,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { tables.intern_ty(*ty), mutbl.stable(tables), )), - ty::FnDef(def_id, generic_args) => TyKind::RigidTy(RigidTy::FnDef( - rustc_internal::fn_def(*def_id), - generic_args.stable(tables), - )), + ty::FnDef(def_id, generic_args) => { + TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables))) + } ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))), ty::Dynamic(existential_predicates, region, dyn_kind) => { TyKind::RigidTy(RigidTy::Dynamic( @@ -1107,11 +1105,11 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { )) } ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure( - rustc_internal::closure_def(*def_id), + tables.closure_def(*def_id), generic_args.stable(tables), )), ty::Generator(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Generator( - rustc_internal::generator_def(*def_id), + tables.generator_def(*def_id), generic_args.stable(tables), movability.stable(tables), )), @@ -1223,7 +1221,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef { use stable_mir::ty::TraitDecl; TraitDecl { - def_id: rustc_internal::trait_def(self.def_id), + def_id: tables.trait_def(self.def_id), unsafety: self.unsafety.stable(tables), paren_sugar: self.paren_sugar, has_auto_impl: self.has_auto_impl, @@ -1272,7 +1270,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::TraitRef; - TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) } + TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) } } } @@ -1516,8 +1514,11 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span { } } -impl<T> From<ErrorGuaranteed> for CompilerError<T> { - fn from(_error: ErrorGuaranteed) -> Self { - CompilerError::CompilationFailed +impl<'tcx> Stable<'tcx> for DefKind { + type T = stable_mir::DefKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + // FIXME: add a real implementation of stable DefKind + opaque(self) } } diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index c579da61e38..0f9d36342ad 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -59,7 +59,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } DefKind::AnonConst => self.normalize_anon_const(goal), DefKind::OpaqueTy => self.normalize_opaque_type(goal), - DefKind::TyAlias { .. } => self.normalize_weak_type(goal), + DefKind::TyAlias => self.normalize_weak_type(goal), kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)), } } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 436f10a4f7b..ec2e0daaf88 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -119,7 +119,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' }, DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)), DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) { - DefKind::TyAlias { .. } => ty::List::empty(), + DefKind::TyAlias => ty::List::empty(), DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)), // Nested opaque types only occur in associated types: // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; ` @@ -136,7 +136,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::TyParam diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 38768f0a05b..06a30677d20 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -53,9 +53,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { fn parent(&self) -> Option<LocalDefId> { match self.tcx.def_kind(self.item) { - DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias { .. } => { - None - } + DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None, DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { Some(self.tcx.local_parent(self.item)) } @@ -118,7 +116,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn visit_nested_item(&mut self, id: rustc_hir::ItemId) { let id = id.owner_id.def_id; - if let DefKind::TyAlias { .. } = self.collector.tcx.def_kind(id) { + if let DefKind::TyAlias = self.collector.tcx.def_kind(id) { let items = self.collector.tcx.opaque_types_defined_by(id); self.collector.opaques.extend(items); } @@ -297,7 +295,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ collector.collect_body_and_predicate_taits(); } // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` - DefKind::TyAlias { .. } | DefKind::AssocTy => { + DefKind::TyAlias | DefKind::AssocTy => { tcx.type_of(item).instantiate_identity().visit_with(&mut collector); } DefKind::OpaqueTy => { diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml new file mode 100644 index 00000000000..c61e217bf9f --- /dev/null +++ b/compiler/stable_mir/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "stable_mir" +version = "0.1.0-preview" +edition = "2021" + +[dependencies] +tracing = "0.1" +scoped-tls = "1.0" diff --git a/compiler/rustc_smir/README.md b/compiler/stable_mir/README.md index 31dee955f49..31dee955f49 100644 --- a/compiler/rustc_smir/README.md +++ b/compiler/stable_mir/README.md diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/stable_mir/rust-toolchain.toml index d75e8e33b1c..d75e8e33b1c 100644 --- a/compiler/rustc_smir/rust-toolchain.toml +++ b/compiler/stable_mir/rust-toolchain.toml diff --git a/compiler/rustc_smir/src/stable_mir/fold.rs b/compiler/stable_mir/src/fold.rs index 831cfb40a15..16ae62311aa 100644 --- a/compiler/rustc_smir/src/stable_mir/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use crate::rustc_internal::Opaque; +use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind, diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/stable_mir/src/lib.rs index 3c86cb4038a..104985493ef 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/stable_mir/src/lib.rs @@ -1,15 +1,21 @@ -//! Module that implements the public interface to the Stable MIR. +//! The WIP stable interface to rustc internals. //! -//! This module shall contain all type definitions and APIs that we expect third-party tools to invoke to -//! interact with the compiler. +//! For more information see <https://github.com/rust-lang/project-stable-mir> //! -//! The goal is to eventually move this module to its own crate which shall be published on -//! [crates.io](https://crates.io). +//! # Note +//! +//! This API is still completely unstable and subject to change. + +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", + test(attr(allow(unused_variables), deny(warnings))) +)] //! -//! ## Note: +//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to +//! interact with the compiler. //! -//! There shouldn't be any direct references to internal compiler constructs in this module. -//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. +//! The goal is to eventually be published on +//! [crates.io](https://crates.io). use std::cell::Cell; use std::fmt; @@ -18,7 +24,9 @@ use std::fmt::Debug; use self::ty::{ GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, }; -use crate::rustc_smir::Tables; + +#[macro_use] +extern crate scoped_tls; pub mod fold; pub mod mir; @@ -33,11 +41,11 @@ pub type CrateNum = usize; /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq)] -pub struct DefId(pub(crate) usize); +pub struct DefId(pub usize); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DefId:") + f.debug_struct("DefId") .field("id", &self.0) .field("name", &with(|cx| cx.name_of_def_id(*self))) .finish() @@ -46,7 +54,7 @@ impl Debug for DefId { /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AllocId(pub(crate) usize); +pub struct AllocId(pub usize); /// A list of crate items. pub type CrateItems = Vec<CrateItem>; @@ -74,16 +82,18 @@ pub enum CompilerError<T> { /// Holds information about a crate. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Crate { - pub(crate) id: CrateNum, + pub id: CrateNum, pub name: Symbol, pub is_local: bool, } +pub type DefKind = Opaque; + /// Holds information about an item in the crate. /// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to /// use this item. #[derive(Clone, PartialEq, Eq, Debug)] -pub struct CrateItem(pub(crate) DefId); +pub struct CrateItem(pub DefId); impl CrateItem { pub fn body(&self) -> mir::Body { @@ -93,6 +103,14 @@ impl CrateItem { pub fn span(&self) -> Span { with(|cx| cx.span_of_an_item(self.0)) } + + pub fn name(&self) -> String { + with(|cx| cx.name_of_def_id(self.0)) + } + + pub fn kind(&self) -> DefKind { + with(|cx| cx.def_kind(self.0)) + } } /// Return the function where execution starts if the current @@ -161,6 +179,12 @@ pub trait Context { /// Prints the name of given `DefId` fn name_of_def_id(&self, def_id: DefId) -> String; + /// Prints a human readable form of `Span` + fn print_span(&self, span: Span) -> String; + + /// Prints the kind of given `DefId` + fn def_kind(&mut self, def_id: DefId) -> DefKind; + /// `Span` of an item fn span_of_an_item(&mut self, def_id: DefId) -> Span; @@ -169,10 +193,6 @@ pub trait Context { /// Create a new `Ty` from scratch without information from rustc. fn mk_ty(&mut self, kind: TyKind) -> Ty; - - /// HACK: Until we have fully stable consumers, we need an escape hatch - /// to get `DefId`s out of `CrateItem`s. - fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)); } // A thread local variable that stores a pointer to the tables mapping between TyCtxt @@ -192,7 +212,7 @@ pub fn run(mut context: impl Context, f: impl FnOnce()) { /// Loads the current context and calls a function with it. /// Do not nest these, as that will ICE. -pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R { +pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R { assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); @@ -200,3 +220,23 @@ pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R { f(unsafe { *(ptr as *mut &mut dyn Context) }) }) } + +/// A type that provides internal information but that can still be used for debug purpose. +#[derive(Clone)] +pub struct Opaque(String); + +impl std::fmt::Display for Opaque { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl std::fmt::Debug for Opaque { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } +} + +pub fn opaque<T: Debug>(value: &T) -> Opaque { + Opaque(format!("{value:?}")) +} diff --git a/compiler/rustc_smir/src/stable_mir/mir.rs b/compiler/stable_mir/src/mir.rs index a9dbc3463f8..a9dbc3463f8 100644 --- a/compiler/rustc_smir/src/stable_mir/mir.rs +++ b/compiler/stable_mir/src/mir.rs diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 449ca4b8145..6f8f7b06fa3 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -1,8 +1,6 @@ -use crate::rustc_internal::Opaque; -use crate::stable_mir::ty::{ - AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region, -}; -use crate::stable_mir::{self, ty::Ty, Span}; +use crate::ty::{AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region}; +use crate::Opaque; +use crate::{ty::Ty, Span}; #[derive(Clone, Debug)] pub struct Body { @@ -135,7 +133,7 @@ pub enum AsyncGeneratorKind { } pub(crate) type LocalDefId = Opaque; -/// [`rustc_middle::mir::Coverage`] is heavily tied to internal details of the +/// The rustc coverage data structures are heavily tied to internal details of the /// coverage implementation that are likely to change, and are unlikely to be /// useful to third-party tools for the foreseeable future. pub(crate) type Coverage = Opaque; @@ -215,7 +213,7 @@ pub enum Rvalue { /// generator lowering, `Generator` aggregate kinds are disallowed too. Aggregate(AggregateKind, Vec<Operand>), - /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second + /// * `Offset` has the same semantics as `<*const T>::offset`, except that the second /// parameter may be a `usize` as well. /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats, /// raw pointers, or function pointers and return a `bool`. The types of the operands must be @@ -245,16 +243,14 @@ pub enum Rvalue { /// deref operation, immediately followed by one or more projections. CopyForDeref(Place), - /// Computes the discriminant of the place, returning it as an integer of type - /// [`discriminant_ty`]. Returns zero for types without discriminant. + /// Computes the discriminant of the place, returning it as an integer. + /// Returns zero for types without discriminant. /// /// The validity requirements for the underlying value are undecided for this rvalue, see /// [#91095]. Note too that the value of the discriminant is not the same thing as the - /// variant index; use [`discriminant_for_variant`] to convert. + /// variant index; /// - /// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty /// [#91095]: https://github.com/rust-lang/rust/issues/91095 - /// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant Discriminant(Place), /// Yields the length of the place, as a `usize`. @@ -295,7 +291,7 @@ pub enum Rvalue { /// /// **Needs clarification**: Are there weird additional semantics here related to the runtime /// nature of this operation? - ThreadLocalRef(stable_mir::CrateItem), + ThreadLocalRef(crate::CrateItem), /// Computes a value as described by the operation. NullaryOp(NullOp, Ty), diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/stable_mir/src/ty.rs index eb9967b3888..82007e30683 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -3,7 +3,7 @@ use super::{ mir::{Body, Mutability}, with, AllocId, DefId, }; -use crate::rustc_internal::Opaque; +use crate::Opaque; use std::fmt::{self, Debug, Formatter}; #[derive(Copy, Clone)] @@ -34,15 +34,16 @@ pub struct Const { } type Ident = Opaque; -pub(crate) type Region = Opaque; +pub type Region = Opaque; #[derive(Clone, Copy, PartialEq, Eq)] -pub struct Span(pub(crate) usize); +pub struct Span(pub usize); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let mut span = None; - with(|context| context.rustc_tables(&mut |tables| span = Some(tables.spans[self.0]))); - f.write_fmt(format_args!("{:?}", &span.unwrap())) + f.debug_struct("Span") + .field("id", &self.0) + .field("repr", &with(|cx| cx.print_span(*self))) + .finish() } } @@ -110,10 +111,10 @@ pub enum Movability { } #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ForeignDef(pub(crate) DefId); +pub struct ForeignDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct FnDef(pub(crate) DefId); +pub struct FnDef(pub DefId); impl FnDef { pub fn body(&self) -> Body { @@ -122,34 +123,34 @@ impl FnDef { } #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ClosureDef(pub(crate) DefId); +pub struct ClosureDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct GeneratorDef(pub(crate) DefId); +pub struct GeneratorDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ParamDef(pub(crate) DefId); +pub struct ParamDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct BrNamedDef(pub(crate) DefId); +pub struct BrNamedDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AdtDef(pub(crate) DefId); +pub struct AdtDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AliasDef(pub(crate) DefId); +pub struct AliasDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct TraitDef(pub(crate) DefId); +pub struct TraitDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct GenericDef(pub(crate) DefId); +pub struct GenericDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ConstDef(pub(crate) DefId); +pub struct ConstDef(pub DefId); #[derive(Clone, PartialEq, Eq, Debug)] -pub struct ImplDef(pub(crate) DefId); +pub struct ImplDef(pub DefId); #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec<GenericArgKind>); @@ -333,7 +334,7 @@ pub type Bytes = Vec<Option<u8>>; pub type Size = usize; #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct Prov(pub(crate) AllocId); +pub struct Prov(pub AllocId); pub type Align = u64; pub type Promoted = u32; pub type InitMaskMaterialized = Vec<u64>; diff --git a/compiler/rustc_smir/src/stable_mir/visitor.rs b/compiler/stable_mir/src/visitor.rs index c86063d2ed6..9c3b4cd994a 100644 --- a/compiler/rustc_smir/src/stable_mir/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use crate::rustc_internal::Opaque; +use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4f19ffa83db..292ccc5780f 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1789,7 +1789,10 @@ pub fn run_cargo( // During check builds we need to keep crate metadata keep = true; } else if rlib_only_metadata { - if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") { + if filename.contains("jemalloc_sys") + || filename.contains("rustc_smir") + || filename.contains("stable_mir") + { // jemalloc_sys and rustc_smir are not linked into librustc_driver.so, // so we need to distribute them as rlib to be able to use them. keep |= filename.ends_with(".rlib"); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index dd43ee03383..fcbcfbf5c67 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -80,7 +80,7 @@ pub(crate) fn try_inline( build_impls(cx, did, attrs_without_docs, &mut ret); clean::UnionItem(build_union(cx, did)) } - Res::Def(DefKind::TyAlias { .. }, did) => { + Res::Def(DefKind::TyAlias, did) => { record_extern_fqn(cx, did, ItemType::TypeAlias); build_impls(cx, did, attrs_without_docs, &mut ret); clean::TypeAliasItem(build_type_alias(cx, did)) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d9ee622848d..34d81f51f76 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1758,7 +1758,7 @@ fn maybe_expand_private_type_alias<'tcx>( cx: &mut DocContext<'tcx>, path: &hir::Path<'tcx>, ) -> Option<Type> { - let Res::Def(DefKind::TyAlias { .. }, def_id) = path.res else { return None }; + let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None }; // Substitute private type aliases let def_id = def_id.as_local()?; let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id()) @@ -2027,7 +2027,7 @@ impl<'tcx> ContainerTy<'tcx> { let (DefKind::Struct | DefKind::Union | DefKind::Enum - | DefKind::TyAlias { .. } + | DefKind::TyAlias | DefKind::Trait) = tcx.def_kind(container) else { return ObjectLifetimeDefault::Empty; @@ -2859,7 +2859,7 @@ fn clean_impl<'tcx>( let for_ = clean_ty(impl_.self_ty, cx); let type_alias = for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) { - DefKind::TyAlias { .. } => Some(clean_middle_ty( + DefKind::TyAlias => Some(clean_middle_ty( ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()), cx, Some(def_id.to_def_id()), diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index fd79160ff4a..be2ee791588 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -115,7 +115,7 @@ impl From<DefKind> for ItemType { DefKind::Struct => Self::Struct, DefKind::Union => Self::Union, DefKind::Trait => Self::Trait, - DefKind::TyAlias { .. } => Self::TypeAlias, + DefKind::TyAlias => Self::TypeAlias, DefKind::TraitAlias => Self::TraitAlias, DefKind::Macro(kind) => match kind { MacroKind::Bang => ItemType::Macro, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8ea9b7a418b..d216305e6a9 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -593,7 +593,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .unwrap_or(Vec::new()) } } - Res::Def(DefKind::TyAlias { .. }, did) => { + Res::Def(DefKind::TyAlias, did) => { // Resolve the link on the type the alias points to. // FIXME: if the associated item is defined directly on the type alias, // it will show up on its documentation page, we should link there instead. diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 414d9e3a6d8096f3e276234ce220c868767a879 +Subproject e6aabe8b3fcf639be3a5bf68e77853bd7b3fa27 diff --git a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs index b00fa104f98..f95d2c2edb1 100644 --- a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs +++ b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields { && fields .iter() .all(|f| f.ident.as_str().as_bytes().iter().all(u8::is_ascii_digit)) - && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias { .. }, ..)) + && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias, ..)) { let expr_spans = fields .iter() diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 5c5ee262052..50d6f3b7e55 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -401,7 +401,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< = get_callee_generic_args_and_args(cx, parent_expr) { // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually - // call `tcx.try_subst_and_normalize_erasing_regions` further down + // call `tcx.try_instantiate_and_normalize_erasing_regions` further down // (i.e., we are explicitly not in the identity context). let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder(); if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id) @@ -452,7 +452,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let output_ty = fn_sig.output(); if output_ty.contains(*param_ty) { - if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions( + if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions( new_subst, cx.param_env, EarlyBinder::bind(output_ty)) { expr = parent_expr; ty = new_ty; diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 0f7bc04ccba..13da79fba7e 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -288,7 +288,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool { /// Checks if the given `QPath` belongs to a type alias. pub fn is_ty_alias(qpath: &QPath<'_>) -> bool { match *qpath { - QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, ..)), + QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)), QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) }, _ => false, } diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs index d05d9e7640f..75064672326 100644 --- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs @@ -219,7 +219,7 @@ fn path_segment_certainty( // See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value. let certainty = lhs.join_clearing_def_ids(rhs); if resolves_to_type { - if let DefKind::TyAlias { .. } = cx.tcx.def_kind(def_id) { + if let DefKind::TyAlias = cx.tcx.def_kind(def_id) { adt_def_id(cx.tcx.type_of(def_id).instantiate_identity()) .map_or(certainty, |def_id| certainty.with_def_id(def_id)) } else { diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index c05349c8e8d..7d3ef4197a7 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -58,14 +58,14 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[ // tidy-alphabetical-start ("bitmaps", "MPL-2.0+"), ("bytesize", "Apache-2.0"), + ("byteyarn", "Apache-2.0"), ("ciborium", "Apache-2.0"), ("ciborium-io", "Apache-2.0"), ("ciborium-ll", "Apache-2.0"), ("dunce", "CC0-1.0 OR MIT-0 OR Apache-2.0"), + ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), ("im-rc", "MPL-2.0+"), - ("imara-diff", "Apache-2.0"), - ("instant", "BSD-3-Clause"), ("normalize-line-endings", "Apache-2.0"), ("openssl", "Apache-2.0"), ("ryu", "Apache-2.0 OR BSL-1.0"), diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs index 23a9e2a064c..3ec1519fb13 100644 --- a/tests/ui-fulldeps/stable-mir/compilation-result.rs +++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs @@ -11,9 +11,10 @@ extern crate rustc_middle; extern crate rustc_smir; +extern crate stable_mir; use rustc_middle::ty::TyCtxt; -use rustc_smir::{rustc_internal, stable_mir}; +use rustc_smir::rustc_internal; use std::io::Write; use std::ops::ControlFlow; diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index a11720c4b55..ce4ee3c2463 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -13,13 +13,13 @@ extern crate rustc_hir; extern crate rustc_middle; extern crate rustc_smir; +extern crate stable_mir; use rustc_hir::def::DefKind; use rustc_middle::ty::TyCtxt; -use rustc_smir::{ - rustc_internal, - stable_mir::{self, fold::Foldable}, -}; +use rustc_smir::rustc_internal; + +use stable_mir::fold::Foldable; use std::assert_matches::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -27,7 +27,7 @@ use std::ops::ControlFlow; const CRATE_NAME: &str = "input"; /// This function uses the Stable MIR APIs to get information about the test crate. -fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { +fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { // Get the local crate using stable_mir API. let local = stable_mir::local_crate(); assert_eq!(&local.name, CRATE_NAME); @@ -36,12 +36,12 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { // Find items in the local crate. let items = stable_mir::all_local_items(); - assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some()); + assert!(get_item(&items, (DefKind::Fn, "foo::bar")).is_some()); // Find the `std` crate. assert!(stable_mir::find_crate("std").is_some()); - let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap(); + let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap(); let body = bar.body(); assert_eq!(body.locals.len(), 2); assert_eq!(body.blocks.len(), 1); @@ -56,7 +56,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap(); + let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap(); let body = foo_bar.body(); assert_eq!(body.locals.len(), 7); assert_eq!(body.blocks.len(), 4); @@ -66,7 +66,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let types = get_item(tcx, &items, (DefKind::Fn, "types")).unwrap(); + let types = get_item(&items, (DefKind::Fn, "types")).unwrap(); let body = types.body(); assert_eq!(body.locals.len(), 6); assert_matches!( @@ -96,7 +96,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { )) ); - let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap(); + let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap(); let body = drop.body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -105,7 +105,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap(); + let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap(); let body = assert.body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -114,7 +114,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let monomorphic = get_item(tcx, &items, (DefKind::Fn, "monomorphic")).unwrap(); + let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap(); for block in monomorphic.body().blocks { match &block.terminator { stable_mir::mir::Terminator::Call { func, .. } => match func { @@ -154,7 +154,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { } } - let foo_const = get_item(tcx, &items, (DefKind::Const, "FOO")).unwrap(); + let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap(); // Ensure we don't panic trying to get the body of a constant. foo_const.body(); @@ -163,13 +163,11 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { // Use internal API to find a function in a crate. fn get_item<'a>( - tcx: TyCtxt, items: &'a stable_mir::CrateItems, item: (DefKind, &str), ) -> Option<&'a stable_mir::CrateItem> { items.iter().find(|crate_item| { - let def_id = rustc_internal::item_def_id(crate_item); - tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1 + crate_item.kind().to_string() == format!("{:?}", item.0) && crate_item.name() == item.1 }) } diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs index 5c59f217be6..99769692342 100644 --- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs +++ b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs @@ -1,6 +1,5 @@ -// FIXME(inherent_associated_types): This should be `check-pass` -// known-bug: #108491 // compile-flags: --crate-type=lib +// check-pass #![feature(inherent_associated_types)] #![allow(incomplete_features)] @@ -8,11 +7,6 @@ // Bounds on the self type play a major role in the resolution of inherent associated types (*). // As a result of that, if a type alias contains any then its bounds have to be respected and the // lint `type_alias_bounds` should not fire. -// -// FIXME(inherent_associated_types): In the current implementation that is. We might move the -// selection phase of IATs from hir_typeck to trait_selection resulting in us not requiring the -// ParamEnv that early allowing us to ignore bounds on type aliases again. -// Triage this before stabilization. #![deny(type_alias_bounds)] diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr deleted file mode 100644 index 5e18543fc90..00000000000 --- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr +++ /dev/null @@ -1,55 +0,0 @@ -error[E0391]: cycle detected when expanding type alias `Alias` - --> $DIR/type-alias-bounds-are-enforced.rs:19:1 - | -LL | pub type Alias<T: Bound> = (Source<T>::Assoc,); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires computing the variances of `Source`... - --> $DIR/type-alias-bounds-are-enforced.rs:21:1 - | -LL | pub struct Source<T>(T); - | ^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing the variances for items in this crate... - = note: ...which again requires expanding type alias `Alias`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/type-alias-bounds-are-enforced.rs:5:1 - | -LL | / #![feature(inherent_associated_types)] -LL | | #![allow(incomplete_features)] -LL | | -LL | | // Bounds on the self type play a major role in the resolution of inherent associated types (*). -... | -LL | | pub type Assoc = (); -LL | | } - | |_^ - = 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[E0391]: cycle detected when expanding type alias `Alias` - --> $DIR/type-alias-bounds-are-enforced.rs:19:1 - | -LL | pub type Alias<T: Bound> = (Source<T>::Assoc,); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires computing the variances of `Source`... - --> $DIR/type-alias-bounds-are-enforced.rs:21:1 - | -LL | pub struct Source<T>(T); - | ^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing the variances for items in this crate... - = note: ...which again requires expanding type alias `Alias`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/type-alias-bounds-are-enforced.rs:5:1 - | -LL | / #![feature(inherent_associated_types)] -LL | | #![allow(incomplete_features)] -LL | | -LL | | // Bounds on the self type play a major role in the resolution of inherent associated types (*). -... | -LL | | pub type Assoc = (); -LL | | } - | |_^ - = 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: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs b/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs new file mode 100644 index 00000000000..3e3bc09a62a --- /dev/null +++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs @@ -0,0 +1,27 @@ +// edition: 2021 + +use std::future::Future; + +async fn bop() { + fold(run(), |mut foo| async move { + &mut foo.bar; + }) +} + +fn fold<Fut, F, U>(_: Foo<U>, f: F) +where + F: FnMut(Foo<U>) -> Fut, +{ + loop {} +} + +struct Foo<F> { + bar: Vec<F>, +} + +fn run() -> Foo<impl Future<Output = ()>> { + //~^ ERROR type annotations needed + loop {} +} + +fn main() {} diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr new file mode 100644 index 00000000000..ee4343b110f --- /dev/null +++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/opaque-cast-field-access-in-future.rs:22:17 + | +LL | fn run() -> Foo<impl Future<Output = ()>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/triagebot.toml b/triagebot.toml index dbced481993..648997ad6f0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -542,6 +542,10 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] message = "This PR changes Stable MIR" cc = ["@oli-obk", "@celinval", "@spastorino"] +[mentions."compiler/stable_mir"] +message = "This PR changes Stable MIR" +cc = ["@oli-obk", "@celinval", "@spastorino"] + [mentions."compiler/rustc_target/src/spec"] message = """ These commits modify **compiler targets**. |
