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.rs9
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs6
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs82
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs19
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs68
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs4
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs26
-rw-r--r--compiler/rustc_middle/src/ty/consts/valtree.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs248
-rw-r--r--compiler/rustc_middle/src/ty/erase_regions.rs13
-rw-r--r--compiler/rustc_middle/src/ty/error.rs27
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs10
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs28
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs44
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs25
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs16
-rw-r--r--compiler/rustc_middle/src/ty/impls_ty.rs10
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs40
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs28
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs212
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs8
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs7
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs210
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs14
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs44
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs197
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs9
-rw-r--r--compiler/rustc_middle/src/ty/util.rs135
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs45
33 files changed, 888 insertions, 708 deletions
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index 85181720d..a2794a100 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -20,12 +20,11 @@ use crate::ty::{self, InferConst, Ty, TyCtxt};
/// affects any type variables or unification state.
pub struct MatchAgainstFreshVars<'tcx> {
tcx: TyCtxt<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
}
impl<'tcx> MatchAgainstFreshVars<'tcx> {
- pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> MatchAgainstFreshVars<'tcx> {
- MatchAgainstFreshVars { tcx, param_env }
+ pub fn new(tcx: TyCtxt<'tcx>) -> MatchAgainstFreshVars<'tcx> {
+ MatchAgainstFreshVars { tcx }
}
}
@@ -33,13 +32,11 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
fn tag(&self) -> &'static str {
"MatchAgainstFreshVars"
}
+
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
- fn param_env(&self) -> ty::ParamEnv<'tcx> {
- self.param_env
- }
fn a_is_expected(&self) -> bool {
true
} // irrelevant
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index f50969dd9..1d9a25628 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -99,7 +99,7 @@ pub struct AdtDefData {
impl PartialOrd for AdtDefData {
fn partial_cmp(&self, other: &AdtDefData) -> Option<Ordering> {
- Some(self.cmp(&other))
+ Some(self.cmp(other))
}
}
@@ -375,7 +375,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(FIRST_VARIANT)
+ self.variant(FIRST_VARIANT)
}
#[inline]
@@ -481,7 +481,7 @@ impl<'tcx> AdtDef<'tcx> {
ErrorHandled::Reported(..) => "enum discriminant evaluation failed",
ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics",
};
- tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg);
+ tcx.sess.span_delayed_bug(tcx.def_span(expr_did), msg);
None
}
}
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 74bdd07a1..8c29bc5a4 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -7,14 +7,13 @@ use std::fmt::Write;
use crate::query::Providers;
use rustc_data_structures::fx::FxIndexMap;
-use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self as hir, LangItem};
+use rustc_hir as hir;
+use rustc_hir::def_id::LocalDefId;
use rustc_span::def_id::LocalDefIdMap;
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol};
-use super::{Ty, TyCtxt};
+use super::TyCtxt;
use self::BorrowKind::*;
@@ -73,72 +72,6 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis
/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.
pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
-/// Represents the various closure traits in the language. This
-/// will determine the type of the environment (`self`, in the
-/// desugaring) argument that the closure expects.
-///
-/// You can get the environment type of a closure using
-/// `tcx.closure_env_ty()`.
-#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable)]
-pub enum ClosureKind {
- // Warning: Ordering is significant here! The ordering is chosen
- // because the trait Fn is a subtrait of FnMut and so in turn, and
- // hence we order it so that Fn < FnMut < FnOnce.
- Fn,
- FnMut,
- FnOnce,
-}
-
-impl ClosureKind {
- /// This is the initial value used when doing upvar inference.
- pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
-
- pub const fn as_str(self) -> &'static str {
- match self {
- ClosureKind::Fn => "Fn",
- ClosureKind::FnMut => "FnMut",
- ClosureKind::FnOnce => "FnOnce",
- }
- }
-
- /// Returns `true` if a type that impls this closure kind
- /// must also implement `other`.
- pub fn extends(self, other: ty::ClosureKind) -> bool {
- self <= other
- }
-
- /// Converts `self` to a [`DefId`] of the corresponding trait.
- ///
- /// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`].
- pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
- tcx.require_lang_item(
- match self {
- ClosureKind::Fn => LangItem::Fn,
- ClosureKind::FnMut => LangItem::FnMut,
- ClosureKind::FnOnce => LangItem::FnOnce,
- },
- None,
- )
- }
-
- /// Returns the representative scalar type for this closure kind.
- /// See `Ty::to_opt_closure_kind` for more details.
- pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
- match self {
- ClosureKind::Fn => tcx.types.i8,
- ClosureKind::FnMut => tcx.types.i16,
- ClosureKind::FnOnce => tcx.types.i32,
- }
- }
-}
-
-impl IntoDiagnosticArg for ClosureKind {
- fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
- DiagnosticArgValue::Str(self.as_str().into())
- }
-}
-
/// A composite describing a `Place` that is captured by a closure.
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
@@ -247,6 +180,13 @@ impl<'tcx> CapturedPlace<'tcx> {
.span
}
}
+
+ pub fn is_by_ref(&self) -> bool {
+ match self.info.capture_kind {
+ ty::UpvarCapture::ByValue => false,
+ ty::UpvarCapture::ByRef(..) => true,
+ }
+ }
}
#[derive(Copy, Clone, Debug, HashStable)]
@@ -262,7 +202,7 @@ fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo
let user_provided_sig = typeck_results.user_provided_sigs[&def];
let captures = typeck_results.closure_min_captures_flattened(def);
let captures = tcx.arena.alloc_from_iter(captures);
- let hir_id = tcx.hir().local_def_id_to_hir_id(def);
+ let hir_id = tcx.local_def_id_to_hir_id(def);
let kind_origin = typeck_results.closure_kind_origins().get(hir_id);
ClosureTypeInfo { user_provided_sig, captures, kind_origin }
}
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 8b67e3966..69ae05ca8 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -8,6 +8,7 @@
use crate::arena::ArenaAllocatable;
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
+use crate::mir::interpret::CtfeProvenance;
use crate::mir::{
self,
interpret::{AllocId, ConstAllocation},
@@ -164,6 +165,13 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for AllocId {
}
}
+impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for CtfeProvenance {
+ fn encode(&self, e: &mut E) {
+ self.alloc_id().encode(e);
+ self.immutable().encode(e);
+ }
+}
+
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::ParamEnv<'tcx> {
fn encode(&self, e: &mut E) {
self.caller_bounds().encode(e);
@@ -295,9 +303,18 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for AllocId {
}
}
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for CtfeProvenance {
+ fn decode(decoder: &mut D) -> Self {
+ let alloc_id: AllocId = Decodable::decode(decoder);
+ let prov = CtfeProvenance::from(alloc_id);
+ let immutable: bool = Decodable::decode(decoder);
+ if immutable { prov.as_immutable() } else { prov }
+ }
+}
+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::SymbolName<'tcx> {
fn decode(decoder: &mut D) -> Self {
- ty::SymbolName::new(decoder.interner(), &decoder.read_str())
+ ty::SymbolName::new(decoder.interner(), decoder.read_str())
}
}
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index af5ffc20d..2d3ee3348 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -1,5 +1,5 @@
use crate::middle::resolve_bound_vars as rbv;
-use crate::mir::interpret::{AllocId, ErrorHandled, LitToConstInput, Scalar};
+use crate::mir::interpret::{ErrorHandled, LitToConstInput, Scalar};
use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
use rustc_data_structures::intern::Interned;
use rustc_error_messages::MultiSpan;
@@ -7,6 +7,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_macros::HashStable;
+use rustc_type_ir::{ConstTy, IntoKind, TypeFlags, WithCachedTypeInfo};
mod int;
mod kind;
@@ -23,10 +24,25 @@ use super::sty::ConstKind;
/// Use this rather than `ConstData`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[rustc_pass_by_value]
-pub struct Const<'tcx>(pub(super) Interned<'tcx, ConstData<'tcx>>);
+pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>);
+
+impl<'tcx> IntoKind for Const<'tcx> {
+ type Kind = ConstKind<'tcx>;
+
+ fn kind(self) -> ConstKind<'tcx> {
+ self.kind()
+ }
+}
+
+impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
+ fn ty(self) -> Ty<'tcx> {
+ self.ty()
+ }
+}
/// Typed constant value.
-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(HashStable, TyEncodable, TyDecodable)]
pub struct ConstData<'tcx> {
pub ty: Ty<'tcx>,
pub kind: ConstKind<'tcx>,
@@ -43,7 +59,17 @@ impl<'tcx> Const<'tcx> {
#[inline]
pub fn kind(self) -> ConstKind<'tcx> {
- self.0.kind.clone()
+ self.0.kind
+ }
+
+ #[inline]
+ pub fn flags(self) -> TypeFlags {
+ self.0.flags
+ }
+
+ #[inline]
+ pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
+ self.0.outer_exclusive_binder
}
#[inline]
@@ -133,7 +159,7 @@ impl<'tcx> Const<'tcx> {
span: S,
msg: &'static str,
) -> Const<'tcx> {
- let reported = tcx.sess.delay_span_bug(span, msg);
+ let reported = tcx.sess.span_delayed_bug(span, msg);
Const::new_error(tcx, reported, ty)
}
@@ -141,7 +167,7 @@ impl<'tcx> Const<'tcx> {
/// becomes `Unevaluated`.
#[instrument(skip(tcx), level = "debug")]
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
- let body_id = match tcx.hir().get_by_def_id(def) {
+ let body_id = match tcx.hir_node_by_def_id(def) {
hir::Node::AnonConst(ac) => ac.body,
_ => span_bug!(
tcx.def_span(def.to_def_id()),
@@ -183,11 +209,9 @@ impl<'tcx> Const<'tcx> {
};
let lit_input = match expr.kind {
- hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
- hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
- hir::ExprKind::Lit(ref lit) => {
- Some(LitToConstInput { lit: &lit.node, ty, neg: true })
- }
+ hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+ hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
+ hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
_ => None,
},
_ => None,
@@ -199,7 +223,7 @@ impl<'tcx> Const<'tcx> {
match tcx.at(expr.span).lit_to_const(lit_input) {
Ok(c) => return Some(c),
Err(e) => {
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
expr.span,
format!("Const::from_anon_const: couldn't lit_to_const {e:?}"),
);
@@ -207,6 +231,10 @@ impl<'tcx> Const<'tcx> {
}
}
+ // FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
+ // does not provide the parents generics to anonymous constants. We still allow generic const
+ // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
+ // ever try to substitute the generic parameters in their bodies.
match expr.kind {
hir::ExprKind::Path(hir::QPath::Resolved(
_,
@@ -291,8 +319,16 @@ impl<'tcx> Const<'tcx> {
let (param_env, unevaluated) = unevaluated.prepare_for_eval(tcx, param_env);
// try to resolve e.g. associated constants to their definition on an impl, and then
// evaluate the const.
- let c = tcx.const_eval_resolve_for_typeck(param_env, unevaluated, span)?;
- Ok(c.expect("`ty::Const::eval` called on a non-valtree-compatible type"))
+ let Some(c) = tcx.const_eval_resolve_for_typeck(param_env, unevaluated, span)?
+ else {
+ // This can happen when we run on ill-typed code.
+ let e = tcx.sess.span_delayed_bug(
+ span.unwrap_or(DUMMY_SP),
+ "`ty::Const::eval` called on a non-valtree-compatible type",
+ );
+ return Err(e.into());
+ };
+ Ok(c)
}
ConstKind::Value(val) => Ok(val),
ConstKind::Error(g) => Err(g.into()),
@@ -392,7 +428,7 @@ impl<'tcx> Const<'tcx> {
}
#[inline]
- pub fn try_to_scalar(self) -> Option<Scalar<AllocId>> {
+ pub fn try_to_scalar(self) -> Option<Scalar> {
self.try_to_valtree()?.try_to_scalar()
}
@@ -407,7 +443,7 @@ impl<'tcx> Const<'tcx> {
}
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) {
+ let default_def_id = match tcx.hir_node_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 9d99344d5..310cf113b 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -71,7 +71,7 @@ impl std::fmt::Debug for ConstInt {
(4, _) => write!(fmt, "_i32")?,
(8, _) => write!(fmt, "_i64")?,
(16, _) => write!(fmt, "_i128")?,
- _ => bug!(),
+ (sz, _) => bug!("unexpected int size i{sz}"),
}
}
Ok(())
@@ -105,7 +105,7 @@ impl std::fmt::Debug for ConstInt {
(4, _) => write!(fmt, "_u32")?,
(8, _) => write!(fmt, "_u64")?,
(16, _) => write!(fmt, "_u128")?,
- _ => bug!(),
+ (sz, _) => bug!("unexpected unsigned int size u{sz}"),
}
}
Ok(())
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 4af841fcf..16e7b16a0 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -3,7 +3,6 @@ use crate::mir;
use crate::ty::abstract_const::CastKind;
use crate::ty::GenericArgsRef;
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
@@ -77,28 +76,3 @@ static_assert_size!(Expr<'_>, 24);
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(super::ConstKind<'_>, 32);
-
-/// An inference variable for a const, for use in const generics.
-#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
-pub enum InferConst {
- /// Infer the value of the const.
- Var(ty::ConstVid),
- /// Infer the value of the effect.
- ///
- /// For why this is separate from the `Var` variant above, see the
- /// documentation on `EffectVid`.
- EffectVar(ty::EffectVid),
- /// A fresh const variable. See `infer::freshen` for more details.
- Fresh(u32),
-}
-
-impl<CTX> HashStable<CTX> for InferConst {
- fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
- match self {
- InferConst::Var(_) | InferConst::EffectVar(_) => {
- panic!("const variables should not be hashed: {self:?}")
- }
- InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
- }
- }
-}
diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs
index fb7bf78ba..ffa0e89c4 100644
--- a/compiler/rustc_middle/src/ty/consts/valtree.rs
+++ b/compiler/rustc_middle/src/ty/consts/valtree.rs
@@ -1,5 +1,5 @@
use super::ScalarInt;
-use crate::mir::interpret::{AllocId, Scalar};
+use crate::mir::interpret::Scalar;
use crate::ty::{self, Ty, TyCtxt};
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
@@ -67,7 +67,7 @@ impl<'tcx> ValTree<'tcx> {
Self::Leaf(i)
}
- pub fn try_to_scalar(self) -> Option<Scalar<AllocId>> {
+ pub fn try_to_scalar(self) -> Option<Scalar> {
self.try_to_scalar_int().map(Scalar::Int)
}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 551c4a15d..b5ca700c2 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -6,7 +6,7 @@ pub mod tls;
use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct};
-use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
+use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::struct_lint_level;
use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
@@ -26,9 +26,9 @@ use crate::traits::solve::{
};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
- ImplPolarity, InferTy, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig,
- Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
- TyVid, TypeAndMut, Visibility,
+ ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
+ PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
+ Visibility,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
@@ -39,7 +39,9 @@ use rustc_data_structures::profiling::SelfProfilerRef;
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, FreezeReadGuard, Lock, Lrc, WorkerLocal};
+use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, WorkerLocal};
+#[cfg(parallel_compiler)]
+use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
@@ -69,7 +71,6 @@ use rustc_type_ir::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
-use std::any::Any;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt;
@@ -87,7 +88,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type Term = ty::Term<'tcx>;
type Binder<T> = Binder<'tcx, T>;
- type TypeAndMut = TypeAndMut<'tcx>;
type CanonicalVars = CanonicalVarInfos<'tcx>;
type Ty = Ty<'tcx>;
@@ -96,7 +96,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ParamTy = ParamTy;
type BoundTy = ty::BoundTy;
type PlaceholderTy = ty::PlaceholderType;
- type InferTy = InferTy;
type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
@@ -104,7 +103,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type AllocId = crate::mir::interpret::AllocId;
type Const = ty::Const<'tcx>;
- type InferConst = ty::InferConst;
type AliasConst = ty::UnevaluatedConst<'tcx>;
type PlaceholderConst = ty::PlaceholderConst;
type ParamConst = ty::ParamConst;
@@ -113,9 +111,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ExprConst = ty::Expr<'tcx>;
type Region = Region<'tcx>;
- type EarlyBoundRegion = ty::EarlyBoundRegion;
+ type EarlyParamRegion = ty::EarlyParamRegion;
type BoundRegion = ty::BoundRegion;
- type FreeRegion = ty::FreeRegion;
+ type LateParamRegion = ty::LateParamRegion;
type InferRegion = ty::RegionVid;
type PlaceholderRegion = ty::PlaceholderRegion;
@@ -124,14 +122,34 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
+ type NormalizesTo = ty::NormalizesTo<'tcx>;
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
type CoercePredicate = ty::CoercePredicate<'tcx>;
type ClosureKind = ty::ClosureKind;
- fn ty_and_mut_to_parts(
- TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>,
- ) -> (Self::Ty, ty::Mutability) {
- (ty, mutbl)
+ fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
+ self.mk_canonical_var_infos(infos)
+ }
+
+ fn mk_bound_ty(self, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self::Ty {
+ Ty::new_bound(self, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
+ }
+
+ fn mk_bound_region(self, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self::Region {
+ Region::new_bound(
+ self,
+ debruijn,
+ ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon },
+ )
+ }
+
+ fn mk_bound_const(
+ self,
+ debruijn: ty::DebruijnIndex,
+ var: ty::BoundVar,
+ ty: Self::Ty,
+ ) -> Self::Const {
+ Const::new_bound(self, debruijn, var, ty)
}
}
@@ -154,7 +172,7 @@ pub struct CtxtInterners<'tcx> {
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
- const_: InternedSet<'tcx, ConstData<'tcx>>,
+ const_: InternedSet<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>,
const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, LayoutS<FieldIdx, VariantIdx>>,
@@ -215,6 +233,32 @@ impl<'tcx> CtxtInterners<'tcx> {
))
}
+ /// Interns a const. (Use `mk_*` functions instead, where possible.)
+ #[allow(rustc::usage_of_ty_tykind)]
+ #[inline(never)]
+ fn intern_const(
+ &self,
+ data: ty::ConstData<'tcx>,
+ sess: &Session,
+ untracked: &Untracked,
+ ) -> Const<'tcx> {
+ Const(Interned::new_unchecked(
+ self.const_
+ .intern(data, |data: ConstData<'_>| {
+ let flags = super::flags::FlagComputation::for_const(&data.kind, data.ty);
+ let stable_hash = self.stable_hash(&flags, sess, untracked, &data);
+
+ InternedInSet(self.arena.alloc(WithCachedTypeInfo {
+ internee: data,
+ stable_hash,
+ flags: flags.flags,
+ outer_exclusive_binder: flags.outer_exclusive_binder,
+ }))
+ })
+ .0,
+ ))
+ }
+
fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
&self,
flags: &ty::flags::FlagComputation,
@@ -327,7 +371,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 })`
+ /// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })`
/// for small values of `i` and `v`.
pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
}
@@ -402,7 +446,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
.map(|i| {
(0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
.map(|v| {
- mk(ty::ReLateBound(
+ mk(ty::ReBound(
ty::DebruijnIndex::from(i),
ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon },
))
@@ -421,11 +465,17 @@ impl<'tcx> CommonLifetimes<'tcx> {
}
impl<'tcx> CommonConsts<'tcx> {
- fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
+ fn new(
+ interners: &CtxtInterners<'tcx>,
+ types: &CommonTypes<'tcx>,
+ sess: &Session,
+ untracked: &Untracked,
+ ) -> CommonConsts<'tcx> {
let mk_const = |c| {
- Const(Interned::new_unchecked(
- interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
- ))
+ interners.intern_const(
+ c, sess, // This is only used to create a stable hashing context.
+ untracked,
+ )
};
CommonConsts {
@@ -445,14 +495,14 @@ impl<'tcx> CommonConsts<'tcx> {
}
}
-/// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
-/// conflict.
+/// This struct contains information regarding a free parameter region,
+/// either a `ReEarlyParam` or `ReLateParam`.
#[derive(Debug)]
pub struct FreeRegionInfo {
- /// `LocalDefId` corresponding to FreeRegion
+ /// `LocalDefId` of the free region.
pub def_id: LocalDefId,
- /// the bound region corresponding to FreeRegion
- pub boundregion: ty::BoundRegionKind,
+ /// the bound region corresponding to free region.
+ pub bound_region: ty::BoundRegionKind,
/// checks if bound region is in Impl Item
pub is_impl_item: bool,
}
@@ -472,6 +522,9 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> {
TyCtxtFeed { tcx: self, key: LOCAL_CRATE }
}
+ pub fn feed_local_def_id(self, key: LocalDefId) -> TyCtxtFeed<'tcx, LocalDefId> {
+ TyCtxtFeed { tcx: self, key }
+ }
/// In order to break cycles involving `AnonConst`, we need to set the expected type by side
/// effect. However, we do not want this as a general capability, so this interface restricts
@@ -520,6 +573,16 @@ pub struct TyCtxt<'tcx> {
gcx: &'tcx GlobalCtxt<'tcx>,
}
+// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution.
+#[cfg(parallel_compiler)]
+unsafe impl DynSend for TyCtxt<'_> {}
+#[cfg(parallel_compiler)]
+unsafe impl DynSync for TyCtxt<'_> {}
+fn _assert_tcx_fields() {
+ sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
+ sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
+}
+
impl<'tcx> Deref for TyCtxt<'tcx> {
type Target = &'tcx GlobalCtxt<'tcx>;
#[inline(always)]
@@ -544,12 +607,6 @@ pub struct GlobalCtxt<'tcx> {
/// `rustc_symbol_mangling` crate for more information.
stable_crate_id: StableCrateId,
- /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
- ///
- /// FIXME(Centril): consider `dyn LintStoreMarker` once
- /// we can upcast to `Any` for some additional type safety.
- pub lint_store: Lrc<dyn Any + sync::DynSync + sync::DynSend>,
-
pub dep_graph: DepGraph,
pub prof: SelfProfilerRef,
@@ -589,6 +646,8 @@ pub struct GlobalCtxt<'tcx> {
pub new_solver_evaluation_cache: solve::EvaluationCache<'tcx>,
pub new_solver_coherence_evaluation_cache: solve::EvaluationCache<'tcx>,
+ pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
+
/// Data layout specification for the current target.
pub data_layout: TargetDataLayout,
@@ -606,6 +665,10 @@ impl<'tcx> GlobalCtxt<'tcx> {
let icx = tls::ImplicitCtxt::new(self);
tls::enter_context(&icx, || f(icx.tcx))
}
+
+ pub fn finish(&self) -> FileEncodeResult {
+ self.dep_graph.finish_encoding(&self.sess.prof)
+ }
}
impl<'tcx> TyCtxt<'tcx> {
@@ -684,8 +747,10 @@ impl<'tcx> TyCtxt<'tcx> {
{
Bound::Included(a)
} else {
- self.sess
- .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute");
+ self.sess.span_delayed_bug(
+ attr.span,
+ "invalid rustc_layout_scalar_valid_range attribute",
+ );
Bound::Unbounded
}
};
@@ -709,7 +774,6 @@ impl<'tcx> TyCtxt<'tcx> {
s: &'tcx Session,
crate_types: Vec<CrateType>,
stable_crate_id: StableCrateId,
- lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
untracked: Untracked,
@@ -724,13 +788,12 @@ impl<'tcx> TyCtxt<'tcx> {
let interners = CtxtInterners::new(arena);
let common_types = CommonTypes::new(&interners, s, &untracked);
let common_lifetimes = CommonLifetimes::new(&interners);
- let common_consts = CommonConsts::new(&interners, &common_types);
+ let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
GlobalCtxt {
sess: s,
crate_types,
stable_crate_id,
- lint_store,
arena,
hir_arena,
interners,
@@ -749,6 +812,7 @@ impl<'tcx> TyCtxt<'tcx> {
evaluation_cache: Default::default(),
new_solver_evaluation_cache: Default::default(),
new_solver_coherence_evaluation_cache: Default::default(),
+ canonical_param_env_cache: Default::default(),
data_layout,
alloc_map: Lock::new(interpret::AllocMap::new()),
}
@@ -779,6 +843,10 @@ impl<'tcx> TyCtxt<'tcx> {
self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
}
+ pub fn is_coroutine(self, def_id: DefId) -> bool {
+ self.coroutine_kind(def_id).is_some()
+ }
+
/// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
pub fn coroutine_is_async(self, def_id: DefId) -> bool {
matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Async(_)))
@@ -790,11 +858,16 @@ impl<'tcx> TyCtxt<'tcx> {
matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine))
}
- /// Returns `true` if the node pointed to by `def_id` is a coroutine for a gen construct.
+ /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Gen(_)))
}
+ /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
+ pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
+ matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::AsyncGen(_)))
+ }
+
pub fn stability(self) -> &'tcx stability::Index {
self.stability_index(())
}
@@ -943,7 +1016,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
pub fn create_def(
self,
parent: LocalDefId,
- data: hir::definitions::DefPathData,
+ name: Symbol,
+ def_kind: DefKind,
) -> TyCtxtFeed<'tcx, LocalDefId> {
// This function modifies `self.definitions` using a side-effect.
// We need to ensure that these side effects are re-run by the incr. comp. engine.
@@ -965,15 +1039,34 @@ impl<'tcx> TyCtxtAt<'tcx> {
// This is fine because:
// - those queries are `eval_always` so we won't miss their result changing;
// - this write will have happened before these queries are called.
- let key = self.untracked.definitions.write().create_def(parent, data);
+ let def_id = self.tcx.create_def(parent, name, def_kind);
- let feed = TyCtxtFeed { tcx: self.tcx, key };
+ let feed = self.tcx.feed_local_def_id(def_id);
feed.def_span(self.span);
feed
}
}
impl<'tcx> TyCtxt<'tcx> {
+ /// `tcx`-dependent operations performed for every created definition.
+ pub fn create_def(self, parent: LocalDefId, name: Symbol, def_kind: DefKind) -> LocalDefId {
+ let data = def_kind.def_path_data(name);
+ let def_id = self.untracked.definitions.write().create_def(parent, data);
+
+ let feed = self.feed_local_def_id(def_id);
+ feed.def_kind(def_kind);
+ // Unique types created for closures participate in type privacy checking.
+ // They have visibilities inherited from the module they are defined in.
+ // Visibilities for opaque types are meaningless, but still provided
+ // so that all items have visibilities.
+ if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
+ let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
+ feed.visibility(ty::Visibility::Restricted(parent_mod));
+ }
+
+ def_id
+ }
+
pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
// Create a dependency to the red node to be sure we re-execute this when the amount of
// definitions change.
@@ -1080,8 +1173,8 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = loop {
let def_id = match region.kind() {
- ty::ReFree(fr) => fr.bound_region.get_id()?.as_local()?,
- ty::ReEarlyBound(ebr) => ebr.def_id.expect_local(),
+ ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?,
+ ty::ReEarlyParam(ebr) => ebr.def_id.expect_local(),
_ => return None, // not a free region
};
let scope = self.local_parent(def_id);
@@ -1094,7 +1187,7 @@ impl<'tcx> TyCtxt<'tcx> {
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
};
- let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
+ let is_impl_item = match self.opt_hir_node_by_def_id(suitable_region_binding_scope) {
Some(Node::Item(..) | Node::TraitItem(..)) => false,
Some(Node::ImplItem(..)) => {
self.is_bound_region_in_impl_item(suitable_region_binding_scope)
@@ -1102,11 +1195,7 @@ impl<'tcx> TyCtxt<'tcx> {
_ => false,
};
- Some(FreeRegionInfo {
- def_id: suitable_region_binding_scope,
- boundregion: bound_region,
- is_impl_item,
- })
+ Some(FreeRegionInfo { def_id: suitable_region_binding_scope, bound_region, is_impl_item })
}
/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
@@ -1114,7 +1203,7 @@ impl<'tcx> TyCtxt<'tcx> {
self,
scope_def_id: LocalDefId,
) -> Vec<&'tcx hir::Ty<'tcx>> {
- let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
+ let hir_id = self.local_def_id_to_hir_id(scope_def_id);
let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
self.hir().fn_decl_by_hir_id(hir_id)
else {
@@ -1133,7 +1222,7 @@ impl<'tcx> TyCtxt<'tcx> {
self,
scope_def_id: LocalDefId,
) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
- let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
+ let hir_id = self.local_def_id_to_hir_id(scope_def_id);
let mut v = TraitObjectVisitor(vec![], self.hir());
// when the return type is a type alias
if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id)
@@ -1141,8 +1230,8 @@ impl<'tcx> TyCtxt<'tcx> {
None,
hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
&& let Some(local_id) = def_id.as_local()
- && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
- && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
+ && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
+ && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
{
v.visit_ty(alias_ty);
if !v.0.is_empty() {
@@ -1548,7 +1637,6 @@ macro_rules! direct_interners {
// crate only, and have a corresponding `mk_` function.
direct_interners! {
region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
- const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>,
const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
layout: pub mk_layout(LayoutS<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
@@ -1725,7 +1813,12 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline]
pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
- self.intern_const(ty::ConstData { kind, ty })
+ self.interners.intern_const(
+ ty::ConstData { kind, ty },
+ self.sess,
+ // This is only used to create a stable hashing context.
+ &self.untracked,
+ )
}
// Avoid this in favour of more specific `Ty::new_*` methods, where possible.
@@ -1743,7 +1836,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
match param.kind {
GenericParamDefKind::Lifetime => {
- ty::Region::new_early_bound(self, param.to_early_bound_region_data()).into()
+ ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
}
GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
GenericParamDefKind::Const { .. } => ty::Const::new_param(
@@ -1954,14 +2047,12 @@ impl<'tcx> TyCtxt<'tcx> {
let msg = decorator.msg();
let (level, src) = self.lint_level_at_node(lint, hir_id);
struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
- decorator.decorate_lint(diag)
+ decorator.decorate_lint(diag);
})
}
/// Emit a lint at the appropriate level for a hir node, with an associated span.
///
- /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
- ///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
#[track_caller]
@@ -1971,9 +2062,7 @@ impl<'tcx> TyCtxt<'tcx> {
hir_id: HirId,
span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>,
- decorate: impl for<'a, 'b> FnOnce(
- &'b mut DiagnosticBuilder<'a, ()>,
- ) -> &'b mut DiagnosticBuilder<'a, ()>,
+ decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
) {
let (level, src) = self.lint_level_at_node(lint, hir_id);
struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
@@ -1988,13 +2077,13 @@ impl<'tcx> TyCtxt<'tcx> {
id: HirId,
decorator: impl for<'a> DecorateLint<'a, ()>,
) {
- self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
+ self.struct_lint_node(lint, id, decorator.msg(), |diag| {
+ decorator.decorate_lint(diag);
+ })
}
/// Emit a lint at the appropriate level for a hir node.
///
- /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
- ///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
#[track_caller]
@@ -2003,9 +2092,7 @@ impl<'tcx> TyCtxt<'tcx> {
lint: &'static Lint,
id: HirId,
msg: impl Into<DiagnosticMessage>,
- decorate: impl for<'a, 'b> FnOnce(
- &'b mut DiagnosticBuilder<'a, ()>,
- ) -> &'b mut DiagnosticBuilder<'a, ()>,
+ decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
) {
let (level, src) = self.lint_level_at_node(lint, id);
struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
@@ -2040,7 +2127,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Given the def-id of an early-bound lifetime on an RPIT corresponding to
/// a duplicated captured lifetime, map it back to the early- or late-bound
/// lifetime of the function from which it originally as captured. If it is
- /// a late-bound lifetime, this will represent the liberated (`ReFree`) lifetime
+ /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
/// of the signature.
// FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
// re-use the generics of the opaque, this function will need to be tweaked slightly.
@@ -2057,7 +2144,7 @@ impl<'tcx> TyCtxt<'tcx> {
loop {
let parent = self.local_parent(rpit_lifetime_param_def_id);
let hir::OpaqueTy { lifetime_mapping, .. } =
- self.hir().get_by_def_id(parent).expect_item().expect_opaque_ty();
+ self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
let Some((lifetime, _)) = lifetime_mapping
.iter()
@@ -2079,9 +2166,9 @@ impl<'tcx> TyCtxt<'tcx> {
}
let generics = self.generics_of(new_parent);
- return ty::Region::new_early_bound(
+ return ty::Region::new_early_param(
self,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: ebv,
index: generics
.param_def_id_to_index(self, ebv)
@@ -2092,7 +2179,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
Some(resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv)) => {
let new_parent = self.parent(lbv);
- return ty::Region::new_free(
+ return ty::Region::new_late_param(
self,
new_parent,
ty::BoundRegionKind::BrNamed(
@@ -2141,15 +2228,14 @@ impl<'tcx> TyCtxt<'tcx> {
/// Whether the trait impl is marked const. This does not consider stability or feature gates.
pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
let Some(local_def_id) = def_id.as_local() else { return false };
- let hir_id = self.local_def_id_to_hir_id(local_def_id);
- let node = self.hir().get(hir_id);
+ let node = self.hir_node_by_def_id(local_def_id);
matches!(
node,
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { generics, .. }),
..
- }) if generics.params.iter().any(|p| self.has_attr(p.def_id, sym::rustc_host))
+ }) if generics.params.iter().any(|p| matches!(p.kind, hir::GenericParamKind::Const { is_host_effect: true, .. }))
)
}
@@ -2158,15 +2244,11 @@ impl<'tcx> TyCtxt<'tcx> {
}
pub fn next_trait_solver_globally(self) -> bool {
- self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
+ self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
}
pub fn next_trait_solver_in_coherence(self) -> bool {
- matches!(
- self.sess.opts.unstable_opts.trait_solver,
- rustc_session::config::TraitSolver::Next
- | rustc_session::config::TraitSolver::NextCoherence
- )
+ self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
}
pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs
index 3371ea3be..cfd36fd8c 100644
--- a/compiler/rustc_middle/src/ty/erase_regions.rs
+++ b/compiler/rustc_middle/src/ty/erase_regions.rs
@@ -53,16 +53,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- // because late-bound regions affect subtyping, we can't
- // erase the bound/free distinction, but we can replace
- // all free regions with 'erased.
- //
- // Note that we *CAN* replace early-bound regions -- the
- // type system never "sees" those, they get substituted
- // away. In codegen, they will always be erased to 'erased
- // whenever a substitution occurs.
+ // We must not erase bound regions. `for<'a> fn(&'a ())` and
+ // `fn(&'free ())` are different types: they may implement different
+ // traits and have a different `TypeId`.
match *r {
- ty::ReLateBound(..) => r,
+ ty::ReBound(..) => r,
_ => self.tcx.lifetimes.re_erased,
}
}
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 738bb5e8b..0e4487852 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -7,8 +7,7 @@ use rustc_hir::def_id::DefId;
use rustc_span::symbol::Symbol;
use rustc_target::spec::abi;
use std::borrow::Cow;
-use std::collections::hash_map::DefaultHasher;
-use std::hash::{Hash, Hasher};
+use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::PathBuf;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
@@ -236,7 +235,7 @@ impl<'tcx> Ty<'tcx> {
_ => "fn item".into(),
},
ty::FnPtr(_) => "fn pointer".into(),
- ty::Dynamic(ref inner, ..) if let Some(principal) = inner.principal() => {
+ ty::Dynamic(inner, ..) if let Some(principal) = inner.principal() => {
format!("`dyn {}`", tcx.def_path_str(principal.def_id())).into()
}
ty::Dynamic(..) => "trait object".into(),
@@ -282,7 +281,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Float(_)
| ty::Str
| ty::Never => "type".into(),
- ty::Tuple(ref tys) if tys.is_empty() => "unit type".into(),
+ ty::Tuple(tys) if tys.is_empty() => "unit type".into(),
ty::Adt(def, _) => def.descr().into(),
ty::Foreign(_) => "extern type".into(),
ty::Array(..) => "array".into(),
@@ -346,33 +345,35 @@ impl<'tcx> TyCtxt<'tcx> {
short
}
- pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
+ pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option<PathBuf>) -> String {
let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
cx.pretty_print_type(ty)
})
.expect("could not write to `String`");
if !self.sess.opts.unstable_opts.write_long_types_to_disk {
- return (regular, None);
+ return regular;
}
let width = self.sess.diagnostic_width();
let length_limit = width.saturating_sub(30);
if regular.len() <= width {
- return (regular, None);
+ return regular;
}
let short = self.ty_string_with_limit(ty, length_limit);
if regular == short {
- return (regular, None);
+ return regular;
}
- // Multiple types might be shortened in a single error, ensure we create a file for each.
+ // Ensure we create an unique file for the type passed in when we create a file.
let mut s = DefaultHasher::new();
ty.hash(&mut s);
let hash = s.finish();
- let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
- match std::fs::write(&path, &regular) {
- Ok(_) => (short, Some(path)),
- Err(_) => (regular, None),
+ *path = Some(path.take().unwrap_or_else(|| {
+ self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
+ }));
+ match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) {
+ Ok(_) => short,
+ Err(_) => regular,
}
}
}
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 75ea53195..38a9cabca 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -62,7 +62,7 @@ pub enum TreatParams {
///
/// N.B. during deep rejection, this acts identically to `ForLookup`.
///
- /// FIXME(-Ztrait-solver=next): Remove this variant and cleanup
+ /// FIXME(-Znext-solver): Remove this variant and cleanup
/// the code.
NextSolverLookup,
}
@@ -189,14 +189,14 @@ pub struct DeepRejectCtxt {
}
impl DeepRejectCtxt {
- pub fn args_refs_may_unify<'tcx>(
+ pub fn args_may_unify<'tcx>(
self,
obligation_args: GenericArgsRef<'tcx>,
impl_args: GenericArgsRef<'tcx>,
) -> bool {
iter::zip(obligation_args, impl_args).all(|(obl, imp)| {
match (obl.unpack(), imp.unpack()) {
- // We don't fast reject based on regions for now.
+ // We don't fast reject based on regions.
(GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true,
(GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => {
self.types_may_unify(obl, imp)
@@ -231,7 +231,7 @@ impl DeepRejectCtxt {
| ty::Never
| ty::Tuple(..)
| ty::FnPtr(..)
- | ty::Foreign(..) => {}
+ | ty::Foreign(..) => debug_assert!(impl_ty.is_known_rigid()),
ty::FnDef(..)
| ty::Closure(..)
| ty::Coroutine(..)
@@ -260,7 +260,7 @@ impl DeepRejectCtxt {
},
ty::Adt(obl_def, obl_args) => match k {
&ty::Adt(impl_def, impl_args) => {
- obl_def == impl_def && self.args_refs_may_unify(obl_args, impl_args)
+ obl_def == impl_def && self.args_may_unify(obl_args, impl_args)
}
_ => false,
},
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index ec36bdc5a..f9a2385b1 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -28,10 +28,11 @@ impl FlagComputation {
result
}
- pub fn for_const(c: ty::Const<'_>) -> TypeFlags {
+ pub fn for_const(c: &ty::ConstKind<'_>, t: Ty<'_>) -> FlagComputation {
let mut result = FlagComputation::new();
- result.add_const(c);
- result.flags
+ result.add_const_kind(c);
+ result.add_ty(t);
+ result
}
fn add_flags(&mut self, flags: TypeFlags) {
@@ -137,7 +138,7 @@ impl FlagComputation {
&ty::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
- self.add_flags(TypeFlags::HAS_TY_LATE_BOUND);
+ self.add_flags(TypeFlags::HAS_TY_BOUND);
}
&ty::Placeholder(..) => {
@@ -263,9 +264,6 @@ impl FlagComputation {
self.add_args(slice::from_ref(&arg));
}
ty::PredicateKind::ObjectSafe(_def_id) => {}
- ty::PredicateKind::ClosureKind(_def_id, args, _kind) => {
- self.add_args(args);
- }
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
self.add_const(uv);
}
@@ -274,6 +272,10 @@ impl FlagComputation {
self.add_const(found);
}
ty::PredicateKind::Ambiguous => {}
+ ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) => {
+ self.add_alias_ty(alias);
+ self.add_term(term);
+ }
ty::PredicateKind::AliasRelate(t1, t2, _) => {
self.add_term(t1);
self.add_term(t2);
@@ -294,14 +296,18 @@ impl FlagComputation {
fn add_region(&mut self, r: ty::Region<'_>) {
self.add_flags(r.type_flags());
- if let ty::ReLateBound(debruijn, _) = *r {
+ if let ty::ReBound(debruijn, _) = *r {
self.add_bound_var(debruijn);
}
}
fn add_const(&mut self, c: ty::Const<'_>) {
- self.add_ty(c.ty());
- match c.kind() {
+ self.add_flags(c.flags());
+ self.add_exclusive_binder(c.outer_exclusive_binder());
+ }
+
+ fn add_const_kind(&mut self, c: &ty::ConstKind<'_>) {
+ match *c {
ty::ConstKind::Unevaluated(uv) => {
self.add_args(uv.args);
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
@@ -317,7 +323,7 @@ impl FlagComputation {
}
ty::ConstKind::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
- self.add_flags(TypeFlags::HAS_CT_LATE_BOUND);
+ self.add_flags(TypeFlags::HAS_CT_BOUND);
}
ty::ConstKind::Param(_) => {
self.add_flags(TypeFlags::HAS_CT_PARAM);
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 00529a1e0..3e64f9a2a 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -68,12 +68,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// Folds over the substructure of a type, visiting its component
/// types and all regions that occur *free* within it.
///
-/// That is, `Ty` can contain function or method types that bind
-/// regions at the call site (`ReLateBound`), and occurrences of
-/// regions (aka "lifetimes") that are bound within a type are not
-/// visited by this folder; only regions that occur free will be
+/// That is, function pointer types and trait object can introduce
+/// new bound regions which are not visited by this visitors as
+/// they are not free; only regions that occur free will be
/// visited by `fld_r`.
-
pub struct RegionFolder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
@@ -117,7 +115,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
#[instrument(skip(self), level = "debug", ret)]
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
+ ty::ReBound(debruijn, _) if debruijn < self.current_index => {
debug!(?self.current_index, "skipped bound region");
r
}
@@ -205,15 +203,15 @@ where
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
+ ty::ReBound(debruijn, br) if debruijn == self.current_index => {
let region = self.delegate.replace_region(br);
- if let ty::ReLateBound(debruijn1, br) = *region {
- // If the callback returns a late-bound region,
+ if let ty::ReBound(debruijn1, br) = *region {
+ // If the callback returns a bound region,
// that region should always use the INNERMOST
// debruijn index. Then we adjust it to the
// correct depth.
assert_eq!(debruijn1, ty::INNERMOST);
- ty::Region::new_late_bound(self.tcx, debruijn, br)
+ ty::Region::new_bound(self.tcx, debruijn, br)
} else {
region
}
@@ -252,7 +250,7 @@ impl<'tcx> TyCtxt<'tcx> {
///
/// This method only replaces late bound regions. Any types or
/// constants bound by `value` will cause an ICE.
- pub fn replace_late_bound_regions<T, F>(
+ pub fn instantiate_bound_regions<T, F>(
self,
value: Binder<'tcx, T>,
mut fld_r: F,
@@ -263,11 +261,11 @@ impl<'tcx> TyCtxt<'tcx> {
{
let mut region_map = BTreeMap::new();
let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br));
- let value = self.replace_late_bound_regions_uncached(value, real_fld_r);
+ let value = self.instantiate_bound_regions_uncached(value, real_fld_r);
(value, region_map)
}
- pub fn replace_late_bound_regions_uncached<T, F>(
+ pub fn instantiate_bound_regions_uncached<T, F>(
self,
value: Binder<'tcx, T>,
mut replace_regions: F,
@@ -327,8 +325,8 @@ impl<'tcx> TyCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
- self.replace_late_bound_regions_uncached(value, |br| {
- ty::Region::new_free(self, all_outlive_scope, br.kind)
+ self.instantiate_bound_regions_uncached(value, |br| {
+ ty::Region::new_late_param(self, all_outlive_scope, br.kind)
})
}
@@ -341,7 +339,7 @@ impl<'tcx> TyCtxt<'tcx> {
value,
FnMutDelegate {
regions: &mut |r: ty::BoundRegion| {
- ty::Region::new_late_bound(
+ ty::Region::new_bound(
self,
ty::INNERMOST,
ty::BoundRegion { var: shift_bv(r.var), kind: r.kind },
@@ -363,11 +361,11 @@ impl<'tcx> TyCtxt<'tcx> {
/// Replaces any late-bound regions bound in `value` with `'erased`. Useful in codegen but also
/// method lookup and a few other places where precise region relationships are not required.
- pub fn erase_late_bound_regions<T>(self, value: Binder<'tcx, T>) -> T
+ pub fn instantiate_bound_regions_with_erased<T>(self, value: Binder<'tcx, T>) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
- self.replace_late_bound_regions(value, |_| self.lifetimes.re_erased).0
+ self.instantiate_bound_regions(value, |_| self.lifetimes.re_erased).0
}
/// Anonymize all bound variables in `value`, this is mostly used to improve caching.
@@ -388,7 +386,7 @@ impl<'tcx> TyCtxt<'tcx> {
.or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon))
.expect_region();
let br = ty::BoundRegion { var, kind };
- ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br)
+ ty::Region::new_bound(self.tcx, ty::INNERMOST, br)
}
fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
let entry = self.map.entry(bt.var);
@@ -454,9 +452,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
+ ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
let debruijn = debruijn.shifted_in(self.amount);
- ty::Region::new_late_bound(self.tcx, debruijn, br)
+ ty::Region::new_bound(self.tcx, debruijn, br)
}
_ => r,
}
@@ -496,8 +494,8 @@ pub fn shift_region<'tcx>(
amount: u32,
) -> ty::Region<'tcx> {
match *region {
- ty::ReLateBound(debruijn, br) if amount > 0 => {
- ty::Region::new_late_bound(tcx, debruijn.shifted_in(amount), br)
+ ty::ReBound(debruijn, br) if amount > 0 => {
+ ty::Region::new_bound(tcx, debruijn.shifted_in(amount), br)
}
_ => region,
}
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 41a1bf04e..63f4bab79 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::intern::Interned;
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
-use rustc_serialize::{self, Decodable, Encodable};
+use rustc_serialize::{Decodable, Encodable};
use rustc_type_ir::WithCachedTypeInfo;
use smallvec::SmallVec;
@@ -70,7 +70,7 @@ impl<'tcx> GenericArgKind<'tcx> {
GenericArgKind::Const(ct) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
- (CONST_TAG, ct.0.0 as *const ty::ConstData<'tcx> as usize)
+ (CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize)
}
};
@@ -86,7 +86,7 @@ impl<'tcx> Ord for GenericArg<'tcx> {
impl<'tcx> PartialOrd for GenericArg<'tcx> {
fn partial_cmp(&self, other: &GenericArg<'tcx>) -> Option<Ordering> {
- Some(self.cmp(&other))
+ Some(self.cmp(other))
}
}
@@ -136,7 +136,7 @@ impl<'tcx> GenericArg<'tcx> {
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
))),
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
- &*((ptr & !TAG_MASK) as *const ty::ConstData<'tcx>),
+ &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
))),
_ => intrinsics::unreachable(),
}
@@ -604,13 +604,6 @@ impl<T> EarlyBinder<Option<T>> {
}
}
-impl<T, U> EarlyBinder<(T, U)> {
- pub fn transpose_tuple2(self) -> (EarlyBinder<T>, EarlyBinder<U>) {
- let EarlyBinder { value: (lhs, rhs) } = self;
- (EarlyBinder { value: lhs }, EarlyBinder { value: rhs })
- }
-}
-
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
where
I::Item: TypeFoldable<TyCtxt<'tcx>>,
@@ -809,7 +802,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
#[cold]
#[inline(never)]
- fn region_param_out_of_range(data: ty::EarlyBoundRegion, args: &[GenericArg<'_>]) -> ! {
+ fn region_param_out_of_range(data: ty::EarlyParamRegion, args: &[GenericArg<'_>]) -> ! {
bug!(
"Region parameter out of range when substituting in region {} (index={}, args = {:?})",
data.name,
@@ -820,7 +813,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
#[cold]
#[inline(never)]
- fn region_param_invalid(data: ty::EarlyBoundRegion, other: GenericArgKind<'_>) -> ! {
+ fn region_param_invalid(data: ty::EarlyParamRegion, other: GenericArgKind<'_>) -> ! {
bug!(
"Unexpected parameter {:?} when substituting in region {} (index={})",
other,
@@ -835,7 +828,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
// regions that appear in a function signature is done using
// the specialized routine `ty::replace_late_regions()`.
match *r {
- ty::ReEarlyBound(data) => {
+ ty::ReEarlyParam(data) => {
let rk = self.args.get(data.index as usize).map(|k| k.unpack());
match rk {
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
@@ -843,8 +836,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
None => region_param_out_of_range(data, self.args),
}
}
- ty::ReLateBound(..)
- | ty::ReFree(_)
+ ty::ReBound(..)
+ | ty::ReLateParam(_)
| ty::ReStatic
| ty::RePlaceholder(_)
| ty::ReErased
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 888ee1d23..c3699b114 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span;
-use super::{Clause, EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
+use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum GenericParamDefKind {
@@ -62,9 +62,9 @@ pub struct GenericParamDef {
}
impl GenericParamDef {
- pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
+ pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion {
if let GenericParamDefKind::Lifetime = self.kind {
- ty::EarlyBoundRegion { def_id: self.def_id, index: self.index, name: self.name }
+ ty::EarlyParamRegion { def_id: self.def_id, index: self.index, name: self.name }
} else {
bug!("cannot convert a non-lifetime parameter def to an early bound region")
}
@@ -260,10 +260,10 @@ impl<'tcx> Generics {
}
}
- /// Returns the `GenericParamDef` associated with this `EarlyBoundRegion`.
+ /// Returns the `GenericParamDef` associated with this `EarlyParamRegion`.
pub fn region_param(
&'tcx self,
- param: &EarlyBoundRegion,
+ param: &ty::EarlyParamRegion,
tcx: TyCtxt<'tcx>,
) -> &'tcx GenericParamDef {
let param = self.param_at(param.index as usize, tcx);
@@ -326,6 +326,8 @@ impl<'tcx> Generics {
own_params.start = 1;
}
+ let verbose = tcx.sess.verbose();
+
// Filter the default arguments.
//
// This currently uses structural equality instead
@@ -340,6 +342,8 @@ impl<'tcx> Generics {
param.default_value(tcx).is_some_and(|default| {
default.instantiate(tcx, args) == args[param.index as usize]
})
+ // filter out trailing effect params, if we're not in `-Zverbose`.
+ || (!verbose && matches!(param.kind, GenericParamDefKind::Const { is_host_effect: true, .. }))
})
.count();
@@ -354,7 +358,7 @@ impl<'tcx> Generics {
args: &'tcx [ty::GenericArg<'tcx>],
) -> &'tcx [ty::GenericArg<'tcx>] {
let own = &args[self.parent_count..][..self.params.len()];
- if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
+ if self.has_self && self.parent.is_none() { &own[1..] } else { own }
}
}
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index b03874a90..129d94769 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -29,7 +29,7 @@ where
}
let mut hasher = StableHasher::new();
- (&self[..]).hash_stable(hcx, &mut hasher);
+ self[..].hash_stable(hcx, &mut hasher);
let hash: Fingerprint = hasher.finish();
cache.borrow_mut().insert(key, hash);
@@ -84,6 +84,14 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
}
}
+// CtfeProvenance is an AllocId and a bool.
+impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::CtfeProvenance {
+ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
+ self.alloc_id().hash_stable(hcx, hasher);
+ self.immutable().hash_stable(hcx, hasher);
+ }
+}
+
impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
type KeyType = region::Scope;
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index f278cace9..ae1794278 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -1,3 +1,5 @@
+use smallvec::SmallVec;
+
use crate::ty::context::TyCtxt;
use crate::ty::{self, DefId, ParamEnv, Ty};
@@ -31,27 +33,31 @@ impl<'tcx> InhabitedPredicate<'tcx> {
/// Returns true if the corresponding type is inhabited in the given
/// `ParamEnv` and module
pub fn apply(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, module_def_id: DefId) -> bool {
- let Ok(result) = self
- .apply_inner::<!>(tcx, param_env, &|id| Ok(tcx.is_descendant_of(module_def_id, id)));
+ let Ok(result) = self.apply_inner::<!>(tcx, param_env, &mut Default::default(), &|id| {
+ Ok(tcx.is_descendant_of(module_def_id, id))
+ });
result
}
/// Same as `apply`, but returns `None` if self contains a module predicate
pub fn apply_any_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
- self.apply_inner(tcx, param_env, &|_| Err(())).ok()
+ self.apply_inner(tcx, param_env, &mut Default::default(), &|_| Err(())).ok()
}
/// Same as `apply`, but `NotInModule(_)` predicates yield `false`. That is,
/// privately uninhabited types are considered always uninhabited.
pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> bool {
- let Ok(result) = self.apply_inner::<!>(tcx, param_env, &|_| Ok(true));
+ let Ok(result) =
+ self.apply_inner::<!>(tcx, param_env, &mut Default::default(), &|_| Ok(true));
result
}
- fn apply_inner<E>(
+ #[instrument(level = "debug", skip(tcx, param_env, in_module), ret)]
+ fn apply_inner<E: std::fmt::Debug>(
self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
+ eval_stack: &mut SmallVec<[Ty<'tcx>; 1]>, // for cycle detection
in_module: &impl Fn(DefId) -> Result<bool, E>,
) -> Result<bool, E> {
match self {
@@ -71,11 +77,25 @@ impl<'tcx> InhabitedPredicate<'tcx> {
match normalized_pred {
// We don't have more information than we started with, so consider inhabited.
Self::GenericType(_) => Ok(true),
- pred => pred.apply_inner(tcx, param_env, in_module),
+ pred => {
+ // A type which is cyclic when monomorphized can happen here since the
+ // layout error would only trigger later. See e.g. `tests/ui/sized/recursive-type-2.rs`.
+ if eval_stack.contains(&t) {
+ return Ok(true); // Recover; this will error later.
+ }
+ eval_stack.push(t);
+ let ret = pred.apply_inner(tcx, param_env, eval_stack, in_module);
+ eval_stack.pop();
+ ret
+ }
}
}
- Self::And([a, b]) => try_and(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
- Self::Or([a, b]) => try_or(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
+ Self::And([a, b]) => {
+ try_and(a, b, |x| x.apply_inner(tcx, param_env, eval_stack, in_module))
+ }
+ Self::Or([a, b]) => {
+ try_or(a, b, |x| x.apply_inner(tcx, param_env, eval_stack, in_module))
+ }
}
}
@@ -197,7 +217,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
// this is basically like `f(a)? && f(b)?` but different in the case of
// `Ok(false) && Err(_) -> Ok(false)`
-fn try_and<T, E>(a: T, b: T, f: impl Fn(T) -> Result<bool, E>) -> Result<bool, E> {
+fn try_and<T, E>(a: T, b: T, mut f: impl FnMut(T) -> Result<bool, E>) -> Result<bool, E> {
let a = f(a);
if matches!(a, Ok(false)) {
return Ok(false);
@@ -209,7 +229,7 @@ fn try_and<T, E>(a: T, b: T, f: impl Fn(T) -> Result<bool, E>) -> Result<bool, E
}
}
-fn try_or<T, E>(a: T, b: T, f: impl Fn(T) -> Result<bool, E>) -> Result<bool, E> {
+fn try_or<T, E>(a: T, b: T, mut f: impl FnMut(T) -> Result<bool, E>) -> Result<bool, E> {
let a = f(a);
if matches!(a, Ok(true)) {
return Ok(true);
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 68ac54e89..d67fb9fd0 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -103,6 +103,7 @@ impl<'tcx> VariantDef {
}
impl<'tcx> Ty<'tcx> {
+ #[instrument(level = "debug", skip(tcx), ret)]
pub fn inhabited_predicate(self, tcx: TyCtxt<'tcx>) -> InhabitedPredicate<'tcx> {
match self.kind() {
// For now, unions are always considered inhabited
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index cebefbccc..1c7a7545e 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -215,7 +215,7 @@ impl<'tcx> InstanceDef<'tcx> {
};
matches!(
tcx.def_key(def_id).disambiguated_data.data,
- DefPathData::Ctor | DefPathData::ClosureExpr
+ DefPathData::Ctor | DefPathData::Closure
)
}
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 4223e503f..225dd2178 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -2,10 +2,10 @@ use crate::error::UnsupportedFnAbi;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::query::TyCtxtAt;
use crate::ty::normalize_erasing_regions::NormalizationError;
-use crate::ty::{self, ConstKind, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::{self, ConstKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_error_messages::DiagnosticMessage;
use rustc_errors::{
- DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
+ DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, IntoDiagnostic, IntoDiagnosticArg,
};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -215,7 +215,7 @@ pub enum LayoutError<'tcx> {
SizeOverflow(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
ReferencesError(ErrorGuaranteed),
- Cycle,
+ Cycle(ErrorGuaranteed),
}
impl<'tcx> LayoutError<'tcx> {
@@ -226,7 +226,7 @@ impl<'tcx> LayoutError<'tcx> {
Unknown(_) => middle_unknown_layout,
SizeOverflow(_) => middle_values_too_big,
NormalizationFailure(_, _) => middle_cannot_be_normalized,
- Cycle => middle_cycle,
+ Cycle(_) => middle_cycle,
ReferencesError(_) => middle_layout_references_error,
}
}
@@ -240,7 +240,7 @@ impl<'tcx> LayoutError<'tcx> {
NormalizationFailure(ty, e) => {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
}
- Cycle => E::Cycle,
+ Cycle(_) => E::Cycle,
ReferencesError(_) => E::ReferencesError,
}
}
@@ -261,7 +261,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
t,
e.get_type_for_failure()
),
- LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"),
+ LayoutError::Cycle(_) => write!(f, "a cycle occurred during layout computation"),
LayoutError::ReferencesError(_) => write!(f, "the type has an unknown layout"),
}
}
@@ -282,8 +282,8 @@ pub struct LayoutCx<'tcx, C> {
impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
type TargetDataLayoutRef = &'tcx TargetDataLayout;
- fn delay_bug(&self, txt: String) {
- self.tcx.sess.delay_span_bug(DUMMY_SP, txt);
+ fn delayed_bug(&self, txt: String) {
+ self.tcx.sess.span_delayed_bug(DUMMY_SP, txt);
}
fn current_data_layout(&self) -> Self::TargetDataLayoutRef {
@@ -333,7 +333,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
Err(err @ LayoutError::Unknown(_)) => err,
// We can't extract SizeSkeleton info from other layout errors
Err(
- e @ LayoutError::Cycle
+ e @ LayoutError::Cycle(_)
| e @ LayoutError::SizeOverflow(_)
| e @ LayoutError::NormalizationFailure(..)
| e @ LayoutError::ReferencesError(_),
@@ -899,13 +899,13 @@ where
ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
// Tuples, coroutines and closures.
- ty::Closure(_, ref args) => field_ty_or_layout(
+ ty::Closure(_, args) => field_ty_or_layout(
TyAndLayout { ty: args.as_closure().tupled_upvars_ty(), ..this },
cx,
i,
),
- ty::Coroutine(def_id, ref args, _) => match this.variants {
+ ty::Coroutine(def_id, args, _) => match this.variants {
Variants::Single { index } => TyMaybeWithLayout::Ty(
args.as_coroutine()
.state_tys(def_id, tcx)
@@ -1273,13 +1273,13 @@ pub enum FnAbiError<'tcx> {
}
impl<'a, 'b> IntoDiagnostic<'a, !> for FnAbiError<'b> {
- fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> {
+ fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, !> {
match self {
- Self::Layout(e) => e.into_diagnostic().into_diagnostic(handler),
+ Self::Layout(e) => e.into_diagnostic().into_diagnostic(dcx),
Self::AdjustForForeignAbi(call::AdjustForForeignAbiError::Unsupported {
arch,
abi,
- }) => UnsupportedFnAbi { arch, abi: abi.name() }.into_diagnostic(handler),
+ }) => UnsupportedFnAbi { arch, abi: abi.name() }.into_diagnostic(dcx),
}
}
}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index e1c616ba0..35c135830 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -42,7 +42,6 @@ use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
-use rustc_hir::Node;
use rustc_index::IndexVec;
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
@@ -66,27 +65,20 @@ use std::ops::ControlFlow;
use std::{fmt, str};
pub use crate::ty::diagnostics::*;
-pub use rustc_type_ir::AliasKind::*;
pub use rustc_type_ir::ConstKind::{
Bound as BoundCt, Error as ErrorCt, Expr as ExprCt, Infer as InferCt, Param as ParamCt,
Placeholder as PlaceholderCt, Unevaluated, Value,
};
-pub use rustc_type_ir::DynKind::*;
-pub use rustc_type_ir::InferTy::*;
-pub use rustc_type_ir::RegionKind::*;
-pub use rustc_type_ir::TyKind::*;
pub use rustc_type_ir::*;
pub use self::binding::BindingMode;
pub use self::binding::BindingMode::*;
pub use self::closure::{
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
- CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
+ CapturedPlace, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
};
-pub use self::consts::{
- Const, ConstData, ConstInt, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree,
-};
+pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
pub use self::context::{
tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed,
};
@@ -96,13 +88,13 @@ pub use self::parameterized::ParameterizedOverTcx;
pub use self::rvalue_scopes::RvalueScopes;
pub use self::sty::BoundRegionKind::*;
pub use self::sty::{
- AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
+ AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind,
BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind,
- ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyBoundRegion, EffectVid, ExistentialPredicate,
- ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, InlineConstArgs,
- InlineConstArgsParts, ParamConst, ParamTy, PolyExistentialPredicate, PolyExistentialProjection,
- PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, PredicateKind, Region,
- RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
+ CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, ExistentialPredicate,
+ ExistentialProjection, ExistentialTraitRef, FnSig, GenSig, InlineConstArgs,
+ InlineConstArgsParts, LateParamRegion, ParamConst, ParamTy, PolyExistentialPredicate,
+ PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyTraitRef, PredicateKind,
+ Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
};
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
@@ -160,7 +152,7 @@ pub struct ResolverOutputs {
#[derive(Debug)]
pub struct ResolverGlobalCtxt {
- pub visibilities: FxHashMap<LocalDefId, Visibility>,
+ pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
pub effective_visibilities: EffectiveVisibilities,
@@ -200,13 +192,10 @@ pub struct ResolverAstLowering {
pub next_node_id: ast::NodeId,
- pub node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>,
+ pub node_id_to_def_id: NodeMap<LocalDefId>,
pub def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
- /// A small map keeping true kinds of built-in macros that appear to be fn-like on
- /// the surface (`macro` items in libcore), but are actually attributes or derives.
- pub builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
/// List functions and methods for which lifetime elision was successful.
pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
@@ -301,6 +290,23 @@ pub enum Visibility<Id = LocalDefId> {
Restricted(Id),
}
+impl Visibility {
+ pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
+ match self {
+ ty::Visibility::Restricted(restricted_id) => {
+ if restricted_id.is_top_level_module() {
+ "pub(crate)".to_string()
+ } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
+ "pub(self)".to_string()
+ } else {
+ format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
+ }
+ }
+ ty::Visibility::Public => "pub".to_string(),
+ }
+ }
+}
+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
pub enum BoundConstness {
/// `T: Trait`
@@ -463,7 +469,15 @@ pub struct CReaderCacheKey {
#[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
-impl ty::EarlyBoundRegion {
+impl<'tcx> IntoKind for Ty<'tcx> {
+ type Kind = TyKind<'tcx>;
+
+ fn kind(self) -> TyKind<'tcx> {
+ *self.kind()
+ }
+}
+
+impl EarlyParamRegion {
/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).
pub fn has_name(&self) -> bool {
@@ -542,6 +556,10 @@ impl<'tcx> Predicate<'tcx> {
pub fn allow_normalization(self) -> bool {
match self.kind().skip_binder() {
PredicateKind::Clause(ClauseKind::WellFormed(_)) => false,
+ // `NormalizesTo` is only used in the new solver, so this shouldn't
+ // matter. Normalizing `term` would be 'wrong' however, as it changes whether
+ // `normalizes-to(<T as Trait>::Assoc, <T as Trait>::Assoc)` holds.
+ PredicateKind::NormalizesTo(..) => false,
PredicateKind::Clause(ClauseKind::Trait(_))
| PredicateKind::Clause(ClauseKind::RegionOutlives(_))
| PredicateKind::Clause(ClauseKind::TypeOutlives(_))
@@ -549,7 +567,6 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
| PredicateKind::AliasRelate(..)
| PredicateKind::ObjectSafe(_)
- | PredicateKind::ClosureKind(_, _, _)
| PredicateKind::Subtype(_)
| PredicateKind::Coerce(_)
| PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
@@ -902,7 +919,7 @@ impl<'tcx> Term<'tcx> {
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
))),
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
- &*((ptr & !TAG_MASK) as *const ty::ConstData<'tcx>),
+ &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
))),
_ => core::intrinsics::unreachable(),
}
@@ -969,7 +986,7 @@ impl<'tcx> TermKind<'tcx> {
TermKind::Const(ct) => {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
- (CONST_TAG, ct.0.0 as *const ty::ConstData<'tcx> as usize)
+ (CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize)
}
};
@@ -1083,6 +1100,33 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
}
}
+/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be
+/// proven by actually normalizing `alias`.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
+#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
+pub struct NormalizesTo<'tcx> {
+ pub alias: AliasTy<'tcx>,
+ pub term: Term<'tcx>,
+}
+
+impl<'tcx> NormalizesTo<'tcx> {
+ pub fn self_ty(self) -> Ty<'tcx> {
+ self.alias.self_ty()
+ }
+
+ pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> NormalizesTo<'tcx> {
+ Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self }
+ }
+
+ pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
+ self.alias.trait_def_id(tcx)
+ }
+
+ pub fn def_id(self) -> DefId {
+ self.alias.def_id
+ }
+}
+
pub trait ToPolyTraitRef<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}
@@ -1264,6 +1308,12 @@ impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> {
}
}
+impl<'tcx> ToPredicate<'tcx> for NormalizesTo<'tcx> {
+ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
+ PredicateKind::NormalizesTo(self).to_predicate(tcx)
+ }
+}
+
impl<'tcx> Predicate<'tcx> {
pub fn to_opt_poly_trait_pred(self) -> Option<PolyTraitPredicate<'tcx>> {
let predicate = self.kind();
@@ -1271,13 +1321,13 @@ impl<'tcx> Predicate<'tcx> {
PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
PredicateKind::Clause(ClauseKind::Projection(..))
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
+ | PredicateKind::NormalizesTo(..)
| PredicateKind::AliasRelate(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
| PredicateKind::Clause(ClauseKind::RegionOutlives(..))
| PredicateKind::Clause(ClauseKind::WellFormed(..))
| PredicateKind::ObjectSafe(..)
- | PredicateKind::ClosureKind(..)
| PredicateKind::Clause(ClauseKind::TypeOutlives(..))
| PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
| PredicateKind::ConstEquate(..)
@@ -1291,13 +1341,13 @@ impl<'tcx> Predicate<'tcx> {
PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
PredicateKind::Clause(ClauseKind::Trait(..))
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
+ | PredicateKind::NormalizesTo(..)
| PredicateKind::AliasRelate(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
| PredicateKind::Clause(ClauseKind::RegionOutlives(..))
| PredicateKind::Clause(ClauseKind::WellFormed(..))
| PredicateKind::ObjectSafe(..)
- | PredicateKind::ClosureKind(..)
| PredicateKind::Clause(ClauseKind::TypeOutlives(..))
| PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
| PredicateKind::ConstEquate(..)
@@ -1305,26 +1355,6 @@ impl<'tcx> Predicate<'tcx> {
}
}
- pub fn to_opt_type_outlives(self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
- let predicate = self.kind();
- match predicate.skip_binder() {
- PredicateKind::Clause(ClauseKind::TypeOutlives(data)) => Some(predicate.rebind(data)),
- PredicateKind::Clause(ClauseKind::Trait(..))
- | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
- | PredicateKind::Clause(ClauseKind::Projection(..))
- | PredicateKind::AliasRelate(..)
- | PredicateKind::Subtype(..)
- | PredicateKind::Coerce(..)
- | PredicateKind::Clause(ClauseKind::RegionOutlives(..))
- | PredicateKind::Clause(ClauseKind::WellFormed(..))
- | PredicateKind::ObjectSafe(..)
- | PredicateKind::ClosureKind(..)
- | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
- | PredicateKind::ConstEquate(..)
- | PredicateKind::Ambiguous => None,
- }
- }
-
/// Matches a `PredicateKind::Clause` and turns it into a `Clause`, otherwise returns `None`.
pub fn as_clause(self) -> Option<Clause<'tcx>> {
match self.kind().skip_binder() {
@@ -1377,7 +1407,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
}
pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
- (&self).into_iter()
+ self.into_iter()
}
}
@@ -1454,7 +1484,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
if let Some(diag) = tcx
.sess
- .diagnostic()
+ .dcx()
.steal_diagnostic(tcx.def_span(opaque_def_id), StashKey::OpaqueHiddenTypeMismatch)
{
diag.cancel();
@@ -1518,8 +1548,44 @@ pub struct Placeholder<T> {
pub type PlaceholderRegion = Placeholder<BoundRegion>;
+impl PlaceholderLike for PlaceholderRegion {
+ fn universe(self) -> UniverseIndex {
+ self.universe
+ }
+
+ fn var(self) -> BoundVar {
+ self.bound.var
+ }
+
+ fn with_updated_universe(self, ui: UniverseIndex) -> Self {
+ Placeholder { universe: ui, ..self }
+ }
+
+ fn new(ui: UniverseIndex, var: BoundVar) -> Self {
+ Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::BrAnon } }
+ }
+}
+
pub type PlaceholderType = Placeholder<BoundTy>;
+impl PlaceholderLike for PlaceholderType {
+ fn universe(self) -> UniverseIndex {
+ self.universe
+ }
+
+ fn var(self) -> BoundVar {
+ self.bound.var
+ }
+
+ fn with_updated_universe(self, ui: UniverseIndex) -> Self {
+ Placeholder { universe: ui, ..self }
+ }
+
+ fn new(ui: UniverseIndex, var: BoundVar) -> Self {
+ Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } }
+ }
+}
+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
pub struct BoundConst<'tcx> {
@@ -1529,6 +1595,24 @@ pub struct BoundConst<'tcx> {
pub type PlaceholderConst = Placeholder<BoundVar>;
+impl PlaceholderLike for PlaceholderConst {
+ fn universe(self) -> UniverseIndex {
+ self.universe
+ }
+
+ fn var(self) -> BoundVar {
+ self.bound
+ }
+
+ fn with_updated_universe(self, ui: UniverseIndex) -> Self {
+ Placeholder { universe: ui, ..self }
+ }
+
+ fn new(ui: UniverseIndex, var: BoundVar) -> Self {
+ Placeholder { universe: ui, bound: var }
+ }
+}
+
/// When type checking, we use the `ParamEnv` to track
/// details about the set of where-clauses that are in scope at this
/// particular point.
@@ -2021,7 +2105,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
for attr in self.get_attrs(did, sym::repr) {
- for r in attr::parse_repr_attr(&self.sess, attr) {
+ for r in attr::parse_repr_attr(self.sess, attr) {
flags.insert(match r {
attr::ReprRust => ReprFlags::empty(),
attr::ReprC => ReprFlags::IS_C,
@@ -2256,7 +2340,7 @@ impl<'tcx> TyCtxt<'tcx> {
// FIXME(@lcnr): Remove this function.
pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [ast::Attribute] {
if let Some(did) = did.as_local() {
- self.hir().attrs(self.hir().local_def_id_to_hir_id(did))
+ self.hir().attrs(self.local_def_id_to_hir_id(did))
} else {
self.item_attrs(did)
}
@@ -2271,7 +2355,7 @@ impl<'tcx> TyCtxt<'tcx> {
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)
+ self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
} else if cfg!(debug_assertions) && rustc_feature::is_builtin_only_local(attr) {
bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr);
} else {
@@ -2287,9 +2371,9 @@ impl<'tcx> TyCtxt<'tcx> {
where
'tcx: 'attr,
{
- let filter_fn = move |a: &&ast::Attribute| a.path_matches(&attr);
+ let filter_fn = move |a: &&ast::Attribute| a.path_matches(attr);
if let Some(did) = did.as_local() {
- self.hir().attrs(self.hir().local_def_id_to_hir_id(did)).iter().filter(filter_fn)
+ self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
} else {
self.item_attrs(did).iter().filter(filter_fn)
}
@@ -2495,22 +2579,6 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
-/// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition.
-pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<LocalDefId> {
- let def_id = def_id.as_local()?;
- if let Node::Item(item) = tcx.hir().get_by_def_id(def_id) {
- if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
- return match opaque_ty.origin {
- hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
- Some(parent)
- }
- hir::OpaqueTyOrigin::TyAlias { .. } => None,
- };
- }
- }
- None
-}
-
pub fn int_ty(ity: ast::IntTy) -> IntTy {
match ity {
ast::IntTy::Isize => IntTy::Isize,
@@ -2599,9 +2667,7 @@ pub struct SymbolName<'tcx> {
impl<'tcx> SymbolName<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, name: &str) -> SymbolName<'tcx> {
- SymbolName {
- name: unsafe { str::from_utf8_unchecked(tcx.arena.alloc_slice(name.as_bytes())) },
- }
+ SymbolName { name: tcx.arena.alloc_str(name) }
}
}
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index fd125af20..27c436c82 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -97,6 +97,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// N.B., currently, higher-ranked type bounds inhibit
/// normalization. Therefore, each time we erase them in
/// codegen, we need to normalize the contents.
+ // FIXME(@lcnr): This method should not be necessary, we now normalize
+ // inside of binders. We should be able to only use
+ // `tcx.instantiate_bound_regions_with_erased`. Same for the `try_X`
+ // variant.
#[tracing::instrument(level = "debug", skip(self, param_env))]
pub fn normalize_erasing_late_bound_regions<T>(
self,
@@ -106,7 +110,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
- let value = self.erase_late_bound_regions(value);
+ let value = self.instantiate_bound_regions_with_erased(value);
self.normalize_erasing_regions(param_env, value)
}
@@ -126,7 +130,7 @@ impl<'tcx> TyCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
- let value = self.erase_late_bound_regions(value);
+ let value = self.instantiate_bound_regions_with_erased(value);
self.try_normalize_erasing_regions(param_env, value)
}
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 8d895732d..1305f63bd 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -102,8 +102,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
// Ignore bound regions and `'static` regions that appear in the
// type, we only need to remap regions that reference lifetimes
// from the function declaration.
- // This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
- ty::ReLateBound(..) | ty::ReStatic => return r,
+ //
+ // E.g. We ignore `'r` in a type like `for<'r> fn(&'r u32)`.
+ ty::ReBound(..) | ty::ReStatic => return r,
// If regions have been erased (by writeback), don't try to unerase
// them.
@@ -112,7 +113,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
ty::ReError(_) => return r,
// The regions that we expect from borrow checking.
- ty::ReEarlyBound(_) | ty::ReFree(_) => {}
+ ty::ReEarlyParam(_) | ty::ReLateParam(_) => {}
ty::RePlaceholder(_) | ty::ReVar(_) => {
// All of the regions in the type should either have been
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 9afa50cf5..a63a4eff5 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -59,6 +59,7 @@ trivially_parameterized_over_tcx! {
crate::middle::codegen_fn_attrs::CodegenFnAttrs,
crate::middle::debugger_visualizer::DebuggerVisualizerFile,
crate::middle::exported_symbols::SymbolExportInfo,
+ crate::middle::lib_features::FeatureStability,
crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
crate::mir::ConstQualifs,
ty::AssocItemContainer,
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 6bbc8f70f..5e0915478 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -131,7 +131,7 @@ pub trait Printer<'tcx>: Sized {
match key.disambiguated_data.data {
// Closures' own generics are only captures, don't print them.
- DefPathData::ClosureExpr => {}
+ DefPathData::Closure => {}
// This covers both `DefKind::AnonConst` and `DefKind::InlineConst`.
// Anon consts doesn't have their own generics, and inline consts' own
// generics are their inferred types, so don't print them.
@@ -250,7 +250,7 @@ fn characteristic_def_id_of_type_cached<'a>(
ty::Ref(_, ty, _) => characteristic_def_id_of_type_cached(ty, visited),
- ty::Tuple(ref tys) => tys.iter().find_map(|ty| {
+ ty::Tuple(tys) => tys.iter().find_map(|ty| {
if visited.insert(ty) {
return characteristic_def_id_of_type_cached(ty, visited);
}
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index baf160bcc..8e045397b 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2,23 +2,22 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar
use crate::query::IntoQueryParam;
use crate::query::Providers;
use crate::traits::util::supertraits_for_pretty_printing;
+use crate::ty::GenericArgKind;
use crate::ty::{
- self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
- TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+ ConstInt, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
+ TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
-use crate::ty::{GenericArg, GenericArgKind};
use rustc_apfloat::ieee::{Double, Single};
+use rustc_apfloat::Float;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
-use rustc_data_structures::sso::SsoHashSet;
use rustc_hir as hir;
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
-use rustc_hir::def_id::{DefId, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
-use rustc_hir::definitions::{DefKey, DefPathData, DefPathDataName, DisambiguatedDefPathData};
+use rustc_hir::def_id::{DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::definitions::{DefKey, DefPathDataName};
use rustc_hir::LangItem;
use rustc_session::config::TrimmedDefPaths;
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
use rustc_session::Limit;
-use rustc_span::sym;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::FileNameDisplayPreference;
use rustc_target::abi::Size;
@@ -282,7 +281,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
/// from at least one local module, and returns `true`. If the crate defining `def_id` is
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
fn try_print_visible_def_path(&mut self, def_id: DefId) -> Result<bool, PrintError> {
- if NO_VISIBLE_PATH.with(|flag| flag.get()) {
+ if with_no_visible_paths() {
return Ok(false);
}
@@ -322,7 +321,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
&& let Some(symbol) = self.tcx().trimmed_def_paths(()).get(&def_id)
{
// If `Assoc` is unique, we don't want to talk about `Trait::Assoc`.
- self.write_str(get_local_name(&self, *symbol, def_id, key).as_str())?;
+ self.write_str(get_local_name(self, *symbol, def_id, key).as_str())?;
return Ok(true);
}
if let Some(symbol) = key.get_opt_name() {
@@ -332,7 +331,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
&& let Some(symbol) = parent_key.get_opt_name()
{
// Trait
- self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
+ self.write_str(get_local_name(self, symbol, parent, parent_key).as_str())?;
self.write_str("::")?;
} else if let DefKind::Variant = kind
&& let Some(parent) = self.tcx().opt_parent(def_id)
@@ -343,7 +342,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
// For associated items and variants, we want the "full" path, namely, include
// the parent type in the path. For example, `Iterator::Item`.
- self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
+ self.write_str(get_local_name(self, symbol, parent, parent_key).as_str())?;
self.write_str("::")?;
} else if let DefKind::Struct
| DefKind::Union
@@ -358,7 +357,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
// If not covered above, like for example items out of `impl` blocks, fallback.
return Ok(false);
}
- self.write_str(get_local_name(&self, symbol, def_id, key).as_str())?;
+ self.write_str(get_local_name(self, symbol, def_id, key).as_str())?;
return Ok(true);
}
Ok(false)
@@ -366,7 +365,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
/// Try to see if this path can be trimmed to a unique symbol name.
fn try_print_trimmed_def_path(&mut self, def_id: DefId) -> Result<bool, PrintError> {
- if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
+ if with_forced_trimmed_paths() {
let trimmed = self.force_print_trimmed_def_path(def_id)?;
if trimmed {
return Ok(true);
@@ -374,8 +373,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
}
if !self.tcx().sess.opts.unstable_opts.trim_diagnostic_paths
|| matches!(self.tcx().sess.opts.trimmed_def_paths, TrimmedDefPaths::Never)
- || NO_TRIMMED_PATH.with(|flag| flag.get())
- || SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get())
+ || with_no_trimmed_paths()
+ || with_crate_prefix()
{
return Ok(false);
}
@@ -660,7 +659,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
p!(print(ty::TypeAndMut { ty, mutbl }))
}
ty::Never => p!("!"),
- ty::Tuple(ref tys) => {
+ ty::Tuple(tys) => {
p!("(", comma_sep(tys.iter()));
if tys.len() == 1 {
p!(",");
@@ -860,7 +859,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
p!("@", print_def_path(did.to_def_id(), args));
} else {
let span = self.tcx().def_span(did);
- let preference = if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
+ let preference = if with_forced_trimmed_paths() {
FileNameDisplayPreference::Short
} else {
FileNameDisplayPreference::Remapped
@@ -1101,7 +1100,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
write!(self, "Sized")?;
}
- if !FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
+ if !with_forced_trimmed_paths() {
for re in lifetimes {
write!(self, " + ")?;
self.print_region(re)?;
@@ -1409,14 +1408,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
) -> Result<(), PrintError> {
define_scoped_cx!(self);
- let (alloc_id, offset) = ptr.into_parts();
+ let (prov, offset) = ptr.into_parts();
match ty.kind() {
// Byte strings (&[u8; N])
ty::Ref(_, inner, _) => {
if let ty::Array(elem, len) = inner.kind() {
if let ty::Uint(ty::UintTy::U8) = elem.kind() {
if let ty::ConstKind::Value(ty::ValTree::Leaf(int)) = len.kind() {
- match self.tcx().try_get_global_alloc(alloc_id) {
+ match self.tcx().try_get_global_alloc(prov.alloc_id()) {
Some(GlobalAlloc::Memory(alloc)) => {
let len = int.assert_bits(self.tcx().data_layout.pointer_size);
let range =
@@ -1446,7 +1445,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
// FIXME: We should probably have a helper method to share code with the "Byte strings"
// printing above (which also has to handle pointers to all sorts of things).
if let Some(GlobalAlloc::Function(instance)) =
- self.tcx().try_get_global_alloc(alloc_id)
+ self.tcx().try_get_global_alloc(prov.alloc_id())
{
self.typed_value(
|this| this.print_value_path(instance.def_id(), instance.args),
@@ -1477,10 +1476,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
ty::Bool if int == ScalarInt::TRUE => p!("true"),
// Float
ty::Float(ty::FloatTy::F32) => {
- p!(write("{}f32", Single::try_from(int).unwrap()))
+ let val = Single::try_from(int).unwrap();
+ p!(write("{}{}f32", val, if val.is_finite() { "" } else { "_" }))
}
ty::Float(ty::FloatTy::F64) => {
- p!(write("{}f64", Double::try_from(int).unwrap()))
+ let val = Double::try_from(int).unwrap();
+ p!(write("{}{}f64", val, if val.is_finite() { "" } else { "_" }))
}
// Int
ty::Uint(_) | ty::Int(_) => {
@@ -1679,7 +1680,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
self.wrap_binder(&sig, |sig, cx| {
define_scoped_cx!(cx);
- p!(print(kind), "(");
+ p!(write("{kind}("));
for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
if i > 0 {
p!(", ");
@@ -1801,13 +1802,13 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
// (but also some things just print a `DefId` generally so maybe we need this?)
fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace {
match tcx.def_key(def_id).disambiguated_data.data {
- DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::ImplTrait => {
+ DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::OpaqueTy => {
Namespace::TypeNS
}
DefPathData::ValueNs(..)
| DefPathData::AnonConst
- | DefPathData::ClosureExpr
+ | DefPathData::Closure
| DefPathData::Ctor => Namespace::ValueNS,
DefPathData::MacroNs(..) => Namespace::MacroNS,
@@ -1883,7 +1884,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
// available, and filename/line-number is mostly uninteresting.
let use_types = !def_id.is_local() || {
// Otherwise, use filename/line-number if forced.
- let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
+ let force_no_types = with_forced_impl_filename_line();
!force_no_types
};
@@ -1948,7 +1949,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
if cnum == LOCAL_CRATE {
if self.tcx.sess.at_least_rust_2018() {
// We add the `crate::` keyword on Rust 2018, only when desired.
- if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
+ if with_crate_prefix() {
write!(self, "{}", kw::Crate)?;
self.empty_path = false;
}
@@ -2031,37 +2032,11 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
) -> Result<(), PrintError> {
print_prefix(self)?;
- let tcx = self.tcx;
-
- let args = args.iter().copied();
-
- let args: Vec<_> = if !tcx.sess.verbose() {
- // skip host param as those are printed as `~const`
- args.filter(|arg| match arg.unpack() {
- // FIXME(effects) there should be a better way than just matching the name
- GenericArgKind::Const(c)
- if tcx.features().effects
- && matches!(
- c.kind(),
- ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. })
- ) =>
- {
- false
- }
- _ => true,
- })
- .collect()
- } else {
- // If -Zverbose is passed, we should print the host parameter instead
- // of eating it.
- args.collect()
- };
-
if !args.is_empty() {
if self.in_value {
write!(self, "::")?;
}
- self.generic_delimiters(|cx| cx.comma_sep(args.into_iter()))
+ self.generic_delimiters(|cx| cx.comma_sep(args.iter().copied()))
} else {
Ok(())
}
@@ -2151,17 +2126,17 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
return true;
}
- if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
+ if with_forced_trimmed_paths() {
return false;
}
let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
match *region {
- ty::ReEarlyBound(ref data) => data.has_name(),
+ ty::ReEarlyParam(ref data) => data.has_name(),
- ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
- | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
+ ty::ReBound(_, ty::BoundRegion { kind: br, .. })
+ | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. })
| ty::RePlaceholder(ty::Placeholder {
bound: ty::BoundRegion { kind: br, .. }, ..
}) => {
@@ -2228,14 +2203,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
// to fit that into a short string. Hence the recommendation to use
// `explain_region()` or `note_and_explain_region()`.
match *region {
- ty::ReEarlyBound(ref data) => {
+ ty::ReEarlyParam(ref data) => {
if data.name != kw::Empty {
p!(write("{}", data.name));
return Ok(());
}
}
- ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
- | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
+ ty::ReBound(_, ty::BoundRegion { kind: br, .. })
+ | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. })
| ty::RePlaceholder(ty::Placeholder {
bound: ty::BoundRegion { kind: br, .. }, ..
}) => {
@@ -2315,7 +2290,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
let name = &mut self.name;
let region = match *r {
- ty::ReLateBound(db, br) if db >= self.current_index => {
+ ty::ReBound(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 {
@@ -2338,9 +2313,9 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
}
_ => return r,
};
- if let ty::ReLateBound(debruijn1, br) = *region {
+ if let ty::ReBound(debruijn1, br) = *region {
assert_eq!(debruijn1, ty::INNERMOST);
- ty::Region::new_late_bound(self.tcx, self.current_index, br)
+ ty::Region::new_bound(self.tcx, self.current_index, br)
} else {
region
}
@@ -2399,7 +2374,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
let possible_names = ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}")));
let mut available_names = possible_names
- .filter(|name| !self.used_region_names.contains(&name))
+ .filter(|name| !self.used_region_names.contains(name))
.collect::<Vec<_>>();
debug!(?available_names);
let num_available = available_names.len();
@@ -2434,7 +2409,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
} else {
let tcx = self.tcx;
- let trim_path = FORCE_TRIMMED_PATH.with(|flag| flag.get());
+ let trim_path = with_forced_trimmed_paths();
// Closure used in `RegionFolder` to create names for anonymous late-bound
// regions. We use two `DebruijnIndex`es (one for the currently folded
// late-bound region and the other for the binder level) to determine
@@ -2445,12 +2420,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
br: ty::BoundRegion| {
let (name, kind) = match br.kind {
ty::BrAnon | ty::BrEnv => {
- let name = next_name(&self);
+ let name = next_name(self);
if let Some(lt_idx) = lifetime_idx {
if lt_idx > binder_level_idx {
let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
- return ty::Region::new_late_bound(
+ return ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
@@ -2461,12 +2436,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
(name, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name))
}
ty::BrNamed(def_id, kw::UnderscoreLifetime | kw::Empty) => {
- let name = next_name(&self);
+ let name = next_name(self);
if let Some(lt_idx) = lifetime_idx {
if lt_idx > binder_level_idx {
let kind = ty::BrNamed(def_id, name);
- return ty::Region::new_late_bound(
+ return ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
@@ -2480,7 +2455,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
if let Some(lt_idx) = lifetime_idx {
if lt_idx > binder_level_idx {
let kind = br.kind;
- return ty::Region::new_late_bound(
+ return ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
@@ -2496,11 +2471,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
start_or_continue(self, "for<", ", ");
do_continue(self, name);
}
- ty::Region::new_late_bound(
- tcx,
- ty::INNERMOST,
- ty::BoundRegion { var: br.var, kind },
- )
+ ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { var: br.var, kind })
};
let mut folder = RegionFolder {
tcx,
@@ -2642,6 +2613,23 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
}
/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
+/// the trait path, and additionally tries to "sugar" `Fn(...)` trait bounds.
+#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
+pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>);
+
+impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintSugared<'tcx> {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
+impl<'tcx> fmt::Debug for TraitRefPrintSugared<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+}
+
+/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
/// the trait name. That is, it will print `Trait` instead of
/// `<T as Trait<U>>`.
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
@@ -2658,6 +2646,10 @@ impl<'tcx> ty::TraitRef<'tcx> {
TraitRefPrintOnlyTraitPath(self)
}
+ pub fn print_trait_sugared(self) -> TraitRefPrintSugared<'tcx> {
+ TraitRefPrintSugared(self)
+ }
+
pub fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> {
TraitRefPrintOnlyTraitName(self)
}
@@ -2667,6 +2659,10 @@ impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> {
pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> {
self.map_bound(|tr| tr.print_only_trait_path())
}
+
+ pub fn print_trait_sugared(self) -> ty::Binder<'tcx, TraitRefPrintSugared<'tcx>> {
+ self.map_bound(|tr| tr.print_trait_sugared())
+ }
}
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
@@ -2746,6 +2742,7 @@ forward_display_to_print! {
ty::PolyExistentialTraitRef<'tcx>,
ty::Binder<'tcx, ty::TraitRef<'tcx>>,
ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+ ty::Binder<'tcx, TraitRefPrintSugared<'tcx>>,
ty::Binder<'tcx, ty::FnSig<'tcx>>,
ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>>,
@@ -2757,6 +2754,10 @@ forward_display_to_print! {
define_print! {
(self, cx):
+ ty::TypeAndMut<'tcx> {
+ p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
+ }
+
ty::ClauseKind<'tcx> {
match *self {
ty::ClauseKind::Trait(ref data) => {
@@ -2785,15 +2786,11 @@ define_print! {
ty::PredicateKind::ObjectSafe(trait_def_id) => {
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
}
- ty::PredicateKind::ClosureKind(closure_def_id, _closure_args, kind) => p!(
- "the closure `",
- print_value_path(closure_def_id, &[]),
- write("` implements the trait `{}`", kind)
- ),
ty::PredicateKind::ConstEquate(c1, c2) => {
p!("the constant `", print(c1), "` equals `", print(c2), "`")
}
ty::PredicateKind::Ambiguous => p!("ambiguous"),
+ ty::PredicateKind::NormalizesTo(data) => p!(print(data)),
ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
}
}
@@ -2806,10 +2803,6 @@ define_print_and_forward_display! {
p!("{{", comma_sep(self.iter()), "}}")
}
- ty::TypeAndMut<'tcx> {
- p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
- }
-
ty::ExistentialTraitRef<'tcx> {
// Use a type that can't appear in defaults of type parameters.
let dummy_self = Ty::new_fresh(cx.tcx(),0);
@@ -2850,16 +2843,39 @@ define_print_and_forward_display! {
p!(print_def_path(self.0.def_id, self.0.args));
}
+ TraitRefPrintSugared<'tcx> {
+ if !with_no_queries()
+ && let Some(kind) = cx.tcx().fn_trait_kind_from_def_id(self.0.def_id)
+ && let ty::Tuple(args) = self.0.args.type_at(1).kind()
+ {
+ p!(write("{}", kind.as_str()), "(");
+ for (i, arg) in args.iter().enumerate() {
+ if i > 0 {
+ p!(", ");
+ }
+ p!(print(arg));
+ }
+ p!(")");
+ } else {
+ p!(print_def_path(self.0.def_id, self.0.args));
+ }
+ }
+
TraitRefPrintOnlyTraitName<'tcx> {
p!(print_def_path(self.0.def_id, &[]));
}
TraitPredPrintModifiersAndPath<'tcx> {
- // FIXME(effects) print `~const` here
+ if let Some(idx) = cx.tcx().generics_of(self.0.trait_ref.def_id).host_effect_index
+ {
+ let arg = self.0.trait_ref.args.const_at(idx);
+ if arg != cx.tcx().consts.true_ && !arg.has_infer() {
+ p!("~const ");
+ }
+ }
if let ty::ImplPolarity::Negative = self.0.polarity {
p!("!")
}
-
p!(print(self.0.trait_ref.print_only_trait_path()));
}
@@ -2894,11 +2910,10 @@ define_print_and_forward_display! {
p!("~const ");
}
}
- // FIXME(effects) print `~const` here
if let ty::ImplPolarity::Negative = self.polarity {
p!("!");
}
- p!(print(self.trait_ref.print_only_trait_path()))
+ p!(print(self.trait_ref.print_trait_sugared()))
}
ty::ProjectionPredicate<'tcx> {
@@ -2907,6 +2922,12 @@ define_print_and_forward_display! {
p!(print(self.term))
}
+ ty::NormalizesTo<'tcx> {
+ p!(print(self.alias), " normalizes-to ");
+ cx.reset_type_limit();
+ p!(print(self.term))
+ }
+
ty::Term<'tcx> {
match self.unpack() {
ty::TermKind::Ty(ty) => p!(print(ty)),
@@ -2922,10 +2943,6 @@ define_print_and_forward_display! {
}
}
- ty::ClosureKind {
- p!(write("{}", self.as_str()))
- }
-
ty::Predicate<'tcx> {
p!(print(self.kind()))
}
@@ -3022,7 +3039,8 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
/// The implementation uses similar import discovery logic to that of 'use' suggestions.
///
/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`].
-fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
+// this is pub to be able to intra-doc-link it
+pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
let mut map: FxHashMap<DefId, Symbol> = FxHashMap::default();
if let TrimmedDefPaths::GoodPath = tcx.sess.opts.trimmed_def_paths {
@@ -3030,7 +3048,7 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
//
// For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths`
// wrapper can be used to suppress this query, in exchange for full paths being formatted.
- tcx.sess.delay_good_path_bug(
+ tcx.sess.good_path_delayed_bug(
"trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging",
);
}
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 27e9be37f..9d92f81db 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -23,8 +23,6 @@ pub enum Cause {
pub trait TypeRelation<'tcx>: Sized {
fn tcx(&self) -> TyCtxt<'tcx>;
- fn param_env(&self) -> ty::ParamEnv<'tcx>;
-
/// Returns a static string we can use for printouts.
fn tag(&self) -> &'static str;
@@ -482,7 +480,7 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
// the (anonymous) type of the same closure expression. So
// all of their regions should be equated.
let args = relate_args_invariantly(relation, a_args, b_args)?;
- Ok(Ty::new_closure(tcx, a_id, &args))
+ Ok(Ty::new_closure(tcx, a_id, args))
}
(&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => {
@@ -505,13 +503,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
Err(err) => {
// Check whether the lengths are both concrete/known values,
// but are unequal, for better diagnostics.
- //
- // It might seem dubious to eagerly evaluate these constants here,
- // we however cannot end up with errors in `Relate` during both
- // `type_of` and `predicates_of`. This means that evaluating the
- // constants should not cause cycle errors here.
- let sz_a = sz_a.try_eval_target_usize(tcx, relation.param_env());
- let sz_b = sz_b.try_eval_target_usize(tcx, relation.param_env());
+ let sz_a = sz_a.try_to_target_usize(tcx);
+ let sz_b = sz_b.try_to_target_usize(tcx);
+
match (sz_a, sz_b) {
(Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err(
TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)),
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 6af68bc5d..1c75d73e5 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -79,9 +79,9 @@ impl fmt::Debug for ty::BoundRegionKind {
}
}
-impl fmt::Debug for ty::FreeRegion {
+impl fmt::Debug for ty::LateParamRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
+ write!(f, "ReLateParam({:?}, {:?})", self.scope, self.bound_region)
}
}
@@ -173,6 +173,12 @@ impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
}
}
+impl<'tcx> fmt::Debug for ty::NormalizesTo<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
+ }
+}
+
impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.kind())
@@ -202,34 +208,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTy<'tcx> {
}
}
-impl fmt::Debug for ty::InferConst {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- InferConst::Var(var) => write!(f, "{var:?}"),
- InferConst::EffectVar(var) => write!(f, "{var:?}"),
- InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
- }
- }
-}
-impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::InferConst {
- fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
- this: WithInfcx<'_, Infcx, &Self>,
- f: &mut core::fmt::Formatter<'_>,
- ) -> core::fmt::Result {
- use ty::InferConst::*;
- match this.infcx.universe_of_ct(*this.data) {
- None => write!(f, "{:?}", this.data),
- Some(universe) => match *this.data {
- Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
- EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
- Fresh(_) => {
- unreachable!()
- }
- },
- }
- }
-}
-
impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
WithInfcx::with_no_infcx(self).fmt(f)
@@ -444,7 +422,7 @@ TrivialTypeTraversalImpls! {
crate::ty::Placeholder<crate::ty::BoundRegion>,
crate::ty::Placeholder<crate::ty::BoundTy>,
crate::ty::Placeholder<ty::BoundVar>,
- crate::ty::FreeRegion,
+ crate::ty::LateParamRegion,
crate::ty::InferTy,
crate::ty::IntVarValue,
crate::ty::adjustment::PointerCoercion,
@@ -462,14 +440,14 @@ TrivialTypeTraversalImpls! {
// interners).
TrivialTypeTraversalAndLiftImpls! {
::rustc_hir::def_id::DefId,
- ::rustc_hir::Mutability,
::rustc_hir::Unsafety,
::rustc_target::spec::abi::Abi,
crate::ty::ClosureKind,
crate::ty::ParamConst,
crate::ty::ParamTy,
- interpret::Scalar,
interpret::AllocId,
+ interpret::CtfeProvenance,
+ interpret::Scalar,
rustc_target::abi::Size,
}
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 44592b10d..a0debc8a1 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -6,7 +6,7 @@ use crate::infer::canonical::Canonical;
use crate::ty::visit::ValidateBoundVars;
use crate::ty::InferTy::*;
use crate::ty::{
- self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
+ self, AdtDef, Discr, IntoKind, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
@@ -15,7 +15,9 @@ use hir::def::DefKind;
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
-use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
+use rustc_errors::{
+ DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan,
+};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
@@ -32,6 +34,7 @@ use std::fmt;
use std::ops::{ControlFlow, Deref, Range};
use ty::util::IntTypeExt;
+use rustc_type_ir::BoundVar;
use rustc_type_ir::ClauseKind as IrClauseKind;
use rustc_type_ir::CollectAndApply;
use rustc_type_ir::ConstKind as IrConstKind;
@@ -41,29 +44,24 @@ use rustc_type_ir::PredicateKind as IrPredicateKind;
use rustc_type_ir::RegionKind as IrRegionKind;
use rustc_type_ir::TyKind as IrTyKind;
use rustc_type_ir::TyKind::*;
+use rustc_type_ir::TypeAndMut as IrTypeAndMut;
use super::GenericParamDefKind;
-// Re-export the `TyKind` from `rustc_type_ir` here for convenience
+// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
#[rustc_diagnostic_item = "TyKind"]
pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
-pub struct TypeAndMut<'tcx> {
- pub ty: Ty<'tcx>,
- pub mutbl: hir::Mutability,
-}
+pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>;
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
#[derive(HashStable)]
-/// A "free" region `fr` can be interpreted as "some region
+/// The parameter representation of late-bound function parameters, "some region
/// at least as big as the scope `fr.scope`".
-pub struct FreeRegion {
+pub struct LateParamRegion {
pub scope: DefId,
pub bound_region: BoundRegionKind,
}
@@ -467,16 +465,6 @@ impl<'tcx> CoroutineArgs<'tcx> {
self.split().return_ty.expect_ty()
}
- /// Returns the "coroutine signature", which consists of its yield
- /// and return types.
- ///
- /// N.B., some bits of the code prefers to see this wrapped in a
- /// binder, but it never contains bound regions. Probably this
- /// function should be removed.
- pub fn poly_sig(self) -> PolyGenSig<'tcx> {
- ty::Binder::dummy(self.sig())
- }
-
/// Returns the "coroutine signature", which consists of its resume, yield
/// and return types.
pub fn sig(self) -> GenSig<'tcx> {
@@ -1036,7 +1024,7 @@ impl<'tcx, T> Binder<'tcx, T> {
/// risky thing to do because it's easy to get confused about
/// De Bruijn indices and the like. It is usually better to
/// discharge the binder using `no_bound_vars` or
- /// `replace_late_bound_regions` or something like
+ /// `instantiate_bound_regions` or something like
/// that. `skip_binder` is only valid when you are either
/// extracting data that has nothing to do with bound vars, you
/// are doing some sort of test that does not involve bound
@@ -1245,6 +1233,28 @@ impl<'tcx> AliasTy<'tcx> {
}
}
+ /// Whether this alias type is an opaque.
+ pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool {
+ matches!(self.opt_kind(tcx), Some(ty::AliasKind::Opaque))
+ }
+
+ /// FIXME: rename `AliasTy` to `AliasTerm` and always handle
+ /// constants. This function can then be removed.
+ pub fn opt_kind(self, tcx: TyCtxt<'tcx>) -> Option<ty::AliasKind> {
+ match tcx.def_kind(self.def_id) {
+ DefKind::AssocTy
+ if let DefKind::Impl { of_trait: false } =
+ tcx.def_kind(tcx.parent(self.def_id)) =>
+ {
+ Some(ty::Inherent)
+ }
+ DefKind::AssocTy => Some(ty::Projection),
+ DefKind::OpaqueTy => Some(ty::Opaque),
+ DefKind::TyAlias => Some(ty::Weak),
+ _ => None,
+ }
+ }
+
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
Ty::new_alias(tcx, self.kind(tcx), self)
}
@@ -1329,8 +1339,6 @@ pub struct GenSig<'tcx> {
pub return_ty: Ty<'tcx>,
}
-pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>;
-
/// Signature of a function type, which we have arbitrarily
/// decided to use to refer to the input/output types.
///
@@ -1466,17 +1474,25 @@ impl ParamConst {
#[rustc_pass_by_value]
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
+impl<'tcx> IntoKind for Region<'tcx> {
+ type Kind = RegionKind<'tcx>;
+
+ fn kind(self) -> RegionKind<'tcx> {
+ *self
+ }
+}
+
impl<'tcx> Region<'tcx> {
#[inline]
- pub fn new_early_bound(
+ pub fn new_early_param(
tcx: TyCtxt<'tcx>,
- early_bound_region: ty::EarlyBoundRegion,
+ early_bound_region: ty::EarlyParamRegion,
) -> Region<'tcx> {
- tcx.intern_region(ty::ReEarlyBound(early_bound_region))
+ tcx.intern_region(ty::ReEarlyParam(early_bound_region))
}
#[inline]
- pub fn new_late_bound(
+ pub fn new_bound(
tcx: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
bound_region: ty::BoundRegion,
@@ -1488,17 +1504,17 @@ impl<'tcx> Region<'tcx> {
{
re
} else {
- tcx.intern_region(ty::ReLateBound(debruijn, bound_region))
+ tcx.intern_region(ty::ReBound(debruijn, bound_region))
}
}
#[inline]
- pub fn new_free(
+ pub fn new_late_param(
tcx: TyCtxt<'tcx>,
scope: DefId,
bound_region: ty::BoundRegionKind,
) -> Region<'tcx> {
- tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region }))
+ tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region }))
}
#[inline]
@@ -1522,7 +1538,7 @@ impl<'tcx> Region<'tcx> {
tcx.intern_region(ty::ReError(reported))
}
- /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it
+ /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` to ensure it
/// gets used.
#[track_caller]
pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
@@ -1533,7 +1549,7 @@ impl<'tcx> Region<'tcx> {
)
}
- /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given
+ /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` with the given
/// `msg` to ensure it gets used.
#[track_caller]
pub fn new_error_with_message<S: Into<MultiSpan>>(
@@ -1541,7 +1557,7 @@ impl<'tcx> Region<'tcx> {
span: S,
msg: &'static str,
) -> Region<'tcx> {
- let reported = tcx.sess.delay_span_bug(span, msg);
+ let reported = tcx.sess.span_delayed_bug(span, msg);
Region::new_error(tcx, reported)
}
@@ -1549,10 +1565,10 @@ impl<'tcx> Region<'tcx> {
/// to avoid the cost of the `match`.
pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
match kind {
- ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region),
- ty::ReLateBound(debruijn, region) => Region::new_late_bound(tcx, debruijn, region),
- ty::ReFree(ty::FreeRegion { scope, bound_region }) => {
- Region::new_free(tcx, scope, bound_region)
+ ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
+ ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region),
+ ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => {
+ Region::new_late_param(tcx, scope, bound_region)
}
ty::ReStatic => tcx.lifetimes.re_static,
ty::ReVar(vid) => Region::new_var(tcx, vid),
@@ -1568,45 +1584,29 @@ impl<'tcx> Deref for Region<'tcx> {
#[inline]
fn deref(&self) -> &RegionKind<'tcx> {
- &self.0.0
+ self.0.0
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
#[derive(HashStable)]
-pub struct EarlyBoundRegion {
+pub struct EarlyParamRegion {
pub def_id: DefId,
pub index: u32,
pub name: Symbol,
}
-impl fmt::Debug for EarlyBoundRegion {
+impl fmt::Debug for EarlyParamRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name)
}
}
rustc_index::newtype_index! {
- /// A **`const`** **v**ariable **ID**.
- #[debug_format = "?{}c"]
- pub struct ConstVid {}
-}
-
-rustc_index::newtype_index! {
- /// An **effect** **v**ariable **ID**.
- ///
- /// Handling effect infer variables happens separately from const infer variables
- /// because we do not want to reuse any of the const infer machinery. If we try to
- /// relate an effect variable with a normal one, we would ICE, which can catch bugs
- /// where we are not correctly using the effect var for an effect param. Fallback
- /// is also implemented on top of having separate effect and normal const variables.
- #[debug_format = "?{}e"]
- pub struct EffectVid {}
-}
-
-rustc_index::newtype_index! {
/// A **region** (lifetime) **v**ariable **ID**.
#[derive(HashStable)]
+ #[encodable]
+ #[orderable]
#[debug_format = "'?{}"]
pub struct RegionVid {}
}
@@ -1617,12 +1617,6 @@ impl Atom for RegionVid {
}
}
-rustc_index::newtype_index! {
- #[derive(HashStable)]
- #[debug_format = "{}"]
- pub struct BoundVar {}
-}
-
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub struct BoundTy {
@@ -1722,9 +1716,9 @@ impl<'tcx> Region<'tcx> {
pub fn get_name(self) -> Option<Symbol> {
if self.has_name() {
match *self {
- ty::ReEarlyBound(ebr) => Some(ebr.name),
- ty::ReLateBound(_, br) => br.kind.get_name(),
- ty::ReFree(fr) => fr.bound_region.get_name(),
+ ty::ReEarlyParam(ebr) => Some(ebr.name),
+ ty::ReBound(_, br) => br.kind.get_name(),
+ ty::ReLateParam(fr) => fr.bound_region.get_name(),
ty::ReStatic => Some(kw::StaticLifetime),
ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
_ => None,
@@ -1744,9 +1738,9 @@ impl<'tcx> Region<'tcx> {
/// Is this region named by the user?
pub fn has_name(self) -> bool {
match *self {
- ty::ReEarlyBound(ebr) => ebr.has_name(),
- ty::ReLateBound(_, br) => br.kind.is_named(),
- ty::ReFree(fr) => fr.bound_region.is_named(),
+ ty::ReEarlyParam(ebr) => ebr.has_name(),
+ ty::ReBound(_, br) => br.kind.is_named(),
+ ty::ReLateParam(fr) => fr.bound_region.is_named(),
ty::ReStatic => true,
ty::ReVar(..) => false,
ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
@@ -1771,8 +1765,8 @@ impl<'tcx> Region<'tcx> {
}
#[inline]
- pub fn is_late_bound(self) -> bool {
- matches!(*self, ty::ReLateBound(..))
+ pub fn is_bound(self) -> bool {
+ matches!(*self, ty::ReBound(..))
}
#[inline]
@@ -1783,7 +1777,7 @@ impl<'tcx> Region<'tcx> {
#[inline]
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
match *self {
- ty::ReLateBound(debruijn, _) => debruijn >= index,
+ ty::ReBound(debruijn, _) => debruijn >= index,
_ => false,
}
}
@@ -1802,20 +1796,20 @@ impl<'tcx> Region<'tcx> {
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
}
- ty::ReEarlyBound(..) => {
+ ty::ReEarlyParam(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PARAM;
}
- ty::ReFree { .. } => {
+ ty::ReLateParam { .. } => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
}
ty::ReStatic => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
}
- ty::ReLateBound(..) => {
- flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
+ ty::ReBound(..) => {
+ flags = flags | TypeFlags::HAS_RE_BOUND;
}
ty::ReErased => {
flags = flags | TypeFlags::HAS_RE_ERASED;
@@ -1851,22 +1845,28 @@ impl<'tcx> Region<'tcx> {
/// function might return the `DefId` of a closure.
pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
match *self {
- ty::ReEarlyBound(br) => tcx.parent(br.def_id),
- ty::ReFree(fr) => fr.scope,
+ ty::ReEarlyParam(br) => tcx.parent(br.def_id),
+ ty::ReLateParam(fr) => fr.scope,
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
}
}
/// True for free regions other than `'static`.
- pub fn is_free(self) -> bool {
- matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_))
+ pub fn is_param(self) -> bool {
+ matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
}
- /// True if `self` is a free region or static.
- pub fn is_free_or_static(self) -> bool {
+ /// True for free region in the current context.
+ ///
+ /// This is the case for `'static` and param regions.
+ pub fn is_free(self) -> bool {
match *self {
- ty::ReStatic => true,
- _ => self.is_free(),
+ ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
+ ty::ReVar(..)
+ | ty::RePlaceholder(..)
+ | ty::ReBound(..)
+ | ty::ReErased
+ | ty::ReError(..) => false,
}
}
@@ -1990,21 +1990,21 @@ impl<'tcx> Ty<'tcx> {
Ty::new(tcx, Error(reported))
}
- /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
+ /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` to ensure it gets used.
#[track_caller]
pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
Ty::new_error_with_message(tcx, DUMMY_SP, "TyKind::Error constructed but no error reported")
}
- /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
+ /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to
/// ensure it gets used.
#[track_caller]
pub fn new_error_with_message<S: Into<MultiSpan>>(
tcx: TyCtxt<'tcx>,
span: S,
- msg: impl Into<String>,
+ msg: impl Into<DiagnosticMessage>,
) -> Ty<'tcx> {
- let reported = tcx.sess.delay_span_bug(span, msg);
+ let reported = tcx.sess.span_delayed_bug(span, msg);
Ty::new(tcx, Error(reported))
}
@@ -2104,7 +2104,7 @@ impl<'tcx> Ty<'tcx> {
#[inline]
pub fn new_tup(tcx: TyCtxt<'tcx>, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
- if ts.is_empty() { tcx.types.unit } else { Ty::new(tcx, Tuple(tcx.mk_type_list(&ts))) }
+ if ts.is_empty() { tcx.types.unit } else { Ty::new(tcx, Tuple(tcx.mk_type_list(ts))) }
}
pub fn new_tup_from_iter<I, T>(tcx: TyCtxt<'tcx>, iter: I) -> T::Output
@@ -2260,7 +2260,7 @@ impl<'tcx> Ty<'tcx> {
impl<'tcx> Ty<'tcx> {
#[inline(always)]
pub fn kind(self) -> &'tcx TyKind<'tcx> {
- &self.0.0
+ self.0.0
}
#[inline(always)]
@@ -2271,7 +2271,7 @@ impl<'tcx> Ty<'tcx> {
#[inline]
pub fn is_unit(self) -> bool {
match self.kind() {
- Tuple(ref tys) => tys.is_empty(),
+ Tuple(tys) => tys.is_empty(),
_ => false,
}
}
@@ -2813,6 +2813,15 @@ impl<'tcx> Ty<'tcx> {
}
}
+ /// Inverse of [`Ty::to_opt_closure_kind`].
+ pub fn from_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> {
+ match kind {
+ ty::ClosureKind::Fn => tcx.types.i8,
+ ty::ClosureKind::FnMut => tcx.types.i16,
+ ty::ClosureKind::FnOnce => tcx.types.i32,
+ }
+ }
+
/// Fast path helper for testing if a type is `Sized`.
///
/// Returning true means the type is known to be sized. Returning
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index e9240d1b2..d372c1cd6 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -126,7 +126,7 @@ pub struct TypeckResults<'tcx> {
/// fn(&'a u32) -> u32
/// ```
///
- /// Note that `'a` is not bound (it would be an `ReFree`) and
+ /// Note that `'a` is not bound (it would be an `ReLateParam`) and
/// that the `Foo` opaque type is replaced by its hidden type.
liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
@@ -241,7 +241,7 @@ impl<'tcx> TypeckResults<'tcx> {
/// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
match *qpath {
- hir::QPath::Resolved(_, ref path) => path.res,
+ hir::QPath::Resolved(_, path) => path.res,
hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.type_dependent_def(id)
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
@@ -391,7 +391,7 @@ impl<'tcx> TypeckResults<'tcx> {
pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
self.pat_binding_modes().get(id).copied().or_else(|| {
- s.delay_span_bug(sp, "missing binding mode");
+ s.span_delayed_bug(sp, "missing binding mode");
None
})
}
@@ -578,6 +578,7 @@ impl<'a, V> LocalTableInContextMut<'a, V> {
rustc_index::newtype_index! {
#[derive(HashStable)]
+ #[encodable]
#[debug_format = "UserType({})"]
pub struct UserTypeAnnotationIndex {
const START_INDEX = 0;
@@ -638,7 +639,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
},
GenericArgKind::Lifetime(r) => match *r {
- ty::ReLateBound(debruijn, br) => {
+ ty::ReBound(debruijn, br) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(debruijn, ty::INNERMOST);
cvar == br.var
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index a251518d1..8b2b76764 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -35,12 +35,14 @@ pub struct Discr<'tcx> {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum CheckRegions {
No,
- /// Only permit early bound regions. This is useful for Adts which
- /// can never have late bound regions.
- OnlyEarlyBound,
- /// Permit both late bound and early bound regions. Use this for functions,
- /// which frequently have late bound regions.
- Bound,
+ /// Only permit parameter regions. This should be used
+ /// for everything apart from functions, which may use
+ /// `ReBound` to represent late-bound regions.
+ OnlyParam,
+ /// Check region parameters from a function definition.
+ /// Allows `ReEarlyParam` and `ReBound` to handle early
+ /// and late-bound region parameters.
+ FromFunction,
}
#[derive(Copy, Clone, Debug)]
@@ -359,7 +361,7 @@ impl<'tcx> TyCtxt<'tcx> {
let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
self.sess
- .delay_span_bug(self.def_span(impl_did), "Drop impl without drop function");
+ .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function");
return;
};
@@ -419,19 +421,16 @@ impl<'tcx> TyCtxt<'tcx> {
let impl_args = match *self.type_of(impl_def_id).instantiate_identity().kind() {
ty::Adt(def_, args) if def_ == def => args,
- _ => bug!(),
+ _ => span_bug!(self.def_span(impl_def_id), "expected ADT for self type of `Drop` impl"),
};
- let item_args = match *self.type_of(def.did()).instantiate_identity().kind() {
- ty::Adt(def_, args) if def_ == def => args,
- _ => bug!(),
- };
+ let item_args = ty::GenericArgs::identity_for_item(self, def.did());
let result = iter::zip(item_args, impl_args)
.filter(|&(_, k)| {
match k.unpack() {
GenericArgKind::Lifetime(region) => match region.kind() {
- ty::ReEarlyBound(ref ebr) => {
+ ty::ReEarlyParam(ref ebr) => {
!impl_generics.region_param(ebr, self).pure_wrt_drop
}
// Error: not a region param
@@ -468,17 +467,17 @@ impl<'tcx> TyCtxt<'tcx> {
for arg in args {
match arg.unpack() {
GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) {
- (CheckRegions::Bound, ty::ReLateBound(di, reg)) => {
+ (CheckRegions::FromFunction, ty::ReBound(di, reg)) => {
if !seen_late.insert((di, reg)) {
return Err(NotUniqueParam::DuplicateParam(lt.into()));
}
}
- (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => {
+ (CheckRegions::OnlyParam | CheckRegions::FromFunction, ty::ReEarlyParam(p)) => {
if !seen.insert(p.index) {
return Err(NotUniqueParam::DuplicateParam(lt.into()));
}
}
- (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => {
+ (CheckRegions::OnlyParam | CheckRegions::FromFunction, _) => {
return Err(NotUniqueParam::NotParam(lt.into()));
}
(CheckRegions::No, _) => {}
@@ -548,16 +547,13 @@ impl<'tcx> TyCtxt<'tcx> {
/// those are not yet phased out). The parent of the closure's
/// `DefId` will also be the context where it appears.
pub fn is_closure(self, def_id: DefId) -> bool {
- matches!(self.def_kind(def_id), DefKind::Closure | DefKind::Coroutine)
+ matches!(self.def_kind(def_id), DefKind::Closure)
}
/// Returns `true` if `def_id` refers to a definition that does not have its own
/// type-checking context, i.e. closure, coroutine or inline const.
pub fn is_typeck_child(self, def_id: DefId) -> bool {
- matches!(
- self.def_kind(def_id),
- DefKind::Closure | DefKind::Coroutine | DefKind::InlineConst
- )
+ matches!(self.def_kind(def_id), DefKind::Closure | DefKind::InlineConst)
}
/// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
@@ -699,22 +695,6 @@ impl<'tcx> TyCtxt<'tcx> {
.map(|decl| ty::EarlyBinder::bind(decl.ty))
}
- /// Normalizes all opaque types in the given value, replacing them
- /// with their underlying types.
- pub fn expand_opaque_types(self, val: Ty<'tcx>) -> Ty<'tcx> {
- let mut visitor = OpaqueTypeExpander {
- seen_opaque_tys: FxHashSet::default(),
- expanded_cache: FxHashMap::default(),
- primary_def_id: None,
- found_recursion: false,
- found_any_recursion: false,
- check_recursion: false,
- expand_coroutines: false,
- tcx: self,
- };
- val.fold_with(&mut visitor)
- }
-
/// Expands the given impl trait type, stopping if the type is recursive.
#[instrument(skip(self), level = "debug", ret)]
pub fn try_expand_impl_trait_type(
@@ -746,11 +726,14 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn def_kind_descr(self, def_kind: DefKind, def_id: DefId) -> &'static str {
match def_kind {
DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method",
- DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
- rustc_hir::CoroutineKind::Async(..) => "async closure",
- rustc_hir::CoroutineKind::Coroutine => "coroutine",
- rustc_hir::CoroutineKind::Gen(..) => "gen closure",
- },
+ DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => {
+ match coroutine_kind {
+ rustc_hir::CoroutineKind::Async(..) => "async closure",
+ rustc_hir::CoroutineKind::AsyncGen(..) => "async gen closure",
+ rustc_hir::CoroutineKind::Coroutine => "coroutine",
+ rustc_hir::CoroutineKind::Gen(..) => "gen closure",
+ }
+ }
_ => def_kind.descr(def_id),
}
}
@@ -764,11 +747,14 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn def_kind_descr_article(self, def_kind: DefKind, def_id: DefId) -> &'static str {
match def_kind {
DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "a",
- DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
- rustc_hir::CoroutineKind::Async(..) => "an",
- rustc_hir::CoroutineKind::Coroutine => "a",
- rustc_hir::CoroutineKind::Gen(..) => "a",
- },
+ DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => {
+ match coroutine_kind {
+ rustc_hir::CoroutineKind::Async(..) => "an",
+ rustc_hir::CoroutineKind::AsyncGen(..) => "an",
+ rustc_hir::CoroutineKind::Coroutine => "a",
+ rustc_hir::CoroutineKind::Gen(..) => "a",
+ }
+ }
_ => def_kind.article(),
}
}
@@ -790,7 +776,60 @@ impl<'tcx> TyCtxt<'tcx> {
// If `extern_crate` is `None`, then the crate was injected (e.g., by the allocator).
// Treat that kind of crate as "indirect", since it's an implementation detail of
// the language.
- || self.extern_crate(key.as_def_id()).map_or(false, |e| e.is_direct())
+ || self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct())
+ }
+
+ pub fn expected_host_effect_param_for_body(self, def_id: impl Into<DefId>) -> ty::Const<'tcx> {
+ let def_id = def_id.into();
+ // FIXME(effects): This is suspicious and should probably not be done,
+ // especially now that we enforce host effects and then properly handle
+ // effect vars during fallback.
+ let mut host_always_on =
+ !self.features().effects || self.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
+
+ // Compute the constness required by the context.
+ let const_context = self.hir().body_const_context(def_id);
+
+ let kind = self.def_kind(def_id);
+ debug_assert_ne!(kind, DefKind::ConstParam);
+
+ if self.has_attr(def_id, sym::rustc_do_not_const_check) {
+ trace!("do not const check this context");
+ host_always_on = true;
+ }
+
+ match const_context {
+ _ if host_always_on => self.consts.true_,
+ Some(hir::ConstContext::Static(_) | hir::ConstContext::Const { .. }) => {
+ self.consts.false_
+ }
+ Some(hir::ConstContext::ConstFn) => {
+ let host_idx = self
+ .generics_of(def_id)
+ .host_effect_index
+ .expect("ConstContext::Maybe must have host effect param");
+ ty::GenericArgs::identity_for_item(self, def_id).const_at(host_idx)
+ }
+ None => self.consts.true_,
+ }
+ }
+
+ /// Constructs generic args for an item, optionally appending a const effect param type
+ pub fn with_opt_host_effect_param(
+ self,
+ caller_def_id: LocalDefId,
+ callee_def_id: DefId,
+ args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
+ ) -> ty::GenericArgsRef<'tcx> {
+ let generics = self.generics_of(callee_def_id);
+ assert_eq!(generics.parent, None);
+
+ let opt_const_param = generics
+ .host_effect_index
+ .is_some()
+ .then(|| ty::GenericArg::from(self.expected_host_effect_param_for_body(caller_def_id)));
+
+ self.mk_args_from_iter(args.into_iter().map(|arg| arg.into()).chain(opt_const_param))
}
}
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 8fc5c0302..e1ce94125 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -1,4 +1,4 @@
-use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
+use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
use rustc_errors::ErrorGuaranteed;
use rustc_data_structures::fx::FxHashSet;
@@ -111,16 +111,16 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
}
/// True if there are any late-bound regions
- fn has_late_bound_regions(&self) -> bool {
- self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
+ fn has_bound_regions(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_RE_BOUND)
}
/// True if there are any late-bound non-region variables
- fn has_non_region_late_bound(&self) -> bool {
- self.has_type_flags(TypeFlags::HAS_LATE_BOUND - TypeFlags::HAS_RE_LATE_BOUND)
+ fn has_non_region_bound_vars(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
}
- /// True if there are any late-bound variables
- fn has_late_bound_vars(&self) -> bool {
- self.has_type_flags(TypeFlags::HAS_LATE_BOUND)
+ /// True if there are any bound variables
+ fn has_bound_vars(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
}
/// Indicates whether this value still has parameters/placeholders/inference variables
@@ -204,7 +204,7 @@ impl<'tcx> TyCtxt<'tcx> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
match *r {
- ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
+ ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
ControlFlow::Continue(())
}
_ => {
@@ -337,7 +337,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
match *r {
- ty::ReLateBound(index, br) if index == self.binder_index => {
+ ty::ReBound(index, br) if index == self.binder_index => {
if self.bound_vars.len() <= br.var.as_usize() {
bug!("Not enough bound vars: {:?} not found in {:?}", br, self.bound_vars);
}
@@ -440,16 +440,15 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
}
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
- // we don't have a `visit_infer_const` callback, so we have to
- // hook in here to catch this case (annoying...), but
- // otherwise we do want to remember to visit the rest of the
- // const, as it has types/regions embedded in a lot of other
- // places.
- match ct.kind() {
- ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => {
- ControlFlow::Break(FoundEscapingVars)
- }
- _ => ct.super_visit_with(self),
+ // If the outer-exclusive-binder is *strictly greater* than
+ // `outer_index`, that means that `ct` contains some content
+ // bound at `outer_index` or above (because
+ // `outer_exclusive_binder` is always 1 higher than the
+ // content in `t`). Therefore, `t` has some escaping vars.
+ if ct.outer_exclusive_binder() > self.outer_index {
+ ControlFlow::Break(FoundEscapingVars)
+ } else {
+ ControlFlow::Continue(())
}
}
@@ -529,9 +528,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
#[inline]
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
- let flags = FlagComputation::for_const(c);
- trace!(r.flags=?flags);
- if flags.intersects(self.flags) {
+ if c.flags().intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
@@ -613,7 +610,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
- if let ty::ReLateBound(debruijn, br) = *r {
+ if let ty::ReBound(debruijn, br) = *r {
if debruijn == self.current_index {
self.regions.insert(br.kind);
}