summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty')
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs8
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs3
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs12
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs7
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs8
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs19
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs16
-rw-r--r--compiler/rustc_middle/src/ty/consts/valtree.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs105
-rw-r--r--compiler/rustc_middle/src/ty/context/tls.rs59
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs10
-rw-r--r--compiler/rustc_middle/src/ty/error.rs8
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs104
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs2
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs23
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs55
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs115
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs219
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs35
-rw-r--r--compiler/rustc_middle/src/ty/query.rs140
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs32
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs15
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs201
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs4
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs81
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs16
-rw-r--r--compiler/rustc_middle/src/ty/util.rs100
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs3
32 files changed, 862 insertions, 547 deletions
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index df9aa765d..468c2c818 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -37,10 +37,6 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
self.tcx
}
- fn intercrate(&self) -> bool {
- false
- }
-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.param_env
}
@@ -48,10 +44,6 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
true
} // irrelevant
- fn mark_ambiguous(&mut self) {
- bug!()
- }
-
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_: ty::Variance,
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index 8ce06404d..cd0f7e8da 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -3,6 +3,7 @@ use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
use rustc_macros::HashStable;
use rustc_span::Span;
+use rustc_target::abi::FieldIdx;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum PointerCast {
@@ -208,5 +209,5 @@ pub struct CoerceUnsizedInfo {
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum CustomCoerceUnsized {
/// Records the index of the field being coerced.
- Struct(usize),
+ Struct(FieldIdx),
}
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index ec21030b3..3a03c0901 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -10,11 +10,11 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
-use rustc_index::vec::{Idx, IndexVec};
+use rustc_index::vec::{IndexSlice, IndexVec};
use rustc_query_system::ich::StableHashingContext;
use rustc_session::DataTypeKind;
use rustc_span::symbol::sym;
-use rustc_target::abi::{ReprOptions, VariantIdx};
+use rustc_target::abi::{ReprOptions, VariantIdx, FIRST_VARIANT};
use std::cell::RefCell;
use std::cmp::Ordering;
@@ -168,7 +168,7 @@ impl<'tcx> AdtDef<'tcx> {
}
#[inline]
- pub fn variants(self) -> &'tcx IndexVec<VariantIdx, VariantDef> {
+ pub fn variants(self) -> &'tcx IndexSlice<VariantIdx, VariantDef> {
&self.0.0.variants
}
@@ -228,7 +228,7 @@ impl AdtDefData {
AdtKind::Struct => AdtFlags::IS_STRUCT,
};
- if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor.is_some() {
+ if kind == AdtKind::Struct && variants[FIRST_VARIANT].ctor.is_some() {
flags |= AdtFlags::HAS_CTOR;
}
@@ -357,7 +357,7 @@ impl<'tcx> AdtDef<'tcx> {
/// Asserts this is a struct or union and returns its unique variant.
pub fn non_enum_variant(self) -> &'tcx VariantDef {
assert!(self.is_struct() || self.is_union());
- &self.variant(VariantIdx::new(0))
+ &self.variant(FIRST_VARIANT)
}
#[inline]
@@ -493,7 +493,7 @@ impl<'tcx> AdtDef<'tcx> {
#[inline]
pub fn variant_range(self) -> Range<VariantIdx> {
- VariantIdx::new(0)..VariantIdx::new(self.variants().len())
+ FIRST_VARIANT..self.variants().next_index()
}
/// Computes the discriminant value used by a specific variant.
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index f1a9e50a4..090b76932 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -1,6 +1,6 @@
pub use self::AssocItemContainer::*;
-use crate::ty::{self, DefIdTree};
+use crate::ty;
use rustc_data_structures::sorted_map::SortedIndexMultiMap;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace};
@@ -30,6 +30,11 @@ pub struct AssocItem {
/// Whether this is a method with an explicit self
/// as its first parameter, allowing method calls.
pub fn_has_self_parameter: bool,
+
+ /// `Some` if the associated item (an associated type) comes from the
+ /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
+ /// provides additional information about its source.
+ pub opt_rpitit_info: Option<ty::ImplTraitInTraitData>,
}
impl AssocItem {
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index dc2bd54b7..f29bf92b0 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -158,12 +158,12 @@ impl<'tcx> CapturedPlace<'tcx> {
for proj in self.place.projections.iter() {
match proj.kind {
HirProjectionKind::Field(idx, variant) => match ty.kind() {
- ty::Tuple(_) => write!(&mut symbol, "__{}", idx).unwrap(),
+ ty::Tuple(_) => write!(&mut symbol, "__{}", idx.index()).unwrap(),
ty::Adt(def, ..) => {
write!(
&mut symbol,
"__{}",
- def.variant(variant).fields[idx as usize].name.as_str(),
+ def.variant(variant).fields[idx].name.as_str(),
)
.unwrap();
}
@@ -356,11 +356,11 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
curr_string = format!(
"{}.{}",
curr_string,
- def.variant(variant).fields[idx as usize].name.as_str()
+ def.variant(variant).fields[idx].name.as_str()
);
}
ty::Tuple(_) => {
- curr_string = format!("{}.{}", curr_string, idx);
+ curr_string = format!("{}.{}", curr_string, idx.index());
}
_ => {
bug!(
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 3ce80e06a..8ef4a46a7 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -511,8 +511,6 @@ macro_rules! implement_ty_decoder {
read_isize -> isize;
read_bool -> bool;
- read_f64 -> f64;
- read_f32 -> f32;
read_char -> char;
read_str -> &str;
}
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 527ec9f6e..bcedae233 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -1,10 +1,10 @@
use crate::middle::resolve_bound_vars as rbv;
use crate::mir::interpret::LitToConstInput;
-use crate::ty::{self, DefIdTree, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
+use crate::ty::{self, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
use rustc_data_structures::intern::Interned;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
use rustc_macros::HashStable;
use std::fmt;
@@ -83,7 +83,7 @@ impl<'tcx> Const<'tcx> {
None => tcx.mk_const(
ty::UnevaluatedConst {
def: def.to_global(),
- substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
+ substs: InternalSubsts::identity_for_item(tcx, def.did),
},
ty,
),
@@ -135,6 +135,9 @@ impl<'tcx> Const<'tcx> {
_,
&hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. },
)) => {
+ // Use the type from the param's definition, since we can resolve it,
+ // not the expected parameter type from WithOptConstParam.
+ let param_ty = tcx.type_of(def_id).subst_identity();
match tcx.named_bound_var(expr.hir_id) {
Some(rbv::ResolvedArg::EarlyBound(_)) => {
// Find the name and index of the const parameter by indexing the generics of
@@ -143,14 +146,14 @@ impl<'tcx> Const<'tcx> {
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.item_name(def_id);
- Some(tcx.mk_const(ty::ParamConst::new(index, name), ty))
+ Some(tcx.mk_const(ty::ParamConst::new(index, name), param_ty))
}
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => Some(tcx.mk_const(
ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)),
- ty,
+ param_ty,
)),
Some(rbv::ResolvedArg::Error(guar)) => {
- Some(tcx.const_error_with_guaranteed(ty, guar))
+ Some(tcx.const_error_with_guaranteed(param_ty, guar))
}
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id),
}
@@ -262,8 +265,8 @@ impl<'tcx> Const<'tcx> {
}
}
-pub fn const_param_default(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Const<'_>> {
- let default_def_id = match tcx.hir().get_by_def_id(def_id.expect_local()) {
+pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Const<'_>> {
+ let default_def_id = match tcx.hir().get_by_def_id(def_id) {
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { default: Some(ac), .. },
..
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index eecd78ab6..c0e557d48 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -237,7 +237,7 @@ impl ScalarInt {
}
/// Tries to convert the `ScalarInt` to an unsigned integer of the given size.
- /// Fails if the size of the `ScalarInt` is unequal to `size` and returns the
+ /// Fails if the size of the `ScalarInt` is not equal to `size` and returns the
/// `ScalarInt`s size in that case.
#[inline]
pub fn try_to_uint(self, size: Size) -> Result<u128, Size> {
@@ -297,7 +297,7 @@ impl ScalarInt {
}
/// Tries to convert the `ScalarInt` to a signed integer of the given size.
- /// Fails if the size of the `ScalarInt` is unequal to `size` and returns the
+ /// Fails if the size of the `ScalarInt` is not equal to `size` and returns the
/// `ScalarInt`s size in that case.
#[inline]
pub fn try_to_int(self, size: Size) -> Result<i128, Size> {
@@ -306,38 +306,38 @@ impl ScalarInt {
}
/// Tries to convert the `ScalarInt` to i8.
- /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 1 }`
+ /// Fails if the size of the `ScalarInt` is not equal to `Size { raw: 1 }`
/// and returns the `ScalarInt`s size in that case.
pub fn try_to_i8(self) -> Result<i8, Size> {
self.try_to_int(Size::from_bits(8)).map(|v| i8::try_from(v).unwrap())
}
/// Tries to convert the `ScalarInt` to i16.
- /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 2 }`
+ /// Fails if the size of the `ScalarInt` is not equal to `Size { raw: 2 }`
/// and returns the `ScalarInt`s size in that case.
pub fn try_to_i16(self) -> Result<i16, Size> {
self.try_to_int(Size::from_bits(16)).map(|v| i16::try_from(v).unwrap())
}
/// Tries to convert the `ScalarInt` to i32.
- /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 4 }`
+ /// Fails if the size of the `ScalarInt` is not equal to `Size { raw: 4 }`
/// and returns the `ScalarInt`s size in that case.
pub fn try_to_i32(self) -> Result<i32, Size> {
self.try_to_int(Size::from_bits(32)).map(|v| i32::try_from(v).unwrap())
}
/// Tries to convert the `ScalarInt` to i64.
- /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 8 }`
+ /// Fails if the size of the `ScalarInt` is not equal to `Size { raw: 8 }`
/// and returns the `ScalarInt`s size in that case.
pub fn try_to_i64(self) -> Result<i64, Size> {
self.try_to_int(Size::from_bits(64)).map(|v| i64::try_from(v).unwrap())
}
/// Tries to convert the `ScalarInt` to i128.
- /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 16 }`
+ /// Fails if the size of the `ScalarInt` is not equal to `Size { raw: 16 }`
/// and returns the `ScalarInt`s size in that case.
pub fn try_to_i128(self) -> Result<i128, Size> {
- self.try_to_int(Size::from_bits(128)).map(|v| i128::try_from(v).unwrap())
+ self.try_to_int(Size::from_bits(128))
}
}
diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs
index 5ed4af2e9..8b96864dd 100644
--- a/compiler/rustc_middle/src/ty/consts/valtree.rs
+++ b/compiler/rustc_middle/src/ty/consts/valtree.rs
@@ -79,7 +79,7 @@ impl<'tcx> ValTree<'tcx> {
}
pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
- self.try_to_scalar_int().map(|s| s.try_to_target_usize(tcx).ok()).flatten()
+ self.try_to_scalar_int().and_then(|s| s.try_to_target_usize(tcx).ok())
}
/// Get the values inside the ValTree as a slice of bytes. This only works for
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index d9af2fd74..63f7cc2ee 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -8,26 +8,26 @@ use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct};
use crate::infer::canonical::CanonicalVarInfo;
use crate::lint::struct_lint_level;
+use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::resolve_bound_vars;
use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstAllocation};
-use crate::mir::{
- Body, BorrowCheckResult, Field, Local, Place, PlaceElem, ProjectionKind, Promoted,
-};
+use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted};
+use crate::query::LocalCrate;
use crate::thir::Thir;
use crate::traits;
+use crate::traits::solve;
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
use crate::ty::query::{self, TyCtxtAt};
use crate::ty::{
- self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
- FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
- ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind,
- ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy,
- Visibility,
+ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
+ GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
+ PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions,
+ TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, Visibility,
};
use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
-use rustc_ast as ast;
+use rustc_ast::{self as ast, attr};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
@@ -37,6 +37,7 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{self, Lock, Lrc, MappedReadGuard, ReadGuard, WorkerLocal};
+use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
};
@@ -63,13 +64,14 @@ use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
-use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
+use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
use rustc_type_ir::sty::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, DynKind, Interner, TypeFlags};
use std::any::Any;
+use std::assert_matches::debug_assert_matches;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt;
@@ -310,7 +312,7 @@ pub struct CommonLifetimes<'tcx> {
pub re_vars: Vec<Region<'tcx>>,
/// Pre-interned values of the form:
- /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(v, None) })`
+ /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(None) })`
/// for small values of `i` and `v`.
pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
}
@@ -385,10 +387,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
.map(|v| {
mk(ty::ReLateBound(
ty::DebruijnIndex::from(i),
- ty::BoundRegion {
- var: ty::BoundVar::from(v),
- kind: ty::BrAnon(v, None),
- },
+ ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon(None) },
))
})
.collect()
@@ -537,6 +536,9 @@ pub struct GlobalCtxt<'tcx> {
/// Merge this with `selection_cache`?
pub evaluation_cache: traits::EvaluationCache<'tcx>,
+ /// Caches the results of goal evaluation in the new solver.
+ pub new_solver_evaluation_cache: solve::EvaluationCache<'tcx>,
+
/// Data layout specification for the current target.
pub data_layout: TargetDataLayout,
@@ -712,6 +714,7 @@ impl<'tcx> TyCtxt<'tcx> {
pred_rcache: Default::default(),
selection_cache: Default::default(),
evaluation_cache: Default::default(),
+ new_solver_evaluation_cache: Default::default(),
data_layout,
alloc_map: Lock::new(interpret::AllocMap::new()),
}
@@ -922,7 +925,7 @@ impl<'tcx> TyCtxt<'tcx> {
crate_name,
// Don't print the whole stable crate id. That's just
// annoying in debug output.
- stable_crate_id.to_u64() >> 8 * 6,
+ stable_crate_id.to_u64() >> (8 * 6),
self.def_path(def_id).to_string_no_crate_verbose()
)
}
@@ -2044,6 +2047,12 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline]
pub fn mk_alias(self, kind: ty::AliasKind, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> {
+ debug_assert_matches!(
+ (kind, self.def_kind(alias_ty.def_id)),
+ (ty::Opaque, DefKind::OpaqueTy)
+ | (ty::Projection, DefKind::AssocTy)
+ | (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder)
+ );
self.mk_ty_from_kind(Alias(kind, alias_ty))
}
@@ -2064,10 +2073,9 @@ impl<'tcx> TyCtxt<'tcx> {
bound_region: ty::BoundRegion,
) -> Region<'tcx> {
// Use a pre-interned one when possible.
- if let ty::BoundRegion { var, kind: ty::BrAnon(v, None) } = bound_region
- && var.as_u32() == v
+ if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region
&& let Some(inner) = self.lifetimes.re_late_bounds.get(debruijn.as_usize())
- && let Some(re) = inner.get(v as usize).copied()
+ && let Some(re) = inner.get(var.as_usize()).copied()
{
re
} else {
@@ -2112,7 +2120,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
+ pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Field(f, ty))
}
@@ -2372,7 +2380,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
let map = self.in_scope_traits_map(id.owner)?;
let candidates = map.get(&id.local_id)?;
- Some(&*candidates)
+ Some(candidates)
}
pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
@@ -2440,6 +2448,40 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn trait_solver_next(self) -> bool {
self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
}
+
+ pub fn lower_impl_trait_in_trait_to_assoc_ty(self) -> bool {
+ self.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty
+ }
+
+ pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
+ if self.lower_impl_trait_in_trait_to_assoc_ty() {
+ self.opt_rpitit_info(def_id).is_some()
+ } else {
+ self.def_kind(def_id) == DefKind::ImplTraitPlaceholder
+ }
+ }
+
+ /// Named module children from all items except `use` and `extern crate` imports.
+ ///
+ /// In addition to regular items this list also includes struct or variant constructors, and
+ /// items inside `extern {}` blocks because all of them introduce names into parent module.
+ /// For non-reexported children every such name is associated with a separate `DefId`.
+ ///
+ /// Module here is understood in name resolution sense - it can be a `mod` item,
+ /// or a crate root, or an enum, or a trait.
+ pub fn module_children_non_reexports(self, def_id: LocalDefId) -> &'tcx [LocalDefId] {
+ self.resolutions(()).module_children_non_reexports.get(&def_id).map_or(&[], |v| &v[..])
+ }
+
+ /// Named module children from `use` and `extern crate` imports.
+ ///
+ /// Reexported names are not associated with individual `DefId`s,
+ /// e.g. a glob import can introduce a lot of names, all with the same `DefId`.
+ /// That's why the list needs to contain `ModChild` structures describing all the names
+ /// individually instead of `DefId`s.
+ pub fn module_children_reexports(self, def_id: LocalDefId) -> &'tcx [ModChild] {
+ self.resolutions(()).module_children_reexports.get(&def_id).map_or(&[], |v| &v[..])
+ }
}
impl<'tcx> TyCtxtAt<'tcx> {
@@ -2482,26 +2524,21 @@ pub struct DeducedParamAttrs {
}
pub fn provide(providers: &mut ty::query::Providers) {
- providers.module_reexports =
- |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
providers.maybe_unused_trait_imports =
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
providers.names_imported_by_glob_use = |tcx, id| {
- tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
+ tcx.arena.alloc(UnordSet::from(
+ tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(),
+ ))
};
providers.extern_mod_stmt_cnum =
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
- providers.is_panic_runtime = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
- };
- providers.is_compiler_builtins = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
- };
- providers.has_panic_handler = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
+ providers.is_panic_runtime =
+ |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime);
+ providers.is_compiler_builtins =
+ |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins);
+ providers.has_panic_handler = |tcx, LocalCrate| {
// We want to check if the panic handler was defined in this crate
tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
};
diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs
index 5426ac8d7..fb0d90930 100644
--- a/compiler/rustc_middle/src/ty/context/tls.rs
+++ b/compiler/rustc_middle/src/ty/context/tls.rs
@@ -4,6 +4,8 @@ use crate::dep_graph::TaskDepsRef;
use crate::ty::query;
use rustc_data_structures::sync::{self, Lock};
use rustc_errors::Diagnostic;
+#[cfg(not(parallel_compiler))]
+use std::cell::Cell;
use std::mem;
use std::ptr;
use thin_vec::ThinVec;
@@ -47,52 +49,15 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
}
}
+// Import the thread-local variable from Rayon, which is preserved for Rayon jobs.
#[cfg(parallel_compiler)]
-mod tlv {
- use rustc_rayon_core as rayon_core;
- use std::ptr;
-
- /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
- /// This is used to get the pointer to the current `ImplicitCtxt`.
- #[inline]
- pub(super) fn get_tlv() -> *const () {
- ptr::from_exposed_addr(rayon_core::tlv::get())
- }
-
- /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
- /// to `value` during the call to `f`. It is restored to its previous value after.
- /// This is used to set the pointer to the new `ImplicitCtxt`.
- #[inline]
- pub(super) fn with_tlv<F: FnOnce() -> R, R>(value: *const (), f: F) -> R {
- rayon_core::tlv::with(value.expose_addr(), f)
- }
-}
+use rayon_core::tlv::TLV;
+// Otherwise define our own
#[cfg(not(parallel_compiler))]
-mod tlv {
- use std::cell::Cell;
- use std::ptr;
-
- thread_local! {
- /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
- static TLV: Cell<*const ()> = const { Cell::new(ptr::null()) };
- }
-
- /// Gets the pointer to the current `ImplicitCtxt`.
- #[inline]
- pub(super) fn get_tlv() -> *const () {
- TLV.with(|tlv| tlv.get())
- }
-
- /// Sets TLV to `value` during the call to `f`.
- /// It is restored to its previous value after.
- /// This is used to set the pointer to the new `ImplicitCtxt`.
- #[inline]
- pub(super) fn with_tlv<F: FnOnce() -> R, R>(value: *const (), f: F) -> R {
- let old = TLV.replace(value);
- let _reset = rustc_data_structures::OnDrop(move || TLV.set(old));
- f()
- }
+thread_local! {
+ /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
+ static TLV: Cell<*const ()> = const { Cell::new(ptr::null()) };
}
#[inline]
@@ -111,7 +76,11 @@ pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) ->
where
F: FnOnce() -> R,
{
- tlv::with_tlv(erase(context), f)
+ TLV.with(|tlv| {
+ let old = tlv.replace(erase(context));
+ let _reset = rustc_data_structures::OnDrop(move || tlv.set(old));
+ f()
+ })
}
/// Allows access to the current `ImplicitCtxt` in a closure if one is available.
@@ -120,7 +89,7 @@ pub fn with_context_opt<F, R>(f: F) -> R
where
F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
{
- let context = tlv::get_tlv();
+ let context = TLV.get();
if context.is_null() {
f(None)
} else {
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index e894e1aaf..ae0bb4949 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -3,9 +3,9 @@
use std::ops::ControlFlow;
use crate::ty::{
- AliasTy, Const, ConstKind, DefIdTree, FallibleTypeFolder, InferConst, InferTy, Opaque,
- PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
- TypeSuperVisitable, TypeVisitable, TypeVisitor,
+ AliasTy, Const, ConstKind, FallibleTypeFolder, InferConst, InferTy, Opaque, PolyTraitPredicate,
+ Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
+ TypeVisitor,
};
use rustc_data_structures::fx::FxHashMap;
@@ -117,7 +117,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
}
let param_name = trait_pred.skip_binder().self_ty().to_string();
- let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string();
+ let mut constraint = trait_pred.to_string();
if let Some((name, term)) = associated_ty {
// FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
@@ -144,7 +144,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
this requirement",
if generics.where_clause_span.is_empty() { "introducing a" } else { "extending the" },
),
- format!("{} {}: {}", generics.add_where_or_trailing_comma(), param_name, constraint),
+ format!("{} {constraint}", generics.add_where_or_trailing_comma()),
Applicability::MaybeIncorrect,
);
true
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 9c171a69d..aff6c77e0 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -151,12 +151,8 @@ impl<'tcx> TypeError<'tcx> {
.into(),
RegionsPlaceholderMismatch => "one type is more general than the other".into(),
ArgumentSorts(values, _) | Sorts(values) => {
- let mut expected = values.expected.sort_string(tcx);
- let mut found = values.found.sort_string(tcx);
- if expected == found {
- expected = values.expected.sort_string(tcx);
- found = values.found.sort_string(tcx);
- }
+ let expected = values.expected.sort_string(tcx);
+ let found = values.found.sort_string(tcx);
report_maybe_different(&expected, &found).into()
}
Traits(values) => {
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 59deade0a..31d00b65e 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -1,6 +1,6 @@
use crate::mir::Mutability;
use crate::ty::subst::GenericArgKind;
-use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeVisitableExt};
use rustc_hir::def_id::DefId;
use std::fmt::Debug;
use std::hash::Hash;
@@ -51,15 +51,36 @@ pub enum SimplifiedType {
/// generic parameters as if they were inference variables in that case.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum TreatParams {
- /// Treat parameters as placeholders in the given environment.
+ /// Treat parameters as infer vars. This is the correct mode for caching
+ /// an impl's type for lookup.
+ AsCandidateKey,
+ /// Treat parameters as placeholders in the given environment. This is the
+ /// correct mode for *lookup*, as during candidate selection.
///
- /// Note that this also causes us to treat projections as if they were
- /// placeholders. This is only correct if the given projection cannot
- /// be normalized in the current context. Even if normalization fails,
- /// it may still succeed later if the projection contains any inference
- /// variables.
- AsPlaceholder,
- AsInfer,
+ /// This also treats projections with inference variables as infer vars
+ /// since they could be further normalized.
+ ForLookup,
+ /// Treat parameters as placeholders in the given environment. This is the
+ /// correct mode for *lookup*, as during candidate selection.
+ ///
+ /// N.B. during deep rejection, this acts identically to `ForLookup`.
+ NextSolverLookup,
+}
+
+/// During fast-rejection, we have the choice of treating projection types
+/// as either simplifyable or not, depending on whether we expect the projection
+/// to be normalized/rigid.
+#[derive(PartialEq, Eq, Debug, Clone, Copy)]
+pub enum TreatProjections {
+ /// In the old solver we don't try to normalize projections
+ /// when looking up impls and only access them by using the
+ /// current self type. This means that if the self type is
+ /// a projection which could later be normalized, we must not
+ /// treat it as rigid.
+ ForLookup,
+ /// We can treat projections in the self type as opaque as
+ /// we separately look up impls for the normalized self type.
+ NextSolverLookup,
}
/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
@@ -115,19 +136,20 @@ pub fn simplify_type<'tcx>(
ty::FnPtr(f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
ty::Placeholder(..) => Some(PlaceholderSimplifiedType),
ty::Param(_) => match treat_params {
- TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType),
- TreatParams::AsInfer => None,
+ TreatParams::ForLookup | TreatParams::NextSolverLookup => {
+ Some(PlaceholderSimplifiedType)
+ }
+ TreatParams::AsCandidateKey => None,
},
ty::Alias(..) => match treat_params {
// When treating `ty::Param` as a placeholder, projections also
// don't unify with anything else as long as they are fully normalized.
//
// We will have to be careful with lazy normalization here.
- TreatParams::AsPlaceholder if !ty.has_non_region_infer() => {
- debug!("treating `{}` as a placeholder", ty);
- Some(PlaceholderSimplifiedType)
- }
- TreatParams::AsPlaceholder | TreatParams::AsInfer => None,
+ // FIXME(lazy_normalization): This is probably not right...
+ TreatParams::ForLookup if !ty.has_non_region_infer() => Some(PlaceholderSimplifiedType),
+ TreatParams::NextSolverLookup => Some(PlaceholderSimplifiedType),
+ TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
},
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
@@ -166,22 +188,24 @@ pub struct DeepRejectCtxt {
}
impl DeepRejectCtxt {
- pub fn generic_args_may_unify<'tcx>(
+ pub fn substs_refs_may_unify<'tcx>(
self,
- obligation_arg: ty::GenericArg<'tcx>,
- impl_arg: ty::GenericArg<'tcx>,
+ obligation_substs: SubstsRef<'tcx>,
+ impl_substs: SubstsRef<'tcx>,
) -> bool {
- match (obligation_arg.unpack(), impl_arg.unpack()) {
- // We don't fast reject based on regions for now.
- (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true,
- (GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => {
- self.types_may_unify(obl, imp)
- }
- (GenericArgKind::Const(obl), GenericArgKind::Const(imp)) => {
- self.consts_may_unify(obl, imp)
+ iter::zip(obligation_substs, impl_substs).all(|(obl, imp)| {
+ match (obl.unpack(), imp.unpack()) {
+ // We don't fast reject based on regions for now.
+ (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true,
+ (GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => {
+ self.types_may_unify(obl, imp)
+ }
+ (GenericArgKind::Const(obl), GenericArgKind::Const(imp)) => {
+ self.consts_may_unify(obl, imp)
+ }
+ _ => bug!("kind mismatch: {obl} {imp}"),
}
- _ => bug!("kind mismatch: {obligation_arg} {impl_arg}"),
- }
+ })
}
pub fn types_may_unify<'tcx>(self, obligation_ty: Ty<'tcx>, impl_ty: Ty<'tcx>) -> bool {
@@ -236,9 +260,7 @@ impl DeepRejectCtxt {
},
ty::Adt(obl_def, obl_substs) => match k {
&ty::Adt(impl_def, impl_substs) => {
- obl_def == impl_def
- && iter::zip(obl_substs, impl_substs)
- .all(|(obl, imp)| self.generic_args_may_unify(obl, imp))
+ obl_def == impl_def && self.substs_refs_may_unify(obl_substs, impl_substs)
}
_ => false,
},
@@ -290,15 +312,20 @@ impl DeepRejectCtxt {
// Impls cannot contain these types as these cannot be named directly.
ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false,
+ // Placeholder types don't unify with anything on their own
ty::Placeholder(..) | ty::Bound(..) => false,
// Depending on the value of `treat_obligation_params`, we either
// treat generic parameters like placeholders or like inference variables.
ty::Param(_) => match self.treat_obligation_params {
- TreatParams::AsPlaceholder => false,
- TreatParams::AsInfer => true,
+ TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
+ TreatParams::AsCandidateKey => true,
},
+ ty::Infer(ty::IntVar(_)) => impl_ty.is_integral(),
+
+ ty::Infer(ty::FloatVar(_)) => impl_ty.is_floating_point(),
+
ty::Infer(_) => true,
// As we're walking the whole type, it may encounter projections
@@ -333,10 +360,13 @@ impl DeepRejectCtxt {
let k = impl_ct.kind();
match obligation_ct.kind() {
ty::ConstKind::Param(_) => match self.treat_obligation_params {
- TreatParams::AsPlaceholder => false,
- TreatParams::AsInfer => true,
+ TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
+ TreatParams::AsCandidateKey => true,
},
+ // Placeholder consts don't unify with anything on their own
+ ty::ConstKind::Placeholder(_) => false,
+
// As we don't necessarily eagerly evaluate constants,
// they might unify with any value.
ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
@@ -349,7 +379,7 @@ impl DeepRejectCtxt {
ty::ConstKind::Infer(_) => true,
- ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
+ ty::ConstKind::Bound(..) => {
bug!("unexpected obl const: {:?}", obligation_ct)
}
}
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 91241ff40..5a6ee1238 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -288,7 +288,7 @@ impl FlagComputation {
self.add_ty(ty);
}
ty::PredicateKind::Ambiguous => {}
- ty::PredicateKind::AliasEq(t1, t2) => {
+ ty::PredicateKind::AliasRelate(t1, t2, _) => {
self.add_term(t1);
self.add_term(t2);
}
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index d66f436f9..203e16bea 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -51,9 +51,7 @@ where
// Region folder
impl<'tcx> TyCtxt<'tcx> {
- /// Folds the escaping and free regions in `value` using `f`, and
- /// sets `skipped_regions` to true if any late-bound region was found
- /// and skipped.
+ /// Folds the escaping and free regions in `value` using `f`.
pub fn fold_regions<T>(
self,
value: T,
@@ -64,17 +62,6 @@ impl<'tcx> TyCtxt<'tcx> {
{
value.fold_with(&mut RegionFolder::new(self, &mut f))
}
-
- pub fn super_fold_regions<T>(
- self,
- value: T,
- mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
- ) -> T
- where
- T: TypeSuperFoldable<TyCtxt<'tcx>>,
- {
- value.super_fold_with(&mut RegionFolder::new(self, &mut f))
- }
}
/// Folds over the substructure of a type, visiting its component
@@ -392,9 +379,7 @@ impl<'tcx> TyCtxt<'tcx> {
let index = entry.index();
let var = ty::BoundVar::from_usize(index);
let kind = entry
- .or_insert_with(|| {
- ty::BoundVariableKind::Region(ty::BrAnon(index as u32, None))
- })
+ .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon(None)))
.expect_region();
let br = ty::BoundRegion { var, kind };
self.tcx.mk_re_late_bound(ty::INNERMOST, br)
@@ -404,9 +389,7 @@ impl<'tcx> TyCtxt<'tcx> {
let index = entry.index();
let var = ty::BoundVar::from_usize(index);
let kind = entry
- .or_insert_with(|| {
- ty::BoundVariableKind::Ty(ty::BoundTyKind::Anon(index as u32))
- })
+ .or_insert_with(|| ty::BoundVariableKind::Ty(ty::BoundTyKind::Anon))
.expect_ty();
self.tcx.mk_bound(ty::INNERMOST, BoundTy { var, kind })
}
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index e268553f8..ac42d6e05 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -1,5 +1,5 @@
use crate::ty::context::TyCtxt;
-use crate::ty::{self, DefId, DefIdTree, ParamEnv, Ty};
+use crate::ty::{self, DefId, ParamEnv, Ty};
/// Represents whether some type is inhabited in a given context.
/// Examples of uninhabited types are `!`, `enum Void {}`, or a struct
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index f4028a5a9..e73225f70 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -82,6 +82,11 @@ pub enum InstanceDef<'tcx> {
/// The `DefId` is the ID of the `call_once` method in `FnOnce`.
ClosureOnceShim { call_once: DefId, track_caller: bool },
+ /// Compiler-generated accessor for thread locals which returns a reference to the thread local
+ /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking
+ /// native support.
+ ThreadLocalShim(DefId),
+
/// `core::ptr::drop_in_place::<T>`.
///
/// The `DefId` is for `core::ptr::drop_in_place`.
@@ -96,6 +101,13 @@ pub enum InstanceDef<'tcx> {
///
/// The `DefId` is for `Clone::clone`, the `Ty` is the type `T` with the builtin `Clone` impl.
CloneShim(DefId, Ty<'tcx>),
+
+ /// Compiler-generated `<T as FnPtr>::addr` implementation.
+ ///
+ /// Automatically generated for all potentially higher-ranked `fn(I) -> R` types.
+ ///
+ /// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`.
+ FnPtrAddrShim(DefId, Ty<'tcx>),
}
impl<'tcx> Instance<'tcx> {
@@ -149,9 +161,11 @@ impl<'tcx> InstanceDef<'tcx> {
| InstanceDef::FnPtrShim(def_id, _)
| InstanceDef::Virtual(def_id, _)
| InstanceDef::Intrinsic(def_id)
+ | InstanceDef::ThreadLocalShim(def_id)
| InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
| InstanceDef::DropGlue(def_id, _)
- | InstanceDef::CloneShim(def_id, _) => def_id,
+ | InstanceDef::CloneShim(def_id, _)
+ | InstanceDef::FnPtrAddrShim(def_id, _) => def_id,
}
}
@@ -159,7 +173,9 @@ impl<'tcx> InstanceDef<'tcx> {
pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
match self {
ty::InstanceDef::Item(def) => Some(def.did),
- ty::InstanceDef::DropGlue(def_id, Some(_)) => Some(def_id),
+ ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => {
+ Some(def_id)
+ }
InstanceDef::VTableShim(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::FnPtrShim(..)
@@ -167,7 +183,8 @@ impl<'tcx> InstanceDef<'tcx> {
| InstanceDef::Intrinsic(..)
| InstanceDef::ClosureOnceShim { .. }
| InstanceDef::DropGlue(..)
- | InstanceDef::CloneShim(..) => None,
+ | InstanceDef::CloneShim(..)
+ | InstanceDef::FnPtrAddrShim(..) => None,
}
}
@@ -182,12 +199,18 @@ impl<'tcx> InstanceDef<'tcx> {
| InstanceDef::Intrinsic(def_id)
| InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
| InstanceDef::DropGlue(def_id, _)
- | InstanceDef::CloneShim(def_id, _) => ty::WithOptConstParam::unknown(def_id),
+ | InstanceDef::CloneShim(def_id, _)
+ | InstanceDef::ThreadLocalShim(def_id)
+ | InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id),
}
}
#[inline]
- pub fn get_attrs(&self, tcx: TyCtxt<'tcx>, attr: Symbol) -> ty::Attributes<'tcx> {
+ pub fn get_attrs(
+ &self,
+ tcx: TyCtxt<'tcx>,
+ attr: Symbol,
+ ) -> impl Iterator<Item = &'tcx rustc_ast::Attribute> {
tcx.get_attrs(self.def_id(), attr)
}
@@ -201,6 +224,7 @@ impl<'tcx> InstanceDef<'tcx> {
let def_id = match *self {
ty::InstanceDef::Item(def) => def.did,
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
+ ty::InstanceDef::ThreadLocalShim(_) => return false,
_ => return true,
};
matches!(
@@ -241,6 +265,9 @@ impl<'tcx> InstanceDef<'tcx> {
)
});
}
+ if let ty::InstanceDef::ThreadLocalShim(..) = *self {
+ return false;
+ }
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
}
@@ -264,6 +291,8 @@ impl<'tcx> InstanceDef<'tcx> {
pub fn has_polymorphic_mir_body(&self) -> bool {
match *self {
InstanceDef::CloneShim(..)
+ | InstanceDef::ThreadLocalShim(..)
+ | InstanceDef::FnPtrAddrShim(..)
| InstanceDef::FnPtrShim(..)
| InstanceDef::DropGlue(_, Some(_)) => false,
InstanceDef::ClosureOnceShim { .. }
@@ -295,6 +324,7 @@ fn fmt_instance(
InstanceDef::Item(_) => Ok(()),
InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
+ InstanceDef::ThreadLocalShim(_) => write!(f, " - shim(tls)"),
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
@@ -302,6 +332,7 @@ fn fmt_instance(
InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
+ InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({})", ty),
}
}
@@ -781,6 +812,12 @@ fn needs_fn_once_adapter_shim(
#[derive(Debug, Copy, Clone, Eq, PartialEq, Decodable, Encodable, HashStable)]
pub struct UnusedGenericParams(FiniteBitSet<u32>);
+impl Default for UnusedGenericParams {
+ fn default() -> Self {
+ UnusedGenericParams::new_all_used()
+ }
+}
+
impl UnusedGenericParams {
pub fn new_all_unused(amount: u32) -> Self {
let mut bitset = FiniteBitSet::new_empty();
@@ -807,4 +844,12 @@ impl UnusedGenericParams {
pub fn all_used(&self) -> bool {
self.0.is_empty()
}
+
+ pub fn bits(&self) -> u32 {
+ self.0.0
+ }
+
+ pub fn from_bits(bits: u32) -> UnusedGenericParams {
+ UnusedGenericParams(FiniteBitSet(bits))
+ }
}
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 254ffc33c..195d951f9 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -5,7 +5,7 @@ use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
-use rustc_index::vec::Idx;
+use rustc_index::vec::IndexVec;
use rustc_session::config::OptLevel;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
@@ -281,6 +281,12 @@ pub enum SizeSkeleton<'tcx> {
/// Any statically computable Layout.
Known(Size),
+ /// This is a generic const expression (i.e. N * 2), which may contain some parameters.
+ /// It must be of type usize, and represents the size of a type in bytes.
+ /// It is not required to be evaluatable to a concrete value, but can be used to check
+ /// that another SizeSkeleton is of equal size.
+ Generic(ty::Const<'tcx>),
+
/// A potentially-fat pointer.
Pointer {
/// If true, this pointer is never null.
@@ -326,6 +332,37 @@ impl<'tcx> SizeSkeleton<'tcx> {
),
}
}
+ ty::Array(inner, len)
+ if len.ty() == tcx.types.usize && tcx.features().transmute_generic_consts =>
+ {
+ match SizeSkeleton::compute(inner, tcx, param_env)? {
+ // This may succeed because the multiplication of two types may overflow
+ // but a single size of a nested array will not.
+ SizeSkeleton::Known(s) => {
+ if let Some(c) = len.try_eval_target_usize(tcx, param_env) {
+ let size = s
+ .bytes()
+ .checked_mul(c)
+ .ok_or_else(|| LayoutError::SizeOverflow(ty))?;
+ return Ok(SizeSkeleton::Known(Size::from_bytes(size)));
+ }
+ let len = tcx.expand_abstract_consts(len);
+ let prev = ty::Const::from_target_usize(tcx, s.bytes());
+ let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, prev) else {
+ return Err(LayoutError::SizeOverflow(ty));
+ };
+ Ok(SizeSkeleton::Generic(gen_size))
+ }
+ SizeSkeleton::Pointer { .. } => Err(err),
+ SizeSkeleton::Generic(g) => {
+ let len = tcx.expand_abstract_consts(len);
+ let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, g) else {
+ return Err(LayoutError::SizeOverflow(ty));
+ };
+ Ok(SizeSkeleton::Generic(gen_size))
+ }
+ }
+ }
ty::Adt(def, substs) => {
// Only newtypes and enums w/ nullable pointer optimization.
@@ -335,7 +372,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
// Get a zero-sized variant or a pointer newtype.
let zero_or_ptr_variant = |i| {
- let i = VariantIdx::new(i);
+ let i = VariantIdx::from_usize(i);
let fields =
def.variant(i).fields.iter().map(|field| {
SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
@@ -355,6 +392,9 @@ impl<'tcx> SizeSkeleton<'tcx> {
}
ptr = Some(field);
}
+ SizeSkeleton::Generic(_) => {
+ return Err(err);
+ }
}
}
Ok(ptr)
@@ -410,11 +450,66 @@ impl<'tcx> SizeSkeleton<'tcx> {
(SizeSkeleton::Pointer { tail: a, .. }, SizeSkeleton::Pointer { tail: b, .. }) => {
a == b
}
+ // constants are always pre-normalized into a canonical form so this
+ // only needs to check if their pointers are identical.
+ (SizeSkeleton::Generic(a), SizeSkeleton::Generic(b)) => a == b,
_ => false,
}
}
}
+/// When creating the layout for types with abstract conts in their size (i.e. [usize; 4 * N]),
+/// to ensure that they have a canonical order and can be compared directly we combine all
+/// constants, and sort the other terms. This allows comparison of expressions of sizes,
+/// allowing for things like transmutating between types that depend on generic consts.
+/// This returns `None` if multiplication of constants overflows.
+fn mul_sorted_consts<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ a: ty::Const<'tcx>,
+ b: ty::Const<'tcx>,
+) -> Option<ty::Const<'tcx>> {
+ use crate::mir::BinOp::Mul;
+ use ty::ConstKind::Expr;
+ use ty::Expr::Binop;
+
+ let mut work = vec![a, b];
+ let mut done = vec![];
+ while let Some(n) = work.pop() {
+ if let Expr(Binop(Mul, l, r)) = n.kind() {
+ work.push(l);
+ work.push(r)
+ } else {
+ done.push(n);
+ }
+ }
+ let mut k = 1;
+ let mut overflow = false;
+ done.retain(|c| {
+ let Some(c) = c.try_eval_target_usize(tcx, param_env) else {
+ return true;
+ };
+ let Some(next) = c.checked_mul(k) else {
+ overflow = true;
+ return false;
+ };
+ k = next;
+ false
+ });
+ if overflow {
+ return None;
+ }
+ if k != 1 {
+ done.push(ty::Const::from_target_usize(tcx, k));
+ } else if k == 0 {
+ return Some(ty::Const::from_target_usize(tcx, 0));
+ }
+ done.sort_unstable();
+
+ // create a single tree from the buffer
+ done.into_iter().reduce(|acc, n| tcx.mk_const(Expr(Binop(Mul, n, acc)), n.ty()))
+}
+
pub trait HasTyCtxt<'tcx>: HasDataLayout {
fn tcx(&self) -> TyCtxt<'tcx>;
}
@@ -636,7 +731,7 @@ where
variants: Variants::Single { index: variant_index },
fields: match NonZeroUsize::new(fields) {
Some(fields) => FieldsShape::Union(fields),
- None => FieldsShape::Arbitrary { offsets: vec![], memory_index: vec![] },
+ None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
},
abi: Abi::Uninhabited,
largest_niche: None,
@@ -730,7 +825,11 @@ where
*/
};
- let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
+ let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type()
+ // Projection eagerly bails out when the pointee references errors,
+ // fall back to structurally deducing metadata.
+ && !pointee.references_error()
+ {
let metadata = tcx.normalize_erasing_regions(
cx.param_env(),
tcx.mk_projection(metadata_def_id, [pointee]),
@@ -794,7 +893,8 @@ where
ty::Adt(def, substs) => {
match this.variants {
Variants::Single { index } => {
- TyMaybeWithLayout::Ty(def.variant(index).fields[i].ty(tcx, substs))
+ let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
+ TyMaybeWithLayout::Ty(field.ty(tcx, substs))
}
// Discriminant field for enums (where applicable).
@@ -1126,10 +1226,11 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
| AvrNonBlockingInterrupt
| CCmseNonSecureCall
| Wasm
- | RustIntrinsic
| PlatformIntrinsic
| Unadjusted => false,
- Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
+ Rust | RustCall | RustCold | RustIntrinsic => {
+ tcx.sess.panic_strategy() == PanicStrategy::Unwind
+ }
}
}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index dce18a585..2e516f291 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -34,6 +34,7 @@ use rustc_attr as attr;
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::steal::Steal;
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
@@ -44,10 +45,12 @@ use rustc_index::vec::IndexVec;
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
use rustc_serialize::{Decodable, Encodable};
+use rustc_session::lint::LintBuffer;
+pub use rustc_session::lint::RegisteredTools;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ExpnId, ExpnKind, Span};
-use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx};
+use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
pub use rustc_target::abi::{ReprFlags, ReprOptions};
use rustc_type_ir::WithCachedTypeInfo;
pub use subst::*;
@@ -148,8 +151,6 @@ mod typeck_results;
// Data types
-pub type RegisteredTools = FxHashSet<Ident>;
-
pub struct ResolverOutputs {
pub global_ctxt: ResolverGlobalCtxt,
pub ast_lowering: ResolverAstLowering,
@@ -165,7 +166,8 @@ pub struct ResolverGlobalCtxt {
pub effective_visibilities: EffectiveVisibilities,
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
- pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
+ pub module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
+ pub module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
pub main_def: Option<MainDefinition>,
pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
@@ -175,7 +177,6 @@ pub struct ResolverGlobalCtxt {
/// Mapping from ident span to path span for paths that don't exist as written, but that
/// 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>>,
@@ -209,6 +210,9 @@ pub struct ResolverAstLowering {
pub builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
/// List functions and methods for which lifetime elision was successful.
pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
+
+ /// Lints that were emitted by the resolver and early lints.
+ pub lint_buffer: Steal<LintBuffer>,
}
#[derive(Clone, Copy, Debug)]
@@ -325,12 +329,15 @@ pub struct ClosureSizeProfileData<'tcx> {
pub after_feature_tys: Ty<'tcx>,
}
-pub trait DefIdTree: Copy {
- fn opt_parent(self, id: DefId) -> Option<DefId>;
+impl TyCtxt<'_> {
+ #[inline]
+ pub fn opt_parent(self, id: DefId) -> Option<DefId> {
+ self.def_key(id).parent.map(|index| DefId { index, ..id })
+ }
#[inline]
#[track_caller]
- fn parent(self, id: DefId) -> DefId {
+ pub fn parent(self, id: DefId) -> DefId {
match self.opt_parent(id) {
Some(id) => id,
// not `unwrap_or_else` to avoid breaking caller tracking
@@ -340,17 +347,17 @@ pub trait DefIdTree: Copy {
#[inline]
#[track_caller]
- fn opt_local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
+ pub fn opt_local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
self.opt_parent(id.to_def_id()).map(DefId::expect_local)
}
#[inline]
#[track_caller]
- fn local_parent(self, id: LocalDefId) -> LocalDefId {
+ pub fn local_parent(self, id: LocalDefId) -> LocalDefId {
self.parent(id.to_def_id()).expect_local()
}
- fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
+ pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
if descendant.krate != ancestor.krate {
return false;
}
@@ -365,13 +372,6 @@ pub trait DefIdTree: Copy {
}
}
-impl<'tcx> DefIdTree for TyCtxt<'tcx> {
- #[inline]
- fn opt_parent(self, id: DefId) -> Option<DefId> {
- self.def_key(id).parent.map(|index| DefId { index, ..id })
- }
-}
-
impl<Id> Visibility<Id> {
pub fn is_public(self) -> bool {
matches!(self, Visibility::Public)
@@ -391,19 +391,19 @@ impl<Id: Into<DefId>> Visibility<Id> {
}
/// Returns `true` if an item with this visibility is accessible from the given module.
- pub fn is_accessible_from(self, module: impl Into<DefId>, tree: impl DefIdTree) -> bool {
+ pub fn is_accessible_from(self, module: impl Into<DefId>, tcx: TyCtxt<'_>) -> bool {
match self {
// Public items are visible everywhere.
Visibility::Public => true,
- Visibility::Restricted(id) => tree.is_descendant_of(module.into(), id.into()),
+ Visibility::Restricted(id) => tcx.is_descendant_of(module.into(), id.into()),
}
}
/// Returns `true` if this visibility is at least as accessible as the given visibility
- pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tree: impl DefIdTree) -> bool {
+ pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tcx: TyCtxt<'_>) -> bool {
match vis {
Visibility::Public => self.is_public(),
- Visibility::Restricted(id) => self.is_accessible_from(id, tree),
+ Visibility::Restricted(id) => self.is_accessible_from(id, tcx),
}
}
}
@@ -544,7 +544,7 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::Clause(Clause::TypeOutlives(_))
| PredicateKind::Clause(Clause::Projection(_))
| PredicateKind::Clause(Clause::ConstArgHasType(..))
- | PredicateKind::AliasEq(..)
+ | PredicateKind::AliasRelate(..)
| PredicateKind::ObjectSafe(_)
| PredicateKind::ClosureKind(_, _, _)
| PredicateKind::Subtype(_)
@@ -641,7 +641,23 @@ pub enum PredicateKind<'tcx> {
/// This predicate requires two terms to be equal to eachother.
///
/// Only used for new solver
- AliasEq(Term<'tcx>, Term<'tcx>),
+ AliasRelate(Term<'tcx>, Term<'tcx>, AliasRelationDirection),
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
+#[derive(HashStable, Debug)]
+pub enum AliasRelationDirection {
+ Equate,
+ Subtype,
+}
+
+impl std::fmt::Display for AliasRelationDirection {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ AliasRelationDirection::Equate => write!(f, "=="),
+ AliasRelationDirection::Subtype => write!(f, "<:"),
+ }
+ }
}
/// The crate outlives map is computed during typeck and contains the
@@ -977,11 +993,11 @@ impl<'tcx> Term<'tcx> {
}
}
- /// This function returns `None` for `AliasKind::Opaque`.
+ /// This function returns the inner `AliasTy` if this term is a projection.
///
/// 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>> {
+ pub fn to_projection_term(&self, tcx: TyCtxt<'tcx>) -> Option<AliasTy<'tcx>> {
match self.unpack() {
TermKind::Ty(ty) => match ty.kind() {
ty::Alias(kind, alias_ty) => match kind {
@@ -999,7 +1015,7 @@ impl<'tcx> Term<'tcx> {
pub fn is_infer(&self) -> bool {
match self.unpack() {
- TermKind::Ty(ty) => ty.is_ty_or_numeric_infer(),
+ TermKind::Ty(ty) => ty.is_ty_var(),
TermKind::Const(ct) => ct.is_ct_infer(),
}
}
@@ -1036,6 +1052,21 @@ impl<'tcx> TermKind<'tcx> {
}
}
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum ParamTerm {
+ Ty(ParamTy),
+ Const(ParamConst),
+}
+
+impl ParamTerm {
+ pub fn index(self) -> usize {
+ match self {
+ ParamTerm::Ty(ty) => ty.index as usize,
+ ParamTerm::Const(ct) => ct.index as usize,
+ }
+ }
+}
+
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
@@ -1129,6 +1160,13 @@ impl<'tcx, T> ToPredicate<'tcx, T> for T {
}
}
+impl<'tcx> ToPredicate<'tcx> for PredicateKind<'tcx> {
+ #[inline(always)]
+ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
+ ty::Binder::dummy(self).to_predicate(tcx)
+ }
+}
+
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
@@ -1143,6 +1181,13 @@ impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> {
}
}
+impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
+ #[inline(always)]
+ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
+ ty::Binder::dummy(self).to_predicate(tcx)
+ }
+}
+
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
@@ -1193,7 +1238,7 @@ impl<'tcx> Predicate<'tcx> {
PredicateKind::Clause(Clause::Trait(t)) => Some(predicate.rebind(t)),
PredicateKind::Clause(Clause::Projection(..))
| PredicateKind::Clause(Clause::ConstArgHasType(..))
- | PredicateKind::AliasEq(..)
+ | PredicateKind::AliasRelate(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
| PredicateKind::Clause(Clause::RegionOutlives(..))
@@ -1214,7 +1259,7 @@ impl<'tcx> Predicate<'tcx> {
PredicateKind::Clause(Clause::Projection(t)) => Some(predicate.rebind(t)),
PredicateKind::Clause(Clause::Trait(..))
| PredicateKind::Clause(Clause::ConstArgHasType(..))
- | PredicateKind::AliasEq(..)
+ | PredicateKind::AliasRelate(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
| PredicateKind::Clause(Clause::RegionOutlives(..))
@@ -1236,7 +1281,7 @@ impl<'tcx> Predicate<'tcx> {
PredicateKind::Clause(Clause::Trait(..))
| PredicateKind::Clause(Clause::ConstArgHasType(..))
| PredicateKind::Clause(Clause::Projection(..))
- | PredicateKind::AliasEq(..)
+ | PredicateKind::AliasRelate(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
| PredicateKind::Clause(Clause::RegionOutlives(..))
@@ -1386,7 +1431,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
// lifetimes with 'static and remapping only those used in the
// `impl Trait` return type, resulting in the parameters
// shifting.
- let id_substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
debug!(?id_substs);
// This zip may have several times the same lifetime in `substs` paired with a different
@@ -1410,12 +1455,12 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
#[derive(HashStable, TyEncodable, TyDecodable)]
pub struct Placeholder<T> {
pub universe: UniverseIndex,
- pub name: T,
+ pub bound: T,
}
-pub type PlaceholderRegion = Placeholder<BoundRegionKind>;
+pub type PlaceholderRegion = Placeholder<BoundRegion>;
-pub type PlaceholderType = Placeholder<BoundTyKind>;
+pub type PlaceholderType = Placeholder<BoundTy>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
@@ -1847,7 +1892,7 @@ pub struct VariantDef {
/// Discriminant of this variant.
pub discr: VariantDiscr,
/// Fields of this variant.
- pub fields: Vec<FieldDef>,
+ pub fields: IndexVec<FieldIdx, FieldDef>,
/// Flags of the variant (e.g. is field list non-exhaustive)?
flags: VariantFlags,
}
@@ -1874,7 +1919,7 @@ impl VariantDef {
variant_did: Option<DefId>,
ctor: Option<(CtorKind, DefId)>,
discr: VariantDiscr,
- fields: Vec<FieldDef>,
+ fields: IndexVec<FieldIdx, FieldDef>,
adt_kind: AdtKind,
parent_did: DefId,
recovered: bool,
@@ -2028,7 +2073,6 @@ impl<'tcx> FieldDef {
}
}
-pub type Attributes<'tcx> = impl Iterator<Item = &'tcx ast::Attribute>;
#[derive(Debug, PartialEq, Eq)]
pub enum ImplOverlapKind {
/// These impls are always allowed to overlap.
@@ -2071,7 +2115,9 @@ pub enum ImplOverlapKind {
Issue33140,
}
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
+/// Useful source information about where a desugared associated type for an
+/// RPITIT originated from.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
pub enum ImplTraitInTraitData {
Trait { fn_def_id: DefId, opaque_def_id: DefId },
Impl { fn_def_id: DefId },
@@ -2214,26 +2260,37 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
- variant
- .fields
- .iter()
- .position(|field| self.hygienic_eq(ident, field.ident(self), variant.def_id))
+ /// If the def-id is an associated type that was desugared from a
+ /// return-position `impl Trait` from a trait, then provide the source info
+ /// about where that RPITIT came from.
+ pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
+ if let DefKind::AssocTy = self.def_kind(def_id) {
+ self.associated_item(def_id).opt_rpitit_info
+ } else {
+ None
+ }
+ }
+
+ pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<FieldIdx> {
+ variant.fields.iter_enumerated().find_map(|(i, field)| {
+ self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i)
+ })
}
/// Returns `true` if the impls are the same polarity and the trait either
/// has no items or is annotated `#[marker]` and prevents item overrides.
+ #[instrument(level = "debug", skip(self), ret)]
pub fn impls_are_allowed_to_overlap(
self,
def_id1: DefId,
def_id2: DefId,
) -> Option<ImplOverlapKind> {
+ let impl_trait_ref1 = self.impl_trait_ref(def_id1);
+ let impl_trait_ref2 = self.impl_trait_ref(def_id2);
// If either trait impl references an error, they're allowed to overlap,
// as one of them essentially doesn't exist.
- if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.subst_identity().references_error())
- || self
- .impl_trait_ref(def_id2)
- .map_or(false, |tr| tr.subst_identity().references_error())
+ if impl_trait_ref1.map_or(false, |tr| tr.subst_identity().references_error())
+ || impl_trait_ref2.map_or(false, |tr| tr.subst_identity().references_error())
{
return Some(ImplOverlapKind::Permitted { marker: false });
}
@@ -2241,19 +2298,11 @@ impl<'tcx> TyCtxt<'tcx> {
match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) {
(ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => {
// `#[rustc_reservation_impl]` impls don't overlap with anything
- debug!(
- "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)",
- def_id1, def_id2
- );
return Some(ImplOverlapKind::Permitted { marker: false });
}
(ImplPolarity::Positive, ImplPolarity::Negative)
| (ImplPolarity::Negative, ImplPolarity::Positive) => {
// `impl AutoTrait for Type` + `impl !AutoTrait for Type`
- debug!(
- "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)",
- def_id1, def_id2
- );
return None;
}
(ImplPolarity::Positive, ImplPolarity::Positive)
@@ -2261,38 +2310,25 @@ impl<'tcx> TyCtxt<'tcx> {
};
let is_marker_overlap = {
- let is_marker_impl = |def_id: DefId| -> bool {
- let trait_ref = self.impl_trait_ref(def_id);
+ let is_marker_impl = |trait_ref: Option<EarlyBinder<TraitRef<'_>>>| -> bool {
trait_ref.map_or(false, |tr| self.trait_def(tr.skip_binder().def_id).is_marker)
};
- is_marker_impl(def_id1) && is_marker_impl(def_id2)
+ is_marker_impl(impl_trait_ref1) && is_marker_impl(impl_trait_ref2)
};
if is_marker_overlap {
- debug!(
- "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)",
- def_id1, def_id2
- );
Some(ImplOverlapKind::Permitted { marker: true })
} else {
if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
if self_ty1 == self_ty2 {
- debug!(
- "impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
- def_id1, def_id2
- );
return Some(ImplOverlapKind::Issue33140);
} else {
- debug!(
- "impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
- def_id1, def_id2, self_ty1, self_ty2
- );
+ debug!("found {self_ty1:?} != {self_ty2:?}");
}
}
}
- debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2);
None
}
}
@@ -2349,7 +2385,9 @@ impl<'tcx> TyCtxt<'tcx> {
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::DropGlue(..)
- | ty::InstanceDef::CloneShim(..) => self.mir_shims(instance),
+ | ty::InstanceDef::CloneShim(..)
+ | ty::InstanceDef::ThreadLocalShim(..)
+ | ty::InstanceDef::FnPtrAddrShim(..) => self.mir_shims(instance),
}
}
@@ -2363,7 +2401,12 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Gets all attributes with the given name.
- pub fn get_attrs(self, did: DefId, attr: Symbol) -> ty::Attributes<'tcx> {
+ pub fn get_attrs(
+ self,
+ did: impl Into<DefId>,
+ attr: Symbol,
+ ) -> impl Iterator<Item = &'tcx ast::Attribute> {
+ let did: DefId = did.into();
let filter_fn = move |a: &&ast::Attribute| a.has_name(attr);
if let Some(did) = did.as_local() {
self.hir().attrs(self.hir().local_def_id_to_hir_id(did)).iter().filter(filter_fn)
@@ -2374,8 +2417,9 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
+ pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx ast::Attribute> {
if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
+ let did: DefId = did.into();
bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
} else {
self.get_attrs(did, attr).next()
@@ -2383,7 +2427,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Determines whether an item is annotated with an attribute.
- pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
+ pub fn has_attr(self, did: impl Into<DefId>, attr: Symbol) -> bool {
+ let did: DefId = did.into();
if cfg!(debug_assertions) && !did.is_local() && rustc_feature::is_builtin_only_local(attr) {
bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr);
} else {
@@ -2493,7 +2538,7 @@ impl<'tcx> TyCtxt<'tcx> {
ident
}
- // FIXME(vincenzoapalzzo): move the HirId to a LocalDefId
+ // FIXME(vincenzopalazzo): move the HirId to a LocalDefId
pub fn adjust_ident_and_get_scope(
self,
mut ident: Ident,
@@ -2540,12 +2585,18 @@ impl<'tcx> TyCtxt<'tcx> {
matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
}
- pub fn impl_trait_in_trait_parent(self, mut def_id: DefId) -> DefId {
- while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
- debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
- def_id = self.parent(def_id);
+ pub fn impl_trait_in_trait_parent_fn(self, mut def_id: DefId) -> DefId {
+ match self.opt_rpitit_info(def_id) {
+ Some(ImplTraitInTraitData::Trait { fn_def_id, .. })
+ | Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) => fn_def_id,
+ None => {
+ while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
+ debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
+ def_id = self.parent(def_id);
+ }
+ def_id
+ }
}
- def_id
}
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
@@ -2560,6 +2611,12 @@ impl<'tcx> TyCtxt<'tcx> {
let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
+ if self.lower_impl_trait_in_trait_to_assoc_ty() {
+ return !self
+ .associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
+ .is_empty();
+ }
+
// 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
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 8849e7eab..7534d06ae 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -63,6 +63,7 @@ trivially_parameterized_over_tcx! {
ty::DeducedParamAttrs,
ty::Generics,
ty::ImplPolarity,
+ ty::ImplTraitInTraitData,
ty::ReprOptions,
ty::TraitDef,
ty::UnusedGenericParams,
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 021c20b58..d947d9604 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -1,5 +1,5 @@
use crate::ty::GenericArg;
-use crate::ty::{self, DefIdTree, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sso::SsoHashSet;
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 6a053c368..72caadaf6 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1,6 +1,6 @@
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::ty::{
- self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
+ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use crate::ty::{GenericArg, GenericArgKind};
@@ -701,10 +701,12 @@ pub trait PrettyPrinter<'tcx>:
ty::Error(_) => p!("[type error]"),
ty::Param(ref param_ty) => p!(print(param_ty)),
ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
- ty::BoundTyKind::Anon(bv) => {
- self.pretty_print_bound_var(debruijn, ty::BoundVar::from_u32(bv))?
- }
- ty::BoundTyKind::Param(_, s) => p!(write("{}", s)),
+ ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
+ ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() {
+ true if debruijn == ty::INNERMOST => p!(write("^{}", s)),
+ true => p!(write("^{}_{}", debruijn.index(), s)),
+ false => p!(write("{}", s)),
+ },
},
ty::Adt(def, substs) => {
p!(print_def_path(def.did(), substs));
@@ -728,15 +730,15 @@ pub trait PrettyPrinter<'tcx>:
}
ty::Alias(ty::Projection, ref data) => {
if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get()))
- && self.tcx().def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
+ && self.tcx().is_impl_trait_in_trait(data.def_id)
{
return self.pretty_print_opaque_impl_type(data.def_id, data.substs);
} else {
p!(print(data))
}
}
- ty::Placeholder(placeholder) => match placeholder.name {
- ty::BoundTyKind::Anon(_) => p!(write("Placeholder({:?})", placeholder)),
+ ty::Placeholder(placeholder) => match placeholder.bound.kind {
+ ty::BoundTyKind::Anon => p!(write("Placeholder({:?})", placeholder)),
ty::BoundTyKind::Param(_, name) => p!(write("{}", name)),
},
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
@@ -1345,7 +1347,7 @@ pub trait PrettyPrinter<'tcx>:
p!(write("{}::{}", self.tcx().crate_name(def.did.krate), self.tcx().def_path(def.did).to_string_no_crate_verbose()))
}
}
- defkind => bug!("`{:?}` has unexpcted defkind {:?}", ct, defkind),
+ defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind),
}
}
ty::ConstKind::Infer(infer_ct) => {
@@ -2100,7 +2102,9 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
- | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
+ | ty::RePlaceholder(ty::Placeholder {
+ bound: ty::BoundRegion { kind: br, .. }, ..
+ }) => {
if br.is_named() {
return true;
}
@@ -2177,7 +2181,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
}
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
- | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
+ | ty::RePlaceholder(ty::Placeholder {
+ bound: ty::BoundRegion { kind: br, .. }, ..
+ }) => {
if let ty::BrNamed(_, name) = br && br.is_named() {
p!(write("{}", name));
return Ok(self);
@@ -2255,7 +2261,10 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
ty::ReLateBound(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 { name: kind, .. }) => {
+ ty::RePlaceholder(ty::PlaceholderRegion {
+ bound: ty::BoundRegion { kind, .. },
+ ..
+ }) => {
// If this is an anonymous placeholder, don't rename. Otherwise, in some
// async fns, we get a `for<'r> Send` bound
match kind {
@@ -2847,7 +2856,7 @@ define_print_and_forward_display! {
p!("the type `", print(ty), "` is found in the environment")
}
ty::PredicateKind::Ambiguous => p!("ambiguous"),
- ty::PredicateKind::AliasEq(t1, t2) => p!(print(t1), " == ", print(t2)),
+ ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
}
}
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 2bc51baf8..fa9fea723 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -17,7 +17,8 @@ use crate::mir::interpret::{
};
use crate::mir::interpret::{LitToConstError, LitToConstInput};
use crate::mir::mono::CodegenUnit;
-use crate::query::Key;
+use crate::query::erase::{erase, restore, Erase};
+use crate::query::{AsLocalKey, Key};
use crate::thir;
use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
@@ -41,7 +42,7 @@ use rustc_arena::TypedArena;
use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
@@ -50,11 +51,15 @@ use rustc_data_structures::unord::UnordSet;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, DocLinkResMap};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
+use rustc_hir::def_id::{
+ CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet,
+};
use rustc_hir::hir_id::OwnerId;
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::vec::IndexVec;
+pub(crate) use rustc_query_system::query::QueryJobId;
+use rustc_query_system::query::*;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::cstore::{CrateDepKind, CrateSource};
use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
@@ -64,18 +69,19 @@ use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi;
use rustc_target::spec::PanicStrategy;
+
+use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
-pub(crate) use rustc_query_system::query::QueryJobId;
-use rustc_query_system::query::*;
-
#[derive(Default)]
pub struct QuerySystem<'tcx> {
pub arenas: QueryArenas<'tcx>,
pub caches: QueryCaches<'tcx>,
+ // Since we erase query value types we tell the typesystem about them with `PhantomData`.
+ _phantom_values: QueryPhantomValues<'tcx>,
}
#[derive(Copy, Clone)]
@@ -97,6 +103,11 @@ pub struct TyCtxtEnsure<'tcx> {
pub tcx: TyCtxt<'tcx>,
}
+#[derive(Copy, Clone)]
+pub struct TyCtxtEnsureWithValue<'tcx> {
+ pub tcx: TyCtxt<'tcx>,
+}
+
impl<'tcx> TyCtxt<'tcx> {
/// Returns a transparent wrapper for `TyCtxt`, which ensures queries
/// are executed instead of just returning their results.
@@ -105,6 +116,15 @@ impl<'tcx> TyCtxt<'tcx> {
TyCtxtEnsure { tcx: self }
}
+ /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
+ /// are executed instead of just returning their results.
+ ///
+ /// This version verifies that the computed result exists in the cache before returning.
+ #[inline(always)]
+ pub fn ensure_with_value(self) -> TyCtxtEnsureWithValue<'tcx> {
+ TyCtxtEnsureWithValue { tcx: self }
+ }
+
/// Returns a transparent wrapper for `TyCtxt` which uses
/// `span` as the location of queries performed through it.
#[inline(always)]
@@ -135,6 +155,20 @@ macro_rules! query_if_arena {
};
}
+/// If `separate_provide_if_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)*) => {
+ $($K)*
+ };
+ ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
+ <$($K)* as AsLocalKey>::LocalKey
+ };
+ ([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
+ local_key_if_separate_extern!([$($modifiers)*] $($K)*)
+ };
+}
+
macro_rules! separate_provide_extern_decl {
([][$name:ident]) => {
()
@@ -196,6 +230,12 @@ macro_rules! define_callbacks {
$(pub type $name<'tcx> = $($K)*;)*
}
#[allow(nonstandard_style, unused_lifetimes)]
+ pub mod query_keys_local {
+ use super::*;
+
+ $(pub type $name<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);)*
+ }
+ #[allow(nonstandard_style, unused_lifetimes)]
pub mod query_values {
use super::*;
@@ -227,8 +267,8 @@ macro_rules! define_callbacks {
pub fn $name<'tcx>(
_tcx: TyCtxt<'tcx>,
value: query_provided::$name<'tcx>,
- ) -> query_values::$name<'tcx> {
- query_if_arena!([$($modifiers)*]
+ ) -> Erase<query_values::$name<'tcx>> {
+ erase(query_if_arena!([$($modifiers)*]
{
if mem::needs_drop::<query_provided::$name<'tcx>>() {
&*_tcx.query_system.arenas.$name.alloc(value)
@@ -237,7 +277,7 @@ macro_rules! define_callbacks {
}
}
(value)
- )
+ ))
}
)*
}
@@ -246,10 +286,40 @@ macro_rules! define_callbacks {
use super::*;
$(
- pub type $name<'tcx> = <<$($K)* as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache;
+ pub type $name<'tcx> = <<$($K)* as Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>>>::Cache;
)*
}
+ $(
+ // Ensure that keys grow no larger than 64 bytes
+ #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+ const _: () = {
+ if mem::size_of::<query_keys::$name<'static>>() > 64 {
+ panic!("{}", concat!(
+ "the query `",
+ stringify!($name),
+ "` has a key type `",
+ stringify!($($K)*),
+ "` that is too large"
+ ));
+ }
+ };
+
+ // Ensure that values grow no larger than 64 bytes
+ #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+ const _: () = {
+ if mem::size_of::<query_values::$name<'static>>() > 64 {
+ panic!("{}", concat!(
+ "the query `",
+ stringify!($name),
+ "` has a value type `",
+ stringify!($V),
+ "` that is too large"
+ ));
+ }
+ };
+ )*
+
pub struct QueryArenas<'tcx> {
$($(#[$attr])* pub $name: query_if_arena!([$($modifiers)*]
(WorkerLocal<TypedArena<<$V as Deref>::Target>>)
@@ -269,6 +339,11 @@ macro_rules! define_callbacks {
}
#[derive(Default)]
+ pub struct QueryPhantomValues<'tcx> {
+ $($(#[$attr])* pub $name: PhantomData<query_values::$name<'tcx>>,)*
+ }
+
+ #[derive(Default)]
pub struct QueryCaches<'tcx> {
$($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
}
@@ -282,7 +357,31 @@ macro_rules! define_callbacks {
match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
Some(_) => return,
- None => self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure),
+ None => self.tcx.queries.$name(
+ self.tcx,
+ DUMMY_SP,
+ key,
+ QueryMode::Ensure { check_cache: false },
+ ),
+ };
+ })*
+ }
+
+ impl<'tcx> TyCtxtEnsureWithValue<'tcx> {
+ $($(#[$attr])*
+ #[inline(always)]
+ pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
+ let key = key.into_query_param();
+ opt_remap_env_constness!([$($modifiers)*][key]);
+
+ match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
+ Some(_) => return,
+ None => self.tcx.queries.$name(
+ self.tcx,
+ DUMMY_SP,
+ key,
+ QueryMode::Ensure { check_cache: true },
+ ),
};
})*
}
@@ -305,17 +404,17 @@ macro_rules! define_callbacks {
let key = key.into_query_param();
opt_remap_env_constness!([$($modifiers)*][key]);
- match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
+ restore::<$V>(match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
Some(value) => value,
None => self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap(),
- }
+ })
})*
}
pub struct Providers {
$(pub $name: for<'tcx> fn(
TyCtxt<'tcx>,
- query_keys::$name<'tcx>,
+ query_keys_local::$name<'tcx>,
) -> query_provided::$name<'tcx>,)*
}
@@ -325,17 +424,14 @@ macro_rules! define_callbacks {
impl Default for Providers {
fn default() -> Self {
- use crate::query::Key;
-
Providers {
$($name: |_, key| bug!(
- "`tcx.{}({:?})` is not supported for {} crate;\n\
+ "`tcx.{}({:?})` is not supported for this key;\n\
hint: Queries can be either made to the local crate, or the external crate. \
This error means you tried to use it for one that's not supported.\n\
If that's not the case, {} was likely never assigned to a provider function.\n",
stringify!($name),
key,
- if key.query_crate_is_local() { "local" } else { "external" },
stringify!($name),
),)*
}
@@ -372,7 +468,7 @@ macro_rules! define_callbacks {
span: Span,
key: query_keys::$name<'tcx>,
mode: QueryMode,
- ) -> Option<$V>;)*
+ ) -> Option<Erase<$V>>;)*
}
};
}
@@ -399,11 +495,13 @@ macro_rules! define_feedable {
opt_remap_env_constness!([$($modifiers)*][key]);
let tcx = self.tcx;
- let value = query_provided_to_value::$name(tcx, value);
+ let erased = query_provided_to_value::$name(tcx, value);
+ let value = restore::<$V>(erased);
let cache = &tcx.query_system.caches.$name;
match try_get_cached(tcx, cache, &key) {
Some(old) => {
+ let old = restore::<$V>(old);
bug!(
"Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
stringify!($name),
@@ -418,7 +516,7 @@ macro_rules! define_feedable {
&value,
hash_result!([$($modifiers)*]),
);
- cache.complete(key, value, dep_node_index);
+ cache.complete(key, erased, dep_node_index);
value
}
}
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 3fc5f5bed..46c931d61 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -22,8 +22,6 @@ pub enum Cause {
pub trait TypeRelation<'tcx>: Sized {
fn tcx(&self) -> TyCtxt<'tcx>;
- fn intercrate(&self) -> bool;
-
fn param_env(&self) -> ty::ParamEnv<'tcx>;
/// Returns a static string we can use for printouts.
@@ -33,9 +31,6 @@ pub trait TypeRelation<'tcx>: Sized {
/// relation. Just affects error messages.
fn a_is_expected(&self) -> bool;
- /// Used during coherence. If called, must emit an always-ambiguous obligation.
- fn mark_ambiguous(&mut self);
-
fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
where
F: FnOnce(&mut Self) -> R,
@@ -559,23 +554,16 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: a_substs, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: b_substs, .. }),
) if a_def_id == b_def_id => {
- if relation.intercrate() {
- // During coherence, opaque types should be treated as equal to each other, even if their generic params
- // differ, as they could resolve to the same hidden type, even for different generic params.
- relation.mark_ambiguous();
- Ok(a)
- } else {
- let opt_variances = tcx.variances_of(a_def_id);
- let substs = relate_substs_with_variances(
- relation,
- a_def_id,
- opt_variances,
- a_substs,
- b_substs,
- false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
- )?;
- Ok(tcx.mk_opaque(a_def_id, substs))
- }
+ let opt_variances = tcx.variances_of(a_def_id);
+ let substs = relate_substs_with_variances(
+ relation,
+ a_def_id,
+ opt_variances,
+ a_substs,
+ b_substs,
+ false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
+ )?;
+ Ok(tcx.mk_opaque(a_def_id, substs))
}
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index ef643531b..5c604bb6d 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -4,7 +4,7 @@
//! to help with the tedium.
use crate::mir::interpret;
-use crate::mir::{Field, ProjectionKind};
+use crate::mir::ProjectionKind;
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -68,7 +68,7 @@ impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
impl fmt::Debug for ty::BoundRegionKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- ty::BrAnon(n, span) => write!(f, "BrAnon({n:?}, {span:?})"),
+ ty::BrAnon(span) => write!(f, "BrAnon({span:?})"),
ty::BrNamed(did, name) => {
if did.is_crate_root() {
write!(f, "BrNamed({})", name)
@@ -177,7 +177,9 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
write!(f, "TypeWellFormedFromEnv({:?})", ty)
}
ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
- ty::PredicateKind::AliasEq(t1, t2) => write!(f, "AliasEq({t1:?}, {t2:?})"),
+ ty::PredicateKind::AliasRelate(t1, t2, dir) => {
+ write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
+ }
}
}
}
@@ -215,6 +217,7 @@ CloneLiftImpls! {
// implementation and traversal implementations (the latter only for
// TyCtxt<'_> interners).
TrivialTypeTraversalAndLiftImpls! {
+ ::rustc_target::abi::FieldIdx,
::rustc_target::abi::VariantIdx,
crate::middle::region::Scope,
crate::ty::FloatTy,
@@ -250,8 +253,9 @@ TrivialTypeTraversalAndLiftImpls! {
crate::ty::AssocItem,
crate::ty::AssocKind,
crate::ty::AliasKind,
- crate::ty::Placeholder<crate::ty::BoundRegionKind>,
- crate::ty::Placeholder<crate::ty::BoundTyKind>,
+ crate::ty::AliasRelationDirection,
+ crate::ty::Placeholder<crate::ty::BoundRegion>,
+ crate::ty::Placeholder<crate::ty::BoundTy>,
crate::ty::ClosureKind,
crate::ty::FreeRegion,
crate::ty::InferTy,
@@ -265,7 +269,6 @@ TrivialTypeTraversalAndLiftImpls! {
::rustc_span::Span,
::rustc_span::symbol::Ident,
::rustc_errors::ErrorGuaranteed,
- Field,
interpret::Scalar,
rustc_target::abi::Size,
ty::BoundVar,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index e6a73e8bb..96c1577d5 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -7,14 +7,15 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
use crate::ty::visit::ValidateBoundVars;
use crate::ty::InferTy::*;
use crate::ty::{
- self, AdtDef, DefIdTree, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable,
- TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
+ self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
+ TypeVisitableExt, TypeVisitor,
};
use crate::ty::{List, ParamEnv};
use hir::def::DefKind;
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
@@ -22,8 +23,8 @@ use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
-use rustc_target::abi::VariantIdx;
-use rustc_target::spec::abi;
+use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
+use rustc_target::spec::abi::{self, Abi};
use std::borrow::Cow;
use std::cmp::Ordering;
use std::fmt;
@@ -60,7 +61,7 @@ pub struct FreeRegion {
#[derive(HashStable)]
pub enum BoundRegionKind {
/// An anonymous region parameter for a given fn (&T)
- BrAnon(u32, Option<Span>),
+ BrAnon(Option<Span>),
/// Named region parameters for functions (a in &'a T)
///
@@ -107,15 +108,6 @@ impl BoundRegionKind {
_ => None,
}
}
-
- pub fn expect_anon(&self) -> u32 {
- match *self {
- BoundRegionKind::BrNamed(_, _) | BoundRegionKind::BrEnv => {
- bug!("expected anon region: {self:?}")
- }
- BoundRegionKind::BrAnon(idx, _) => idx,
- }
- }
}
pub trait Article {
@@ -136,10 +128,6 @@ impl<'tcx> Article for TyKind<'tcx> {
}
}
-// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(TyKind<'_>, 32);
-
/// A closure can be modeled as a struct that looks like:
/// ```ignore (illustrative)
/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
@@ -517,8 +505,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
#[inline]
pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
// FIXME requires optimized MIR
- let num_variants = tcx.generator_layout(def_id).unwrap().variant_fields.len();
- VariantIdx::new(0)..VariantIdx::new(num_variants)
+ FIRST_VARIANT..tcx.generator_layout(def_id).unwrap().variant_fields.next_index()
}
/// The discriminant for the given variant. Panics if the `variant_index` is
@@ -878,8 +865,8 @@ impl<'tcx> PolyTraitRef<'tcx> {
}
}
-impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
- fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
self.to_string().into_diagnostic_arg()
}
}
@@ -924,6 +911,12 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
}
}
+impl<'tcx> IntoDiagnosticArg for ExistentialTraitRef<'tcx> {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
pub type PolyExistentialTraitRef<'tcx> = Binder<'tcx, ExistentialTraitRef<'tcx>>;
impl<'tcx> PolyExistentialTraitRef<'tcx> {
@@ -940,12 +933,6 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
}
}
-impl rustc_errors::IntoDiagnosticArg for PolyExistentialTraitRef<'_> {
- fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
- self.to_string().into_diagnostic_arg()
- }
-}
-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub enum BoundVariableKind {
@@ -1160,78 +1147,12 @@ impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
}
}
-struct SkipBindersAt<'tcx> {
- tcx: TyCtxt<'tcx>,
- index: ty::DebruijnIndex,
-}
-
-impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> {
- type Error = ();
-
- fn interner(&self) -> TyCtxt<'tcx> {
- self.tcx
- }
-
- fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
- where
- T: ty::TypeFoldable<TyCtxt<'tcx>>,
- {
- self.index.shift_in(1);
- let value = t.try_map_bound(|t| t.try_fold_with(self));
- self.index.shift_out(1);
- value
- }
-
- fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
- if !ty.has_escaping_bound_vars() {
- Ok(ty)
- } else if let ty::Bound(index, bv) = *ty.kind() {
- if index == self.index {
- Err(())
- } else {
- Ok(self.interner().mk_bound(index.shifted_out(1), bv))
- }
- } else {
- ty.try_super_fold_with(self)
- }
- }
-
- fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
- if !r.has_escaping_bound_vars() {
- Ok(r)
- } else if let ty::ReLateBound(index, bv) = r.kind() {
- if index == self.index {
- Err(())
- } else {
- Ok(self.interner().mk_re_late_bound(index.shifted_out(1), bv))
- }
- } else {
- r.try_super_fold_with(self)
- }
- }
-
- fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
- if !ct.has_escaping_bound_vars() {
- Ok(ct)
- } else if let ty::ConstKind::Bound(index, bv) = ct.kind() {
- if index == self.index {
- Err(())
- } else {
- Ok(self.interner().mk_const(
- ty::ConstKind::Bound(index.shifted_out(1), bv),
- ct.ty().try_fold_with(self)?,
- ))
- }
- } else {
- ct.try_super_fold_with(self)
- }
- }
-
- fn try_fold_predicate(
- &mut self,
- p: ty::Predicate<'tcx>,
- ) -> Result<ty::Predicate<'tcx>, Self::Error> {
- if !p.has_escaping_bound_vars() { Ok(p) } else { p.try_super_fold_with(self) }
+impl<'tcx, T> IntoDiagnosticArg for Binder<'tcx, T>
+where
+ T: IntoDiagnosticArg,
+{
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ self.0.into_diagnostic_arg()
}
}
@@ -1288,7 +1209,7 @@ impl<'tcx> AliasTy<'tcx> {
match tcx.def_kind(self.def_id) {
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
DefKind::ImplTraitPlaceholder => {
- tcx.parent(tcx.impl_trait_in_trait_parent(self.def_id))
+ tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id))
}
kind => bug!("expected a projection AliasTy; found {kind:?}"),
}
@@ -1376,6 +1297,12 @@ impl<'tcx> FnSig<'tcx> {
}
}
+impl<'tcx> IntoDiagnosticArg for FnSig<'tcx> {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
impl<'tcx> PolyFnSig<'tcx> {
@@ -1403,6 +1330,18 @@ impl<'tcx> PolyFnSig<'tcx> {
pub fn abi(&self) -> abi::Abi {
self.skip_binder().abi
}
+
+ pub fn is_fn_trait_compatible(&self) -> bool {
+ matches!(
+ self.skip_binder(),
+ ty::FnSig {
+ unsafety: rustc_hir::Unsafety::Normal,
+ abi: Abi::Rust,
+ c_variadic: false,
+ ..
+ }
+ )
+ }
}
pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;
@@ -1522,22 +1461,13 @@ pub struct BoundTy {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub enum BoundTyKind {
- Anon(u32),
+ Anon,
Param(DefId, Symbol),
}
-impl BoundTyKind {
- pub fn expect_anon(self) -> u32 {
- match self {
- BoundTyKind::Anon(i) => i,
- _ => bug!(),
- }
- }
-}
-
impl From<BoundVar> for BoundTy {
fn from(var: BoundVar) -> Self {
- BoundTy { var, kind: BoundTyKind::Anon(var.as_u32()) }
+ BoundTy { var, kind: BoundTyKind::Anon }
}
}
@@ -1616,19 +1546,24 @@ impl<'tcx> Region<'tcx> {
pub fn get_name(self) -> Option<Symbol> {
if self.has_name() {
- let name = match *self {
+ match *self {
ty::ReEarlyBound(ebr) => Some(ebr.name),
ty::ReLateBound(_, br) => br.kind.get_name(),
ty::ReFree(fr) => fr.bound_region.get_name(),
ty::ReStatic => Some(kw::StaticLifetime),
- ty::RePlaceholder(placeholder) => placeholder.name.get_name(),
+ ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
_ => None,
- };
-
- return name;
+ }
+ } else {
+ None
}
+ }
- None
+ pub fn get_name_or_anon(self) -> Symbol {
+ match self.get_name() {
+ Some(name) => name,
+ None => sym::anon,
+ }
}
/// Is this region named by the user?
@@ -1639,7 +1574,7 @@ impl<'tcx> Region<'tcx> {
ty::ReFree(fr) => fr.bound_region.is_named(),
ty::ReStatic => true,
ty::ReVar(..) => false,
- ty::RePlaceholder(placeholder) => placeholder.name.is_named(),
+ ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
ty::ReErased => false,
ty::ReError(_) => false,
}
@@ -1762,10 +1697,10 @@ impl<'tcx> Region<'tcx> {
matches!(self.kind(), ty::ReVar(_))
}
- pub fn as_var(self) -> Option<RegionVid> {
+ pub fn as_var(self) -> RegionVid {
match self.kind() {
- ty::ReVar(vid) => Some(vid),
- _ => None,
+ ty::ReVar(vid) => vid,
+ _ => bug!("expected region {:?} to be of kind ReVar", self),
}
}
}
@@ -1892,7 +1827,7 @@ impl<'tcx> Ty<'tcx> {
Adt(def, substs) => {
assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
let variant = def.non_enum_variant();
- let f0_ty = variant.fields[0].ty(tcx, substs);
+ let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, substs);
match f0_ty.kind() {
// If the first field is an array, we assume it is the only field and its
@@ -1902,7 +1837,7 @@ impl<'tcx> Ty<'tcx> {
// The way we evaluate the `N` in `[T; N]` here only works since we use
// `simd_size_and_type` post-monomorphization. It will probably start to ICE
// if we use it in generic code. See the `simd-array-trait` ui test.
- (f0_len.eval_target_usize(tcx, ParamEnv::empty()) as u64, *f0_elem_ty)
+ (f0_len.eval_target_usize(tcx, ParamEnv::empty()), *f0_elem_ty)
}
// Otherwise, the fields of this Adt are the SIMD components (and we assume they
// all have the same type).
@@ -1914,11 +1849,6 @@ impl<'tcx> Ty<'tcx> {
}
#[inline]
- pub fn is_region_ptr(self) -> bool {
- matches!(self.kind(), Ref(..))
- }
-
- #[inline]
pub fn is_mutable_ptr(self) -> bool {
matches!(
self.kind(),
@@ -1944,7 +1874,7 @@ impl<'tcx> Ty<'tcx> {
/// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
#[inline]
pub fn is_any_ptr(self) -> bool {
- self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
+ self.is_ref() || self.is_unsafe_ptr() || self.is_fn_ptr()
}
#[inline]
@@ -2508,3 +2438,14 @@ impl<'tcx> VarianceDiagInfo<'tcx> {
}
}
}
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+ use super::*;
+ use rustc_data_structures::static_assert_size;
+ // tidy-alphabetical-start
+ static_assert_size!(RegionKind<'_>, 28);
+ static_assert_size!(TyKind<'_>, 32);
+ // tidy-alphabetical-end
+}
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index b090bd9d8..f05b87343 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -302,8 +302,8 @@ impl<'tcx> InternalSubsts<'tcx> {
}
/// Creates an `InternalSubsts` that maps each generic parameter to itself.
- pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
- Self::for_item(tcx, def_id, |param, _| tcx.mk_param_from_def(param))
+ pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> SubstsRef<'tcx> {
+ Self::for_item(tcx, def_id.into(), |param, _| tcx.mk_param_from_def(param))
}
/// Creates an `InternalSubsts` for generic parameter definitions,
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 233c0df2d..6747da7ab 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -1,5 +1,5 @@
use crate::traits::specialization_graph;
-use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
+use crate::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
use crate::ty::visit::TypeVisitableExt;
use crate::ty::{Ident, Ty, TyCtxt};
use hir::def_id::LOCAL_CRATE;
@@ -100,8 +100,9 @@ impl<'tcx> TraitDef {
}
impl<'tcx> TyCtxt<'tcx> {
- pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
- let impls = self.trait_impls_of(def_id);
+ /// `trait_def_id` MUST BE the `DefId` of a trait.
+ pub fn for_each_impl<F: FnMut(DefId)>(self, trait_def_id: DefId, mut f: F) {
+ let impls = self.trait_impls_of(trait_def_id);
for &impl_def_id in impls.blanket_impls.iter() {
f(impl_def_id);
@@ -114,27 +115,45 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- /// Iterate over every impl that could possibly match the
- /// self type `self_ty`.
- pub fn for_each_relevant_impl<F: FnMut(DefId)>(
+ /// Iterate over every impl that could possibly match the self type `self_ty`.
+ ///
+ /// `trait_def_id` MUST BE the `DefId` of a trait.
+ pub fn for_each_relevant_impl(
self,
- def_id: DefId,
+ trait_def_id: DefId,
self_ty: Ty<'tcx>,
- mut f: F,
+ f: impl FnMut(DefId),
) {
- let _: Option<()> = self.find_map_relevant_impl(def_id, self_ty, |did| {
- f(did);
- None
- });
+ self.for_each_relevant_impl_treating_projections(
+ trait_def_id,
+ self_ty,
+ TreatProjections::ForLookup,
+ f,
+ )
}
+ pub fn for_each_relevant_impl_treating_projections(
+ self,
+ trait_def_id: DefId,
+ self_ty: Ty<'tcx>,
+ treat_projections: TreatProjections,
+ mut f: impl FnMut(DefId),
+ ) {
+ let _: Option<()> =
+ self.find_map_relevant_impl(trait_def_id, self_ty, treat_projections, |did| {
+ f(did);
+ None
+ });
+ }
+
+ /// `trait_def_id` MUST BE the `DefId` of a trait.
pub fn non_blanket_impls_for_ty(
self,
- def_id: DefId,
+ trait_def_id: DefId,
self_ty: Ty<'tcx>,
) -> impl Iterator<Item = DefId> + 'tcx {
- let impls = self.trait_impls_of(def_id);
- if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsInfer) {
+ let impls = self.trait_impls_of(trait_def_id);
+ if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) {
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
return impls.iter().copied();
}
@@ -145,18 +164,21 @@ impl<'tcx> TyCtxt<'tcx> {
/// Applies function to every impl that could possibly match the self type `self_ty` and returns
/// the first non-none value.
- pub fn find_map_relevant_impl<T, F: FnMut(DefId) -> Option<T>>(
+ ///
+ /// `trait_def_id` MUST BE the `DefId` of a trait.
+ pub fn find_map_relevant_impl<T>(
self,
- def_id: DefId,
+ trait_def_id: DefId,
self_ty: Ty<'tcx>,
- mut f: F,
+ treat_projections: TreatProjections,
+ mut f: impl FnMut(DefId) -> Option<T>,
) -> Option<T> {
// FIXME: This depends on the set of all impls for the trait. That is
// unfortunate wrt. incremental compilation.
//
// If we want to be faster, we could have separate queries for
// blanket and non-blanket impls, and compare them separately.
- let impls = self.trait_impls_of(def_id);
+ let impls = self.trait_impls_of(trait_def_id);
for &impl_def_id in impls.blanket_impls.iter() {
if let result @ Some(_) = f(impl_def_id) {
@@ -164,14 +186,17 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
- // Note that we're using `TreatParams::AsPlaceholder` to query `non_blanket_impls` while using
- // `TreatParams::AsInfer` while actually adding them.
- //
+ // Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
+ // `TreatParams::AsCandidateKey` while actually adding them.
+ let treat_params = match treat_projections {
+ TreatProjections::NextSolverLookup => TreatParams::NextSolverLookup,
+ TreatProjections::ForLookup => TreatParams::ForLookup,
+ };
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
// whose outer level is not a parameter or projection. Especially for things like
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
- if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsPlaceholder) {
+ if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) {
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
for &impl_def_id in impls {
if let result @ Some(_) = f(impl_def_id) {
@@ -190,9 +215,11 @@ impl<'tcx> TyCtxt<'tcx> {
None
}
- /// Returns an iterator containing all impls
- pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
- let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);
+ /// Returns an iterator containing all impls for `trait_def_id`.
+ ///
+ /// `trait_def_id` MUST BE the `DefId` of a trait.
+ pub fn all_impls(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
+ let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(trait_def_id);
blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned()
}
@@ -231,7 +258,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
}
if let Some(simplified_self_ty) =
- fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsInfer)
+ fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)
{
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
} else {
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 586958247..47943b94c 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -8,10 +8,9 @@ use crate::{
},
};
use rustc_data_structures::{
- fx::FxHashMap,
+ fx::{FxHashMap, FxIndexMap},
sync::Lrc,
unord::{UnordItems, UnordSet},
- vec_map::VecMap,
};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
@@ -26,6 +25,7 @@ use rustc_macros::HashStable;
use rustc_middle::mir::FakeReadCause;
use rustc_session::Session;
use rustc_span::Span;
+use rustc_target::abi::FieldIdx;
use std::{collections::hash_map::Entry, hash::Hash, iter};
use super::RvalueScopes;
@@ -43,7 +43,7 @@ pub struct TypeckResults<'tcx> {
/// or patterns (`S { field }`). The index is often useful by itself, but to learn more
/// about the field you also need definition of the variant to which the field
/// belongs, but it may not exist if it's a tuple field (`tuple.0`).
- field_indices: ItemLocalMap<usize>,
+ field_indices: ItemLocalMap<FieldIdx>,
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated outside inference. See
@@ -155,7 +155,7 @@ pub struct TypeckResults<'tcx> {
/// by this function. We also store the
/// type here, so that mir-borrowck 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: VecMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
+ pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
/// Tracks the minimum captures required for a closure;
/// see `MinCaptureInformationMap` for more details.
@@ -314,19 +314,19 @@ impl<'tcx> TypeckResults<'tcx> {
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
}
- pub fn field_indices(&self) -> LocalTableInContext<'_, usize> {
+ pub fn field_indices(&self) -> LocalTableInContext<'_, FieldIdx> {
LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
}
- pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> {
+ pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, FieldIdx> {
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
}
- pub fn field_index(&self, id: hir::HirId) -> usize {
+ pub fn field_index(&self, id: hir::HirId) -> FieldIdx {
self.field_indices().get(id).cloned().expect("no index for a field")
}
- pub fn opt_field_index(&self, id: hir::HirId) -> Option<usize> {
+ pub fn opt_field_index(&self, id: hir::HirId) -> Option<FieldIdx> {
self.field_indices().get(id).cloned()
}
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 90270e0ee..c8a78ec03 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -2,10 +2,11 @@
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir;
+use crate::ty::fast_reject::TreatProjections;
use crate::ty::layout::IntegerExt;
use crate::ty::{
- self, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder,
- TypeSuperFoldable, TypeVisitableExt,
+ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+ TypeVisitableExt,
};
use crate::ty::{GenericArgKind, SubstsRef};
use rustc_apfloat::Float as _;
@@ -14,11 +15,12 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_index::bit_set::GrowableBitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_macros::HashStable;
-use rustc_span::{sym, DUMMY_SP};
+use rustc_session::Limit;
+use rustc_span::sym;
use rustc_target::abi::{Integer, IntegerType, Size, TargetDataLayout};
use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
@@ -59,22 +61,13 @@ impl<'tcx> fmt::Display for Discr<'tcx> {
}
}
-fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
- let (int, signed) = match *ty.kind() {
- ty::Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
- ty::Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false),
- _ => bug!("non integer discriminant"),
- };
- (int.size(), signed)
-}
-
impl<'tcx> Discr<'tcx> {
/// Adds `1` to the value and wraps around if the maximum for the type is reached.
pub fn wrap_incr(self, tcx: TyCtxt<'tcx>) -> Self {
self.checked_add(tcx, 1).0
}
pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
- let (size, signed) = int_size_and_signed(tcx, self.ty);
+ let (size, signed) = self.ty.int_size_and_signed(tcx);
let (val, oflo) = if signed {
let min = size.signed_int_min();
let max = size.signed_int_max();
@@ -233,17 +226,20 @@ impl<'tcx> TyCtxt<'tcx> {
let recursion_limit = self.recursion_limit();
for iteration in 0.. {
if !recursion_limit.value_within_limit(iteration) {
- return self.ty_error_with_message(
- DUMMY_SP,
- &format!("reached the recursion limit finding the struct tail for {}", ty),
- );
+ let suggested_limit = match recursion_limit {
+ Limit(0) => Limit(2),
+ limit => limit * 2,
+ };
+ let reported =
+ self.sess.emit_err(crate::error::RecursionLimitReached { ty, suggested_limit });
+ return self.ty_error(reported);
}
match *ty.kind() {
ty::Adt(def, substs) => {
if !def.is_struct() {
break;
}
- match def.non_enum_variant().fields.last() {
+ match def.non_enum_variant().fields.raw.last() {
Some(field) => {
f();
ty = field.ty(self, substs);
@@ -317,7 +313,7 @@ impl<'tcx> TyCtxt<'tcx> {
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
if a_def == b_def && a_def.is_struct() =>
{
- if let Some(f) = a_def.non_enum_variant().fields.last() {
+ if let Some(f) = a_def.non_enum_variant().fields.raw.last() {
a = f.ty(self, a_substs);
b = f.ty(self, b_substs);
} else {
@@ -363,14 +359,20 @@ impl<'tcx> TyCtxt<'tcx> {
self.ensure().coherent_trait(drop_trait);
let ty = self.type_of(adt_did).subst_identity();
- let (did, constness) = self.find_map_relevant_impl(drop_trait, ty, |impl_did| {
- if let Some(item_id) = self.associated_item_def_ids(impl_did).first() {
- if validate(self, impl_did).is_ok() {
- return Some((*item_id, self.constness(impl_did)));
+ let (did, constness) = self.find_map_relevant_impl(
+ drop_trait,
+ ty,
+ // FIXME: This could also be some other mode, like "unexpected"
+ TreatProjections::ForLookup,
+ |impl_did| {
+ if let Some(item_id) = self.associated_item_def_ids(impl_did).first() {
+ if validate(self, impl_did).is_ok() {
+ return Some((*item_id, self.constness(impl_did)));
+ }
}
- }
- None
- })?;
+ None
+ },
+ )?;
Some(ty::Destructor { did, constness })
}
@@ -599,6 +601,28 @@ impl<'tcx> TyCtxt<'tcx> {
self.static_mutability(def_id) == Some(hir::Mutability::Mut)
}
+ /// Returns `true` if the item pointed to by `def_id` is a thread local which needs a
+ /// thread local shim generated.
+ #[inline]
+ pub fn needs_thread_local_shim(self, def_id: DefId) -> bool {
+ !self.sess.target.dll_tls_export
+ && self.is_thread_local_static(def_id)
+ && !self.is_foreign_item(def_id)
+ }
+
+ /// Returns the type a reference to the thread local takes in MIR.
+ pub fn thread_local_ptr_ty(self, def_id: DefId) -> Ty<'tcx> {
+ let static_ty = self.type_of(def_id).subst_identity();
+ if self.is_mutable_static(def_id) {
+ self.mk_mut_ptr(static_ty)
+ } else if self.is_foreign_item(def_id) {
+ self.mk_imm_ptr(static_ty)
+ } else {
+ // FIXME: These things don't *really* have 'static lifetime.
+ self.mk_imm_ref(self.lifetimes.re_static, static_ty)
+ }
+ }
+
/// Get the type of the pointer to the static that we use in MIR.
pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> {
// Make sure that any constants in the static's type are evaluated.
@@ -684,10 +708,6 @@ impl<'tcx> TyCtxt<'tcx> {
ty::EarlyBinder(self.explicit_item_bounds(def_id))
}
- pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder<ty::ImplSubject<'tcx>> {
- ty::EarlyBinder(self.impl_subject(def_id))
- }
-
/// Returns names of captured upvars for closures and generators.
///
/// Here are some examples:
@@ -922,12 +942,21 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
}
impl<'tcx> Ty<'tcx> {
+ pub fn int_size_and_signed(self, tcx: TyCtxt<'tcx>) -> (Size, bool) {
+ let (int, signed) = match *self.kind() {
+ ty::Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
+ ty::Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false),
+ _ => bug!("non integer discriminant"),
+ };
+ (int.size(), signed)
+ }
+
/// Returns the maximum value for the given numeric type (including `char`s)
/// or returns `None` if the type is not numeric.
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<ty::Const<'tcx>> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
- let (size, signed) = int_size_and_signed(tcx, self);
+ let (size, signed) = self.int_size_and_signed(tcx);
let val =
if signed { size.signed_int_max() as u128 } else { size.unsigned_int_max() };
Some(val)
@@ -948,7 +977,7 @@ impl<'tcx> Ty<'tcx> {
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<ty::Const<'tcx>> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
- let (size, signed) = int_size_and_signed(tcx, self);
+ let (size, signed) = self.int_size_and_signed(tcx);
let val = if signed { size.truncate(size.signed_int_min() as u128) } else { 0 };
Some(val)
}
@@ -1432,8 +1461,7 @@ pub fn reveal_opaque_types_in_bounds<'tcx>(
}
/// Determines whether an item is annotated with `doc(hidden)`.
-fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
- assert!(def_id.is_local());
+fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
tcx.get_attrs(def_id, sym::doc)
.filter_map(|attr| attr.meta_item_list())
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
@@ -1447,7 +1475,7 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
/// Determines whether an item is an intrinsic by Abi.
-pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
}
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 6814cadb9..08a62c900 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -83,6 +83,9 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
| TypeFlags::HAS_CT_PLACEHOLDER,
)
}
+ fn has_non_region_placeholders(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_TY_PLACEHOLDER | TypeFlags::HAS_CT_PLACEHOLDER)
+ }
fn needs_subst(&self) -> bool {
self.has_type_flags(TypeFlags::NEEDS_SUBST)
}