diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6460613d7d502..27f0b6bce38da 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -236,7 +236,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { freshener: infcx.freshener(), intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, - treat_inductive_cycle: TreatInductiveCycleAs::Recur, + treat_inductive_cycle: TreatInductiveCycleAs::Ambig, } } @@ -1620,16 +1620,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for bound in self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) { - // HACK: On subsequent recursions, we only care about bounds that don't + // HACK: In the initial recursion, we only care about bounds for the + // `self_ty`. On subsequent recursions, we care about bounds that don't // share the same type as `self_ty`. This is because for truly rigid // projections, we will never be able to equate, e.g. `::A` // with `<::A as Tr>::A`. - if in_parent_alias_type { - match bound.kind().skip_binder() { - ty::ClauseKind::Trait(tr) if tr.self_ty() == self_ty => continue, - ty::ClauseKind::Projection(p) if p.self_ty() == self_ty => continue, - _ => {} + match bound.kind().skip_binder() { + ty::ClauseKind::Trait(tr) + if (tr.self_ty() == self_ty) ^ !in_parent_alias_type => + { + continue; + } + ty::ClauseKind::Projection(p) + if (p.self_ty() == self_ty) ^ !in_parent_alias_type => + { + continue; } + _ => {} } for_each(self, bound, idx)?; diff --git a/tests/ui/marker_trait_attr/unsound-overlap.rs b/tests/ui/marker_trait_attr/unsound-overlap.rs index 2e5101b822c0c..2ce26b610f65d 100644 --- a/tests/ui/marker_trait_attr/unsound-overlap.rs +++ b/tests/ui/marker_trait_attr/unsound-overlap.rs @@ -8,6 +8,7 @@ trait B {} impl B for T {} impl A for T {} impl A for &str {} +//~^ ERROR type annotations needed: cannot satisfy `&str: A` impl A for (T,) {} trait TraitWithAssoc { type Assoc; diff --git a/tests/ui/marker_trait_attr/unsound-overlap.stderr b/tests/ui/marker_trait_attr/unsound-overlap.stderr index 5e58f5227ed61..13498fa4b2202 100644 --- a/tests/ui/marker_trait_attr/unsound-overlap.stderr +++ b/tests/ui/marker_trait_attr/unsound-overlap.stderr @@ -1,5 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `&str: A` + --> $DIR/unsound-overlap.rs:10:12 + | +LL | impl A for &str {} + | ^^^^ + | +note: multiple `impl`s satisfying `&str: A` found + --> $DIR/unsound-overlap.rs:9:1 + | +LL | impl A for T {} + | ^^^^^^^^^^^^^^^^^^ +LL | impl A for &str {} + | ^^^^^^^^^^^^^^^ + error[E0119]: conflicting implementations of trait `TraitWithAssoc` for type `((&str,),)` - --> $DIR/unsound-overlap.rs:20:1 + --> $DIR/unsound-overlap.rs:21:1 | LL | impl TraitWithAssoc for T { | ------------------------------- first implementation here @@ -7,6 +21,7 @@ LL | impl TraitWithAssoc for T { LL | impl TraitWithAssoc for ((&str,),) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `((&str,),)` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0119, E0283. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/issue-39448.rs b/tests/ui/specialization/issue-39448.rs index a15c4bd6b7ffc..1c8843d983a47 100644 --- a/tests/ui/specialization/issue-39448.rs +++ b/tests/ui/specialization/issue-39448.rs @@ -22,6 +22,7 @@ trait FromA { } impl> FromA for U { + //~^ ERROR cycle detected when computing whether impls specialize one another default fn from(x: T) -> Self { ToA::to(x) } @@ -42,7 +43,7 @@ where #[allow(dead_code)] fn foo(x: T, y: U) -> U { - x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement + x.foo(y.to()).to() } fn main() { diff --git a/tests/ui/specialization/issue-39448.stderr b/tests/ui/specialization/issue-39448.stderr index dc5db4f4285cd..e2c5f8c484689 100644 --- a/tests/ui/specialization/issue-39448.stderr +++ b/tests/ui/specialization/issue-39448.stderr @@ -8,28 +8,21 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -error[E0275]: overflow evaluating the requirement `T: FromA` - --> $DIR/issue-39448.rs:45:13 - | -LL | x.foo(y.to()).to() - | ^^ - | -note: required for `T` to implement `FromA` - --> $DIR/issue-39448.rs:24:29 +error[E0391]: cycle detected when computing whether impls specialize one another + --> $DIR/issue-39448.rs:24:1 | LL | impl> FromA for U { - | -------- ^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required for `U` to implement `ToA` - --> $DIR/issue-39448.rs:34:12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: ...which requires evaluating trait selection obligation `u16: FromA`... + = note: ...which again requires computing whether impls specialize one another, completing the cycle +note: cycle used when building specialization graph of trait `FromA` + --> $DIR/issue-39448.rs:20:1 | -LL | impl ToA for T - | ^^^^^^ ^ -LL | where -LL | U: FromA, - | -------- unsatisfied trait bound introduced here +LL | trait FromA { + | ^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/specialization/issue-39618.rs b/tests/ui/specialization/issue-39618.rs index 5b9b012e66531..14a6fcf572eae 100644 --- a/tests/ui/specialization/issue-39618.rs +++ b/tests/ui/specialization/issue-39618.rs @@ -2,8 +2,6 @@ // FIXME(JohnTitor): Centril pointed out this looks suspicions, we should revisit here. // More context: https://github.com/rust-lang/rust/pull/69192#discussion_r379846796 -//@ check-pass - #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Foo { @@ -19,6 +17,7 @@ impl Bar for T where T: Foo { } impl Foo for T where T: Bar { + //~^ ERROR cycle detected when computing whether impls specialize one another fn foo(&self) {} } diff --git a/tests/ui/specialization/issue-39618.stderr b/tests/ui/specialization/issue-39618.stderr index 19de60c7c1787..756162ce92c37 100644 --- a/tests/ui/specialization/issue-39618.stderr +++ b/tests/ui/specialization/issue-39618.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-39618.rs:7:12 + --> $DIR/issue-39618.rs:5:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,5 +8,21 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0391]: cycle detected when computing whether impls specialize one another + --> $DIR/issue-39618.rs:19:1 + | +LL | impl Foo for T where T: Bar { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: ...which requires evaluating trait selection obligation `u64: Bar`... + = note: ...which again requires computing whether impls specialize one another, completing the cycle +note: cycle used when building specialization graph of trait `Foo` + --> $DIR/issue-39618.rs:7:1 + | +LL | trait Foo { + | ^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error; 1 warning emitted +For more information about this error, try `rustc --explain E0391`.