summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/mod.rs')
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs183
1 files changed, 132 insertions, 51 deletions
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<Ident>;
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<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
- pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
- /// 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<Symbol, bool>,
pub main_def: Option<MainDefinition>,
pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
/// 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<Span, Span>,
pub registered_tools: RegisteredTools,
+ pub doc_link_resolutions: FxHashMap<LocalDefId, DocLinkResMap>,
+ pub doc_link_traits_in_scope: FxHashMap<LocalDefId, Vec<DefId>>,
+ pub all_macro_rules: FxHashMap<Symbol, Res<ast::NodeId>>,
}
/// 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<TyKind<'tcx>>>);
-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 <T as TraitRef>::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<StableHashingContext<'a>> for Term<'tcx> {
}
}
-impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> {
- fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
+ fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+ self,
+ folder: &mut F,
+ ) -> Result<Self, F::Error> {
Ok(self.unpack().try_fold_with(folder)?.pack())
}
}
-impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
+ fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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<AliasTy<'tcx>> {
+ 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<T> {
pub type PlaceholderRegion = Placeholder<BoundRegionKind>;
-pub type PlaceholderType = Placeholder<BoundVar>;
+pub type PlaceholderType = Placeholder<BoundTyKind>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
@@ -1589,8 +1622,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
}
}
-impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
- fn try_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>(
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
+ fn try_fold_with<F: ty::fold::FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
@@ -1602,8 +1635,8 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
}
}
-impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> {
- fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
+ fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.caller_bounds().visit_with(visitor)?;
self.reveal().visit_with(visitor)
}
@@ -1728,7 +1761,7 @@ impl<'tcx> ParamEnv<'tcx> {
/// `where Box<u32>: 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<T: TypeVisitable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
+ pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(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<AssocItem> {
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<DefId> {
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:
///