diff options
Diffstat (limited to 'compiler/rustc_middle/src')
22 files changed, 604 insertions, 75 deletions
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index fa6a2db38ef..feaad5bb96e 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -27,7 +27,7 @@ macro_rules! arena_types { rustc_middle::mir::Body<'tcx> >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [decode] borrowck_result: rustc_middle::mir::ConcreteOpaqueTypes<'tcx>, + [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>, [] resolver: rustc_data_structures::steal::Steal<( rustc_middle::ty::ResolverAstLowering, std::sync::Arc<rustc_ast::Crate>, diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 0be26712b9c..3ff9eea8cc4 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -37,7 +37,6 @@ pub(crate) struct OpaqueHiddenTypeMismatch<'tcx> { pub sub: TypeMismatchReason, } -// FIXME(autodiff): I should get used somewhere #[derive(Diagnostic)] #[diag(middle_unsupported_union)] pub struct UnsupportedUnion { diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index 9d2f0a45237..dc6a3334a4c 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -77,7 +77,7 @@ declare_hooks! { /// session, if it still exists. This is used during incremental compilation to /// turn a deserialized `DefPathHash` into its current `DefId`. /// Will fetch a DefId from a DefPathHash for a foreign crate. - hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId; + hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> Option<DefId>; /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 5023b2740ef..754a258eef9 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,7 +29,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(bootstrap, feature(round_char_boundary))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 28142382b13..8eb7aa71fcd 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1298,6 +1298,10 @@ pub struct BasicBlockData<'tcx> { /// List of statements in this block. pub statements: Vec<Statement<'tcx>>, + /// All debuginfos happen before the statement. + /// Put debuginfos here when the last statement is eliminated. + pub after_last_stmt_debuginfos: StmtDebugInfos<'tcx>, + /// Terminator for this block. /// /// N.B., this should generally ONLY be `None` during construction. @@ -1325,7 +1329,12 @@ impl<'tcx> BasicBlockData<'tcx> { terminator: Option<Terminator<'tcx>>, is_cleanup: bool, ) -> BasicBlockData<'tcx> { - BasicBlockData { statements, terminator, is_cleanup } + BasicBlockData { + statements, + after_last_stmt_debuginfos: StmtDebugInfos::default(), + terminator, + is_cleanup, + } } /// Accessor for terminator. @@ -1360,6 +1369,36 @@ impl<'tcx> BasicBlockData<'tcx> { self.terminator().successors() } } + + pub fn retain_statements<F>(&mut self, mut f: F) + where + F: FnMut(&Statement<'tcx>) -> bool, + { + // Place debuginfos into the next retained statement, + // this `debuginfos` variable is used to cache debuginfos between two retained statements. + let mut debuginfos = StmtDebugInfos::default(); + self.statements.retain_mut(|stmt| { + let retain = f(stmt); + if retain { + stmt.debuginfos.prepend(&mut debuginfos); + } else { + debuginfos.append(&mut stmt.debuginfos); + } + retain + }); + self.after_last_stmt_debuginfos.prepend(&mut debuginfos); + } + + pub fn strip_nops(&mut self) { + self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop)) + } + + pub fn drop_debuginfo(&mut self) { + self.after_last_stmt_debuginfos.drop_debuginfo(); + for stmt in self.statements.iter_mut() { + stmt.debuginfos.drop_debuginfo(); + } + } } /////////////////////////////////////////////////////////////////////////// @@ -1664,10 +1703,10 @@ mod size_asserts { use super::*; // tidy-alphabetical-start - static_assert_size!(BasicBlockData<'_>, 128); + static_assert_size!(BasicBlockData<'_>, 152); static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 64); - static_assert_size!(Statement<'_>, 32); + static_assert_size!(Statement<'_>, 56); static_assert_size!(Terminator<'_>, 96); static_assert_size!(VarDebugInfo<'_>, 88); // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 96148fd5b92..d87e3abe3b2 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -719,6 +719,11 @@ impl<'de, 'tcx> MirWriter<'de, 'tcx> { let mut current_location = Location { block, statement_index: 0 }; for statement in &data.statements { (self.extra_data)(PassWhere::BeforeLocation(current_location), w)?; + + for debuginfo in statement.debuginfos.iter() { + writeln!(w, "{INDENT}{INDENT}// DBG: {debuginfo:?};")?; + } + let indented_body = format!("{INDENT}{INDENT}{statement:?};"); if self.options.include_extra_comments { writeln!( @@ -749,6 +754,10 @@ impl<'de, 'tcx> MirWriter<'de, 'tcx> { current_location.statement_index += 1; } + for debuginfo in data.after_last_stmt_debuginfos.iter() { + writeln!(w, "{INDENT}{INDENT}// DBG: {debuginfo:?};")?; + } + // Terminator at the bottom. (self.extra_data)(PassWhere::BeforeLocation(current_location), w)?; if data.terminator.is_some() { @@ -829,6 +838,19 @@ impl Debug for Statement<'_> { } } +impl Debug for StmtDebugInfo<'_> { + fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { + match self { + StmtDebugInfo::AssignRef(local, place) => { + write!(fmt, "{local:?} = &{place:?}") + } + StmtDebugInfo::InvalidAssign(local) => { + write!(fmt, "{local:?} = &?") + } + } + } +} + impl Display for NonDivergingIntrinsic<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -1274,7 +1296,6 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> for &elem in projection.iter().rev() { match elem { ProjectionElem::OpaqueCast(_) - | ProjectionElem::Subtype(_) | ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => { write!(fmt, "(")?; @@ -1300,9 +1321,6 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::OpaqueCast(ty) => { write!(fmt, " as {ty})")?; } - ProjectionElem::Subtype(ty) => { - write!(fmt, " as subtype {ty})")?; - } ProjectionElem::Downcast(Some(name), _index) => { write!(fmt, " as {name})")?; } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index a509c40c89c..2e6c9f207e2 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -84,11 +84,10 @@ impl Debug for CoroutineLayout<'_> { } } -/// All the opaque types that are restricted to concrete types -/// by this function. Unlike the value in `TypeckResults`, this has -/// unerased regions. +/// All the opaque types that have had their hidden type fully computed. +/// Unlike the value in `TypeckResults`, this has unerased regions. #[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)] -pub struct ConcreteOpaqueTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>); +pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>); /// The result of the `mir_const_qualif` query. /// diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 28294b47e90..f310e1e5762 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -1,5 +1,7 @@ //! Functionality for statements, operands, places, and things that appear in them. +use std::ops; + use tracing::{debug, instrument}; use super::interpret::GlobalAlloc; @@ -15,17 +17,28 @@ use crate::ty::CoroutineArgsExt; pub struct Statement<'tcx> { pub source_info: SourceInfo, pub kind: StatementKind<'tcx>, + /// Some debuginfos appearing before the primary statement. + pub debuginfos: StmtDebugInfos<'tcx>, } impl<'tcx> Statement<'tcx> { /// Changes a statement to a nop. This is both faster than deleting instructions and avoids /// invalidating statement indices in `Location`s. - pub fn make_nop(&mut self) { - self.kind = StatementKind::Nop + pub fn make_nop(&mut self, drop_debuginfo: bool) { + if matches!(self.kind, StatementKind::Nop) { + return; + } + let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop); + if !drop_debuginfo { + let Some(debuginfo) = replaced_stmt.as_debuginfo() else { + bug!("debuginfo is not yet supported.") + }; + self.debuginfos.push(debuginfo); + } } pub fn new(source_info: SourceInfo, kind: StatementKind<'tcx>) -> Self { - Statement { source_info, kind } + Statement { source_info, kind, debuginfos: StmtDebugInfos::default() } } } @@ -63,6 +76,17 @@ impl<'tcx> StatementKind<'tcx> { _ => None, } } + + pub fn as_debuginfo(&self) -> Option<StmtDebugInfo<'tcx>> { + match self { + StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place))) + if let Some(local) = place.as_local() => + { + Some(StmtDebugInfo::AssignRef(local, *ref_place)) + } + _ => None, + } + } } /////////////////////////////////////////////////////////////////////////// @@ -222,7 +246,6 @@ impl<'tcx> PlaceTy<'tcx> { fty, )), ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast_and_subtype(ty)), - ProjectionElem::Subtype(ty) => PlaceTy::from_ty(handle_opaque_cast_and_subtype(ty)), // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general. ProjectionElem::UnwrapUnsafeBinder(ty) => { @@ -244,7 +267,6 @@ impl<V, T> ProjectionElem<V, T> { Self::Field(_, _) | Self::Index(_) | Self::OpaqueCast(_) - | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) @@ -259,7 +281,6 @@ impl<V, T> ProjectionElem<V, T> { Self::Deref | Self::Index(_) => false, Self::Field(_, _) | Self::OpaqueCast(_) - | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) @@ -286,7 +307,6 @@ impl<V, T> ProjectionElem<V, T> { | Self::Field(_, _) => true, Self::ConstantIndex { from_end: true, .. } | Self::Index(_) - | Self::Subtype(_) | Self::OpaqueCast(_) | Self::Subslice { .. } => false, @@ -319,7 +339,6 @@ impl<V, T> ProjectionElem<V, T> { ProjectionElem::Subslice { from, to, from_end } } ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(t(ty)), - ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(t(ty)), ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(t(ty)), ProjectionElem::Index(val) => ProjectionElem::Index(v(val)?), }) @@ -508,6 +527,20 @@ impl<'tcx> PlaceRef<'tcx> { }) } + /// Return the place accessed locals that include the base local. + pub fn accessed_locals(self) -> impl Iterator<Item = Local> { + std::iter::once(self.local).chain(self.projection.iter().filter_map(|proj| match proj { + ProjectionElem::Index(local) => Some(*local), + ProjectionElem::Deref + | ProjectionElem::Field(_, _) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Downcast(_, _) + | ProjectionElem::OpaqueCast(_) + | ProjectionElem::UnwrapUnsafeBinder(_) => None, + })) + } + /// Generates a new place by appending `more_projections` to the existing ones /// and interning the result. pub fn project_deeper( @@ -706,7 +739,8 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::PtrToPtr | CastKind::PointerCoercion(_, _) | CastKind::PointerWithExposedProvenance - | CastKind::Transmute, + | CastKind::Transmute + | CastKind::Subtype, _, _, ) @@ -971,3 +1005,71 @@ impl RawPtrKind { } } } + +#[derive(Default, Debug, Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +pub struct StmtDebugInfos<'tcx>(Vec<StmtDebugInfo<'tcx>>); + +impl<'tcx> StmtDebugInfos<'tcx> { + pub fn push(&mut self, debuginfo: StmtDebugInfo<'tcx>) { + self.0.push(debuginfo); + } + + pub fn drop_debuginfo(&mut self) { + self.0.clear(); + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn prepend(&mut self, debuginfos: &mut Self) { + if debuginfos.is_empty() { + return; + }; + debuginfos.0.append(self); + std::mem::swap(debuginfos, self); + } + + pub fn append(&mut self, debuginfos: &mut Self) { + if debuginfos.is_empty() { + return; + }; + self.0.append(debuginfos); + } + + pub fn extend(&mut self, debuginfos: &Self) { + if debuginfos.is_empty() { + return; + }; + self.0.extend_from_slice(debuginfos); + } + + pub fn retain<F>(&mut self, f: F) + where + F: FnMut(&StmtDebugInfo<'tcx>) -> bool, + { + self.0.retain(f); + } +} + +impl<'tcx> ops::Deref for StmtDebugInfos<'tcx> { + type Target = Vec<StmtDebugInfo<'tcx>>; + + #[inline] + fn deref(&self) -> &Vec<StmtDebugInfo<'tcx>> { + &self.0 + } +} + +impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> { + #[inline] + fn deref_mut(&mut self) -> &mut Vec<StmtDebugInfo<'tcx>> { + &mut self.0 + } +} + +#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +pub enum StmtDebugInfo<'tcx> { + AssignRef(Local, Place<'tcx>), + InvalidAssign(Local), +} diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index e6c8512564e..a823c365394 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1275,18 +1275,6 @@ pub enum ProjectionElem<V, T> { /// A transmute from an unsafe binder to the type that it wraps. This is a projection /// of a place, so it doesn't necessarily constitute a move out of the binder. UnwrapUnsafeBinder(T), - - /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where - /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping - /// explicit during optimizations and codegen. - /// - /// This projection doesn't impact the runtime behavior of the program except for potentially changing - /// some type metadata of the interpreter or codegen backend. - /// - /// This goal is achieved with mir_transform pass `Subtyper`, which runs right after - /// borrowchecker, as we only care about subtyping that can affect trait selection and - /// `TypeId`. - Subtype(T), } /// Alias for projections as they appear in places, where the base is a place @@ -1513,6 +1501,18 @@ pub enum CastKind { /// MIR is well-formed if the input and output types have different sizes, /// but running a transmute between differently-sized types is UB. Transmute, + + /// A `Subtype` cast is applied to any `StatementKind::Assign` where + /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping + /// explicit during optimizations and codegen. + /// + /// This cast doesn't impact the runtime behavior of the program except for potentially changing + /// some type metadata of the interpreter or codegen backend. + /// + /// This goal is achieved with mir_transform pass `Subtyper`, which runs right after + /// borrowchecker, as we only care about subtyping that can affect trait selection and + /// `TypeId`. + Subtype, } /// Represents how a [`CastKind::PointerCoercion`] was constructed. diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 4034a3a06e9..4249914346c 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -444,6 +444,14 @@ impl<'tcx> Terminator<'tcx> { self.kind.successors() } + /// Return `Some` if all successors are identical. + #[inline] + pub fn identical_successor(&self) -> Option<BasicBlock> { + let mut successors = self.successors(); + let first_succ = successors.next()?; + if successors.all(|succ| first_succ == succ) { Some(first_succ) } else { None } + } + #[inline] pub fn successors_mut<'a>(&'a mut self, f: impl FnMut(&'a mut BasicBlock)) { self.kind.successors_mut(f) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 81df239dee4..9654e189f2e 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -95,6 +95,14 @@ macro_rules! make_mir_visitor { self.super_source_scope_data(scope_data); } + fn visit_statement_debuginfo( + &mut self, + stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>, + location: Location + ) { + self.super_statement_debuginfo(stmt_debuginfo, location); + } + fn visit_statement( &mut self, statement: & $($mutability)? Statement<'tcx>, @@ -301,6 +309,7 @@ macro_rules! make_mir_visitor { { let BasicBlockData { statements, + after_last_stmt_debuginfos, terminator, is_cleanup: _ } = data; @@ -312,8 +321,11 @@ macro_rules! make_mir_visitor { index += 1; } + let location = Location { block, statement_index: index }; + for debuginfo in after_last_stmt_debuginfos as & $($mutability)? [_] { + self.visit_statement_debuginfo(debuginfo, location); + } if let Some(terminator) = terminator { - let location = Location { block, statement_index: index }; self.visit_terminator(terminator, location); } } @@ -376,14 +388,45 @@ macro_rules! make_mir_visitor { } } + fn super_statement_debuginfo( + &mut self, + stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>, + location: Location + ) { + match stmt_debuginfo { + StmtDebugInfo::AssignRef(local, place) => { + self.visit_local( + $(& $mutability)? *local, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location + ); + self.visit_place( + place, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location + ); + }, + StmtDebugInfo::InvalidAssign(local) => { + self.visit_local( + $(& $mutability)? *local, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location + ); + } + } + } + fn super_statement( &mut self, statement: & $($mutability)? Statement<'tcx>, location: Location ) { - let Statement { source_info, kind } = statement; + let Statement { source_info, kind, debuginfos } = statement; self.visit_source_info(source_info); + for debuginfo in debuginfos as & $($mutability)? [_] { + self.visit_statement_debuginfo(debuginfo, location); + } match kind { StatementKind::Assign(box (place, rvalue)) => { self.visit_assign(place, rvalue, location); @@ -1166,11 +1209,6 @@ macro_rules! visit_place_fns { self.visit_ty(&mut new_ty, TyContext::Location(location)); if ty != new_ty { Some(PlaceElem::OpaqueCast(new_ty)) } else { None } } - PlaceElem::Subtype(ty) => { - let mut new_ty = ty; - self.visit_ty(&mut new_ty, TyContext::Location(location)); - if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None } - } PlaceElem::UnwrapUnsafeBinder(ty) => { let mut new_ty = ty; self.visit_ty(&mut new_ty, TyContext::Location(location)); @@ -1244,7 +1282,6 @@ macro_rules! visit_place_fns { ) { match elem { ProjectionElem::OpaqueCast(ty) - | ProjectionElem::Subtype(ty) | ProjectionElem::Field(_, ty) | ProjectionElem::UnwrapUnsafeBinder(ty) => { self.visit_ty(ty, TyContext::Location(location)); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 326df9239aa..895c8c0295a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1244,7 +1244,7 @@ rustc_queries! { /// Borrow-checks the given typeck root, e.g. functions, const/static items, /// and its children, e.g. closures, inline consts. - query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> { + query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> { desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 614b6471f18..95adb561c70 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -95,7 +95,15 @@ impl<'tcx> Const<'tcx> { debruijn: ty::DebruijnIndex, bound_const: ty::BoundConst, ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Bound(debruijn, bound_const)) + Const::new(tcx, ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const)) + } + + #[inline] + pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Const<'tcx> { + Const::new( + tcx, + ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, ty::BoundConst { var }), + ) } #[inline] @@ -180,6 +188,10 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> { Const::new_bound(tcx, debruijn, ty::BoundConst { var }) } + fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: rustc_type_ir::BoundVar) -> Self { + Const::new_canonical_bound(tcx, var) + } + fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Self { Const::new_placeholder(tcx, placeholder) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a42af7bb3e3..1b89a49cf98 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1110,6 +1110,15 @@ const NUM_PREINTERNED_FRESH_TYS: u32 = 20; const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3; const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3; const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3; + +// From general profiling of the *max vars during canonicalization* of a value: +// - about 90% of the time, there are no canonical vars +// - about 9% of the time, there is only one canonical var +// - there are rarely more than 3-5 canonical vars (with exceptions in particularly pathological cases) +// This may not match the number of bound vars found in `for`s. +// Given that this is all heap interned, it seems likely that interning fewer +// vars here won't make an appreciable difference. Though, if we were to inline the data (in an array), +// we may want to consider reducing the number for canonicalized vars down to 4 or so. const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20; // This number may seem high, but it is reached in all but the smallest crates. @@ -1160,9 +1169,14 @@ pub struct CommonTypes<'tcx> { pub fresh_float_tys: Vec<Ty<'tcx>>, /// Pre-interned values of the form: - /// `Bound(DebruijnIndex(i), BoundTy { var: v, kind: BoundTyKind::Anon})` + /// `Bound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundTy { var: v, kind: BoundTyKind::Anon})` /// for small values of `i` and `v`. pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>, + + // Pre-interned values of the form: + // `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })` + // for small values of `v`. + pub anon_canonical_bound_tys: Vec<Ty<'tcx>>, } pub struct CommonLifetimes<'tcx> { @@ -1176,9 +1190,14 @@ pub struct CommonLifetimes<'tcx> { pub re_vars: Vec<Region<'tcx>>, /// Pre-interned values of the form: - /// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BoundRegionKind::Anon })` + /// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })` /// for small values of `i` and `v`. pub anon_re_bounds: Vec<Vec<Region<'tcx>>>, + + // Pre-interned values of the form: + // `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })` + // for small values of `v`. + pub anon_re_canonical_bounds: Vec<Region<'tcx>>, } pub struct CommonConsts<'tcx> { @@ -1211,7 +1230,7 @@ impl<'tcx> CommonTypes<'tcx> { (0..NUM_PREINTERNED_ANON_BOUND_TYS_V) .map(|v| { mk(ty::Bound( - ty::DebruijnIndex::from(i), + ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)), ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon }, )) }) @@ -1219,6 +1238,15 @@ impl<'tcx> CommonTypes<'tcx> { }) .collect(); + let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V) + .map(|v| { + mk(ty::Bound( + ty::BoundVarIndexKind::Canonical, + ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon }, + )) + }) + .collect(); + CommonTypes { unit: mk(Tuple(List::empty())), bool: mk(Bool), @@ -1250,6 +1278,7 @@ impl<'tcx> CommonTypes<'tcx> { fresh_int_tys, fresh_float_tys, anon_bound_tys, + anon_canonical_bound_tys, } } } @@ -1270,7 +1299,7 @@ impl<'tcx> CommonLifetimes<'tcx> { (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V) .map(|v| { mk(ty::ReBound( - ty::DebruijnIndex::from(i), + ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)), ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon, @@ -1281,11 +1310,21 @@ impl<'tcx> CommonLifetimes<'tcx> { }) .collect(); + let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V) + .map(|v| { + mk(ty::ReBound( + ty::BoundVarIndexKind::Canonical, + ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon }, + )) + }) + .collect(); + CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased), re_vars, anon_re_bounds, + anon_re_canonical_bounds, } } } @@ -2012,7 +2051,7 @@ impl<'tcx> TyCtxt<'tcx> { if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) { Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id()) } else { - Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id)) + self.def_path_hash_to_def_id_extern(hash, stable_crate_id) } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 7d56ec1635f..ee29afcff63 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -125,7 +125,9 @@ where fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { - ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => { + ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ty) + if debruijn == self.current_index => + { let ty = self.delegate.replace_ty(bound_ty); debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST)); ty::shift_vars(self.tcx, ty, self.current_index.as_u32()) @@ -146,9 +148,11 @@ where fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match r.kind() { - ty::ReBound(debruijn, br) if debruijn == self.current_index => { + ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) + if debruijn == self.current_index => + { let region = self.delegate.replace_region(br); - if let ty::ReBound(debruijn1, br) = region.kind() { + if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn1), br) = region.kind() { // If the callback returns a bound region, // that region should always use the INNERMOST // debruijn index. Then we adjust it to the @@ -165,7 +169,9 @@ where fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { - ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => { + ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const) + if debruijn == self.current_index => + { let ct = self.delegate.replace_const(bound_const); debug_assert!(!ct.has_vars_bound_above(ty::INNERMOST)); ty::shift_vars(self.tcx, ct, self.current_index.as_u32()) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0ffef393a33..ce4de6b95e0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -25,6 +25,7 @@ pub use generic_args::{GenericArgKind, TermKind, *}; pub use generics::*; pub use intrinsic::IntrinsicDef; use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx}; +use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_ast::node_id::NodeMap; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; @@ -62,7 +63,7 @@ pub use rustc_type_ir::solve::SizedTraitKind; pub use rustc_type_ir::*; #[allow(hidden_glob_reexports, unused_imports)] use rustc_type_ir::{InferCtxtLike, Interner}; -use tracing::{debug, instrument}; +use tracing::{debug, instrument, trace}; pub use vtable::*; use {rustc_ast as ast, rustc_hir as hir}; @@ -2216,3 +2217,225 @@ pub struct DestructuredConst<'tcx> { pub variant: Option<VariantIdx>, pub fields: &'tcx [ty::Const<'tcx>], } + +/// Generate TypeTree information for autodiff. +/// This function creates TypeTree metadata that describes the memory layout +/// of function parameters and return types for Enzyme autodiff. +pub fn fnc_typetrees<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>) -> FncTree { + // Check if TypeTrees are disabled via NoTT flag + if tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::NoTT) { + return FncTree { args: vec![], ret: TypeTree::new() }; + } + + // Check if this is actually a function type + if !fn_ty.is_fn() { + return FncTree { args: vec![], ret: TypeTree::new() }; + } + + // Get the function signature + let fn_sig = fn_ty.fn_sig(tcx); + let sig = tcx.instantiate_bound_regions_with_erased(fn_sig); + + // Create TypeTrees for each input parameter + let mut args = vec![]; + for ty in sig.inputs().iter() { + let type_tree = typetree_from_ty(tcx, *ty); + args.push(type_tree); + } + + // Create TypeTree for return type + let ret = typetree_from_ty(tcx, sig.output()); + + FncTree { args, ret } +} + +/// Generate TypeTree for a specific type. +/// This function analyzes a Rust type and creates appropriate TypeTree metadata. +pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree { + let mut visited = Vec::new(); + typetree_from_ty_inner(tcx, ty, 0, &mut visited) +} + +/// Maximum recursion depth for TypeTree generation to prevent stack overflow +/// from pathological deeply nested types. Combined with cycle detection. +const MAX_TYPETREE_DEPTH: usize = 6; + +/// Internal recursive function for TypeTree generation with cycle detection and depth limiting. +fn typetree_from_ty_inner<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + depth: usize, + visited: &mut Vec<Ty<'tcx>>, +) -> TypeTree { + if depth >= MAX_TYPETREE_DEPTH { + trace!("typetree depth limit {} reached for type: {}", MAX_TYPETREE_DEPTH, ty); + return TypeTree::new(); + } + + if visited.contains(&ty) { + return TypeTree::new(); + } + + visited.push(ty); + let result = typetree_from_ty_impl(tcx, ty, depth, visited); + visited.pop(); + result +} + +/// Implementation of TypeTree generation logic. +fn typetree_from_ty_impl<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + depth: usize, + visited: &mut Vec<Ty<'tcx>>, +) -> TypeTree { + typetree_from_ty_impl_inner(tcx, ty, depth, visited, false) +} + +/// Internal implementation with context about whether this is for a reference target. +fn typetree_from_ty_impl_inner<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + depth: usize, + visited: &mut Vec<Ty<'tcx>>, + is_reference_target: bool, +) -> TypeTree { + if ty.is_scalar() { + let (kind, size) = if ty.is_integral() || ty.is_char() || ty.is_bool() { + (Kind::Integer, ty.primitive_size(tcx).bytes_usize()) + } else if ty.is_floating_point() { + match ty { + x if x == tcx.types.f16 => (Kind::Half, 2), + x if x == tcx.types.f32 => (Kind::Float, 4), + x if x == tcx.types.f64 => (Kind::Double, 8), + x if x == tcx.types.f128 => (Kind::F128, 16), + _ => (Kind::Integer, 0), + } + } else { + (Kind::Integer, 0) + }; + + // Use offset 0 for scalars that are direct targets of references (like &f64) + // Use offset -1 for scalars used directly (like function return types) + let offset = if is_reference_target && !ty.is_array() { 0 } else { -1 }; + return TypeTree(vec![Type { offset, size, kind, child: TypeTree::new() }]); + } + + if ty.is_ref() || ty.is_raw_ptr() || ty.is_box() { + let inner_ty = if let Some(inner) = ty.builtin_deref(true) { + inner + } else { + return TypeTree::new(); + }; + + let child = typetree_from_ty_impl_inner(tcx, inner_ty, depth + 1, visited, true); + return TypeTree(vec![Type { + offset: -1, + size: tcx.data_layout.pointer_size().bytes_usize(), + kind: Kind::Pointer, + child, + }]); + } + + if ty.is_array() { + if let ty::Array(element_ty, len_const) = ty.kind() { + let len = len_const.try_to_target_usize(tcx).unwrap_or(0); + if len == 0 { + return TypeTree::new(); + } + let element_tree = + typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false); + let mut types = Vec::new(); + for elem_type in &element_tree.0 { + types.push(Type { + offset: -1, + size: elem_type.size, + kind: elem_type.kind, + child: elem_type.child.clone(), + }); + } + + return TypeTree(types); + } + } + + if ty.is_slice() { + if let ty::Slice(element_ty) = ty.kind() { + let element_tree = + typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false); + return element_tree; + } + } + + if let ty::Tuple(tuple_types) = ty.kind() { + if tuple_types.is_empty() { + return TypeTree::new(); + } + + let mut types = Vec::new(); + let mut current_offset = 0; + + for tuple_ty in tuple_types.iter() { + let element_tree = + typetree_from_ty_impl_inner(tcx, tuple_ty, depth + 1, visited, false); + + let element_layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tuple_ty)) + .ok() + .map(|layout| layout.size.bytes_usize()) + .unwrap_or(0); + + for elem_type in &element_tree.0 { + types.push(Type { + offset: if elem_type.offset == -1 { + current_offset as isize + } else { + current_offset as isize + elem_type.offset + }, + size: elem_type.size, + kind: elem_type.kind, + child: elem_type.child.clone(), + }); + } + + current_offset += element_layout; + } + + return TypeTree(types); + } + + if let ty::Adt(adt_def, args) = ty.kind() { + if adt_def.is_struct() { + let struct_layout = + tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)); + if let Ok(layout) = struct_layout { + let mut types = Vec::new(); + + for (field_idx, field_def) in adt_def.all_fields().enumerate() { + let field_ty = field_def.ty(tcx, args); + let field_tree = + typetree_from_ty_impl_inner(tcx, field_ty, depth + 1, visited, false); + + let field_offset = layout.fields.offset(field_idx).bytes_usize(); + + for elem_type in &field_tree.0 { + types.push(Type { + offset: if elem_type.offset == -1 { + field_offset as isize + } else { + field_offset as isize + elem_type.offset + }, + size: elem_type.size, + kind: elem_type.kind, + child: elem_type.child.clone(), + }); + } + } + + return TypeTree(types); + } + } + } + + TypeTree::new() +} diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 8f7c8170f7a..4d1fcaeda5e 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2664,7 +2664,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { let name = &mut self.name; let region = match r.kind() { - ty::ReBound(db, br) if db >= self.current_index => { + ty::ReBound(ty::BoundVarIndexKind::Bound(db), br) if db >= self.current_index => { *self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br)) } ty::RePlaceholder(ty::PlaceholderRegion { @@ -2687,7 +2687,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { } _ => return r, }; - if let ty::ReBound(debruijn1, br) = region.kind() { + if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn1), br) = region.kind() { assert_eq!(debruijn1, ty::INNERMOST); ty::Region::new_bound(self.tcx, self.current_index, br) } else { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 3a7852dea06..f0687f2bc72 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -31,7 +31,7 @@ impl<'tcx> rustc_type_ir::Flags for Region<'tcx> { fn outer_exclusive_binder(&self) -> ty::DebruijnIndex { match self.kind() { - ty::ReBound(debruijn, _) => debruijn.shifted_in(1), + ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn.shifted_in(1), _ => ty::INNERMOST, } } @@ -59,7 +59,20 @@ impl<'tcx> Region<'tcx> { { re } else { - tcx.intern_region(ty::ReBound(debruijn, bound_region)) + tcx.intern_region(ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), bound_region)) + } + } + + #[inline] + pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Region<'tcx> { + // Use a pre-interned one when possible. + if let Some(re) = tcx.lifetimes.anon_re_canonical_bounds.get(var.as_usize()).copied() { + re + } else { + tcx.intern_region(ty::ReBound( + ty::BoundVarIndexKind::Canonical, + ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }, + )) } } @@ -122,7 +135,12 @@ impl<'tcx> Region<'tcx> { pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { match kind { ty::ReEarlyParam(region) => Region::new_early_param(tcx, region), - ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region), + ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), region) => { + Region::new_bound(tcx, debruijn, region) + } + ty::ReBound(ty::BoundVarIndexKind::Canonical, region) => { + Region::new_canonical_bound(tcx, region.var) + } ty::ReLateParam(ty::LateParamRegion { scope, kind }) => { Region::new_late_param(tcx, scope, kind) } @@ -148,6 +166,10 @@ impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> { Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }) } + fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: rustc_type_ir::BoundVar) -> Self { + Region::new_canonical_bound(tcx, var) + } + fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Self { Region::new_placeholder(tcx, placeholder) } @@ -223,7 +245,7 @@ impl<'tcx> Region<'tcx> { #[inline] pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { match self.kind() { - ty::ReBound(debruijn, _) => debruijn >= index, + ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index, _ => false, } } @@ -254,7 +276,11 @@ impl<'tcx> Region<'tcx> { ty::ReStatic => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } - ty::ReBound(..) => { + ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => { + flags = flags | TypeFlags::HAS_RE_BOUND; + flags = flags | TypeFlags::HAS_CANONICAL_BOUND; + } + ty::ReBound(ty::BoundVarIndexKind::Bound(..), _) => { flags = flags | TypeFlags::HAS_RE_BOUND; } ty::ReErased => { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index de35e5e847c..a3fdd4e35b6 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -487,7 +487,23 @@ impl<'tcx> Ty<'tcx> { { ty } else { - Ty::new(tcx, Bound(index, bound_ty)) + Ty::new(tcx, Bound(ty::BoundVarIndexKind::Bound(index), bound_ty)) + } + } + + #[inline] + pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: BoundVar) -> Ty<'tcx> { + // Use a pre-interned one when possible. + if let Some(ty) = tcx.types.anon_canonical_bound_tys.get(var.as_usize()).copied() { + ty + } else { + Ty::new( + tcx, + Bound( + ty::BoundVarIndexKind::Canonical, + ty::BoundTy { var, kind: ty::BoundTyKind::Anon }, + ), + ) } } @@ -952,6 +968,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> { Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon }) } + fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Self { + Ty::new_canonical_bound(tcx, var) + } + fn new_alias( interner: TyCtxt<'tcx>, kind: ty::AliasTyKind, diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 8dd80aab946..b276b993ec9 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -167,7 +167,7 @@ pub struct TypeckResults<'tcx> { /// We also store the type here, so that the compiler can use it as a hint /// for figuring out hidden types, even if they are only set in dead code /// (which doesn't show up in MIR). - pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>, + pub hidden_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. @@ -250,7 +250,7 @@ impl<'tcx> TypeckResults<'tcx> { coercion_casts: Default::default(), used_trait_imports: Default::default(), tainted_by_errors: None, - concrete_opaque_types: Default::default(), + hidden_types: Default::default(), closure_min_captures: Default::default(), closure_fake_reads: Default::default(), rvalue_scopes: Default::default(), @@ -798,8 +798,8 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { match arg.kind() { GenericArgKind::Type(ty) => match ty.kind() { ty::Bound(debruijn, b) => { - // We only allow a `ty::INNERMOST` index in generic parameters. - assert_eq!(*debruijn, ty::INNERMOST); + // We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters. + assert_eq!(*debruijn, ty::BoundVarIndexKind::Canonical); cvar == b.var } _ => false, @@ -807,8 +807,8 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { GenericArgKind::Lifetime(r) => match r.kind() { ty::ReBound(debruijn, b) => { - // We only allow a `ty::INNERMOST` index in generic parameters. - assert_eq!(debruijn, ty::INNERMOST); + // We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters. + assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical); cvar == b.var } _ => false, @@ -816,8 +816,8 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { GenericArgKind::Const(ct) => match ct.kind() { ty::ConstKind::Bound(debruijn, b) => { - // We only allow a `ty::INNERMOST` index in generic parameters. - assert_eq!(debruijn, ty::INNERMOST); + // We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters. + assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical); cvar == b.var } _ => false, diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index f0c47f257cc..e84ac56b31d 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -78,7 +78,9 @@ impl<'tcx> TyCtxt<'tcx> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { match r.kind() { - ty::ReBound(debruijn, _) if debruijn < self.outer_index => { + ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) + if debruijn < self.outer_index => + { ControlFlow::Continue(()) } _ => { @@ -205,7 +207,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector { } fn visit_region(&mut self, r: ty::Region<'tcx>) { - if let ty::ReBound(debruijn, br) = r.kind() { + if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) = r.kind() { if debruijn == self.current_index { self.regions.insert(br.kind); } diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index e2f09fdcb4b..a3e9054fdcb 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -104,7 +104,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( .expect("failed to build vtable representation"); assert!(layout.is_sized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); - let align = layout.align.abi.bytes(); + let align = layout.align.bytes(); let ptr_size = tcx.data_layout.pointer_size(); let ptr_align = tcx.data_layout.pointer_align().abi; |
