From 2752e328c9696aa3f8f61046507392ecdedc6667 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Oct 2022 15:31:38 +0000 Subject: Allow opaque types in trait impl headers and rely on coherence to reject unsound cases --- compiler/rustc_trait_selection/src/traits/coherence.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_trait_selection/src') diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 3cf2959a9ff..ff013b761e3 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -18,7 +18,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::CRATE_HIR_ID; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; @@ -94,7 +94,7 @@ pub fn overlapping_impls<'tcx>( return None; } - let infcx = tcx.infer_ctxt().build(); + let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); let selcx = &mut SelectionContext::intercrate(&infcx); let overlaps = overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some(); @@ -105,7 +105,7 @@ pub fn overlapping_impls<'tcx>( // In the case where we detect an error, run the check again, but // this time tracking intercrate ambiguity causes for better // diagnostics. (These take time and can lead to false errors.) - let infcx = tcx.infer_ctxt().build(); + let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); let selcx = &mut SelectionContext::intercrate(&infcx); selcx.enable_tracking_intercrate_ambiguity_causes(); Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) -- cgit 1.4.1-3-g733a5 From 94fe30ff2fa39a912325121846074a659e8ec420 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Oct 2022 12:00:21 +0000 Subject: Treat different opaque types of the same def id as equal during coherence --- compiler/rustc_hir_analysis/src/check/dropck.rs | 4 ++ compiler/rustc_infer/src/infer/at.rs | 1 + compiler/rustc_infer/src/infer/combine.rs | 9 ++++ compiler/rustc_infer/src/infer/equate.rs | 4 ++ .../rustc_infer/src/infer/error_reporting/mod.rs | 4 ++ compiler/rustc_infer/src/infer/glb.rs | 4 ++ compiler/rustc_infer/src/infer/lub.rs | 4 ++ compiler/rustc_infer/src/infer/mod.rs | 29 +++++++++++++ compiler/rustc_infer/src/infer/nll_relate/mod.rs | 8 ++++ .../src/infer/outlives/test_type_match.rs | 5 +++ compiler/rustc_infer/src/infer/sub.rs | 5 +++ compiler/rustc_middle/src/ty/_match.rs | 5 +++ compiler/rustc_middle/src/ty/relate.rs | 28 ++++++++----- .../rustc_trait_selection/src/traits/coherence.rs | 10 +++-- .../rustc_trait_selection/src/traits/select/mod.rs | 48 ++++++---------------- .../impl_trait_for_same_tait.rs | 34 +++++++++++++++ .../impl_trait_for_same_tait.stderr | 30 ++++++++++++++ 17 files changed, 182 insertions(+), 50 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs create mode 100644 src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr (limited to 'compiler/rustc_trait_selection/src') diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index a74016e220e..923a55f705d 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -244,6 +244,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { self.tcx } + fn intercrate(&self) -> bool { + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 5ff3779fa14..2483ab724a4 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -81,6 +81,7 @@ impl<'tcx> InferCtxt<'tcx> { .normalize_fn_sig_for_diagnostic .as_ref() .map(|f| f.clone()), + intercrate: self.intercrate, } } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index c2552561c42..743e776d58c 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -521,6 +521,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } + + fn intercrate(&self) -> bool { + self.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } @@ -799,6 +804,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { self.infcx.tcx } + fn intercrate(&self) -> bool { + self.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 59728148a84..dca955778f8 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.fields.tcx() } + fn intercrate(&self) -> bool { + self.fields.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index d773aa5f1fc..8b14fe18fec 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2937,6 +2937,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { self.0.tcx } + fn intercrate(&self) -> bool { + self.0.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { // Unused, only for consts which we treat as always equal ty::ParamEnv::empty() diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 6ffefcb7a28..16a80a1a5d6 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -30,6 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { "Glb" } + fn intercrate(&self) -> bool { + self.fields.infcx.intercrate + } + fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index d6e56fcb7fd..ef6b7ebfeea 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -30,6 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { "Lub" } + fn intercrate(&self) -> bool { + self.fields.infcx.intercrate + } + fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b9ed6b28c22..fd4ca9365f9 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -337,6 +337,26 @@ pub struct InferCtxt<'tcx> { normalize_fn_sig_for_diagnostic: Option, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>, + + /// During coherence we have to assume that other crates may add + /// additional impls which we currently don't know about. + /// + /// To deal with this evaluation should be conservative + /// and consider the possibility of impls from outside this crate. + /// This comes up primarily when resolving ambiguity. Imagine + /// there is some trait reference `$0: Bar` where `$0` is an + /// inference variable. If `intercrate` is true, then we can never + /// say for sure that this reference is not implemented, even if + /// there are *no impls at all for `Bar`*, because `$0` could be + /// bound to some type that in a downstream crate that implements + /// `Bar`. + /// + /// Outside of coherence we set this to false because we are only + /// interested in types that the user could actually have written. + /// In other words, we consider `$0: Bar` to be unimplemented if + /// there is no type that the user could *actually name* that + /// would satisfy it. This avoids crippling inference, basically. + pub intercrate: bool, } /// See the `error_reporting` module for more details. @@ -554,6 +574,7 @@ pub struct InferCtxtBuilder<'tcx> { considering_regions: bool, normalize_fn_sig_for_diagnostic: Option, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>, + intercrate: bool, } pub trait TyCtxtInferExt<'tcx> { @@ -567,6 +588,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { defining_use_anchor: DefiningAnchor::Error, considering_regions: true, normalize_fn_sig_for_diagnostic: None, + intercrate: false, } } } @@ -583,6 +605,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } + pub fn intercrate(mut self) -> Self { + self.intercrate = true; + self + } + pub fn ignoring_regions(mut self) -> Self { self.considering_regions = false; self @@ -622,6 +649,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { defining_use_anchor, considering_regions, ref normalize_fn_sig_for_diagnostic, + intercrate, } = *self; InferCtxt { tcx, @@ -641,6 +669,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic .as_ref() .map(|f| f.clone()), + intercrate, } } } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 167a82d4499..6e846171d67 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -531,6 +531,10 @@ where self.infcx.tcx } + fn intercrate(&self) -> bool { + self.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.delegate.param_env() } @@ -898,6 +902,10 @@ where self.infcx.tcx } + fn intercrate(&self) -> bool { + self.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.delegate.param_env() } diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index a5c21f0fb9b..198e6b1d4f2 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -136,6 +136,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn tag(&self) -> &'static str { "Match" } + + fn intercrate(&self) -> bool { + false + } + fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index bd3c5780b89..2faf7db5b13 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -35,6 +35,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { fn tag(&self) -> &'static str { "Sub" } + + fn intercrate(&self) -> bool { + self.fields.infcx.intercrate + } + fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index e6aab30a150..bcf2058b9f0 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -36,6 +36,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } + + fn intercrate(&self) -> bool { + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 6d02551716e..1a9b959fb84 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -23,6 +23,8 @@ pub enum Cause { pub trait TypeRelation<'tcx>: Sized { fn tcx(&self) -> TyCtxt<'tcx>; + fn intercrate(&self) -> bool; + fn param_env(&self) -> ty::ParamEnv<'tcx>; /// Returns a static string we can use for printouts. @@ -562,16 +564,22 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( (&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs)) if a_def_id == b_def_id => { - let opt_variances = tcx.variances_of(a_def_id); - let substs = relate_substs_with_variances( - relation, - a_def_id, - opt_variances, - a_substs, - b_substs, - false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle - )?; - Ok(tcx.mk_opaque(a_def_id, substs)) + if relation.intercrate() { + // During coherence, opaque types should be treated as equal to each other, even if their generic params + // differ, as they could resolve to the same hidden type, even for different generic params. + Ok(a) + } else { + let opt_variances = tcx.variances_of(a_def_id); + let substs = relate_substs_with_variances( + relation, + a_def_id, + opt_variances, + a_substs, + b_substs, + false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle + )?; + Ok(tcx.mk_opaque(a_def_id, substs)) + } } _ => Err(TypeError::Sorts(expected_found(relation, a, b))), diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index ff013b761e3..8006af2a40f 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -94,8 +94,9 @@ pub fn overlapping_impls<'tcx>( return None; } - let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); - let selcx = &mut SelectionContext::intercrate(&infcx); + let infcx = + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build(); + let selcx = &mut SelectionContext::new(&infcx); let overlaps = overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some(); if !overlaps { @@ -105,8 +106,9 @@ pub fn overlapping_impls<'tcx>( // In the case where we detect an error, run the check again, but // this time tracking intercrate ambiguity causes for better // diagnostics. (These take time and can lead to false errors.) - let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); - let selcx = &mut SelectionContext::intercrate(&infcx); + let infcx = + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build(); + let selcx = &mut SelectionContext::new(&infcx); selcx.enable_tracking_intercrate_ambiguity_causes(); Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a9314b1b85e..87fcfdb33fc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -110,25 +110,6 @@ pub struct SelectionContext<'cx, 'tcx> { /// require themselves. freshener: TypeFreshener<'cx, 'tcx>, - /// During coherence we have to assume that other crates may add - /// additional impls which we currently don't know about. - /// - /// To deal with this evaluation should be conservative - /// and consider the possibility of impls from outside this crate. - /// This comes up primarily when resolving ambiguity. Imagine - /// there is some trait reference `$0: Bar` where `$0` is an - /// inference variable. If `intercrate` is true, then we can never - /// say for sure that this reference is not implemented, even if - /// there are *no impls at all for `Bar`*, because `$0` could be - /// bound to some type that in a downstream crate that implements - /// `Bar`. - /// - /// Outside of coherence we set this to false because we are only - /// interested in types that the user could actually have written. - /// In other words, we consider `$0: Bar` to be unimplemented if - /// there is no type that the user could *actually name* that - /// would satisfy it. This avoids crippling inference, basically. - intercrate: bool, /// If `intercrate` is set, we remember predicates which were /// considered ambiguous because of impls potentially added in other crates. /// This is used in coherence to give improved diagnostics. @@ -226,16 +207,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, freshener: infcx.freshener_keep_static(), - intercrate: false, intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, } } - pub fn intercrate(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> { - SelectionContext { intercrate: true, ..SelectionContext::new(infcx) } - } - pub fn with_query_mode( infcx: &'cx InferCtxt<'tcx>, query_mode: TraitQueryMode, @@ -247,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Enables tracking of intercrate ambiguity causes. See /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { - assert!(self.intercrate); + assert!(self.is_intercrate()); assert!(self.intercrate_ambiguity_causes.is_none()); self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); @@ -257,7 +233,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// was enabled and disables tracking at the same time. If /// tracking is not enabled, just returns an empty vector. pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet { - assert!(self.intercrate); + assert!(self.is_intercrate()); self.intercrate_ambiguity_causes.take().unwrap_or_default() } @@ -270,7 +246,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } pub fn is_intercrate(&self) -> bool { - self.intercrate + self.infcx.intercrate } /////////////////////////////////////////////////////////////////////////// @@ -751,7 +727,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: TraitObligation<'tcx>, ) -> Result { - if !self.intercrate + if !self.is_intercrate() && obligation.is_global() && obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst()) { @@ -1014,7 +990,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return None; } @@ -1044,7 +1020,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return; } @@ -1225,9 +1201,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { - debug!("is_knowable(intercrate={:?})", self.intercrate); + debug!("is_knowable(intercrate={:?})", self.is_intercrate()); - if !self.intercrate || stack.obligation.polarity() == ty::ImplPolarity::Negative { + if !self.is_intercrate() || stack.obligation.polarity() == ty::ImplPolarity::Negative { return Ok(()); } @@ -1258,7 +1234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the master cache. Since coherence executes pretty quickly, // it's not worth going to more trouble to increase the // hit-rate, I don't think. - if self.intercrate { + if self.is_intercrate() { return false; } @@ -1275,7 +1251,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return None; } let tcx = self.tcx(); @@ -1314,7 +1290,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return false; } match result { @@ -2192,7 +2168,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?; nested_obligations.extend(obligations); - if !self.intercrate + if !self.is_intercrate() && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation { debug!("reservation impls only apply in intercrate mode"); diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs new file mode 100644 index 00000000000..d942a268a7a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs @@ -0,0 +1,34 @@ +#![feature(type_alias_impl_trait)] + +trait Foo {} +impl Foo for () {} +impl Foo for i32 {} + +type Bar = impl std::fmt::Debug; +fn defining_use() -> Bar { + 42 +} + +trait Bop {} + +impl Bop for Bar<()> {} + +// If the hidden type is the same, this is effectively a second impl for the same type. +impl Bop for Bar {} +//~^ ERROR conflicting implementations + +type Barr = impl std::fmt::Debug; +fn defining_use2() -> Barr { + 42 +} + +// Even completely different opaque types must conflict. +impl Bop for Barr {} +//~^ ERROR conflicting implementations + +// And obviously the hidden type must conflict, too. +impl Bop for i32 {} +//~^ ERROR conflicting implementations + +fn main() { +} diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr new file mode 100644 index 00000000000..aaf75cc3db9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr @@ -0,0 +1,30 @@ +error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` + --> $DIR/impl_trait_for_same_tait.rs:17:1 + | +LL | impl Bop for Bar<()> {} + | -------------------- first implementation here +... +LL | impl Bop for Bar {} + | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` + +error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` + --> $DIR/impl_trait_for_same_tait.rs:26:1 + | +LL | impl Bop for Bar<()> {} + | -------------------- first implementation here +... +LL | impl Bop for Barr {} + | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` + +error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` + --> $DIR/impl_trait_for_same_tait.rs:30:1 + | +LL | impl Bop for Bar<()> {} + | -------------------- first implementation here +... +LL | impl Bop for i32 {} + | ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0119`. -- cgit 1.4.1-3-g733a5 From ae80c764d46a3c250a6cc41e5d2de5b8ed48567e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 2 Nov 2022 15:10:05 +0000 Subject: Add an always-ambiguous predicate to make sure that we don't accidentlally allow trait resolution to prove false things during coherence --- compiler/rustc_borrowck/src/type_check/relate_tys.rs | 7 +------ compiler/rustc_hir_analysis/src/check/dropck.rs | 4 ++++ .../src/impl_wf_check/min_specialization.rs | 1 + compiler/rustc_hir_analysis/src/outlives/explicit.rs | 1 + compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 + compiler/rustc_hir_typeck/src/method/probe.rs | 1 + .../rustc_infer/src/infer/canonical/query_response.rs | 7 +------ compiler/rustc_infer/src/infer/combine.rs | 18 ++++++++++++++++++ compiler/rustc_infer/src/infer/equate.rs | 4 ++++ compiler/rustc_infer/src/infer/error_reporting/mod.rs | 4 ++++ compiler/rustc_infer/src/infer/glb.rs | 4 ++++ compiler/rustc_infer/src/infer/lub.rs | 4 ++++ compiler/rustc_infer/src/infer/nll_relate/mod.rs | 15 ++++++++++----- compiler/rustc_infer/src/infer/outlives/mod.rs | 1 + .../rustc_infer/src/infer/outlives/test_type_match.rs | 4 ++++ compiler/rustc_infer/src/infer/sub.rs | 4 ++++ compiler/rustc_infer/src/traits/util.rs | 1 + compiler/rustc_lint/src/builtin.rs | 1 + compiler/rustc_middle/src/ty/_match.rs | 4 ++++ compiler/rustc_middle/src/ty/flags.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 8 ++++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 1 + compiler/rustc_middle/src/ty/relate.rs | 4 ++++ compiler/rustc_middle/src/ty/structural_impls.rs | 1 + .../rustc_trait_selection/src/traits/auto_trait.rs | 1 + .../src/traits/error_reporting/mod.rs | 2 ++ compiler/rustc_trait_selection/src/traits/fulfill.rs | 2 ++ .../rustc_trait_selection/src/traits/object_safety.rs | 2 ++ .../rustc_trait_selection/src/traits/select/mod.rs | 1 + compiler/rustc_trait_selection/src/traits/wf.rs | 2 ++ compiler/rustc_traits/src/chalk/lowering.rs | 4 ++++ compiler/rustc_traits/src/implied_outlives_bounds.rs | 1 + compiler/rustc_traits/src/normalize_erasing_regions.rs | 1 + src/librustdoc/clean/mod.rs | 1 + .../clippy/clippy_utils/src/qualify_min_const_fn.rs | 1 + 35 files changed, 102 insertions(+), 17 deletions(-) (limited to 'compiler/rustc_trait_selection/src') diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 94d51032866..45c6405d03a 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -2,7 +2,6 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{self, Const, Ty}; use rustc_span::Span; @@ -156,10 +155,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, '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.type_checker .fully_perform_op( self.locations, @@ -172,6 +168,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> }, ) .unwrap(); - Ok(()) } } diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 923a55f705d..e0b465bab16 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -260,6 +260,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 55cca0cd2d7..bae43138b4d 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } } diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index 7534482cce9..f0381353551 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -59,6 +59,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => (), } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b85a2325728..efce33bfe47 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -702,6 +702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // code is looking for a self type of an unresolved // inference variable. | ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, }, ) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 9d75ccad133..44c3edf06a8 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -803,6 +803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } }); diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 34f54328230..fb86fad8458 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -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(()) } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 743e776d58c..53a19f8e4ec 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -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( &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>( &mut self, _variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index dca955778f8..8682f4d3b7a 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -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, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8b14fe18fec..41e21efb212 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2954,6 +2954,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance>( &mut self, _variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 16a80a1a5d6..67f3e67e963 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -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>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index ef6b7ebfeea..1aaae714345 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -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>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 6e846171d67..be7b0bc6032 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -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>, - ) -> Result<(), TypeError<'tcx>>; + fn register_opaque_type_obligations(&mut self, obligations: Vec>); /// 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>( &mut self, @@ -918,6 +919,10 @@ where true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 2d19d1823fd..8f780579451 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -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)) diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 198e6b1d4f2..5d204dd70ed 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -151,6 +151,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { true } // irrelevant + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 2faf7db5b13..2c6987cc3f4 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -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(&mut self, cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index e12c069dcc1..b2a31ac7e6f 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -285,6 +285,7 @@ impl<'tcx> Elaborator<'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { // Nothing to elaborate } + ty::PredicateKind::Ambiguous => {} } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c2d0a662ddb..01a5ba65d8f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1659,6 +1659,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Coerce(..) | ConstEvaluatable(..) | ConstEquate(..) | + Ambiguous | TypeWellFormedFromEnv(..) => continue, }; if predicate.is_global() { diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index bcf2058b9f0..cd147d7e558 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -48,6 +48,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { true } // irrelevant + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 7201737be65..ee4b8f91c54 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -259,6 +259,7 @@ impl FlagComputation { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { self.add_ty(ty); } + ty::PredicateKind::Ambiguous => {} } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ffb4ad4db88..a4dddc17b6f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -619,6 +619,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Coerce(_) | PredicateKind::ConstEvaluatable(_) | PredicateKind::ConstEquate(_, _) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(_) => true, } } @@ -701,6 +702,10 @@ pub enum PredicateKind<'tcx> { /// /// Only used for Chalk. TypeWellFormedFromEnv(Ty<'tcx>), + + /// A marker predicate that is always ambiguous. + /// Used for coherence to mark opaque types as possibly equal to each other but ambiguous. + Ambiguous, } /// The crate outlives map is computed during typeck and contains the @@ -1181,6 +1186,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::TypeOutlives(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1199,6 +1205,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::TypeOutlives(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1217,6 +1224,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ClosureKind(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 023c9d26c42..4db4d57e26f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2703,6 +2703,7 @@ define_print_and_forward_display! { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { p!("the type `", print(ty), "` is found in the environment") } + ty::PredicateKind::Ambiguous => p!("ambiguous"), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 1a9b959fb84..3461ae870e4 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -34,6 +34,9 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; + /// Used during coherence. If called, must emit an always-ambiguous obligation. + fn mark_ambiguous(&mut self); + fn with_cause(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -567,6 +570,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( if relation.intercrate() { // During coherence, opaque types should be treated as equal to each other, even if their generic params // differ, as they could resolve to the same hidden type, even for different generic params. + relation.mark_ambiguous(); Ok(a) } else { let opt_variances = tcx.variances_of(a_def_id); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 9f0598d0ba8..18da620b298 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -173,6 +173,7 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { write!(f, "TypeWellFormedFromEnv({:?})", ty) } + ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"), } } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 5869bc76b59..0cd6ed88f00 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -843,6 +843,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => {} + ty::PredicateKind::Ambiguous => return false, }; } true diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c3547f64b5c..e4734d3d982 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1176,6 +1176,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } + ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"), + ty::PredicateKind::TypeWellFormedFromEnv(..) => span_bug!( span, "TypeWellFormedFromEnv predicate should only exist in the environment" diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index d84f768cce4..d238e7556ae 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -336,6 +336,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder)); ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)])) } + ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } @@ -569,6 +570,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } } + ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 9745e0137ee..db6f59ceebe 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -319,6 +319,7 @@ fn predicate_references_self<'tcx>( | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -350,6 +351,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => false, } }) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 87fcfdb33fc..ab9a0d57a4d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -717,6 +717,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for chalk") } + ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), } }) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d05e893de43..38bd3bc4322 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -155,6 +155,7 @@ pub fn predicate_obligations<'tcx>( wf.compute(c1.into()); wf.compute(c2.into()); } + ty::PredicateKind::Ambiguous => {} ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } @@ -878,6 +879,7 @@ pub(crate) fn required_region_bounds<'tcx>( | ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => { // Search for a bound of the form `erased_self_ty diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 25cedefa261..3e8bb9e575b 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -121,6 +121,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment bug!("unexpected predicate {}", predicate), }; let value = chalk_ir::ProgramClauseImplication { @@ -212,6 +213,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::ConstEquate(..) => { chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } @@ -625,6 +627,7 @@ impl<'tcx> LowerInto<'tcx, Option { bug!("unexpected predicate {}", &self) } @@ -754,6 +757,7 @@ impl<'tcx> LowerInto<'tcx, Option { bug!("unexpected predicate {}", &self) } diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 82f6111f6f9..2d1a3869926 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -97,6 +97,7 @@ fn compute_implied_outlives_bounds<'tcx>( | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::WellFormed(arg) => { wf_args.push(arg); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index f1835d317e8..5200908527a 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -66,6 +66,7 @@ fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => true, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c20595614b0..a49c631035b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -318,6 +318,7 @@ pub(crate) fn clean_predicate<'tcx>( | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"), } } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 45b63a4aa5d..b48bacb9ace 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -37,6 +37,7 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"), ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"), ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {predicate:#?}"), + ty::PredicateKind::Ambiguous => panic!("ambiguous predicate on function: {predicate:#?}"), } } match predicates.parent { -- cgit 1.4.1-3-g733a5