forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#126139 - compiler-errors:specializes, r=lcnr
Only compute `specializes` query if (min)specialization is enabled in the crate of the specializing impl Fixes (after backport) rust-lang#125197 ### What rust-lang#122791 makes it so that inductive cycles are no longer hard errors. That means that when we are testing, for example, whether these impls overlap: ```rust impl PartialEq<Self> for AnyId { fn eq(&self, _: &Self) -> bool { todo!() } } impl<T: Identifier> PartialEq<T> for AnyId { fn eq(&self, _: &T) -> bool { todo!() } } ``` ...given... ```rust pub trait Identifier: Display + 'static {} impl<T> Identifier for T where T: PartialEq + Display + 'static {} ``` Then we try to see if the second impl holds given `T = AnyId`. That requires `AnyId: Identifier`, which requires that `AnyId: PartialEq`, which is satisfied by these two impl candidates... The `PartialEq<T>` impl is a cycle, and we used to winnow it when we used to treat inductive cycles as errors. However, now that we don't winnow it, this means that we *now* try calling `candidate_should_be_dropped_in_favor_of`, which tries to check whether one of the impls specializes the other: the `specializes` query. In that query, we currently bail early if the impl is local. However, in a foreign crate, we try to compute if the two impls specialize each other by doing trait solving. This may itself lead to the same situation where we call `specializes`, which will lead to a query cycle. ### How does this fix the problem We now record whether specialization is enabled in foreign crates, and extend this early-return behavior to foreign impls too. This means that we can only encounter these cycles if we truly have a specializing impl from a crate with specialization enabled. ----- r? `@oli-obk` or `@lcnr`
- Loading branch information
Showing
9 changed files
with
81 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//@ aux-build: anyid-repro-125197.rs | ||
//@ check-pass | ||
|
||
// Makes sure that we don't check `specializes(impl1, impl2)` for a pair of impls that don't | ||
// actually participate in specialization. Since <https://github.com/rust-lang/rust/pull/122791>, | ||
// we don't treat inductive cycles as errors -- so we may need to winnow more pairs of impls, and | ||
// we try to winnow impls in favor of other impls. However, if we're *inside* the `specializes` | ||
// query, then may have a query cycle if we call `specializes` again! | ||
|
||
extern crate anyid_repro_125197; | ||
use anyid_repro_125197::AnyId; | ||
|
||
fn main() { | ||
let x = "hello, world"; | ||
let y: AnyId = x.into(); | ||
let _ = y == x; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use std::fmt::Display; | ||
use std::sync::Arc; | ||
|
||
pub struct AnyId(()); | ||
|
||
impl PartialEq<Self> for AnyId { | ||
fn eq(&self, _: &Self) -> bool { | ||
todo!() | ||
} | ||
} | ||
|
||
impl<T: Identifier> PartialEq<T> for AnyId { | ||
fn eq(&self, _: &T) -> bool { | ||
todo!() | ||
} | ||
} | ||
|
||
impl<T: Identifier> From<T> for AnyId { | ||
fn from(_: T) -> Self { | ||
todo!() | ||
} | ||
} | ||
|
||
pub trait Identifier: Display + 'static {} | ||
|
||
impl<T> Identifier for T where T: PartialEq + Display + 'static {} |