Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 94fe30f

Browse files
committed
Treat different opaque types of the same def id as equal during coherence
1 parent 2752e32 commit 94fe30f

File tree

17 files changed

+182
-50
lines changed

17 files changed

+182
-50
lines changed

compiler/rustc_hir_analysis/src/check/dropck.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
244244
self.tcx
245245
}
246246

247+
fn intercrate(&self) -> bool {
248+
false
249+
}
250+
247251
fn param_env(&self) -> ty::ParamEnv<'tcx> {
248252
self.param_env
249253
}

compiler/rustc_infer/src/infer/at.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl<'tcx> InferCtxt<'tcx> {
8181
.normalize_fn_sig_for_diagnostic
8282
.as_ref()
8383
.map(|f| f.clone()),
84+
intercrate: self.intercrate,
8485
}
8586
}
8687
}

compiler/rustc_infer/src/infer/combine.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
521521
fn tcx(&self) -> TyCtxt<'tcx> {
522522
self.infcx.tcx
523523
}
524+
525+
fn intercrate(&self) -> bool {
526+
self.infcx.intercrate
527+
}
528+
524529
fn param_env(&self) -> ty::ParamEnv<'tcx> {
525530
self.param_env
526531
}
@@ -799,6 +804,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
799804
self.infcx.tcx
800805
}
801806

807+
fn intercrate(&self) -> bool {
808+
self.infcx.intercrate
809+
}
810+
802811
fn param_env(&self) -> ty::ParamEnv<'tcx> {
803812
self.param_env
804813
}

compiler/rustc_infer/src/infer/equate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
3232
self.fields.tcx()
3333
}
3434

35+
fn intercrate(&self) -> bool {
36+
self.fields.infcx.intercrate
37+
}
38+
3539
fn param_env(&self) -> ty::ParamEnv<'tcx> {
3640
self.fields.param_env
3741
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,6 +2937,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
29372937
self.0.tcx
29382938
}
29392939

2940+
fn intercrate(&self) -> bool {
2941+
self.0.intercrate
2942+
}
2943+
29402944
fn param_env(&self) -> ty::ParamEnv<'tcx> {
29412945
// Unused, only for consts which we treat as always equal
29422946
ty::ParamEnv::empty()

compiler/rustc_infer/src/infer/glb.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
3030
"Glb"
3131
}
3232

33+
fn intercrate(&self) -> bool {
34+
self.fields.infcx.intercrate
35+
}
36+
3337
fn tcx(&self) -> TyCtxt<'tcx> {
3438
self.fields.tcx()
3539
}

compiler/rustc_infer/src/infer/lub.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
3030
"Lub"
3131
}
3232

33+
fn intercrate(&self) -> bool {
34+
self.fields.infcx.intercrate
35+
}
36+
3337
fn tcx(&self) -> TyCtxt<'tcx> {
3438
self.fields.tcx()
3539
}

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,26 @@ pub struct InferCtxt<'tcx> {
337337

338338
normalize_fn_sig_for_diagnostic:
339339
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
340+
341+
/// During coherence we have to assume that other crates may add
342+
/// additional impls which we currently don't know about.
343+
///
344+
/// To deal with this evaluation should be conservative
345+
/// and consider the possibility of impls from outside this crate.
346+
/// This comes up primarily when resolving ambiguity. Imagine
347+
/// there is some trait reference `$0: Bar` where `$0` is an
348+
/// inference variable. If `intercrate` is true, then we can never
349+
/// say for sure that this reference is not implemented, even if
350+
/// there are *no impls at all for `Bar`*, because `$0` could be
351+
/// bound to some type that in a downstream crate that implements
352+
/// `Bar`.
353+
///
354+
/// Outside of coherence we set this to false because we are only
355+
/// interested in types that the user could actually have written.
356+
/// In other words, we consider `$0: Bar` to be unimplemented if
357+
/// there is no type that the user could *actually name* that
358+
/// would satisfy it. This avoids crippling inference, basically.
359+
pub intercrate: bool,
340360
}
341361

342362
/// See the `error_reporting` module for more details.
@@ -554,6 +574,7 @@ pub struct InferCtxtBuilder<'tcx> {
554574
considering_regions: bool,
555575
normalize_fn_sig_for_diagnostic:
556576
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
577+
intercrate: bool,
557578
}
558579

559580
pub trait TyCtxtInferExt<'tcx> {
@@ -567,6 +588,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
567588
defining_use_anchor: DefiningAnchor::Error,
568589
considering_regions: true,
569590
normalize_fn_sig_for_diagnostic: None,
591+
intercrate: false,
570592
}
571593
}
572594
}
@@ -583,6 +605,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
583605
self
584606
}
585607

608+
pub fn intercrate(mut self) -> Self {
609+
self.intercrate = true;
610+
self
611+
}
612+
586613
pub fn ignoring_regions(mut self) -> Self {
587614
self.considering_regions = false;
588615
self
@@ -622,6 +649,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
622649
defining_use_anchor,
623650
considering_regions,
624651
ref normalize_fn_sig_for_diagnostic,
652+
intercrate,
625653
} = *self;
626654
InferCtxt {
627655
tcx,
@@ -641,6 +669,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
641669
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
642670
.as_ref()
643671
.map(|f| f.clone()),
672+
intercrate,
644673
}
645674
}
646675
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ where
531531
self.infcx.tcx
532532
}
533533

534+
fn intercrate(&self) -> bool {
535+
self.infcx.intercrate
536+
}
537+
534538
fn param_env(&self) -> ty::ParamEnv<'tcx> {
535539
self.delegate.param_env()
536540
}
@@ -898,6 +902,10 @@ where
898902
self.infcx.tcx
899903
}
900904

905+
fn intercrate(&self) -> bool {
906+
self.infcx.intercrate
907+
}
908+
901909
fn param_env(&self) -> ty::ParamEnv<'tcx> {
902910
self.delegate.param_env()
903911
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
136136
fn tag(&self) -> &'static str {
137137
"Match"
138138
}
139+
140+
fn intercrate(&self) -> bool {
141+
false
142+
}
143+
139144
fn tcx(&self) -> TyCtxt<'tcx> {
140145
self.tcx
141146
}

0 commit comments

Comments
 (0)