summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_infer
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_infer')
-rw-r--r--compiler/rustc_infer/messages.ftl3
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs24
-rw-r--r--compiler/rustc_infer/src/infer/at.rs5
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs13
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs8
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs33
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs63
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs49
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs10
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs54
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs27
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs8
-rw-r--r--compiler/rustc_infer/src/infer/generalize.rs10
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/mod.rs33
-rw-r--r--compiler/rustc_infer/src/infer/lattice.rs2
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs190
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs138
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs29
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs5
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs12
-rw-r--r--compiler/rustc_infer/src/infer/projection.rs36
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs144
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs19
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs4
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs3
-rw-r--r--compiler/rustc_infer/src/infer/undo_log.rs15
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs11
-rw-r--r--compiler/rustc_infer/src/traits/util.rs128
37 files changed, 547 insertions, 567 deletions
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index f44c4a7c1..4d0e77063 100644
--- a/compiler/rustc_infer/messages.ftl
+++ b/compiler/rustc_infer/messages.ftl
@@ -278,9 +278,6 @@ infer_ril_introduced_by = requirement introduced by this return type
infer_ril_introduced_here = `'static` requirement introduced here
infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type
-infer_sarwa_option = you can convert from `&Option<T>` to `Option<&T>` using `.as_ref()`
-infer_sarwa_result = you can convert from `&Result<T, E>` to `Result<&T, &E>` using `.as_ref()`
-
infer_sbfrit_box_return_expr = if you change the return type to expect trait objects, box the returned expressions
infer_sbfrit_change_return_type = you could change the return type to be a boxed trait object
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index b1e819e83..7e1fa08f2 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -1247,30 +1247,6 @@ pub struct FnConsiderCasting {
}
#[derive(Subdiagnostic)]
-pub enum SuggestAsRefWhereAppropriate<'a> {
- #[suggestion(
- infer_sarwa_option,
- code = "{snippet}.as_ref()",
- applicability = "machine-applicable"
- )]
- Option {
- #[primary_span]
- span: Span,
- snippet: &'a str,
- },
- #[suggestion(
- infer_sarwa_result,
- code = "{snippet}.as_ref()",
- applicability = "machine-applicable"
- )]
- Result {
- #[primary_span]
- span: Span,
- snippet: &'a str,
- },
-}
-
-#[derive(Subdiagnostic)]
pub enum SuggestAccessingField<'a> {
#[suggestion(
infer_suggest_accessing_field,
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 0c8854e96..433735e82 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -40,6 +40,7 @@ pub enum DefineOpaqueTypes {
No,
}
+#[derive(Clone, Copy)]
pub struct At<'a, 'tcx> {
pub infcx: &'a InferCtxt<'tcx>,
pub cause: &'a ObligationCause<'tcx>,
@@ -70,8 +71,8 @@ impl<'tcx> InferCtxt<'tcx> {
tcx: self.tcx,
defining_use_anchor: self.defining_use_anchor,
considering_regions: self.considering_regions,
+ skip_leak_check: self.skip_leak_check,
inner: self.inner.clone(),
- skip_leak_check: self.skip_leak_check.clone(),
lexical_region_resolutions: self.lexical_region_resolutions.clone(),
selection_cache: self.selection_cache.clone(),
evaluation_cache: self.evaluation_cache.clone(),
@@ -79,9 +80,9 @@ impl<'tcx> InferCtxt<'tcx> {
reported_closure_mismatch: self.reported_closure_mismatch.clone(),
tainted_by_errors: self.tainted_by_errors.clone(),
err_count_on_creation: self.err_count_on_creation,
- in_snapshot: self.in_snapshot.clone(),
universe: self.universe.clone(),
intercrate: self.intercrate,
+ next_trait_solver: self.next_trait_solver,
}
}
}
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 427d05c8b..e57532e2d 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -382,7 +382,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
// any equated inference vars correctly!
let root_vid = self.infcx.root_var(vid);
if root_vid != vid {
- t = self.infcx.tcx.mk_ty_var(root_vid);
+ t = Ty::new_var(self.infcx.tcx, root_vid);
vid = root_vid;
}
@@ -497,7 +497,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
// any equated inference vars correctly!
let root_vid = self.infcx.root_const_var(vid);
if root_vid != vid {
- ct = self.infcx.tcx.mk_const(ty::InferConst::Var(root_vid), ct.ty());
+ ct = ty::Const::new_var(self.infcx.tcx, root_vid, ct.ty());
vid = root_vid;
}
@@ -771,7 +771,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
) -> ty::Region<'tcx> {
let var = self.canonical_var(info, r.into());
let br = ty::BoundRegion { var, kind: ty::BrAnon(None) };
- self.interner().mk_re_late_bound(self.binder_index, br)
+ ty::Region::new_late_bound(self.interner(), self.binder_index, br)
}
/// Given a type variable `ty_var` of the given kind, first check
@@ -785,7 +785,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
self.fold_ty(bound_to)
} else {
let var = self.canonical_var(info, ty_var.into());
- self.interner().mk_bound(self.binder_index, var.into())
+ Ty::new_bound(self.tcx, self.binder_index, var.into())
}
}
@@ -804,10 +804,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
self.fold_const(bound_to)
} else {
let var = self.canonical_var(info, const_var.into());
- self.interner().mk_const(
- ty::ConstKind::Bound(self.binder_index, var),
- self.fold_ty(const_var.ty()),
- )
+ ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty()))
}
}
}
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 2abdd5b0a..f765c41a3 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -26,7 +26,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVari
use rustc_index::IndexVec;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::GenericArg;
-use rustc_middle::ty::{self, List, TyCtxt};
+use rustc_middle::ty::{self, List, Ty, TyCtxt};
use rustc_span::source_map::Span;
pub use rustc_middle::infer::canonical::*;
@@ -128,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> {
CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound }) => {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, bound };
- self.tcx.mk_placeholder(placeholder_mapped).into()
+ Ty::new_placeholder(self.tcx, placeholder_mapped).into()
}
CanonicalVarKind::Region(ui) => self
@@ -141,7 +141,7 @@ impl<'tcx> InferCtxt<'tcx> {
CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, bound }) => {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, bound };
- self.tcx.mk_re_placeholder(placeholder_mapped).into()
+ ty::Region::new_placeholder(self.tcx, placeholder_mapped).into()
}
CanonicalVarKind::Const(ui, ty) => self
@@ -155,7 +155,7 @@ impl<'tcx> InferCtxt<'tcx> {
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }, ty) => {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound };
- self.tcx.mk_const(placeholder_mapped, ty).into()
+ ty::Const::new_placeholder(self.tcx, placeholder_mapped, ty).into()
}
}
}
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 88256c819..9c3ab04de 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -520,7 +520,7 @@ impl<'tcx> InferCtxt<'tcx> {
self.at(cause, param_env)
.eq(
DefineOpaqueTypes::Yes,
- self.tcx.mk_opaque(a.def_id.to_def_id(), a.substs),
+ Ty::new_opaque(self.tcx, a.def_id.to_def_id(), a.substs),
b,
)?
.obligations,
@@ -584,12 +584,12 @@ impl<'tcx> InferCtxt<'tcx> {
let ty::OutlivesPredicate(k1, r2) = predicate;
let atom = match k1.unpack() {
- GenericArgKind::Lifetime(r1) => {
- ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate(r1, r2)))
- }
- GenericArgKind::Type(t1) => {
- ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(t1, r2)))
- }
+ GenericArgKind::Lifetime(r1) => ty::PredicateKind::Clause(
+ ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)),
+ ),
+ GenericArgKind::Type(t1) => ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
+ ty::OutlivesPredicate(t1, r2),
+ )),
GenericArgKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// encounter this branch.
@@ -668,14 +668,15 @@ pub fn make_query_region_constraints<'tcx>(
let constraint = match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
- Constraint::VarSubVar(v1, v2) => {
- ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), tcx.mk_re_var(v1))
- }
+ Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
+ ty::Region::new_var(tcx, v2).into(),
+ ty::Region::new_var(tcx, v1),
+ ),
Constraint::VarSubReg(v1, r2) => {
- ty::OutlivesPredicate(r2.into(), tcx.mk_re_var(v1))
+ ty::OutlivesPredicate(r2.into(), ty::Region::new_var(tcx, v1))
}
Constraint::RegSubVar(r1, v2) => {
- ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), r1)
+ ty::OutlivesPredicate(ty::Region::new_var(tcx, v2).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
};
@@ -719,7 +720,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
}
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
- self.infcx.tcx.mk_re_placeholder(placeholder)
+ ty::Region::new_placeholder(self.infcx.tcx, placeholder)
}
fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
@@ -738,10 +739,8 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
self.obligations.push(Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
- predicate: ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
- ty::OutlivesPredicate(sup, sub),
- )))
- .to_predicate(self.infcx.tcx),
+ predicate: ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(sup, sub))
+ .to_predicate(self.infcx.tcx),
recursion_depth: 0,
});
}
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index b6b935de6..a9cdb8c51 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -34,7 +34,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
-use rustc_middle::ty::{self, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{IntType, UintType};
use rustc_span::DUMMY_SP;
@@ -103,17 +103,17 @@ impl<'tcx> InferCtxt<'tcx> {
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
(
- ty::Alias(AliasKind::Projection, _),
+ ty::Alias(..),
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
)
| (
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
- ty::Alias(AliasKind::Projection, _),
- ) if self.tcx.trait_solver_next() => {
+ ty::Alias(..),
+ ) if self.next_trait_solver() => {
bug!()
}
- (_, ty::Alias(..)) | (ty::Alias(..), _) if self.tcx.trait_solver_next() => {
+ (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
relation.register_type_relate_obligation(a, b);
Ok(a)
}
@@ -124,13 +124,10 @@ impl<'tcx> InferCtxt<'tcx> {
}
// During coherence, opaque types should be treated as *possibly*
- // equal to each other, even if their generic params differ, as
- // they could resolve to the same hidden type, even for different
- // generic params.
- (
- &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
- &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
- ) if self.intercrate && a_def_id == b_def_id => {
+ // equal to any other type (except for possibly itself). This is an
+ // extremely heavy hammer, but can be relaxed in a fowards-compatible
+ // way later.
+ (&ty::Alias(ty::Opaque, _), _) | (_, &ty::Alias(ty::Opaque, _)) if self.intercrate => {
relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
Ok(a)
}
@@ -192,11 +189,11 @@ impl<'tcx> InferCtxt<'tcx> {
// HACK: equating both sides with `[const error]` eagerly prevents us
// from leaving unconstrained inference vars during things like impl
// matching in the solver.
- let a_error = self.tcx.const_error(a.ty(), guar);
+ let a_error = ty::Const::new_error(self.tcx, guar, a.ty());
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
return self.unify_const_variable(vid, a_error, relation.param_env());
}
- let b_error = self.tcx.const_error(b.ty(), guar);
+ let b_error = ty::Const::new_error(self.tcx, guar, b.ty());
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
return self.unify_const_variable(vid, b_error, relation.param_env());
}
@@ -227,9 +224,20 @@ impl<'tcx> InferCtxt<'tcx> {
return self.unify_const_variable(vid, a, relation.param_env());
}
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
- if self.tcx.lazy_normalization() =>
+ if self.tcx.features().generic_const_exprs || self.next_trait_solver() =>
{
- relation.register_const_equate_obligation(a, b);
+ let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
+
+ relation.register_predicates([ty::Binder::dummy(if self.next_trait_solver() {
+ ty::PredicateKind::AliasRelate(
+ a.into(),
+ b.into(),
+ ty::AliasRelationDirection::Equate,
+ )
+ } else {
+ ty::PredicateKind::ConstEquate(a, b)
+ })]);
+
return Ok(b);
}
_ => {}
@@ -314,8 +322,8 @@ impl<'tcx> InferCtxt<'tcx> {
.unify_var_value(vid, Some(val))
.map_err(|e| int_unification_error(vid_is_expected, e))?;
match val {
- IntType(v) => Ok(self.tcx.mk_mach_int(v)),
- UintType(v) => Ok(self.tcx.mk_mach_uint(v)),
+ IntType(v) => Ok(Ty::new_int(self.tcx, v)),
+ UintType(v) => Ok(Ty::new_uint(self.tcx, v)),
}
}
@@ -330,7 +338,7 @@ impl<'tcx> InferCtxt<'tcx> {
.float_unification_table()
.unify_var_value(vid, Some(ty::FloatVarValue(val)))
.map_err(|e| float_unification_error(vid_is_expected, e))?;
- Ok(self.tcx.mk_mach_float(val))
+ Ok(Ty::new_float(self.tcx, val))
}
}
@@ -406,7 +414,9 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.tcx(),
self.trace.cause.clone(),
self.param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())),
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
+ b_ty.into(),
+ ))),
));
}
@@ -453,19 +463,6 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
/// be used if control over the obligation causes is required.
fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>);
- /// Register an obligation that both constants must be equal to each other.
- ///
- /// If they aren't equal then the relation doesn't hold.
- fn register_const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
- let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
-
- self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() {
- ty::PredicateKind::AliasRelate(a.into(), b.into(), ty::AliasRelationDirection::Equate)
- } else {
- ty::PredicateKind::ConstEquate(a, b)
- })]);
- }
-
/// Register an obligation that both types must be related to each other according to
/// the [`ty::AliasRelationDirection`] given by [`ObligationEmittingRelation::alias_relate_direction`]
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 42dfe4f6b..495c250a7 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -105,7 +105,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
&& def_id.is_local()
- && !self.tcx().trait_solver_next() =>
+ && !self.fields.infcx.next_trait_solver() =>
{
self.fields.obligations.extend(
infcx
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 35c05e80b..b826ced04 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -76,6 +76,7 @@ use rustc_middle::ty::{
};
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
use rustc_target::spec::abi;
+use std::borrow::Cow;
use std::ops::{ControlFlow, Deref};
use std::path::PathBuf;
use std::{cmp, fmt, iter};
@@ -314,7 +315,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let mut err = tcx.sess.create_err(errors::OpaqueCapturesLifetime {
span,
- opaque_ty: tcx.mk_opaque(opaque_ty_key.def_id.to_def_id(), opaque_ty_key.substs),
+ opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.substs),
opaque_ty_span: tcx.def_span(opaque_ty_key.def_id),
});
@@ -407,7 +408,7 @@ impl<'tcx> InferCtxt<'tcx> {
predicate
.kind()
.map_bound(|kind| match kind {
- ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate))
+ ty::ClauseKind::Projection(projection_predicate)
if projection_predicate.projection_ty.def_id == item_def_id =>
{
projection_predicate.term.ty()
@@ -846,7 +847,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) {
err.subdiagnostic(subdiag);
}
- if let Some(ret_sp) = opt_suggest_box_span {
+ // don't suggest wrapping either blocks in `if .. {} else {}`
+ let is_empty_arm = |id| {
+ let hir::Node::Block(blk) = self.tcx.hir().get(id)
+ else {
+ return false;
+ };
+ if blk.expr.is_some() || !blk.stmts.is_empty() {
+ return false;
+ }
+ let Some((_, hir::Node::Expr(expr))) = self.tcx.hir().parent_iter(id).nth(1)
+ else {
+ return false;
+ };
+ matches!(expr.kind, hir::ExprKind::If(..))
+ };
+ if let Some(ret_sp) = opt_suggest_box_span
+ && !is_empty_arm(then_id)
+ && !is_empty_arm(else_id)
+ {
self.suggest_boxing_for_return_impl_trait(
err,
ret_sp,
@@ -1470,7 +1489,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
diag: &mut Diagnostic,
cause: &ObligationCause<'tcx>,
- secondary_span: Option<(Span, String)>,
+ secondary_span: Option<(Span, Cow<'static, str>)>,
mut values: Option<ValuePairs<'tcx>>,
terr: TypeError<'tcx>,
swap_secondary_and_primary: bool,
@@ -1629,7 +1648,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
};
- let mut label_or_note = |span: Span, msg: &str| {
+ let mut label_or_note = |span: Span, msg: Cow<'static, str>| {
if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
diag.span_label(span, msg);
} else {
@@ -1643,15 +1662,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
..
})) = values
{
- format!("expected this to be `{}`", expected)
+ Cow::from(format!("expected this to be `{}`", expected))
} else {
- terr.to_string(self.tcx).to_string()
+ terr.to_string(self.tcx)
};
- label_or_note(sp, &terr);
- label_or_note(span, &msg);
+ label_or_note(sp, terr);
+ label_or_note(span, msg);
} else {
- label_or_note(span, &terr.to_string(self.tcx));
- label_or_note(sp, &msg);
+ label_or_note(span, terr.to_string(self.tcx));
+ label_or_note(sp, msg);
}
} else {
if let Some(values) = values
@@ -1663,12 +1682,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
let found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
if expected == found {
- label_or_note(span, &terr.to_string(self.tcx));
+ label_or_note(span, terr.to_string(self.tcx));
} else {
- label_or_note(span, &format!("expected {expected}, found {found}"));
+ label_or_note(span, Cow::from(format!("expected {expected}, found {found}")));
}
} else {
- label_or_note(span, &terr.to_string(self.tcx));
+ label_or_note(span, terr.to_string(self.tcx));
}
}
@@ -1896,7 +1915,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if should_suggest_fixes {
self.suggest_tuple_pattern(cause, &exp_found, diag);
- self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
self.suggest_function_pointers(cause, span, &exp_found, diag);
@@ -2357,6 +2375,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ty::AliasKind::Projection | ty::AliasKind::Inherent => {
format!("the associated type `{}`", p)
}
+ ty::AliasKind::Weak => format!("the type alias `{}`", p),
ty::AliasKind::Opaque => format!("the opaque type `{}`", p),
},
};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index f3b2ec4c5..bb75ecc6a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -265,9 +265,9 @@ impl<'tcx> InferCtxt<'tcx> {
kind: UnderspecifiedArgKind::Type {
prefix: "type parameter".into(),
},
- parent: def_id.and_then(|def_id| {
- InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id)
- }),
+ parent: InferenceDiagnosticsParentData::for_def_id(
+ self.tcx, def_id,
+ ),
};
}
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index c9c1f0aea..0b3bc1ce6 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -79,7 +79,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
)) => self.try_report_trait_placeholder_mismatch(
- Some(self.tcx().mk_re_var(*vid)),
+ Some(ty::Region::new_var(self.tcx(), *vid)),
cause,
Some(*sub_placeholder),
Some(*sup_placeholder),
@@ -95,7 +95,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
_,
_,
)) => self.try_report_trait_placeholder_mismatch(
- Some(self.tcx().mk_re_var(*vid)),
+ Some(ty::Region::new_var(self.tcx(), *vid)),
cause,
Some(*sub_placeholder),
None,
@@ -111,7 +111,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
)) => self.try_report_trait_placeholder_mismatch(
- Some(self.tcx().mk_re_var(*vid)),
+ Some(ty::Region::new_var(self.tcx(), *vid)),
cause,
None,
Some(*sup_placeholder),
@@ -127,7 +127,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
)) => self.try_report_trait_placeholder_mismatch(
- Some(self.tcx().mk_re_var(*vid)),
+ Some(ty::Region::new_var(self.tcx(), *vid)),
cause,
None,
Some(*sup_placeholder),
@@ -141,7 +141,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch(
- Some(self.tcx().mk_re_var(*vid)),
+ Some(ty::Region::new_var(self.tcx(), *vid)),
cause,
None,
Some(*sup_placeholder),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index aad988582..a9b485a6f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -288,7 +288,7 @@ pub fn suggest_new_region_bound(
// Get the identity type for this RPIT
let did = item_id.owner_id.to_def_id();
- let ty = tcx.mk_opaque(did, ty::InternalSubsts::identity_for_item(tcx, did));
+ let ty = Ty::new_opaque(tcx, did, ty::InternalSubsts::identity_for_item(tcx, did));
if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg {
GenericBound::Outlives(Lifetime {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index ce70bcc5c..12d38ced0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -41,8 +41,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// all of the region highlighting machinery only deals with those.
let guar = self.emit_err(
var_origin.span(),
- self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(expected)),
- self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(found)),
+ Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(expected)),
+ Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(found)),
*trait_item_def_id,
);
return Some(guar);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 07a9eff2d..e55e9e75f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -11,7 +11,7 @@ use rustc_errors::{
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::{self, IsSuggestable, Region};
+use rustc_middle::ty::{self, IsSuggestable, Region, Ty};
use rustc_span::symbol::kw;
use super::ObligationCauseAsDiagArg;
@@ -304,7 +304,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let trait_substs = trait_ref
.subst_identity()
// Replace the explicit self type with `Self` for better suggestion rendering
- .with_self_ty(self.tcx, self.tcx.mk_ty_param(0, kw::SelfUpper))
+ .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
.substs;
let trait_item_substs = ty::InternalSubsts::identity_for_item(self.tcx, impl_item_def_id)
.rebase_onto(self.tcx, impl_def_id, trait_substs);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 421eb807a..63613b590 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -139,7 +139,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
tcx,
generics,
diag,
- &format!("{}", proj.self_ty()),
+ &proj.self_ty().to_string(),
&path,
None,
matching_span,
@@ -153,7 +153,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
tcx,
generics,
diag,
- &format!("{}", proj.self_ty()),
+ &proj.self_ty().to_string(),
&path,
None,
matching_span,
@@ -234,13 +234,13 @@ impl<T> Trait<T> for X {
);
}
(_, ty::Alias(ty::Projection | ty::Inherent, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
- let msg = format!(
+ let msg = || format!(
"consider constraining the associated type `{}` to `{}`",
values.found, values.expected,
);
if !(self.suggest_constraining_opaque_associated_type(
diag,
- &msg,
+ msg,
proj_ty,
values.expected,
) || self.suggest_constraint(
@@ -250,17 +250,18 @@ impl<T> Trait<T> for X {
proj_ty,
values.expected,
)) {
- diag.help(msg);
+ diag.help(msg());
diag.note(
"for more information, visit \
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
);
}
}
- (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => {
+ (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::Fn | DefKind::Static(_) | DefKind::Const | DefKind::AssocFn | DefKind::AssocConst) => {
if tcx.is_type_alias_impl_trait(alias.def_id) {
if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) {
- diag.span_note(tcx.def_span(body_owner_def_id), "\
+ let sp = tcx.def_ident_span(body_owner_def_id).unwrap_or_else(|| tcx.def_span(body_owner_def_id));
+ diag.span_note(sp, "\
this item must have the opaque type in its signature \
in order to be able to register hidden types");
}
@@ -308,7 +309,7 @@ impl<T> Trait<T> for X {
fn suggest_constraint(
&self,
diag: &mut Diagnostic,
- msg: &str,
+ msg: impl Fn() -> String,
body_owner_def_id: DefId,
proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>,
@@ -340,7 +341,7 @@ impl<T> Trait<T> for X {
assoc,
assoc_substs,
ty,
- msg,
+ &msg,
false,
) {
return true;
@@ -374,10 +375,18 @@ impl<T> Trait<T> for X {
) {
let tcx = self.tcx;
- let msg = format!(
- "consider constraining the associated type `{}` to `{}`",
- values.expected, values.found
- );
+ // Don't suggest constraining a projection to something containing itself
+ if self.tcx.erase_regions(values.found).contains(self.tcx.erase_regions(values.expected)) {
+ return;
+ }
+
+ let msg = || {
+ format!(
+ "consider constraining the associated type `{}` to `{}`",
+ values.expected, values.found
+ )
+ };
+
let body_owner = tcx.hir().get_if_local(body_owner_def_id);
let current_method_ident = body_owner.and_then(|n| n.ident()).map(|i| i.name);
@@ -428,10 +437,11 @@ impl<T> Trait<T> for X {
if callable_scope {
diag.help(format!(
"{} or calling a method that returns `{}`",
- msg, values.expected
+ msg(),
+ values.expected
));
} else {
- diag.help(msg);
+ diag.help(msg());
}
diag.note(
"for more information, visit \
@@ -463,7 +473,7 @@ fn foo(&self) -> Self::T { String::new() }
fn suggest_constraining_opaque_associated_type(
&self,
diag: &mut Diagnostic,
- msg: &str,
+ msg: impl Fn() -> String,
proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>,
) -> bool {
@@ -564,7 +574,9 @@ fn foo(&self) -> Self::T { String::new() }
let Some(hir_id) = body_owner_def_id.as_local() else {
return false;
};
- let hir_id = tcx.hir().local_def_id_to_hir_id(hir_id);
+ let Some(hir_id) = tcx.opt_local_def_id_to_hir_id(hir_id) else {
+ return false;
+ };
// When `body_owner` is an `impl` or `trait` item, look in its associated types for
// `expected` and point at it.
let parent_id = tcx.hir().get_parent_item(hir_id);
@@ -583,7 +595,7 @@ fn foo(&self) -> Self::T { String::new() }
// FIXME: account for returning some type in a trait fn impl that has
// an assoc type as a return type (#72076).
if let hir::Defaultness::Default { has_value: true } =
- tcx.impl_defaultness(item.id.owner_id)
+ tcx.defaultness(item.id.owner_id)
{
let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity();
if self.infcx.can_eq(param_env, assoc_ty, found) {
@@ -635,7 +647,7 @@ fn foo(&self) -> Self::T { String::new() }
assoc: ty::AssocItem,
assoc_substs: &[ty::GenericArg<'tcx>],
ty: Ty<'tcx>,
- msg: &str,
+ msg: impl Fn() -> String,
is_bound_surely_present: bool,
) -> bool {
// FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
@@ -678,7 +690,7 @@ fn foo(&self) -> Self::T { String::new() }
assoc: ty::AssocItem,
assoc_substs: &[ty::GenericArg<'tcx>],
ty: Ty<'tcx>,
- msg: &str,
+ msg: impl Fn() -> String,
) -> bool {
let tcx = self.tcx;
@@ -693,7 +705,7 @@ fn foo(&self) -> Self::T { String::new() }
let item_args = self.format_generic_args(assoc_substs);
(span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(tcx), item_args, ty))
};
- diag.span_suggestion_verbose(span, msg, sugg, MaybeIncorrect);
+ diag.span_suggestion_verbose(span, msg(), sugg, MaybeIncorrect);
return true;
}
false
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index d885d0407..1422bdc9e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -13,9 +13,9 @@ use rustc_span::{sym, BytePos, Span};
use crate::errors::{
ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
- FunctionPointerSuggestion, SuggestAccessingField, SuggestAsRefWhereAppropriate,
- SuggestBoxingForReturnImplTrait, SuggestRemoveSemiOrReturnBinding, SuggestTuplePatternMany,
- SuggestTuplePatternOne, TypeErrorAdditionalDiags,
+ FunctionPointerSuggestion, SuggestAccessingField, SuggestBoxingForReturnImplTrait,
+ SuggestRemoveSemiOrReturnBinding, SuggestTuplePatternMany, SuggestTuplePatternOne,
+ TypeErrorAdditionalDiags,
};
use super::TypeErrCtxt;
@@ -289,27 +289,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}
- /// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate,
- /// suggests it.
- pub(super) fn suggest_as_ref_where_appropriate(
- &self,
- span: Span,
- exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
- diag: &mut Diagnostic,
- ) {
- if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
- && let Some(msg) = self.should_suggest_as_ref_kind(exp_found.expected, exp_found.found)
- {
- // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&`
- let snippet = snippet.trim_start_matches('&');
- let subdiag = match msg {
- SuggestAsRefKind::Option => SuggestAsRefWhereAppropriate::Option { span, snippet },
- SuggestAsRefKind::Result => SuggestAsRefWhereAppropriate::Result { span, snippet },
- };
- diag.subdiagnostic(subdiag);
- }
- }
-
pub(super) fn suggest_function_pointers(
&self,
cause: &ObligationCause<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 0219167f6..05769b790 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -95,7 +95,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
Entry::Vacant(entry) => {
let index = self.const_freshen_count;
self.const_freshen_count += 1;
- let ct = self.infcx.tcx.mk_const(freshener(index), ty);
+ let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty);
entry.insert(ct);
ct
}
@@ -188,7 +188,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
match v {
ty::TyVar(v) => {
let opt_ty = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
- Some(self.freshen_ty(opt_ty, ty::TyVar(v), |n| self.infcx.tcx.mk_fresh_ty(n)))
+ Some(self.freshen_ty(opt_ty, ty::TyVar(v), |n| Ty::new_fresh(self.infcx.tcx, n)))
}
ty::IntVar(v) => Some(
@@ -200,7 +200,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
.probe_value(v)
.map(|v| v.to_type(self.infcx.tcx)),
ty::IntVar(v),
- |n| self.infcx.tcx.mk_fresh_int_ty(n),
+ |n| Ty::new_fresh_int(self.infcx.tcx, n),
),
),
@@ -213,7 +213,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
.probe_value(v)
.map(|v| v.to_type(self.infcx.tcx)),
ty::FloatVar(v),
- |n| self.infcx.tcx.mk_fresh_float_ty(n),
+ |n| Ty::new_fresh_float(self.infcx.tcx, n),
),
),
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs
index d4a1dacde..780250167 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/generalize.rs
@@ -277,7 +277,7 @@ where
let origin = *inner.type_variables().var_origin(vid);
let new_var_id =
inner.type_variables().new_var(self.for_universe, origin);
- let u = self.tcx().mk_ty_var(new_var_id);
+ let u = Ty::new_var(self.tcx(), new_var_id);
// Record that we replaced `vid` with `new_var_id` as part of a generalization
// operation. This is needed to detect cyclic types. To see why, see the
@@ -398,7 +398,7 @@ where
origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.for_universe },
});
- Ok(self.tcx().mk_const(new_var_id, c.ty()))
+ Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
}
}
}
@@ -412,7 +412,11 @@ where
substs,
substs,
)?;
- Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty()))
+ Ok(ty::Const::new_unevaluated(
+ self.tcx(),
+ ty::UnevaluatedConst { def, substs },
+ c.ty(),
+ ))
}
ty::ConstKind::Placeholder(placeholder) => {
if self.for_universe.can_name(placeholder.universe) {
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
index c304cd25c..510b1797d 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
@@ -6,7 +6,7 @@ use super::{HigherRankedType, InferCtxt};
use crate::infer::CombinedSnapshot;
use rustc_middle::ty::fold::FnMutDelegate;
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, Binder, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable};
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
/// Checks whether `for<..> sub <: for<..> sup` holds.
@@ -82,17 +82,20 @@ impl<'tcx> InferCtxt<'tcx> {
let delegate = FnMutDelegate {
regions: &mut |br: ty::BoundRegion| {
- self.tcx
- .mk_re_placeholder(ty::PlaceholderRegion { universe: next_universe, bound: br })
+ ty::Region::new_placeholder(
+ self.tcx,
+ ty::PlaceholderRegion { universe: next_universe, bound: br },
+ )
},
types: &mut |bound_ty: ty::BoundTy| {
- self.tcx.mk_placeholder(ty::PlaceholderType {
- universe: next_universe,
- bound: bound_ty,
- })
+ Ty::new_placeholder(
+ self.tcx,
+ ty::PlaceholderType { universe: next_universe, bound: bound_ty },
+ )
},
consts: &mut |bound_var: ty::BoundVar, ty| {
- self.tcx.mk_const(
+ ty::Const::new_placeholder(
+ self.tcx,
ty::PlaceholderConst { universe: next_universe, bound: bound_var },
ty,
)
@@ -103,13 +106,15 @@ impl<'tcx> InferCtxt<'tcx> {
self.tcx.replace_bound_vars_uncached(binder, delegate)
}
- /// See [RegionConstraintCollector::leak_check][1].
+ /// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
+ /// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
+ /// universe.
///
/// [1]: crate::infer::region_constraints::RegionConstraintCollector::leak_check
pub fn leak_check(
&self,
- overly_polymorphic: bool,
- snapshot: &CombinedSnapshot<'tcx>,
+ outer_universe: ty::UniverseIndex,
+ only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
) -> RelateResult<'tcx, ()> {
// If the user gave `-Zno-leak-check`, or we have been
// configured to skip the leak check, then skip the leak check
@@ -117,15 +122,15 @@ impl<'tcx> InferCtxt<'tcx> {
// subtyping errors that it would have caught will now be
// caught later on, during region checking. However, we
// continue to use it for a transition period.
- if self.tcx.sess.opts.unstable_opts.no_leak_check || self.skip_leak_check.get() {
+ if self.tcx.sess.opts.unstable_opts.no_leak_check || self.skip_leak_check {
return Ok(());
}
self.inner.borrow_mut().unwrap_region_constraints().leak_check(
self.tcx,
- overly_polymorphic,
+ outer_universe,
self.universe(),
- snapshot,
+ only_consider_snapshot,
)
}
}
diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs
index 7190d33d2..9ef35429f 100644
--- a/compiler/rustc_infer/src/infer/lattice.rs
+++ b/compiler/rustc_infer/src/infer/lattice.rs
@@ -113,7 +113,7 @@ where
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
if this.define_opaque_types() == DefineOpaqueTypes::Yes
&& def_id.is_local()
- && !this.tcx().trait_solver_next() =>
+ && !this.infcx().next_trait_solver() =>
{
this.register_obligations(
infcx
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 8482ae2aa..485e34fe2 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -347,7 +347,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// name the placeholder, then the placeholder is
// larger; otherwise, the only ancestor is `'static`.
Err(placeholder) if empty_ui.can_name(placeholder.universe) => {
- self.tcx().mk_re_placeholder(placeholder)
+ ty::Region::new_placeholder(self.tcx(), placeholder)
}
Err(_) => self.tcx().lifetimes.re_static,
};
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index cd99fc312..fca32b73d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -6,6 +6,7 @@ pub use self::RegionVariableOrigin::*;
pub use self::SubregionOrigin::*;
pub use self::ValuePairs::*;
pub use combine::ObligationEmittingRelation;
+use rustc_data_structures::undo_log::UndoLogs;
use self::opaque_types::OpaqueTypeStorage;
pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
@@ -251,14 +252,13 @@ pub struct InferCtxt<'tcx> {
/// solving is left to borrowck instead.
pub considering_regions: bool,
- pub inner: RefCell<InferCtxtInner<'tcx>>,
-
/// If set, this flag causes us to skip the 'leak check' during
/// higher-ranked subtyping operations. This flag is a temporary one used
/// to manage the removal of the leak-check: for the time being, we still run the
- /// leak-check, but we issue warnings. This flag can only be set to true
- /// when entering a snapshot.
- skip_leak_check: Cell<bool>,
+ /// leak-check, but we issue warnings.
+ skip_leak_check: bool,
+
+ pub inner: RefCell<InferCtxtInner<'tcx>>,
/// Once region inference is done, the values for each variable.
lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
@@ -298,9 +298,6 @@ pub struct InferCtxt<'tcx> {
// FIXME(matthewjasper) Merge into `tainted_by_errors`
err_count_on_creation: usize,
- /// This flag is true while there is an active snapshot.
- in_snapshot: Cell<bool>,
-
/// What is the innermost universe we have created? Starts out as
/// `UniverseIndex::root()` but grows from there as we enter
/// universal quantifiers.
@@ -331,6 +328,8 @@ pub struct InferCtxt<'tcx> {
/// there is no type that the user could *actually name* that
/// would satisfy it. This avoids crippling inference, basically.
pub intercrate: bool,
+
+ next_trait_solver: bool,
}
/// See the `error_reporting` module for more details.
@@ -543,8 +542,12 @@ pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
defining_use_anchor: DefiningAnchor,
considering_regions: bool,
+ skip_leak_check: bool,
/// Whether we are in coherence mode.
intercrate: bool,
+ /// Whether we should use the new trait solver in the local inference context,
+ /// which affects things like which solver is used in `predicate_may_hold`.
+ next_trait_solver: bool,
}
pub trait TyCtxtInferExt<'tcx> {
@@ -557,7 +560,9 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
tcx: self,
defining_use_anchor: DefiningAnchor::Error,
considering_regions: true,
+ skip_leak_check: false,
intercrate: false,
+ next_trait_solver: self.next_trait_solver_globally(),
}
}
}
@@ -574,6 +579,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
self
}
+ pub fn with_next_trait_solver(mut self, next_trait_solver: bool) -> Self {
+ self.next_trait_solver = next_trait_solver;
+ self
+ }
+
pub fn intercrate(mut self, intercrate: bool) -> Self {
self.intercrate = intercrate;
self
@@ -584,6 +594,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
self
}
+ pub fn skip_leak_check(mut self, skip_leak_check: bool) -> Self {
+ self.skip_leak_check = skip_leak_check;
+ self
+ }
+
/// Given a canonical value `C` as a starting point, create an
/// inference context that contains each of the bound values
/// within instantiated as a fresh variable. The `f` closure is
@@ -605,11 +620,19 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
}
pub fn build(&mut self) -> InferCtxt<'tcx> {
- let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
+ let InferCtxtBuilder {
+ tcx,
+ defining_use_anchor,
+ considering_regions,
+ skip_leak_check,
+ intercrate,
+ next_trait_solver,
+ } = *self;
InferCtxt {
tcx,
defining_use_anchor,
considering_regions,
+ skip_leak_check,
inner: RefCell::new(InferCtxtInner::new()),
lexical_region_resolutions: RefCell::new(None),
selection_cache: Default::default(),
@@ -618,10 +641,9 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
reported_closure_mismatch: Default::default(),
tainted_by_errors: Cell::new(None),
err_count_on_creation: tcx.sess.err_count(),
- in_snapshot: Cell::new(false),
- skip_leak_check: Cell::new(false),
universe: Cell::new(ty::UniverseIndex::ROOT),
intercrate,
+ next_trait_solver,
}
}
}
@@ -654,10 +676,13 @@ pub struct CombinedSnapshot<'tcx> {
undo_snapshot: Snapshot<'tcx>,
region_constraints_snapshot: RegionSnapshot,
universe: ty::UniverseIndex,
- was_in_snapshot: bool,
}
impl<'tcx> InferCtxt<'tcx> {
+ pub fn next_trait_solver(&self) -> bool {
+ self.next_trait_solver
+ }
+
/// Creates a `TypeErrCtxt` for emitting various inference errors.
/// During typeck, use `FnCtxt::err_ctxt` instead.
pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
@@ -673,10 +698,6 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
- pub fn is_in_snapshot(&self) -> bool {
- self.in_snapshot.get()
- }
-
pub fn freshen<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
t.fold_with(&mut self.freshener())
}
@@ -704,19 +725,19 @@ impl<'tcx> InferCtxt<'tcx> {
.type_variables()
.unsolved_variables()
.into_iter()
- .map(|t| self.tcx.mk_ty_var(t))
+ .map(|t| Ty::new_var(self.tcx, t))
.collect();
vars.extend(
(0..inner.int_unification_table().len())
.map(|i| ty::IntVid { index: i as u32 })
.filter(|&vid| inner.int_unification_table().probe_value(vid).is_none())
- .map(|v| self.tcx.mk_int_var(v)),
+ .map(|v| Ty::new_int_var(self.tcx, v)),
);
vars.extend(
(0..inner.float_unification_table().len())
.map(|i| ty::FloatVid { index: i as u32 })
.filter(|&vid| inner.float_unification_table().probe_value(vid).is_none())
- .map(|v| self.tcx.mk_float_var(v)),
+ .map(|v| Ty::new_float_var(self.tcx, v)),
);
vars
}
@@ -737,31 +758,30 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
+ pub fn in_snapshot(&self) -> bool {
+ UndoLogs::<UndoLog<'tcx>>::in_snapshot(&self.inner.borrow_mut().undo_log)
+ }
+
+ pub fn num_open_snapshots(&self) -> usize {
+ UndoLogs::<UndoLog<'tcx>>::num_open_snapshots(&self.inner.borrow_mut().undo_log)
+ }
+
fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
debug!("start_snapshot()");
- let in_snapshot = self.in_snapshot.replace(true);
-
let mut inner = self.inner.borrow_mut();
CombinedSnapshot {
undo_snapshot: inner.undo_log.start_snapshot(),
region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(),
universe: self.universe(),
- was_in_snapshot: in_snapshot,
}
}
#[instrument(skip(self, snapshot), level = "debug")]
fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'tcx>) {
- let CombinedSnapshot {
- undo_snapshot,
- region_constraints_snapshot,
- universe,
- was_in_snapshot,
- } = snapshot;
-
- self.in_snapshot.set(was_in_snapshot);
+ let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot;
+
self.universe.set(universe);
let mut inner = self.inner.borrow_mut();
@@ -771,14 +791,8 @@ impl<'tcx> InferCtxt<'tcx> {
#[instrument(skip(self, snapshot), level = "debug")]
fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>) {
- let CombinedSnapshot {
- undo_snapshot,
- region_constraints_snapshot: _,
- universe: _,
- was_in_snapshot,
- } = snapshot;
-
- self.in_snapshot.set(was_in_snapshot);
+ let CombinedSnapshot { undo_snapshot, region_constraints_snapshot: _, universe: _ } =
+ snapshot;
self.inner.borrow_mut().commit(undo_snapshot);
}
@@ -815,32 +829,9 @@ impl<'tcx> InferCtxt<'tcx> {
r
}
- /// If `should_skip` is true, then execute `f` then unroll any bindings it creates.
- #[instrument(skip(self, f), level = "debug")]
- pub fn probe_maybe_skip_leak_check<R, F>(&self, should_skip: bool, f: F) -> R
- where
- F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
- {
- let snapshot = self.start_snapshot();
- let was_skip_leak_check = self.skip_leak_check.get();
- if should_skip {
- self.skip_leak_check.set(true);
- }
- let r = f(&snapshot);
- self.rollback_to("probe", snapshot);
- self.skip_leak_check.set(was_skip_leak_check);
- r
- }
-
- /// Scan the constraints produced since `snapshot` began and returns:
- ///
- /// - `None` -- if none of them involves "region outlives" constraints.
- /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder.
- /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders.
- pub fn region_constraints_added_in_snapshot(
- &self,
- snapshot: &CombinedSnapshot<'tcx>,
- ) -> Option<bool> {
+ /// Scan the constraints produced since `snapshot` and check whether
+ /// we added any region constraints.
+ pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
self.inner
.borrow_mut()
.unwrap_region_constraints()
@@ -987,7 +978,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
- self.tcx.mk_ty_var(self.next_ty_var_id(origin))
+ Ty::new_var(self.tcx, self.next_ty_var_id(origin))
}
pub fn next_ty_var_id_in_universe(
@@ -1004,11 +995,11 @@ impl<'tcx> InferCtxt<'tcx> {
universe: ty::UniverseIndex,
) -> Ty<'tcx> {
let vid = self.next_ty_var_id_in_universe(origin, universe);
- self.tcx.mk_ty_var(vid)
+ Ty::new_var(self.tcx, vid)
}
pub fn next_const_var(&self, ty: Ty<'tcx>, origin: ConstVariableOrigin) -> ty::Const<'tcx> {
- self.tcx.mk_const(self.next_const_var_id(origin), ty)
+ ty::Const::new_var(self.tcx, self.next_const_var_id(origin), ty)
}
pub fn next_const_var_in_universe(
@@ -1022,7 +1013,7 @@ impl<'tcx> InferCtxt<'tcx> {
.borrow_mut()
.const_unification_table()
.new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } });
- self.tcx.mk_const(vid, ty)
+ ty::Const::new_var(self.tcx, vid, ty)
}
pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> {
@@ -1037,7 +1028,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
pub fn next_int_var(&self) -> Ty<'tcx> {
- self.tcx.mk_int_var(self.next_int_var_id())
+ Ty::new_int_var(self.tcx, self.next_int_var_id())
}
fn next_float_var_id(&self) -> FloatVid {
@@ -1045,7 +1036,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
pub fn next_float_var(&self) -> Ty<'tcx> {
- self.tcx.mk_float_var(self.next_float_var_id())
+ Ty::new_float_var(self.tcx, self.next_float_var_id())
}
/// Creates a fresh region variable with the next available index.
@@ -1065,7 +1056,7 @@ impl<'tcx> InferCtxt<'tcx> {
) -> ty::Region<'tcx> {
let region_var =
self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin);
- self.tcx.mk_re_var(region_var)
+ ty::Region::new_var(self.tcx, region_var)
}
/// Return the universe that the region `r` was created in. For
@@ -1119,13 +1110,13 @@ impl<'tcx> InferCtxt<'tcx> {
TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeParameterDefinition(
param.name,
- Some(param.def_id),
+ param.def_id,
),
span,
},
);
- self.tcx.mk_ty_var(ty_var_id).into()
+ Ty::new_var(self.tcx, ty_var_id).into()
}
GenericParamDefKind::Const { .. } => {
let origin = ConstVariableOrigin {
@@ -1140,15 +1131,15 @@ impl<'tcx> InferCtxt<'tcx> {
origin,
val: ConstVariableValue::Unknown { universe: self.universe() },
});
- self.tcx
- .mk_const(
- const_var_id,
- self.tcx
- .type_of(param.def_id)
- .no_bound_vars()
- .expect("const parameter types cannot be generic"),
- )
- .into()
+ ty::Const::new_var(
+ self.tcx,
+ const_var_id,
+ self.tcx
+ .type_of(param.def_id)
+ .no_bound_vars()
+ .expect("const parameter types cannot be generic"),
+ )
+ .into()
}
}
}
@@ -1206,15 +1197,15 @@ impl<'tcx> InferCtxt<'tcx> {
.var_origin(vid)
}
- /// Takes ownership of the list of variable regions. This implies
- /// that all the region constraints have already been taken, and
- /// hence that `resolve_regions_and_report_errors` can never be
- /// called. This is used only during NLL processing to "hand off" ownership
- /// of the set of region variables into the NLL region context.
+ /// Clone the list of variable regions. This is used only during NLL processing
+ /// to put the set of region variables into the NLL region context.
pub fn get_region_var_origins(&self) -> VarInfos {
let mut inner = self.inner.borrow_mut();
let (var_infos, data) = inner
.region_constraint_storage
+ // We clone instead of taking because borrowck still wants to use
+ // the inference context after calling this for diagnostics
+ // and the new trait solver.
.clone()
.expect("regions already resolved")
.with_log(&mut inner.undo_log)
@@ -1274,7 +1265,7 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(value) = inner.int_unification_table().probe_value(vid) {
value.to_type(self.tcx)
} else {
- self.tcx.mk_int_var(inner.int_unification_table().find(vid))
+ Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid))
}
}
@@ -1285,7 +1276,7 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(value) = inner.float_unification_table().probe_value(vid) {
value.to_type(self.tcx)
} else {
- self.tcx.mk_float_var(inner.float_unification_table().find(vid))
+ Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid))
}
}
@@ -1468,6 +1459,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// universes. Updates `self.universe` to that new universe.
pub fn create_next_universe(&self) -> ty::UniverseIndex {
let u = self.universe.get().next_universe();
+ debug!("create_next_universe {u:?}");
self.universe.set(u);
u
}
@@ -1480,7 +1472,7 @@ impl<'tcx> InferCtxt<'tcx> {
span: Option<Span>,
) -> Result<ty::Const<'tcx>, ErrorHandled> {
match self.const_eval_resolve(param_env, unevaluated, span) {
- Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)),
+ Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, ty)),
Ok(None) => {
let tcx = self.tcx;
let def_id = unevaluated.def;
@@ -1953,13 +1945,16 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
self.idx += 1;
idx
};
- self.tcx.mk_placeholder(ty::PlaceholderType {
- universe: ty::UniverseIndex::ROOT,
- bound: ty::BoundTy {
- var: ty::BoundVar::from_u32(idx),
- kind: ty::BoundTyKind::Anon,
+ Ty::new_placeholder(
+ self.tcx,
+ ty::PlaceholderType {
+ universe: ty::UniverseIndex::ROOT,
+ bound: ty::BoundTy {
+ var: ty::BoundVar::from_u32(idx),
+ kind: ty::BoundTyKind::Anon,
+ },
},
- })
+ )
} else {
t.super_fold_with(self)
}
@@ -1972,7 +1967,8 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
if ty.has_non_region_param() || ty.has_non_region_infer() {
bug!("const `{c}`'s type should not reference params or types");
}
- self.tcx.mk_const(
+ ty::Const::new_placeholder(
+ self.tcx,
ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT,
bound: ty::BoundVar::from_u32({
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index d3fd01b96..71c07f31b 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -491,12 +491,12 @@ where
(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
- ) if a_def_id == b_def_id || infcx.tcx.trait_solver_next() => {
+ ) if a_def_id == b_def_id || infcx.next_trait_solver() => {
infcx.super_combine_tys(self, a, b).or_else(|err| {
// This behavior is only there for the old solver, the new solver
// shouldn't ever fail. Instead, it unconditionally emits an
// alias-relate goal.
- assert!(!self.tcx().trait_solver_next());
+ assert!(!self.infcx.next_trait_solver());
self.tcx().sess.delay_span_bug(
self.delegate.span(),
"failure to relate an opaque to itself should result in an error later on",
@@ -506,7 +506,7 @@ where
}
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
- if def_id.is_local() && !self.tcx().trait_solver_next() =>
+ if def_id.is_local() && !self.infcx.next_trait_solver() =>
{
self.relate_opaques(a, b)
}
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 9d5ec228d..5927f79a1 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -33,9 +33,6 @@ pub struct OpaqueTypeDecl<'tcx> {
/// There can be multiple, but they are all `lub`ed together at the end
/// to obtain the canonical hidden type.
pub hidden_type: OpaqueHiddenType<'tcx>,
-
- /// The origin of the opaque type.
- pub origin: hir::OpaqueTyOrigin,
}
impl<'tcx> InferCtxt<'tcx> {
@@ -49,7 +46,7 @@ impl<'tcx> InferCtxt<'tcx> {
param_env: ty::ParamEnv<'tcx>,
) -> InferOk<'tcx, T> {
// We handle opaque types differently in the new solver.
- if self.tcx.trait_solver_next() {
+ if self.next_trait_solver() {
return InferOk { value, obligations: vec![] };
}
@@ -108,7 +105,7 @@ impl<'tcx> InferCtxt<'tcx> {
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => {
let def_id = def_id.expect_local();
- let origin = match self.defining_use_anchor {
+ match self.defining_use_anchor {
DefiningAnchor::Bind(_) => {
// Check that this is `impl Trait` type is
// declared by `parent_def_id` -- i.e., one whose
@@ -144,9 +141,11 @@ impl<'tcx> InferCtxt<'tcx> {
// let x = || foo(); // returns the Opaque assoc with `foo`
// }
// ```
- self.opaque_type_origin(def_id)?
+ if self.opaque_type_origin(def_id).is_none() {
+ return None;
+ }
}
- DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id),
+ DefiningAnchor::Bubble => {}
DefiningAnchor::Error => return None,
};
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
@@ -170,7 +169,6 @@ impl<'tcx> InferCtxt<'tcx> {
cause.clone(),
param_env,
b,
- origin,
a_is_expected,
))
}
@@ -380,7 +378,7 @@ impl<'tcx> InferCtxt<'tcx> {
DefiningAnchor::Bind(bind) => bind,
};
- let origin = self.opaque_type_origin_unchecked(def_id);
+ let origin = self.tcx.opaque_type_origin(def_id);
let in_definition_scope = match origin {
// Async `impl Trait`
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
@@ -397,13 +395,6 @@ impl<'tcx> InferCtxt<'tcx> {
};
in_definition_scope.then_some(origin)
}
-
- /// Returns the origin of the opaque type `def_id` even if we are not in its
- /// defining scope.
- #[instrument(skip(self), level = "trace", ret)]
- fn opaque_type_origin_unchecked(&self, def_id: LocalDefId) -> OpaqueTyOrigin {
- self.tcx.hir().expect_item(def_id).expect_opaque_ty().origin
- }
}
/// Visitor that requires that (almost) all regions in the type visited outlive
@@ -482,17 +473,6 @@ where
}
}
- ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
- // Skip lifetime parameters that are not captures.
- let variances = self.tcx.variances_of(proj.def_id);
-
- for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
- if *v != ty::Variance::Bivariant {
- s.visit_with(self);
- }
- }
- }
-
_ => {
ty.super_visit_with(self);
}
@@ -524,30 +504,22 @@ impl<'tcx> InferCtxt<'tcx> {
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
- origin: hir::OpaqueTyOrigin,
a_is_expected: bool,
) -> InferResult<'tcx, ()> {
- // Ideally, we'd get the span where *this specific `ty` came
- // from*, but right now we just use the span from the overall
- // value being folded. In simple cases like `-> impl Foo`,
- // these are the same span, but not in cases like `-> (impl
- // Foo, impl Bar)`.
- let span = cause.span;
- let prev = self.inner.borrow_mut().opaque_types().register(
+ let mut obligations = Vec::new();
+
+ self.insert_hidden_type(
opaque_type_key,
- OpaqueHiddenType { ty: hidden_ty, span },
- origin,
- );
- let mut obligations = if let Some(prev) = prev {
- self.at(&cause, param_env)
- .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
- .obligations
- } else {
- Vec::new()
- };
+ &cause,
+ param_env,
+ hidden_ty,
+ a_is_expected,
+ &mut obligations,
+ )?;
self.add_item_bounds_for_hidden_type(
- opaque_type_key,
+ opaque_type_key.def_id.to_def_id(),
+ opaque_type_key.substs,
cause,
param_env,
hidden_ty,
@@ -557,32 +529,60 @@ impl<'tcx> InferCtxt<'tcx> {
Ok(InferOk { value: (), obligations })
}
- /// Registers an opaque's hidden type -- only should be used when the opaque
- /// can be defined. For something more fallible -- checks the anchors, tries
- /// to unify opaques in both dirs, etc. -- use `InferCtxt::handle_opaque_type`.
- pub fn register_hidden_type_in_new_solver(
+ /// Insert a hidden type into the opaque type storage, equating it
+ /// with any previous entries if necessary.
+ ///
+ /// This **does not** add the item bounds of the opaque as nested
+ /// obligations. That is only necessary when normalizing the opaque
+ /// itself, not when getting the opaque type constraints from
+ /// somewhere else.
+ pub fn insert_hidden_type(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
+ cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
- ) -> InferResult<'tcx, ()> {
- assert!(self.tcx.trait_solver_next());
- let origin = self
- .opaque_type_origin(opaque_type_key.def_id)
- .expect("should be called for defining usages only");
- self.register_hidden_type(
- opaque_type_key,
- ObligationCause::dummy(),
- param_env,
- hidden_ty,
- origin,
- true,
- )
+ a_is_expected: bool,
+ obligations: &mut Vec<PredicateObligation<'tcx>>,
+ ) -> Result<(), TypeError<'tcx>> {
+ // Ideally, we'd get the span where *this specific `ty` came
+ // from*, but right now we just use the span from the overall
+ // value being folded. In simple cases like `-> impl Foo`,
+ // these are the same span, but not in cases like `-> (impl
+ // Foo, impl Bar)`.
+ let span = cause.span;
+ if self.intercrate {
+ // During intercrate we do not define opaque types but instead always
+ // force ambiguity unless the hidden type is known to not implement
+ // our trait.
+ obligations.push(traits::Obligation::new(
+ self.tcx,
+ cause.clone(),
+ param_env,
+ ty::PredicateKind::Ambiguous,
+ ))
+ } else {
+ let prev = self
+ .inner
+ .borrow_mut()
+ .opaque_types()
+ .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
+ if let Some(prev) = prev {
+ obligations.extend(
+ self.at(&cause, param_env)
+ .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
+ .obligations,
+ );
+ }
+ };
+
+ Ok(())
}
pub fn add_item_bounds_for_hidden_type(
&self,
- OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>,
+ def_id: DefId,
+ substs: ty::SubstsRef<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
@@ -602,7 +602,7 @@ impl<'tcx> InferCtxt<'tcx> {
ty::Alias(ty::Projection, projection_ty)
if !projection_ty.has_escaping_bound_vars()
&& !tcx.is_impl_trait_in_trait(projection_ty.def_id)
- && !tcx.trait_solver_next() =>
+ && !self.next_trait_solver() =>
{
self.infer_projection(
param_env,
@@ -615,7 +615,7 @@ impl<'tcx> InferCtxt<'tcx> {
// Replace all other mentions of the same opaque type with the hidden type,
// as the bounds must hold on the hidden type after all.
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. })
- if def_id.to_def_id() == def_id2 && substs == substs2 =>
+ if def_id == def_id2 && substs == substs2 =>
{
hidden_ty
}
@@ -624,16 +624,14 @@ impl<'tcx> InferCtxt<'tcx> {
ty::Alias(
ty::Projection,
ty::AliasTy { def_id: def_id2, substs: substs2, .. },
- ) if def_id.to_def_id() == def_id2 && substs == substs2 => hidden_ty,
+ ) if def_id == def_id2 && substs == substs2 => hidden_ty,
_ => ty,
},
lt_op: |lt| lt,
ct_op: |ct| ct,
});
- if let ty::PredicateKind::Clause(ty::Clause::Projection(projection)) =
- predicate.kind().skip_binder()
- {
+ if let ty::ClauseKind::Projection(projection) = predicate.kind().skip_binder() {
if projection.term.references_error() {
// No point on adding any obligations since there's a type error involved.
obligations.clear();
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index a0f6d7eca..a737761ba 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -1,5 +1,4 @@
use rustc_data_structures::undo_log::UndoLogs;
-use rustc_hir::OpaqueTyOrigin;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
use rustc_span::DUMMY_SP;
@@ -60,14 +59,13 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
&mut self,
key: OpaqueTypeKey<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
- origin: OpaqueTyOrigin,
) -> Option<Ty<'tcx>> {
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
return Some(prev.ty);
}
- let decl = OpaqueTypeDecl { hidden_type, origin };
+ let decl = OpaqueTypeDecl { hidden_type };
self.storage.opaque_types.insert(key, decl);
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
None
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 8a44d5031..cb92fc6dd 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -20,27 +20,18 @@ pub fn explicit_outlives_bounds<'tcx>(
param_env
.caller_bounds()
.into_iter()
- .map(ty::Predicate::kind)
+ .map(ty::Clause::kind)
.filter_map(ty::Binder::no_bound_vars)
.filter_map(move |kind| match kind {
- ty::PredicateKind::Clause(ty::Clause::Projection(..))
- | ty::PredicateKind::Clause(ty::Clause::Trait(..))
- | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
- | ty::PredicateKind::AliasRelate(..)
- | ty::PredicateKind::Coerce(..)
- | ty::PredicateKind::Subtype(..)
- | ty::PredicateKind::WellFormed(..)
- | ty::PredicateKind::ObjectSafe(..)
- | ty::PredicateKind::ClosureKind(..)
- | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
- | ty::PredicateKind::ConstEvaluatable(..)
- | ty::PredicateKind::ConstEquate(..)
- | ty::PredicateKind::Ambiguous
- | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
- ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate(
- r_a,
- r_b,
- ))) => Some(OutlivesBound::RegionSubRegion(r_b, r_a)),
+ ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
+ Some(OutlivesBound::RegionSubRegion(r_b, r_a))
+ }
+ ty::ClauseKind::Trait(_)
+ | ty::ClauseKind::TypeOutlives(_)
+ | ty::ClauseKind::Projection(_)
+ | ty::ClauseKind::ConstArgHasType(_, _)
+ | ty::ClauseKind::WellFormed(_)
+ | ty::ClauseKind::ConstEvaluatable(_) => None,
})
}
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 9c20c814b..73df6d03f 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -125,10 +125,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// right before lexical region resolution.
#[instrument(level = "debug", skip(self, outlives_env))]
pub fn process_registered_region_obligations(&self, outlives_env: &OutlivesEnvironment<'tcx>) {
- assert!(
- !self.in_snapshot.get(),
- "cannot process registered region obligations in a snapshot"
- );
+ assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
let my_region_obligations = self.take_registered_region_obligations();
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index c2bf0f3db..1a5e2b520 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -223,7 +223,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
// parameter environments are already elaborated, so we don't
// have to worry about that.
let c_b = self.param_env.caller_bounds();
- let param_bounds = self.collect_outlives_from_predicate_list(erased_ty, c_b.into_iter());
+ let param_bounds = self.collect_outlives_from_clause_list(erased_ty, c_b.into_iter());
// Next, collect regions we scraped from the well-formedness
// constraints in the fn signature. To do that, we walk the list
@@ -293,10 +293,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
) -> impl Iterator<Item = ty::Region<'tcx>> {
let tcx = self.tcx;
let bounds = tcx.item_bounds(alias_ty.def_id);
- trace!("{:#?}", bounds.0);
+ trace!("{:#?}", bounds.skip_binder());
bounds
.subst_iter(tcx, alias_ty.substs)
- .filter_map(|p| p.to_opt_type_outlives())
+ .filter_map(|p| p.as_type_outlives_clause())
.filter_map(|p| p.no_bound_vars())
.map(|OutlivesPredicate(_, r)| r)
}
@@ -307,15 +307,15 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
/// when comparing `ty` for equality, so `ty` must be something
/// that does not involve inference variables and where you
/// otherwise want a precise match.
- fn collect_outlives_from_predicate_list(
+ fn collect_outlives_from_clause_list(
&self,
erased_ty: Ty<'tcx>,
- predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
+ clauses: impl Iterator<Item = ty::Clause<'tcx>>,
) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>>
{
let tcx = self.tcx;
let param_env = self.param_env;
- predicates.filter_map(|p| p.to_opt_type_outlives()).filter(move |outlives_predicate| {
+ clauses.filter_map(|p| p.as_type_outlives_clause()).filter(move |outlives_predicate| {
super::test_type_match::can_match_erased_ty(
tcx,
param_env,
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs
index fa6529dfa..38e74e538 100644
--- a/compiler/rustc_infer/src/infer/projection.rs
+++ b/compiler/rustc_infer/src/infer/projection.rs
@@ -21,28 +21,18 @@ impl<'tcx> InferCtxt<'tcx> {
recursion_depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> Ty<'tcx> {
- if self.tcx.trait_solver_next() {
- // FIXME(-Ztrait-solver=next): Instead of branching here,
- // completely change the normalization routine with the new solver.
- //
- // The new solver correctly handles projection equality so this hack
- // is not necessary. if re-enabled it should emit `PredicateKind::AliasRelate`
- // not `PredicateKind::Clause(Clause::Projection(..))` as in the new solver
- // `Projection` is used as `normalizes-to` which will fail for `<T as Trait>::Assoc eq ?0`.
- return projection_ty.to_ty(self.tcx);
- } else {
- let def_id = projection_ty.def_id;
- let ty_var = self.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::NormalizeProjectionType,
- span: self.tcx.def_span(def_id),
- });
- let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Projection(
- ty::ProjectionPredicate { projection_ty, term: ty_var.into() },
- )));
- let obligation =
- Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
- obligations.push(obligation);
- ty_var
- }
+ debug_assert!(!self.next_trait_solver());
+ let def_id = projection_ty.def_id;
+ let ty_var = self.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::NormalizeProjectionType,
+ span: self.tcx.def_span(def_id),
+ });
+ let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection(
+ ty::ProjectionPredicate { projection_ty, term: ty_var.into() },
+ )));
+ let obligation =
+ Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
+ obligations.push(obligation);
+ ty_var
}
}
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 89cfc9ea3..dd65f66cc 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -3,7 +3,6 @@ use crate::infer::CombinedSnapshot;
use rustc_data_structures::{
fx::FxIndexMap,
graph::{scc::Sccs, vec_graph::VecGraph},
- undo_log::UndoLogs,
};
use rustc_index::Idx;
use rustc_middle::ty::error::TypeError;
@@ -13,7 +12,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
/// Searches new universes created during `snapshot`, looking for
/// placeholders that may "leak" out from the universes they are contained
/// in. If any leaking placeholders are found, then an `Err` is returned
- /// (typically leading to the snapshot being reversed).
+ /// (typically leading to the snapshot being reversed). This algorithm
+ /// only looks at placeholders which cannot be named by `outer_universe`,
+ /// as this is the universe we're currently checking for a leak.
///
/// The leak check *used* to be the only way we had to handle higher-ranked
/// obligations. Now that we have integrated universes into the region
@@ -55,6 +56,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
/// * if they must also be equal to a placeholder P, and U cannot name P, report an error, as that
/// indicates `P: R` and `R` is in an incompatible universe
///
+ /// To improve performance and for the old trait solver caching to be sound, this takes
+ /// an optional snapshot in which case we only look at region constraints added in that
+ /// snapshot. If we were to not do that the `leak_check` during evaluation can rely on
+ /// region constraints added outside of that evaluation. As that is not reflected in the
+ /// cache key this would be unsound.
+ ///
/// # Historical note
///
/// Older variants of the leak check used to report errors for these
@@ -62,36 +69,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
///
/// * R: P1, even if R cannot name P1, because R = 'static is a valid sol'n
/// * R: P1, R: P2, as above
+ #[instrument(level = "debug", skip(self, tcx, only_consider_snapshot), ret)]
pub fn leak_check(
&mut self,
tcx: TyCtxt<'tcx>,
- overly_polymorphic: bool,
+ outer_universe: ty::UniverseIndex,
max_universe: ty::UniverseIndex,
- snapshot: &CombinedSnapshot<'tcx>,
+ only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
) -> RelateResult<'tcx, ()> {
- debug!(
- "leak_check(max_universe={:?}, snapshot.universe={:?}, overly_polymorphic={:?})",
- max_universe, snapshot.universe, overly_polymorphic
- );
-
- assert!(UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));
-
- let universe_at_start_of_snapshot = snapshot.universe;
- if universe_at_start_of_snapshot == max_universe {
+ if outer_universe == max_universe {
return Ok(());
}
- let mini_graph =
- &MiniGraph::new(tcx, self.undo_log.region_constraints(), &self.storage.data.verifys);
+ let mini_graph = &MiniGraph::new(tcx, &self, only_consider_snapshot);
- let mut leak_check = LeakCheck::new(
- tcx,
- universe_at_start_of_snapshot,
- max_universe,
- overly_polymorphic,
- mini_graph,
- self,
- );
+ let mut leak_check = LeakCheck::new(tcx, outer_universe, max_universe, mini_graph, self);
leak_check.assign_placeholder_values()?;
leak_check.propagate_scc_value()?;
Ok(())
@@ -100,9 +92,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
struct LeakCheck<'me, 'tcx> {
tcx: TyCtxt<'tcx>,
- universe_at_start_of_snapshot: ty::UniverseIndex,
- /// Only used when reporting region errors.
- overly_polymorphic: bool,
+ outer_universe: ty::UniverseIndex,
mini_graph: &'me MiniGraph<'tcx>,
rcc: &'me RegionConstraintCollector<'me, 'tcx>,
@@ -130,17 +120,15 @@ struct LeakCheck<'me, 'tcx> {
impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
fn new(
tcx: TyCtxt<'tcx>,
- universe_at_start_of_snapshot: ty::UniverseIndex,
+ outer_universe: ty::UniverseIndex,
max_universe: ty::UniverseIndex,
- overly_polymorphic: bool,
mini_graph: &'me MiniGraph<'tcx>,
rcc: &'me RegionConstraintCollector<'me, 'tcx>,
) -> Self {
let dummy_scc_universe = SccUniverse { universe: max_universe, region: None };
Self {
tcx,
- universe_at_start_of_snapshot,
- overly_polymorphic,
+ outer_universe,
mini_graph,
rcc,
scc_placeholders: IndexVec::from_elem_n(None, mini_graph.sccs.num_sccs()),
@@ -165,7 +153,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
// Detect those SCCs that directly contain a placeholder
if let ty::RePlaceholder(placeholder) = **region {
- if self.universe_at_start_of_snapshot.cannot_name(placeholder.universe) {
+ if self.outer_universe.cannot_name(placeholder.universe) {
self.assign_scc_value(scc, placeholder)?;
}
}
@@ -280,7 +268,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
placeholder1: ty::PlaceholderRegion,
placeholder2: ty::PlaceholderRegion,
) -> TypeError<'tcx> {
- self.error(placeholder1, self.tcx.mk_re_placeholder(placeholder2))
+ self.error(placeholder1, ty::Region::new_placeholder(self.tcx, placeholder2))
}
fn error(
@@ -289,11 +277,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
other_region: ty::Region<'tcx>,
) -> TypeError<'tcx> {
debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region);
- if self.overly_polymorphic {
- TypeError::RegionsOverlyPolymorphic(placeholder.bound.kind, other_region)
- } else {
- TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound.kind, other_region)
- }
+ TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound.kind, other_region)
}
}
@@ -379,56 +363,70 @@ struct MiniGraph<'tcx> {
}
impl<'tcx> MiniGraph<'tcx> {
- fn new<'a>(
+ fn new(
tcx: TyCtxt<'tcx>,
- undo_log: impl Iterator<Item = &'a UndoLog<'tcx>>,
- verifys: &[Verify<'tcx>],
- ) -> Self
- where
- 'tcx: 'a,
- {
+ region_constraints: &RegionConstraintCollector<'_, 'tcx>,
+ only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
+ ) -> Self {
let mut nodes = FxIndexMap::default();
let mut edges = Vec::new();
// Note that if `R2: R1`, we get a callback `r1, r2`, so `target` is first parameter.
- Self::iterate_undo_log(tcx, undo_log, verifys, |target, source| {
- let source_node = Self::add_node(&mut nodes, source);
- let target_node = Self::add_node(&mut nodes, target);
- edges.push((source_node, target_node));
- });
+ Self::iterate_region_constraints(
+ tcx,
+ region_constraints,
+ only_consider_snapshot,
+ |target, source| {
+ let source_node = Self::add_node(&mut nodes, source);
+ let target_node = Self::add_node(&mut nodes, target);
+ edges.push((source_node, target_node));
+ },
+ );
let graph = VecGraph::new(nodes.len(), edges);
let sccs = Sccs::new(&graph);
Self { nodes, sccs }
}
/// Invokes `each_edge(R1, R2)` for each edge where `R2: R1`
- fn iterate_undo_log<'a>(
+ fn iterate_region_constraints(
tcx: TyCtxt<'tcx>,
- undo_log: impl Iterator<Item = &'a UndoLog<'tcx>>,
- verifys: &[Verify<'tcx>],
+ region_constraints: &RegionConstraintCollector<'_, 'tcx>,
+ only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
mut each_edge: impl FnMut(ty::Region<'tcx>, ty::Region<'tcx>),
- ) where
- 'tcx: 'a,
- {
- for undo_entry in undo_log {
- match undo_entry {
- &AddConstraint(Constraint::VarSubVar(a, b)) => {
- each_edge(tcx.mk_re_var(a), tcx.mk_re_var(b));
- }
- &AddConstraint(Constraint::RegSubVar(a, b)) => {
- each_edge(a, tcx.mk_re_var(b));
- }
- &AddConstraint(Constraint::VarSubReg(a, b)) => {
- each_edge(tcx.mk_re_var(a), b);
- }
- &AddConstraint(Constraint::RegSubReg(a, b)) => {
- each_edge(a, b);
+ ) {
+ let mut each_constraint = |constraint| match constraint {
+ &Constraint::VarSubVar(a, b) => {
+ each_edge(ty::Region::new_var(tcx, a), ty::Region::new_var(tcx, b));
+ }
+ &Constraint::RegSubVar(a, b) => {
+ each_edge(a, ty::Region::new_var(tcx, b));
+ }
+ &Constraint::VarSubReg(a, b) => {
+ each_edge(ty::Region::new_var(tcx, a), b);
+ }
+ &Constraint::RegSubReg(a, b) => {
+ each_edge(a, b);
+ }
+ };
+
+ if let Some(snapshot) = only_consider_snapshot {
+ for undo_entry in
+ region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
+ {
+ match undo_entry {
+ AddConstraint(constraint) => {
+ each_constraint(constraint);
+ }
+ &AddVerify(i) => span_bug!(
+ region_constraints.data().verifys[i].origin.span(),
+ "we never add verifications while doing higher-ranked things",
+ ),
+ &AddCombination(..) | &AddVar(..) => {}
}
- &AddVerify(i) => span_bug!(
- verifys[i].origin.span(),
- "we never add verifications while doing higher-ranked things",
- ),
- &AddCombination(..) | &AddVar(..) => {}
+ }
+ } else {
+ for (constraint, _origin) in &region_constraints.data().constraints {
+ each_constraint(constraint)
}
}
}
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index c7a307b89..613da8a0b 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -400,7 +400,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
data
}
- pub(super) fn data(&self) -> &RegionConstraintData<'tcx> {
+ pub fn data(&self) -> &RegionConstraintData<'tcx> {
&self.data
}
@@ -610,13 +610,13 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
let resolved = ut
.probe_value(root_vid)
.get_value_ignoring_universes()
- .unwrap_or_else(|| tcx.mk_re_var(root_vid));
+ .unwrap_or_else(|| ty::Region::new_var(tcx, root_vid));
// Don't resolve a variable to a region that it cannot name.
if self.var_universe(vid).can_name(self.universe(resolved)) {
resolved
} else {
- tcx.mk_re_var(vid)
+ ty::Region::new_var(tcx, vid)
}
}
@@ -637,7 +637,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
) -> Region<'tcx> {
let vars = TwoRegions { a, b };
if let Some(&c) = self.combine_map(t).get(&vars) {
- return tcx.mk_re_var(c);
+ return ty::Region::new_var(tcx, c);
}
let a_universe = self.universe(a);
let b_universe = self.universe(b);
@@ -645,7 +645,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
self.combine_map(t).insert(vars, c);
self.undo_log.push(AddCombination(t, vars));
- let new_r = tcx.mk_re_var(c);
+ let new_r = ty::Region::new_var(tcx, c);
for old_r in [a, b] {
match t {
Glb => self.make_subregion(origin.clone(), new_r, old_r),
@@ -683,15 +683,10 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
/// See `InferCtxt::region_constraints_added_in_snapshot`.
- pub fn region_constraints_added_in_snapshot(&self, mark: &Snapshot<'tcx>) -> Option<bool> {
+ pub fn region_constraints_added_in_snapshot(&self, mark: &Snapshot<'tcx>) -> bool {
self.undo_log
.region_constraints_in_snapshot(mark)
- .map(|&elt| match elt {
- AddConstraint(constraint) => Some(constraint.involves_placeholders()),
- _ => None,
- })
- .max()
- .unwrap_or(None)
+ .any(|&elt| matches!(elt, AddConstraint(_)))
}
#[inline]
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index ceafafb55..27e1ed56f 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -118,7 +118,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
(&ty::Error(e), _) | (_, &ty::Error(e)) => {
infcx.set_tainted_by_errors(e);
- Ok(self.tcx().ty_error(e))
+ Ok(Ty::new_error(self.tcx(), e))
}
(
@@ -132,7 +132,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
&& def_id.is_local()
- && !self.tcx().trait_solver_next() =>
+ && !self.fields.infcx.next_trait_solver() =>
{
self.fields.obligations.extend(
infcx
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index f7ab05b2d..01c11d163 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -123,13 +123,12 @@ pub enum TypeVariableOriginKind {
NormalizeProjectionType,
TypeInference,
OpaqueTypeInference(DefId),
- TypeParameterDefinition(Symbol, Option<DefId>),
+ TypeParameterDefinition(Symbol, DefId),
/// One of the upvars or closure kind parameters in a `ClosureSubsts`
/// (before it has been determined).
// FIXME(eddyb) distinguish upvar inference variables from the rest.
ClosureSynthetic,
- SubstitutionPlaceholder,
AutoDeref,
AdjustmentType,
diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs
index 955c54e85..25d06b21e 100644
--- a/compiler/rustc_infer/src/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/undo_log.rs
@@ -138,11 +138,9 @@ impl<'tcx> InferCtxtInner<'tcx> {
}
if self.undo_log.num_open_snapshots == 1 {
- // The root snapshot. It's safe to clear the undo log because
- // there's no snapshot further out that we might need to roll back
- // to.
+ // After the root snapshot the undo log should be empty.
assert!(snapshot.undo_len == 0);
- self.undo_log.logs.clear();
+ assert!(self.undo_log.logs.is_empty());
}
self.undo_log.num_open_snapshots -= 1;
@@ -183,15 +181,6 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> {
self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..)))
}
- pub(crate) fn region_constraints(
- &self,
- ) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {
- self.logs.iter().filter_map(|log| match log {
- UndoLog::RegionConstraintCollector(log) => Some(log),
- _ => None,
- })
- }
-
fn assert_open_snapshot(&self, snapshot: &Snapshot<'tcx>) {
// Failures here may indicate a failure to follow a stack discipline.
assert!(self.logs.len() >= snapshot.undo_len);
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index b5a7d0326..9f440f398 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -25,9 +25,11 @@ impl<'tcx> InferCtxt<'tcx> {
"impl has stricter requirements than trait"
);
- if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
- let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
- err.span_label(span, format!("definition of `{}` from trait", item_name));
+ if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
+ if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
+ let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
+ err.span_label(span, format!("definition of `{}` from trait", item_name));
+ }
}
err.span_label(error_span, format!("impl has extra requirement {}", requirement));
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 8ce8b4e20..626dd9359 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -62,7 +62,8 @@ impl<'tcx, P> From<Obligation<'tcx, P>> for solve::Goal<'tcx, P> {
}
pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
-pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
+pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>;
+pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
impl<'tcx> PredicateObligation<'tcx> {
/// Flips the polarity of the inner predicate.
@@ -79,14 +80,14 @@ impl<'tcx> PredicateObligation<'tcx> {
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
self.param_env = self.param_env.without_const();
- if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
- self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred.without_const()))));
+ if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
+ self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const()))));
}
self
}
}
-impl<'tcx> TraitObligation<'tcx> {
+impl<'tcx> PolyTraitObligation<'tcx> {
/// Returns `true` if the trait predicate is considered `const` in its ParamEnv.
pub fn is_const(&self) -> bool {
matches!(
@@ -193,7 +194,7 @@ impl<'tcx> FulfillmentError<'tcx> {
}
}
-impl<'tcx> TraitObligation<'tcx> {
+impl<'tcx> PolyTraitObligation<'tcx> {
pub fn polarity(&self) -> ty::ImplPolarity {
self.predicate.skip_binder().polarity
}
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 74a78f380..074ff7ec9 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -3,7 +3,7 @@ use smallvec::smallvec;
use crate::infer::outlives::components::{push_outlives_components, Component};
use crate::traits::{self, Obligation, PredicateObligation};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
-use rustc_middle::ty::{self, ToPredicate, TyCtxt};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::Ident;
use rustc_span::Span;
@@ -80,14 +80,14 @@ pub struct Elaborator<'tcx, O> {
pub trait Elaboratable<'tcx> {
fn predicate(&self) -> ty::Predicate<'tcx>;
- // Makes a new `Self` but with a different predicate.
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self;
+ // Makes a new `Self` but with a different clause that comes from elaboration.
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self;
- // Makes a new `Self` but with a different predicate and a different cause
- // code (if `Self` has one).
+ // Makes a new `Self` but with a different clause and a different cause
+ // code (if `Self` has one, such as [`PredicateObligation`]).
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
span: Span,
parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
index: usize,
@@ -99,18 +99,18 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> {
self.predicate
}
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
recursion_depth: 0,
- predicate,
+ predicate: clause.as_predicate(),
}
}
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
span: Span,
parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
index: usize,
@@ -123,7 +123,12 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> {
span,
}))
});
- Obligation { cause, param_env: self.param_env, recursion_depth: 0, predicate }
+ Obligation {
+ cause,
+ param_env: self.param_env,
+ recursion_depth: 0,
+ predicate: clause.as_predicate(),
+ }
}
}
@@ -132,18 +137,18 @@ impl<'tcx> Elaboratable<'tcx> for ty::Predicate<'tcx> {
*self
}
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
- predicate
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ clause.as_predicate()
}
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
- predicate
+ clause.as_predicate()
}
}
@@ -152,18 +157,58 @@ impl<'tcx> Elaboratable<'tcx> for (ty::Predicate<'tcx>, Span) {
self.0
}
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
- (predicate, self.1)
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ (clause.as_predicate(), self.1)
+ }
+
+ fn child_with_derived_cause(
+ &self,
+ clause: ty::Clause<'tcx>,
+ _span: Span,
+ _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
+ _index: usize,
+ ) -> Self {
+ (clause.as_predicate(), self.1)
+ }
+}
+
+impl<'tcx> Elaboratable<'tcx> for (ty::Clause<'tcx>, Span) {
+ fn predicate(&self) -> ty::Predicate<'tcx> {
+ self.0.as_predicate()
+ }
+
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ (clause, self.1)
}
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
- (predicate, self.1)
+ (clause, self.1)
+ }
+}
+
+impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
+ fn predicate(&self) -> ty::Predicate<'tcx> {
+ self.as_predicate()
+ }
+
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ clause
+ }
+
+ fn child_with_derived_cause(
+ &self,
+ clause: ty::Clause<'tcx>,
+ _span: Span,
+ _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
+ _index: usize,
+ ) -> Self {
+ clause
}
}
@@ -199,7 +244,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
let bound_predicate = elaboratable.predicate().kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
// Negative trait bounds do not imply any supertrait bounds
if data.polarity == ty::ImplPolarity::Negative {
return;
@@ -212,13 +257,13 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
};
let obligations =
- predicates.predicates.iter().enumerate().map(|(index, &(mut pred, span))| {
+ predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| {
// when parent predicate is non-const, elaborate it to non-const predicates.
if data.constness == ty::BoundConstness::NotConst {
- pred = pred.without_const(tcx);
+ clause = clause.without_const(tcx);
}
elaboratable.child_with_derived_cause(
- pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
+ clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
span,
bound_predicate.rebind(data),
index,
@@ -227,7 +272,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
debug!(?data, ?obligations, "super_predicates");
self.extend_deduped(obligations);
}
- ty::PredicateKind::WellFormed(..) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) => {
// Currently, we do not elaborate WF predicates,
// although we easily could.
}
@@ -243,13 +288,13 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
// Currently, we do not "elaborate" predicates like `X -> Y`,
// though conceivably we might.
}
- ty::PredicateKind::Clause(ty::Clause::Projection(..)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => {
// Nothing to elaborate in a projection predicate.
}
ty::PredicateKind::ClosureKind(..) => {
// Nothing to elaborate when waiting for a closure's kind to be inferred.
}
- ty::PredicateKind::ConstEvaluatable(..) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => {
// Currently, we do not elaborate const-evaluatable
// predicates.
}
@@ -257,10 +302,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
// Currently, we do not elaborate const-equate
// predicates.
}
- ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {
// Nothing to elaborate from `'a: 'b`.
}
- ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
+ ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
ty_max,
r_min,
))) => {
@@ -292,17 +337,15 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
if r.is_late_bound() {
None
} else {
- Some(ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
- ty::OutlivesPredicate(r, r_min),
+ Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
+ r, r_min,
)))
}
}
Component::Param(p) => {
- let ty = tcx.mk_ty_param(p.index, p.name);
- Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
- ty::OutlivesPredicate(ty, r_min),
- )))
+ let ty = Ty::new_param(tcx, p.index, p.name);
+ Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min)))
}
Component::UnresolvedInferenceVariable(_) => None,
@@ -310,8 +353,9 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
Component::Alias(alias_ty) => {
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
- Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
- ty::OutlivesPredicate(alias_ty.to_ty(tcx), r_min),
+ Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
+ alias_ty.to_ty(tcx),
+ r_min,
)))
}
@@ -321,20 +365,16 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
None
}
})
- .map(|predicate_kind| {
- bound_predicate.rebind(predicate_kind).to_predicate(tcx)
- })
- .map(|predicate| elaboratable.child(predicate)),
+ .map(|clause| {
+ elaboratable.child(bound_predicate.rebind(clause).to_predicate(tcx))
+ }),
);
}
- ty::PredicateKind::TypeWellFormedFromEnv(..) => {
- // Nothing to elaborate
- }
ty::PredicateKind::Ambiguous => {}
ty::PredicateKind::AliasRelate(..) => {
// No
}
- ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => {
// Nothing to elaborate
}
}
@@ -400,7 +440,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
tcx.super_predicates_that_define_assoc_item((trait_ref.def_id(), assoc_name));
for (super_predicate, _) in super_predicates.predicates {
let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref);
- if let Some(binder) = subst_predicate.to_opt_poly_trait_pred() {
+ if let Some(binder) = subst_predicate.as_trait_clause() {
stack.push(binder.map_bound(|t| t.trait_ref));
}
}