Skip to content

Commit ae80c76

Browse files
committed
Add an always-ambiguous predicate to make sure that we don't accidentlally allow trait resolution to prove false things during coherence
1 parent 94fe30f commit ae80c76

File tree

35 files changed

+102
-17
lines changed

35 files changed

+102
-17
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
22
use rustc_infer::infer::NllRegionVariableOrigin;
33
use rustc_infer::traits::PredicateObligations;
44
use rustc_middle::mir::ConstraintCategory;
5-
use rustc_middle::ty::error::TypeError;
65
use rustc_middle::ty::relate::TypeRelation;
76
use rustc_middle::ty::{self, Const, Ty};
87
use rustc_span::Span;
@@ -156,10 +155,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
156155
true
157156
}
158157

159-
fn register_opaque_type_obligations(
160-
&mut self,
161-
obligations: PredicateObligations<'tcx>,
162-
) -> Result<(), TypeError<'tcx>> {
158+
fn register_opaque_type_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
163159
self.type_checker
164160
.fully_perform_op(
165161
self.locations,
@@ -172,6 +168,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
172168
},
173169
)
174170
.unwrap();
175-
Ok(())
176171
}
177172
}

compiler/rustc_hir_analysis/src/check/dropck.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
260260
true
261261
}
262262

263+
fn mark_ambiguous(&mut self) {
264+
bug!()
265+
}
266+
263267
fn relate_with_variance<T: Relate<'tcx>>(
264268
&mut self,
265269
_: ty::Variance,

compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>(
517517
| ty::PredicateKind::ClosureKind(..)
518518
| ty::PredicateKind::ConstEvaluatable(..)
519519
| ty::PredicateKind::ConstEquate(..)
520+
| ty::PredicateKind::Ambiguous
520521
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
521522
}
522523
}

compiler/rustc_hir_analysis/src/outlives/explicit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
5959
| ty::PredicateKind::Coerce(..)
6060
| ty::PredicateKind::ConstEvaluatable(..)
6161
| ty::PredicateKind::ConstEquate(..)
62+
| ty::PredicateKind::Ambiguous
6263
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
6364
}
6465
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
702702
// code is looking for a self type of an unresolved
703703
// inference variable.
704704
| ty::PredicateKind::ClosureKind(..)
705+
| ty::PredicateKind::Ambiguous
705706
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
706707
},
707708
)

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
803803
| ty::PredicateKind::TypeOutlives(..)
804804
| ty::PredicateKind::ConstEvaluatable(..)
805805
| ty::PredicateKind::ConstEquate(..)
806+
| ty::PredicateKind::Ambiguous
806807
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
807808
}
808809
});

compiler/rustc_infer/src/infer/canonical/query_response.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use rustc_index::vec::Idx;
2323
use rustc_index::vec::IndexVec;
2424
use rustc_middle::arena::ArenaAllocatable;
2525
use rustc_middle::mir::ConstraintCategory;
26-
use rustc_middle::ty::error::TypeError;
2726
use rustc_middle::ty::fold::TypeFoldable;
2827
use rustc_middle::ty::relate::TypeRelation;
2928
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
@@ -741,11 +740,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
741740
true
742741
}
743742

744-
fn register_opaque_type_obligations(
745-
&mut self,
746-
obligations: PredicateObligations<'tcx>,
747-
) -> Result<(), TypeError<'tcx>> {
743+
fn register_opaque_type_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
748744
self.obligations.extend(obligations);
749-
Ok(())
750745
}
751746
}

compiler/rustc_infer/src/infer/combine.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,15 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
450450
ty::Binder::dummy(predicate),
451451
));
452452
}
453+
454+
pub fn mark_ambiguous(&mut self) {
455+
self.obligations.push(Obligation::new(
456+
self.tcx(),
457+
self.trace.cause.clone(),
458+
self.param_env,
459+
ty::Binder::dummy(ty::PredicateKind::Ambiguous),
460+
));
461+
}
453462
}
454463

455464
struct Generalizer<'cx, 'tcx> {
@@ -538,6 +547,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
538547
true
539548
}
540549

550+
fn mark_ambiguous(&mut self) {
551+
// The generalizer always compares types against themselves,
552+
// and thus doesn't really take part in coherence.
553+
}
554+
541555
fn binders<T>(
542556
&mut self,
543557
a: ty::Binder<'tcx, T>,
@@ -820,6 +834,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
820834
true
821835
}
822836

837+
fn mark_ambiguous(&mut self) {
838+
bug!()
839+
}
840+
823841
fn relate_with_variance<T: Relate<'tcx>>(
824842
&mut self,
825843
_variance: ty::Variance,

compiler/rustc_infer/src/infer/equate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
4444
self.a_is_expected
4545
}
4646

47+
fn mark_ambiguous(&mut self) {
48+
self.fields.mark_ambiguous();
49+
}
50+
4751
fn relate_item_substs(
4852
&mut self,
4953
_item_def_id: DefId,

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2954,6 +2954,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
29542954
true
29552955
}
29562956

2957+
fn mark_ambiguous(&mut self) {
2958+
bug!()
2959+
}
2960+
29572961
fn relate_with_variance<T: relate::Relate<'tcx>>(
29582962
&mut self,
29592963
_variance: ty::Variance,

compiler/rustc_infer/src/infer/glb.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
4646
self.a_is_expected
4747
}
4848

49+
fn mark_ambiguous(&mut self) {
50+
self.fields.mark_ambiguous();
51+
}
52+
4953
fn relate_with_variance<T: Relate<'tcx>>(
5054
&mut self,
5155
variance: ty::Variance,

compiler/rustc_infer/src/infer/lub.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
4646
self.a_is_expected
4747
}
4848

49+
fn mark_ambiguous(&mut self) {
50+
self.fields.mark_ambiguous();
51+
}
52+
4953
fn relate_with_variance<T: Relate<'tcx>>(
5054
&mut self,
5155
variance: ty::Variance,

compiler/rustc_infer/src/infer/nll_relate/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,7 @@ pub trait TypeRelatingDelegate<'tcx> {
9393
);
9494

9595
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
96-
fn register_opaque_type_obligations(
97-
&mut self,
98-
obligations: Vec<PredicateObligation<'tcx>>,
99-
) -> Result<(), TypeError<'tcx>>;
96+
fn register_opaque_type_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>);
10097

10198
/// Creates a new universe index. Used when instantiating placeholders.
10299
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@@ -419,7 +416,7 @@ where
419416
.infcx
420417
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
421418
.obligations;
422-
self.delegate.register_opaque_type_obligations(obligations)?;
419+
self.delegate.register_opaque_type_obligations(obligations);
423420
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
424421
Ok(a)
425422
}
@@ -547,6 +544,10 @@ where
547544
true
548545
}
549546

547+
fn mark_ambiguous(&mut self) {
548+
bug!()
549+
}
550+
550551
#[instrument(skip(self, info), level = "trace", ret)]
551552
fn relate_with_variance<T: Relate<'tcx>>(
552553
&mut self,
@@ -918,6 +919,10 @@ where
918919
true
919920
}
920921

922+
fn mark_ambiguous(&mut self) {
923+
bug!()
924+
}
925+
921926
fn relate_with_variance<T: Relate<'tcx>>(
922927
&mut self,
923928
variance: ty::Variance,

compiler/rustc_infer/src/infer/outlives/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn explicit_outlives_bounds<'tcx>(
2929
| ty::PredicateKind::TypeOutlives(..)
3030
| ty::PredicateKind::ConstEvaluatable(..)
3131
| ty::PredicateKind::ConstEquate(..)
32+
| ty::PredicateKind::Ambiguous
3233
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
3334
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
3435
Some(OutlivesBound::RegionSubRegion(r_b, r_a))

compiler/rustc_infer/src/infer/outlives/test_type_match.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
151151
true
152152
} // irrelevant
153153

154+
fn mark_ambiguous(&mut self) {
155+
bug!()
156+
}
157+
154158
fn relate_with_variance<T: Relate<'tcx>>(
155159
&mut self,
156160
_: ty::Variance,

compiler/rustc_infer/src/infer/sub.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
5252
self.a_is_expected
5353
}
5454

55+
fn mark_ambiguous(&mut self) {
56+
self.fields.mark_ambiguous()
57+
}
58+
5559
fn with_cause<F, R>(&mut self, cause: Cause, f: F) -> R
5660
where
5761
F: FnOnce(&mut Self) -> R,

compiler/rustc_infer/src/traits/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ impl<'tcx> Elaborator<'tcx> {
285285
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
286286
// Nothing to elaborate
287287
}
288+
ty::PredicateKind::Ambiguous => {}
288289
}
289290
}
290291
}

compiler/rustc_lint/src/builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
16591659
Coerce(..) |
16601660
ConstEvaluatable(..) |
16611661
ConstEquate(..) |
1662+
Ambiguous |
16621663
TypeWellFormedFromEnv(..) => continue,
16631664
};
16641665
if predicate.is_global() {

compiler/rustc_middle/src/ty/_match.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
4848
true
4949
} // irrelevant
5050

51+
fn mark_ambiguous(&mut self) {
52+
bug!()
53+
}
54+
5155
fn relate_with_variance<T: Relate<'tcx>>(
5256
&mut self,
5357
_: ty::Variance,

compiler/rustc_middle/src/ty/flags.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ impl FlagComputation {
259259
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
260260
self.add_ty(ty);
261261
}
262+
ty::PredicateKind::Ambiguous => {}
262263
}
263264
}
264265

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ impl<'tcx> Predicate<'tcx> {
619619
| PredicateKind::Coerce(_)
620620
| PredicateKind::ConstEvaluatable(_)
621621
| PredicateKind::ConstEquate(_, _)
622+
| PredicateKind::Ambiguous
622623
| PredicateKind::TypeWellFormedFromEnv(_) => true,
623624
}
624625
}
@@ -701,6 +702,10 @@ pub enum PredicateKind<'tcx> {
701702
///
702703
/// Only used for Chalk.
703704
TypeWellFormedFromEnv(Ty<'tcx>),
705+
706+
/// A marker predicate that is always ambiguous.
707+
/// Used for coherence to mark opaque types as possibly equal to each other but ambiguous.
708+
Ambiguous,
704709
}
705710

706711
/// The crate outlives map is computed during typeck and contains the
@@ -1181,6 +1186,7 @@ impl<'tcx> Predicate<'tcx> {
11811186
| PredicateKind::TypeOutlives(..)
11821187
| PredicateKind::ConstEvaluatable(..)
11831188
| PredicateKind::ConstEquate(..)
1189+
| PredicateKind::Ambiguous
11841190
| PredicateKind::TypeWellFormedFromEnv(..) => None,
11851191
}
11861192
}
@@ -1199,6 +1205,7 @@ impl<'tcx> Predicate<'tcx> {
11991205
| PredicateKind::TypeOutlives(..)
12001206
| PredicateKind::ConstEvaluatable(..)
12011207
| PredicateKind::ConstEquate(..)
1208+
| PredicateKind::Ambiguous
12021209
| PredicateKind::TypeWellFormedFromEnv(..) => None,
12031210
}
12041211
}
@@ -1217,6 +1224,7 @@ impl<'tcx> Predicate<'tcx> {
12171224
| PredicateKind::ClosureKind(..)
12181225
| PredicateKind::ConstEvaluatable(..)
12191226
| PredicateKind::ConstEquate(..)
1227+
| PredicateKind::Ambiguous
12201228
| PredicateKind::TypeWellFormedFromEnv(..) => None,
12211229
}
12221230
}

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,6 +2703,7 @@ define_print_and_forward_display! {
27032703
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
27042704
p!("the type `", print(ty), "` is found in the environment")
27052705
}
2706+
ty::PredicateKind::Ambiguous => p!("ambiguous"),
27062707
}
27072708
}
27082709

compiler/rustc_middle/src/ty/relate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ pub trait TypeRelation<'tcx>: Sized {
3434
/// relation. Just affects error messages.
3535
fn a_is_expected(&self) -> bool;
3636

37+
/// Used during coherence. If called, must emit an always-ambiguous obligation.
38+
fn mark_ambiguous(&mut self);
39+
3740
fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
3841
where
3942
F: FnOnce(&mut Self) -> R,
@@ -567,6 +570,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
567570
if relation.intercrate() {
568571
// During coherence, opaque types should be treated as equal to each other, even if their generic params
569572
// differ, as they could resolve to the same hidden type, even for different generic params.
573+
relation.mark_ambiguous();
570574
Ok(a)
571575
} else {
572576
let opt_variances = tcx.variances_of(a_def_id);

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
173173
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
174174
write!(f, "TypeWellFormedFromEnv({:?})", ty)
175175
}
176+
ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
176177
}
177178
}
178179
}

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
843843
| ty::PredicateKind::ConstEvaluatable(..)
844844
| ty::PredicateKind::Coerce(..)
845845
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
846+
ty::PredicateKind::Ambiguous => return false,
846847
};
847848
}
848849
true

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
11761176
)
11771177
}
11781178

1179+
ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"),
1180+
11791181
ty::PredicateKind::TypeWellFormedFromEnv(..) => span_bug!(
11801182
span,
11811183
"TypeWellFormedFromEnv predicate should only exist in the environment"

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
336336
ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
337337
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
338338
}
339+
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
339340
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
340341
bug!("TypeWellFormedFromEnv is only used for Chalk")
341342
}
@@ -569,6 +570,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
569570
}
570571
}
571572
}
573+
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
572574
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
573575
bug!("TypeWellFormedFromEnv is only used for Chalk")
574576
}

0 commit comments

Comments
 (0)