summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/nll_relate/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/nll_relate/mod.rs')
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs111
1 files changed, 32 insertions, 79 deletions
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index f235cb5ab..573cd91a2 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -21,26 +21,21 @@
//! thing we relate in chalk are basically domain goals and their
//! constituents)
-use crate::infer::combine::ConstEquateRelation;
use crate::infer::InferCtxt;
use crate::infer::{ConstVarValue, ConstVariableValue};
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
-use crate::traits::{Obligation, PredicateObligation};
+use crate::traits::{Obligation, PredicateObligations};
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
use std::fmt::Debug;
use std::ops::ControlFlow;
-#[derive(PartialEq)]
-pub enum NormalizationStrategy {
- Lazy,
- Eager,
-}
+use super::combine::ObligationEmittingRelation;
pub struct TypeRelating<'me, 'tcx, D>
where
@@ -55,7 +50,7 @@ where
///
/// - Covariant means `a <: b`.
/// - Contravariant means `b <: a`.
- /// - Invariant means `a == b.
+ /// - Invariant means `a == b`.
/// - Bivariant means that it doesn't matter.
ambient_variance: ty::Variance,
@@ -92,7 +87,7 @@ pub trait TypeRelatingDelegate<'tcx> {
info: ty::VarianceDiagInfo<'tcx>,
);
- fn register_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>);
+ fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>);
/// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@@ -105,7 +100,11 @@ pub trait TypeRelatingDelegate<'tcx> {
/// we will invoke this method to instantiate `'a` with an
/// inference variable (though `'b` would be instantiated first,
/// as a placeholder).
- fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>;
+ fn next_existential_region_var(
+ &mut self,
+ was_placeholder: bool,
+ name: Option<Symbol>,
+ ) -> ty::Region<'tcx>;
/// Creates a new region variable representing a
/// higher-ranked region that is instantiated universally.
@@ -125,9 +124,6 @@ pub trait TypeRelatingDelegate<'tcx> {
/// relation stating that `'?0: 'a`).
fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
- /// Define the normalization strategy to use, eager or lazy.
- fn normalization() -> NormalizationStrategy;
-
/// Enables some optimizations if we do not expect inference variables
/// in the RHS of the relation.
fn forbid_inference_vars() -> bool;
@@ -196,7 +192,7 @@ where
let placeholder = ty::PlaceholderRegion { universe, name: br.kind };
delegate.next_placeholder_region(placeholder)
} else {
- delegate.next_existential_region_var(true)
+ delegate.next_existential_region_var(true, br.kind.get_name())
}
}
};
@@ -265,38 +261,6 @@ where
self.delegate.push_outlives(sup, sub, info);
}
- /// Relate a projection type and some value type lazily. This will always
- /// succeed, but we push an additional `ProjectionEq` goal depending
- /// on the value type:
- /// - if the value type is any type `T` which is not a projection, we push
- /// `ProjectionEq(projection = T)`.
- /// - if the value type is another projection `other_projection`, we create
- /// a new inference variable `?U` and push the two goals
- /// `ProjectionEq(projection = ?U)`, `ProjectionEq(other_projection = ?U)`.
- fn relate_projection_ty(
- &mut self,
- projection_ty: ty::AliasTy<'tcx>,
- value_ty: Ty<'tcx>,
- ) -> Ty<'tcx> {
- use rustc_span::DUMMY_SP;
-
- match *value_ty.kind() {
- ty::Alias(ty::Projection, other_projection_ty) => {
- let var = self.infcx.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::MiscVariable,
- span: DUMMY_SP,
- });
- // FIXME(lazy-normalization): This will always ICE, because the recursive
- // call will end up in the _ arm below.
- self.relate_projection_ty(projection_ty, var);
- self.relate_projection_ty(other_projection_ty, var);
- var
- }
-
- _ => bug!("should never be invoked with eager normalization"),
- }
- }
-
/// Relate a type inference variable with a value type. This works
/// by creating a "generalization" G of the value where all the
/// lifetimes are replaced with fresh inference values. This
@@ -335,12 +299,6 @@ where
return Ok(value_ty);
}
- ty::Alias(ty::Projection, projection_ty)
- if D::normalization() == NormalizationStrategy::Lazy =>
- {
- return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
- }
-
_ => (),
}
@@ -627,18 +585,6 @@ where
self.relate_opaques(a, b)
}
- (&ty::Alias(ty::Projection, projection_ty), _)
- if D::normalization() == NormalizationStrategy::Lazy =>
- {
- Ok(self.relate_projection_ty(projection_ty, b))
- }
-
- (_, &ty::Alias(ty::Projection, projection_ty))
- if D::normalization() == NormalizationStrategy::Lazy =>
- {
- Ok(self.relate_projection_ty(projection_ty, a))
- }
-
_ => {
debug!(?a, ?b, ?self.ambient_variance);
@@ -663,13 +609,13 @@ where
debug!(?v_b);
if self.ambient_covariance() {
- // Covariance: a <= b. Hence, `b: a`.
- self.push_outlives(v_b, v_a, self.ambient_variance_info);
+ // Covariant: &'a u8 <: &'b u8. Hence, `'a: 'b`.
+ self.push_outlives(v_a, v_b, self.ambient_variance_info);
}
if self.ambient_contravariance() {
- // Contravariant: b <= a. Hence, `a: b`.
- self.push_outlives(v_a, v_b, self.ambient_variance_info);
+ // Contravariant: &'b u8 <: &'a u8. Hence, `'b: 'a`.
+ self.push_outlives(v_b, v_a, self.ambient_variance_info);
}
Ok(a)
@@ -813,16 +759,23 @@ where
}
}
-impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>
+impl<'tcx, D> ObligationEmittingRelation<'tcx> for TypeRelating<'_, 'tcx, D>
where
D: TypeRelatingDelegate<'tcx>,
{
- fn const_equate_obligation(&mut self, _a: ty::Const<'tcx>, _b: ty::Const<'tcx>) {
- // We don't have to worry about the equality of consts during borrow checking
- // as consts always have a static lifetime.
- // FIXME(oli-obk): is this really true? We can at least have HKL and with
- // inline consts we may have further lifetimes that may be unsound to treat as
- // 'static.
+ fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
+ self.delegate.register_obligations(
+ obligations
+ .into_iter()
+ .map(|to_pred| {
+ Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred)
+ })
+ .collect(),
+ );
+ }
+
+ fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
+ self.delegate.register_obligations(obligations);
}
}
@@ -840,8 +793,8 @@ struct ScopeInstantiator<'me, 'tcx> {
bound_region_scope: &'me mut BoundRegionScope<'tcx>,
}
-impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
- fn visit_binder<T: TypeVisitable<'tcx>>(
+impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> {
+ fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
&mut self,
t: &ty::Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {