Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[crater only] Always make inductive cycles as ambig during typeck #116494

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -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. `<T as Tr>::A`
// with `<<T as Tr>::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)?;
Expand Down
1 change: 1 addition & 0 deletions tests/ui/marker_trait_attr/unsound-overlap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ trait B {}
impl<T: A> B for T {}
impl<T: B> A for T {}
impl A for &str {}
//~^ ERROR type annotations needed: cannot satisfy `&str: A`
impl<T: A + B> A for (T,) {}
trait TraitWithAssoc {
type Assoc;
Expand Down
21 changes: 18 additions & 3 deletions tests/ui/marker_trait_attr/unsound-overlap.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
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<T: B> 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<T: A> TraitWithAssoc for T {
| ------------------------------- first implementation here
...
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`.
3 changes: 2 additions & 1 deletion tests/ui/specialization/issue-39448.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ trait FromA<T> {
}

impl<T: A, U: A + FromA<T>> FromA<T> for U {
//~^ ERROR cycle detected when computing whether impls specialize one another
default fn from(x: T) -> Self {
ToA::to(x)
}
Expand All @@ -42,7 +43,7 @@ where

#[allow(dead_code)]
fn foo<T: A, U: A>(x: T, y: U) -> U {
x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement
x.foo(y.to()).to()
}

fn main() {
Expand Down
31 changes: 12 additions & 19 deletions tests/ui/specialization/issue-39448.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<U>`
--> $DIR/issue-39448.rs:45:13
|
LL | x.foo(y.to()).to()
| ^^
|
note: required for `T` to implement `FromA<U>`
--> $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<T: A, U: A + FromA<T>> FromA<T> for U {
| -------- ^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
note: required for `U` to implement `ToA<T>`
--> $DIR/issue-39448.rs:34:12
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: ...which requires evaluating trait selection obligation `u16: FromA<u8>`...
= 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<T, U> ToA<U> for T
| ^^^^^^ ^
LL | where
LL | U: FromA<T>,
| -------- unsatisfied trait bound introduced here
LL | trait FromA<T> {
| ^^^^^^^^^^^^^^
= 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`.
3 changes: 1 addition & 2 deletions tests/ui/specialization/issue-39618.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -19,6 +17,7 @@ impl<T> Bar for T where T: Foo {
}

impl<T> Foo for T where T: Bar {
//~^ ERROR cycle detected when computing whether impls specialize one another
fn foo(&self) {}
}

Expand Down
20 changes: 18 additions & 2 deletions tests/ui/specialization/issue-39618.stderr
Original file line number Diff line number Diff line change
@@ -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)]
| ^^^^^^^^^^^^^^
Expand All @@ -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<T> 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`.
Loading