diff options
Diffstat (limited to 'compiler/rustc_middle')
20 files changed, 269 insertions, 102 deletions
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index be8a3403ba9..bd315577efb 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -47,10 +47,10 @@ pub struct UnsupportedUnion { // FIXME(autodiff): I should get used somewhere #[derive(Diagnostic)] #[diag(middle_autodiff_unsafe_inner_const_ref)] -pub struct AutodiffUnsafeInnerConstRef { +pub struct AutodiffUnsafeInnerConstRef<'tcx> { #[primary_span] pub span: Span, - pub ty: String, + pub ty: Ty<'tcx>, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 743812e3a20..890756a17ca 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -248,7 +248,7 @@ pub enum InvalidMetaKind { } impl IntoDiagArg for InvalidMetaKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(match self { InvalidMetaKind::SliceTooBig => "slice_too_big", InvalidMetaKind::TooBig => "too_big", @@ -282,7 +282,7 @@ pub struct Misalignment { macro_rules! impl_into_diag_arg_through_debug { ($($ty:ty),*$(,)?) => {$( impl IntoDiagArg for $ty { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(format!("{self:?}"))) } } @@ -401,7 +401,7 @@ pub enum PointerKind { } impl IntoDiagArg for PointerKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { DiagArgValue::Str( match self { Self::Ref(_) => "ref", @@ -666,7 +666,7 @@ macro_rules! err_ub_custom { msg: || $msg, add_args: Box::new(move |mut set_arg| { $($( - set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); + set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name, &mut None)); )*)? }) } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 875f5282bf2..f880b1364c2 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -319,6 +319,7 @@ pub fn write_mir_pretty<'tcx>( writeln!(w, "// WARNING: This output format is intended for human consumers only")?; writeln!(w, "// and is subject to change without notice. Knock yourself out.")?; + writeln!(w, "// HINT: See also -Z dump-mir for MIR at specific points during compilation.")?; let mut first = true; for def_id in dump_mir_def_ids(tcx, single) { diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index b887370fd69..bc77f22af67 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -357,7 +357,7 @@ impl<O> AssertKind<O> { macro_rules! add { ($name: expr, $value: expr) => { - adder($name.into(), $value.into_diag_arg()); + adder($name.into(), $value.into_diag_arg(&mut None)); }; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7c4ea06a746..46a960d9945 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -143,11 +143,11 @@ rustc_queries! { /// Represents crate as a whole (as distinct from the top-level crate module). /// - /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), + /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir_crate()`), /// we will have to assume that any change means that you need to be recompiled. /// This is because the `hir_crate` query gives you access to all other items. - /// To avoid this fate, do not call `tcx.hir().krate()`; instead, - /// prefer wrappers like `tcx.visit_all_items_in_krate()`. + /// To avoid this fate, do not call `tcx.hir_crate()`; instead, + /// prefer wrappers like [`TyCtxt::hir_visit_all_item_likes_in_crate`]. query hir_crate(key: ()) -> &'tcx Crate<'tcx> { arena_cache eval_always diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 690b8128b1a..66a9e5fed4c 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -258,7 +258,7 @@ macro_rules! query_if_arena { }; } -/// If `separate_provide_if_extern`, then the key can be projected to its +/// If `separate_provide_extern`, then the key can be projected to its /// local key via `<$K as AsLocalKey>::LocalKey`. macro_rules! local_key_if_separate_extern { ([] $($K:tt)*) => { diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index b72edc1c532..7c9280fae16 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -118,7 +118,7 @@ impl std::fmt::Debug for ConstInt { impl IntoDiagArg for ConstInt { // FIXME this simply uses the Debug impl, but we could probably do better by converting both // to an inherent method that returns `Cow`. - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { DiagArgValue::Str(format!("{self:?}").into()) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 00993c40dea..d0aa2b8cbda 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -324,11 +324,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.features() } - fn bound_coroutine_hidden_types( + fn coroutine_hidden_types( self, def_id: DefId, - ) -> impl IntoIterator<Item = ty::EarlyBinder<'tcx, ty::Binder<'tcx, Ty<'tcx>>>> { - self.bound_coroutine_hidden_types(def_id) + ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> { + self.coroutine_hidden_types(def_id) } fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { @@ -594,6 +594,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_is_auto(trait_def_id) } + fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { + self.trait_is_coinductive(trait_def_id) + } + fn trait_is_alias(self, trait_def_id: DefId) -> bool { self.trait_is_alias(trait_def_id) } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index cb218a27e62..881381a5ee6 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -19,8 +19,16 @@ use crate::ty::{ TypeSuperVisitable, TypeVisitable, TypeVisitor, }; +impl IntoDiagArg for Ty<'_> { + fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let ty = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(ty)) + }) + } +} + into_diag_arg_using_display! { - Ty<'_>, ty::Region<'_>, } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 8c1991ddb36..a0e67929c52 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -213,10 +213,9 @@ impl<'tcx> Ty<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn string_with_limit<'a, T>(self, p: T, length_limit: usize) -> String + pub fn string_with_limit<T>(self, p: T, length_limit: usize) -> String where - T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy, - <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, + T: Copy + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>, { let mut type_limit = 50; let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { @@ -253,10 +252,9 @@ impl<'tcx> TyCtxt<'tcx> { /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user /// where we wrote the file to is only printed once. - pub fn short_string<'a, T>(self, p: T, path: &mut Option<PathBuf>) -> String + pub fn short_string<T>(self, p: T, path: &mut Option<PathBuf>) -> String where - T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy + Hash, - <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, + T: Copy + Hash + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>, { let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { self.lift(p).expect("could not lift for printing").print(cx) diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index ed0b3059d75..27576a2ec4a 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -159,8 +159,8 @@ unsafe impl<'tcx> Sync for GenericArg<'tcx> where } impl<'tcx> IntoDiagArg for GenericArg<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e9c19331e4a..98ca71b86be 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -111,8 +111,9 @@ pub enum InstanceKind<'tcx> { /// Dynamic dispatch to `<dyn Trait as Trait>::fn`. /// - /// This `InstanceKind` does not have callable MIR. Calls to `Virtual` instances must be - /// codegen'd as virtual calls through the vtable. + /// This `InstanceKind` may have a callable MIR as the default implementation. + /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. + /// *This means we might not know exactly what is being called.* /// /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more /// details on that). diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index eb14ed20fba..272bb0cc915 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -315,8 +315,8 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { } impl<'tcx> IntoDiagArg for LayoutError<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index eb70a35d370..d926d6cc02a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -122,6 +122,7 @@ pub mod normalize_erasing_regions; pub mod pattern; pub mod print; pub mod relate; +pub mod significant_drop_order; pub mod trait_def; pub mod util; pub mod visit; diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 553de83dfcb..1674ca4cfc5 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -4,7 +4,6 @@ use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, extension}; use rustc_type_ir as ir; -use tracing::instrument; use crate::ty::{ self, DebruijnIndex, EarlyBinder, PredicatePolarity, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, @@ -51,10 +50,6 @@ impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> self.as_clause() } - fn is_coinductive(self, interner: TyCtxt<'tcx>) -> bool { - self.is_coinductive(interner) - } - fn allow_normalization(self) -> bool { self.allow_normalization() } @@ -119,17 +114,6 @@ impl<'tcx> Predicate<'tcx> { Some(tcx.mk_predicate(kind)) } - #[instrument(level = "debug", skip(tcx), ret)] - pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool { - match self.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { - tcx.trait_is_coinductive(data.def_id()) - } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => true, - _ => false, - } - } - /// Whether this projection can be soundly normalized. /// /// Wf predicates must not be normalized, as normalization @@ -158,15 +142,21 @@ impl<'tcx> Predicate<'tcx> { } } -impl rustc_errors::IntoDiagArg for Predicate<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(self.to_string())) +impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> { + fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let pred = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(pred)) + }) } } -impl rustc_errors::IntoDiagArg for Clause<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(self.to_string())) +impl<'tcx> rustc_errors::IntoDiagArg for Clause<'tcx> { + fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let clause = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(clause)) + }) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ed0839f47e6..c77b37a302b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1516,10 +1516,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ExprKind::Binop(op) => { let (_, _, c1, c2) = expr.binop_args(); - let precedence = |binop: crate::mir::BinOp| { - use rustc_ast::util::parser::AssocOp; - AssocOp::from_ast_binop(binop.to_hir_binop()).precedence() - }; + let precedence = |binop: crate::mir::BinOp| binop.to_hir_binop().precedence(); let op_precedence = precedence(op); let formatted_op = op.to_hir_binop().as_str(); let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) { @@ -2898,12 +2895,15 @@ where /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only /// the trait path. That is, it will print `Trait<U>` instead of /// `<T as Trait<U>>`. -#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>); impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintOnlyTraitPath<'tcx> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let trait_ref = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref)) + }) } } @@ -2915,12 +2915,15 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> { /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only /// the trait path, and additionally tries to "sugar" `Fn(...)` trait bounds. -#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>); impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintSugared<'tcx> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let trait_ref = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref)) + }) } } diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs new file mode 100644 index 00000000000..7f0d82d89fe --- /dev/null +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -0,0 +1,172 @@ +use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::unord::UnordSet; +use rustc_hir::def_id::DefId; +use rustc_span::Span; +use smallvec::{SmallVec, smallvec}; +use tracing::{debug, instrument}; + +use crate::ty::{self, Ty, TyCtxt}; + +/// An additional filter to exclude well-known types from the ecosystem +/// because their drops are trivial. +/// This returns additional types to check if the drops are delegated to those. +/// A typical example is `hashbrown::HashMap<K, V>`, whose drop is delegated to `K` and `V`. +fn true_significant_drop_ty<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, +) -> Option<SmallVec<[Ty<'tcx>; 2]>> { + if let ty::Adt(def, args) = ty.kind() { + let mut did = def.did(); + let mut name_rev = vec![]; + loop { + let key = tcx.def_key(did); + + match key.disambiguated_data.data { + rustc_hir::definitions::DefPathData::CrateRoot => { + name_rev.push(tcx.crate_name(did.krate)) + } + rustc_hir::definitions::DefPathData::TypeNs(symbol) => name_rev.push(symbol), + _ => return None, + } + if let Some(parent) = key.parent { + did = DefId { krate: did.krate, index: parent }; + } else { + break; + } + } + let name_str: Vec<_> = name_rev.iter().rev().map(|x| x.as_str()).collect(); + debug!(?name_str); + match name_str[..] { + // These are the types from Rust core ecosystem + ["syn" | "proc_macro2", ..] + | ["core" | "std", "task", "LocalWaker" | "Waker"] + | ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(smallvec![]), + // These are important types from Rust ecosystem + ["tracing", "instrument", "Instrumented"] | ["bytes", "Bytes"] => Some(smallvec![]), + ["hashbrown", "raw", "RawTable" | "RawIntoIter"] => { + if let [ty, ..] = &***args + && let Some(ty) = ty.as_type() + { + Some(smallvec![ty]) + } else { + None + } + } + ["hashbrown", "raw", "RawDrain"] => { + if let [_, ty, ..] = &***args + && let Some(ty) = ty.as_type() + { + Some(smallvec![ty]) + } else { + None + } + } + _ => None, + } + } else { + None + } +} + +/// Returns the list of types with a "potentially sigificant" that may be dropped +/// by dropping a value of type `ty`. +#[instrument(level = "trace", skip(tcx, typing_env))] +pub fn extract_component_raw<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + ty_seen: &mut UnordSet<Ty<'tcx>>, +) -> SmallVec<[Ty<'tcx>; 4]> { + // Droppiness does not depend on regions, so let us erase them. + let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + + let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty)); + debug!(?ty, "components"); + let mut out_tys = smallvec![]; + for ty in tys { + if let Some(tys) = true_significant_drop_ty(tcx, ty) { + // Some types can be further opened up because the drop is simply delegated + for ty in tys { + if ty_seen.insert(ty) { + out_tys.extend(extract_component_raw(tcx, typing_env, ty, ty_seen)); + } + } + } else { + if ty_seen.insert(ty) { + out_tys.push(ty); + } + } + } + out_tys +} + +#[instrument(level = "trace", skip(tcx, typing_env))] +pub fn extract_component_with_significant_dtor<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, +) -> SmallVec<[Ty<'tcx>; 4]> { + let mut tys = extract_component_raw(tcx, typing_env, ty, &mut Default::default()); + let mut deduplicate = FxHashSet::default(); + tys.retain(|oty| deduplicate.insert(*oty)); + tys.into_iter().collect() +} + +/// Extract the span of the custom destructor of a type +/// especially the span of the `impl Drop` header or its entire block +/// when we are working with current local crate. +#[instrument(level = "trace", skip(tcx))] +pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> { + match ty.kind() { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Error(_) + | ty::Str + | ty::Never + | ty::RawPtr(_, _) + | ty::Ref(_, _, _) + | ty::FnPtr(_, _) + | ty::Tuple(_) + | ty::Dynamic(_, _, _) + | ty::Alias(_, _) + | ty::Bound(_, _) + | ty::Pat(_, _) + | ty::Placeholder(_) + | ty::Infer(_) + | ty::Slice(_) + | ty::Array(_, _) + | ty::UnsafeBinder(_) => None, + + ty::Adt(adt_def, _) => { + let did = adt_def.did(); + let try_local_did_span = |did: DefId| { + if let Some(local) = did.as_local() { + tcx.source_span(local) + } else { + tcx.def_span(did) + } + }; + let dtor = if let Some(dtor) = tcx.adt_destructor(did) { + dtor.did + } else if let Some(dtor) = tcx.adt_async_destructor(did) { + dtor.future + } else { + return Some(try_local_did_span(did)); + }; + let def_key = tcx.def_key(dtor); + let Some(parent_index) = def_key.parent else { return Some(try_local_did_span(dtor)) }; + let parent_did = DefId { index: parent_index, krate: dtor.krate }; + Some(try_local_did_span(parent_did)) + } + ty::Coroutine(did, _) + | ty::CoroutineWitness(did, _) + | ty::CoroutineClosure(did, _) + | ty::Closure(did, _) + | ty::FnDef(did, _) + | ty::Foreign(did) => Some(tcx.def_span(did)), + ty::Param(_) => None, + } +} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d5617adf26b..e46ab302be2 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -342,6 +342,7 @@ impl ParamConst { ParamConst::new(def.index, def.name) } + #[instrument(level = "debug")] pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { let mut candidates = env.caller_bounds().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index d4484a16fea..7d9c23c05f9 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -394,8 +394,10 @@ impl<'tcx> TypeckResults<'tcx> { matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _)))) } - pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> { - self.pat_binding_modes().get(id).copied().or_else(|| { + /// Returns the computed binding mode for a `PatKind::Binding` pattern + /// (after match ergonomics adjustments). + pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> BindingMode { + self.pat_binding_modes().get(id).copied().unwrap_or_else(|| { s.dcx().span_bug(sp, "missing binding mode"); }) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4d917963cd6..237aa66f486 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -740,51 +740,37 @@ impl<'tcx> TyCtxt<'tcx> { } /// Return the set of types that should be taken into account when checking - /// trait bounds on a coroutine's internal state. - // FIXME(compiler-errors): We should remove this when the old solver goes away; - // and all other usages of this function should go through `bound_coroutine_hidden_types` - // instead. - pub fn coroutine_hidden_types( - self, - def_id: DefId, - ) -> impl Iterator<Item = ty::EarlyBinder<'tcx, Ty<'tcx>>> { - let coroutine_layout = self.mir_coroutine_witnesses(def_id); - coroutine_layout - .as_ref() - .map_or_else(|| [].iter(), |l| l.field_tys.iter()) - .filter(|decl| !decl.ignore_for_traits) - .map(|decl| ty::EarlyBinder::bind(decl.ty)) - } - - /// Return the set of types that should be taken into account when checking /// trait bounds on a coroutine's internal state. This properly replaces /// `ReErased` with new existential bound lifetimes. - pub fn bound_coroutine_hidden_types( + pub fn coroutine_hidden_types( self, def_id: DefId, - ) -> impl Iterator<Item = ty::EarlyBinder<'tcx, ty::Binder<'tcx, Ty<'tcx>>>> { + ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> { let coroutine_layout = self.mir_coroutine_witnesses(def_id); - coroutine_layout - .as_ref() - .map_or_else(|| [].iter(), |l| l.field_tys.iter()) - .filter(|decl| !decl.ignore_for_traits) - .map(move |decl| { - let mut vars = vec![]; - let ty = fold_regions(self, decl.ty, |re, debruijn| { - assert_eq!(re, self.lifetimes.re_erased); - let var = ty::BoundVar::from_usize(vars.len()); - vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)); - ty::Region::new_bound( - self, - debruijn, - ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }, - ) - }); - ty::EarlyBinder::bind(ty::Binder::bind_with_vars( - ty, - self.mk_bound_variable_kinds(&vars), - )) - }) + let mut vars = vec![]; + let bound_tys = self.mk_type_list_from_iter( + coroutine_layout + .as_ref() + .map_or_else(|| [].iter(), |l| l.field_tys.iter()) + .filter(|decl| !decl.ignore_for_traits) + .map(|decl| { + let ty = fold_regions(self, decl.ty, |re, debruijn| { + assert_eq!(re, self.lifetimes.re_erased); + let var = ty::BoundVar::from_usize(vars.len()); + vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)); + ty::Region::new_bound( + self, + debruijn, + ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }, + ) + }); + ty + }), + ); + ty::EarlyBinder::bind(ty::Binder::bind_with_vars( + bound_tys, + self.mk_bound_variable_kinds(&vars), + )) } /// Expands the given impl trait type, stopping if the type is recursive. |
