From 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:43 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/ty/mod.rs | 183 ++++++++++++++++++++++++++---------- 1 file changed, 132 insertions(+), 51 deletions(-) (limited to 'compiler/rustc_middle/src/ty/mod.rs') diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7dfcd1bb5..dce18a585 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -12,7 +12,7 @@ #![allow(rustc::usage_of_ty_tykind)] pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; -pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -31,23 +31,22 @@ pub use generics::*; use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_attr as attr; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, CtorOf, DefKind, LifetimeRes, Res}; +use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_hir::Node; use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::{Decodable, Encodable}; -use rustc_session::cstore::Untracked; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{ExpnId, Span}; +use rustc_span::{ExpnId, ExpnKind, Span}; use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx}; pub use rustc_target::abi::{ReprFlags, ReprOptions}; use rustc_type_ir::WithCachedTypeInfo; @@ -74,7 +73,7 @@ pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; pub use self::closure::{ is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo, - CapturedPlace, ClosureKind, MinCaptureInformationMap, MinCaptureList, + CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList, RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath, CAPTURE_STRUCT_LOCAL, }; @@ -154,7 +153,6 @@ pub type RegisteredTools = FxHashSet; pub struct ResolverOutputs { pub global_ctxt: ResolverGlobalCtxt, pub ast_lowering: ResolverAstLowering, - pub untracked: Untracked, } #[derive(Debug)] @@ -167,12 +165,8 @@ pub struct ResolverGlobalCtxt { pub effective_visibilities: EffectiveVisibilities, pub extern_crate_map: FxHashMap, pub maybe_unused_trait_imports: FxIndexSet, - pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, pub reexport_map: FxHashMap>, pub glob_map: FxHashMap>, - /// Extern prelude entries. The value is `true` if the entry was introduced - /// via `extern crate` item and not `--extern` option or compiler built-in. - pub extern_prelude: FxHashMap, pub main_def: Option, pub trait_impls: FxIndexMap>, /// A list of proc macro LocalDefIds, written out in the order in which @@ -182,6 +176,9 @@ pub struct ResolverGlobalCtxt { /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`. pub confused_type_with_std_module: FxHashMap, pub registered_tools: RegisteredTools, + pub doc_link_resolutions: FxHashMap, + pub doc_link_traits_in_scope: FxHashMap>, + pub all_macro_rules: FxHashMap>, } /// Resolutions that should only be used for lowering. @@ -453,18 +450,6 @@ pub struct CReaderCacheKey { #[rustc_pass_by_value] pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo>>); -impl<'tcx> TyCtxt<'tcx> { - /// A "bool" type used in rustc_mir_transform unit tests when we - /// have not spun up a TyCtxt. - pub const BOOL_TY_FOR_UNIT_TESTING: Ty<'tcx> = - Ty(Interned::new_unchecked(&WithCachedTypeInfo { - internee: ty::Bool, - stable_hash: Fingerprint::ZERO, - flags: TypeFlags::empty(), - outer_exclusive_binder: DebruijnIndex::from_usize(0), - })); -} - impl ty::EarlyBoundRegion { /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). @@ -558,6 +543,8 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(Clause::RegionOutlives(_)) | PredicateKind::Clause(Clause::TypeOutlives(_)) | PredicateKind::Clause(Clause::Projection(_)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) + | PredicateKind::AliasEq(..) | PredicateKind::ObjectSafe(_) | PredicateKind::ClosureKind(_, _, _) | PredicateKind::Subtype(_) @@ -595,6 +582,10 @@ pub enum Clause<'tcx> { /// `where ::Name == X`, approximately. /// See the `ProjectionPredicate` struct for details. Projection(ProjectionPredicate<'tcx>), + + /// Ensures that a const generic argument to a parameter `const N: u8` + /// is of type `u8`. + ConstArgHasType(Const<'tcx>, Ty<'tcx>), } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -645,6 +636,12 @@ pub enum PredicateKind<'tcx> { /// A marker predicate that is always ambiguous. /// Used for coherence to mark opaque types as possibly equal to each other but ambiguous. Ambiguous, + + /// Separate from `Clause::Projection` which is used for normalization in new solver. + /// This predicate requires two terms to be equal to eachother. + /// + /// Only used for new solver + AliasEq(Term<'tcx>, Term<'tcx>), } /// The crate outlives map is computed during typeck and contains the @@ -713,7 +710,7 @@ impl<'tcx> Predicate<'tcx> { // The substitution from the input trait-ref is therefore going to be // `'a => 'x` (where `'x` has a DB index of 1). // - The supertrait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an - // early-bound parameter and `'b' is a late-bound parameter with a + // early-bound parameter and `'b` is a late-bound parameter with a // DB index of 1. // - If we replace `'a` with `'x` from the input, it too will have // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>` @@ -756,7 +753,7 @@ impl<'tcx> Predicate<'tcx> { let new = EarlyBinder(shifted_pred).subst(tcx, trait_ref.skip_binder().substs); // 3) ['x] + ['b] -> ['x, 'b] let bound_vars = - tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars)); + tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars)); tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars)) } } @@ -917,14 +914,17 @@ impl<'a, 'tcx> HashStable> for Term<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for Term<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { Ok(self.unpack().try_fold_with(folder)?.pack()) } } -impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for Term<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { self.unpack().visit_with(visitor) } } @@ -976,6 +976,33 @@ impl<'tcx> Term<'tcx> { TermKind::Const(c) => c.into(), } } + + /// This function returns `None` for `AliasKind::Opaque`. + /// + /// FIXME: rename `AliasTy` to `AliasTerm` and make sure we correctly + /// deal with constants. + pub fn to_alias_term_no_opaque(&self, tcx: TyCtxt<'tcx>) -> Option> { + match self.unpack() { + TermKind::Ty(ty) => match ty.kind() { + ty::Alias(kind, alias_ty) => match kind { + AliasKind::Projection => Some(*alias_ty), + AliasKind::Opaque => None, + }, + _ => None, + }, + TermKind::Const(ct) => match ct.kind() { + ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def.did, uv.substs)), + _ => None, + }, + } + } + + pub fn is_infer(&self) -> bool { + match self.unpack() { + TermKind::Ty(ty) => ty.is_ty_or_numeric_infer(), + TermKind::Const(ct) => ct.is_ct_infer(), + } + } } const TAG_MASK: usize = 0b11; @@ -1165,6 +1192,8 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::Trait(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Projection(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) + | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) @@ -1184,6 +1213,8 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::Projection(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Trait(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) + | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) @@ -1203,7 +1234,9 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::TypeOutlives(data)) => Some(predicate.rebind(data)), PredicateKind::Clause(Clause::Trait(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::Clause(Clause::Projection(..)) + | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) @@ -1322,7 +1355,7 @@ pub struct OpaqueHiddenType<'tcx> { } impl<'tcx> OpaqueHiddenType<'tcx> { - pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) { + pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) -> ErrorGuaranteed { // Found different concrete types for the opaque type. let sub_diag = if self.span == other.span { TypeMismatchReason::ConflictType { span: self.span } @@ -1334,7 +1367,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { other_ty: other.ty, other_span: other.span, sub: sub_diag, - }); + }) } #[instrument(level = "debug", skip(tcx), ret)] @@ -1382,7 +1415,7 @@ pub struct Placeholder { pub type PlaceholderRegion = Placeholder; -pub type PlaceholderType = Placeholder; +pub type PlaceholderType = Placeholder; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] #[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] @@ -1589,8 +1622,8 @@ impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { - fn try_fold_with>( +impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { + fn try_fold_with>>( self, folder: &mut F, ) -> Result { @@ -1602,8 +1635,8 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { self.caller_bounds().visit_with(visitor)?; self.reveal().visit_with(visitor) } @@ -1728,7 +1761,7 @@ impl<'tcx> ParamEnv<'tcx> { /// `where Box: Copy`, which are clearly never /// satisfiable. We generally want to behave as if they were true, /// although the surrounding function is never reachable. - pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { + pub fn and>>(self, value: T) -> ParamEnvAnd<'tcx, T> { match self.reveal() { Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, @@ -1986,7 +2019,7 @@ impl<'tcx> FieldDef { /// Returns the type of this field. The resulting type is not normalized. The `subst` is /// typically obtained via the second field of [`TyKind::Adt`]. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { - tcx.bound_type_of(self.did).subst(tcx, subst) + tcx.type_of(self.did).subst(tcx, subst) } /// Computes the `Ident` of this variant by looking up the `Span` @@ -2038,6 +2071,12 @@ pub enum ImplOverlapKind { Issue33140, } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] +pub enum ImplTraitInTraitData { + Trait { fn_def_id: DefId, opaque_def_id: DefId }, + Impl { fn_def_id: DefId }, +} + impl<'tcx> TyCtxt<'tcx> { pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> { self.typeck(self.hir().body_owner_def_id(body)) @@ -2167,7 +2206,7 @@ impl<'tcx> TyCtxt<'tcx> { Some(Ident::new(def, span)) } - pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> { + pub fn opt_associated_item(self, def_id: DefId) -> Option { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { Some(self.associated_item(def_id)) } else { @@ -2357,15 +2396,17 @@ impl<'tcx> TyCtxt<'tcx> { self.trait_def(trait_def_id).has_auto_impl } + /// Returns `true` if this is coinductive, either because it is + /// an auto trait or because it has the `#[rustc_coinductive]` attribute. + pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { + self.trait_def(trait_def_id).is_coinductive + } + /// Returns `true` if this is a trait alias. pub fn trait_is_alias(self, trait_def_id: DefId) -> bool { self.def_kind(trait_def_id) == DefKind::TraitAlias } - pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { - self.trait_is_auto(trait_def_id) || self.lang_items().sized_trait() == Some(trait_def_id) - } - /// Returns layout of a generator. Layout might be unavailable if the /// generator is tainted by errors. pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> { @@ -2396,15 +2437,30 @@ impl<'tcx> TyCtxt<'tcx> { pub fn impl_of_method(self, def_id: DefId) -> Option { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { let parent = self.parent(def_id); - if let DefKind::Impl = self.def_kind(parent) { + if let DefKind::Impl { .. } = self.def_kind(parent) { return Some(parent); } } None } - /// If the given `DefId` belongs to a trait that was automatically derived, returns `true`. - pub fn is_builtin_derive(self, def_id: DefId) -> bool { + /// Check if the given `DefId` is `#\[automatically_derived\]`, *and* + /// whether it was produced by expanding a builtin derive macro. + pub fn is_builtin_derived(self, def_id: DefId) -> bool { + if self.is_automatically_derived(def_id) + && let Some(def_id) = def_id.as_local() + && let outer = self.def_span(def_id).ctxt().outer_expn_data() + && matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _)) + && self.has_attr(outer.macro_def_id.unwrap(), sym::rustc_builtin_macro) + { + true + } else { + false + } + } + + /// Check if the given `DefId` is `#\[automatically_derived\]`. + pub fn is_automatically_derived(self, def_id: DefId) -> bool { self.has_attr(def_id, sym::automatically_derived) } @@ -2437,6 +2493,7 @@ impl<'tcx> TyCtxt<'tcx> { ident } + // FIXME(vincenzoapalzzo): move the HirId to a LocalDefId pub fn adjust_ident_and_get_scope( self, mut ident: Ident, @@ -2470,10 +2527,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn is_object_safe(self, key: DefId) -> bool { - self.object_safety_violations(key).is_empty() - } - #[inline] pub fn is_const_fn_raw(self, def_id: DefId) -> bool { matches!( @@ -2494,6 +2547,34 @@ impl<'tcx> TyCtxt<'tcx> { } def_id } + + pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool { + if self.def_kind(def_id) != DefKind::AssocFn { + return false; + } + + let Some(item) = self.opt_associated_item(def_id) else { return false; }; + if item.container != ty::AssocItemContainer::ImplContainer { + return false; + } + + let Some(trait_item_def_id) = item.trait_item_def_id else { return false; }; + + // FIXME(RPITIT): This does a somewhat manual walk through the signature + // of the trait fn to look for any RPITITs, but that's kinda doing a lot + // of work. We can probably remove this when we refactor RPITITs to be + // associated types. + self.fn_sig(trait_item_def_id).subst_identity().skip_binder().output().walk().any(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Alias(ty::Projection, data) = ty.kind() + && self.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder + { + true + } else { + false + } + }) + } } /// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition. @@ -2619,7 +2700,7 @@ impl<'tcx> fmt::Debug for SymbolName<'tcx> { } #[derive(Debug, Default, Copy, Clone)] -pub struct FoundRelationships { +pub struct InferVarInfo { /// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo` /// obligation, where: /// -- cgit v1.2.3