1
Fork 0

Add an always-ambiguous predicate to make sure that we don't accidentlally allow trait resolution to prove false things during coherence

This commit is contained in:
Oli Scherer 2022-11-02 15:10:05 +00:00
parent 94fe30ff2f
commit ae80c764d4
35 changed files with 102 additions and 17 deletions

View file

@ -23,7 +23,6 @@ use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec;
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
@ -741,11 +740,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
true
}
fn register_opaque_type_obligations(
&mut self,
obligations: PredicateObligations<'tcx>,
) -> Result<(), TypeError<'tcx>> {
fn register_opaque_type_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
self.obligations.extend(obligations);
Ok(())
}
}

View file

@ -450,6 +450,15 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
ty::Binder::dummy(predicate),
));
}
pub fn mark_ambiguous(&mut self) {
self.obligations.push(Obligation::new(
self.tcx(),
self.trace.cause.clone(),
self.param_env,
ty::Binder::dummy(ty::PredicateKind::Ambiguous),
));
}
}
struct Generalizer<'cx, 'tcx> {
@ -538,6 +547,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
true
}
fn mark_ambiguous(&mut self) {
// The generalizer always compares types against themselves,
// and thus doesn't really take part in coherence.
}
fn binders<T>(
&mut self,
a: ty::Binder<'tcx, T>,
@ -820,6 +834,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
true
}
fn mark_ambiguous(&mut self) {
bug!()
}
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_variance: ty::Variance,

View file

@ -44,6 +44,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
self.a_is_expected
}
fn mark_ambiguous(&mut self) {
self.fields.mark_ambiguous();
}
fn relate_item_substs(
&mut self,
_item_def_id: DefId,

View file

@ -2954,6 +2954,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
true
}
fn mark_ambiguous(&mut self) {
bug!()
}
fn relate_with_variance<T: relate::Relate<'tcx>>(
&mut self,
_variance: ty::Variance,

View file

@ -46,6 +46,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
self.a_is_expected
}
fn mark_ambiguous(&mut self) {
self.fields.mark_ambiguous();
}
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,

View file

@ -46,6 +46,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
self.a_is_expected
}
fn mark_ambiguous(&mut self) {
self.fields.mark_ambiguous();
}
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,

View file

@ -93,10 +93,7 @@ pub trait TypeRelatingDelegate<'tcx> {
);
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
fn register_opaque_type_obligations(
&mut self,
obligations: Vec<PredicateObligation<'tcx>>,
) -> Result<(), TypeError<'tcx>>;
fn register_opaque_type_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>);
/// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@ -419,7 +416,7 @@ where
.infcx
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
.obligations;
self.delegate.register_opaque_type_obligations(obligations)?;
self.delegate.register_opaque_type_obligations(obligations);
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
Ok(a)
}
@ -547,6 +544,10 @@ where
true
}
fn mark_ambiguous(&mut self) {
bug!()
}
#[instrument(skip(self, info), level = "trace", ret)]
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
@ -918,6 +919,10 @@ where
true
}
fn mark_ambiguous(&mut self) {
bug!()
}
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,

View file

@ -29,6 +29,7 @@ pub fn explicit_outlives_bounds<'tcx>(
| ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::Ambiguous
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
Some(OutlivesBound::RegionSubRegion(r_b, r_a))

View file

@ -151,6 +151,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
true
} // irrelevant
fn mark_ambiguous(&mut self) {
bug!()
}
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_: ty::Variance,

View file

@ -52,6 +52,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
self.a_is_expected
}
fn mark_ambiguous(&mut self) {
self.fields.mark_ambiguous()
}
fn with_cause<F, R>(&mut self, cause: Cause, f: F) -> R
where
F: FnOnce(&mut Self) -> R,

View file

@ -285,6 +285,7 @@ impl<'tcx> Elaborator<'tcx> {
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
// Nothing to elaborate
}
ty::PredicateKind::Ambiguous => {}
}
}
}