-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Diagnostic forgets about transitive trait bounds when there are multiple candidate impls. #90665
Comments
Okay actually I think this has nothing to do with auto traits and is entirely the fault of min_specialization. If we transform the original example to use a trait bound on a non-auto trait like Before adding a specializing impl (playground): #![feature(min_specialization)]
#![feature(rustc_attrs)]
use std::fmt::Display;
#[rustc_specialization_trait]
trait Special {}
trait Foo {
fn foo(&self);
}
impl<T: Display> Foo for T {
default fn foo(&self) {
println!("foo: {self}");
}
}
fn main() {
let vec = vec![1, 2, 3];
Foo::foo(&vec);
}
After adding a specializing impl (playground): #![feature(min_specialization)]
#![feature(rustc_attrs)]
use std::fmt::Display;
#[rustc_specialization_trait]
trait Special {}
trait Foo {
fn foo(&self);
}
impl<T: Display> Foo for T {
default fn foo(&self) {
println!("foo: {self}");
}
}
impl<T: Display + Special> Foo for T {
fn foo(&self) {
println!("special foo: {self}");
}
}
fn main() {
let vec = vec![1, 2, 3];
Foo::foo(&vec);
}
@rustbot label -F-auto_traits |
I think I've narrowed down the cause to this part of rust/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs Lines 140 to 156 in 88a1922
This is inside of So the problem isn't inherent to specialization. Rather, any time there is more than one candidate impl for an obligation, we will fail to give the more helpful error message. We can reproduce this without specialization by using a trait with a generic parameter. With only one candidate impl, the error message is helpful (playground): trait Foo<T> {
fn foo();
}
trait Bound {}
impl<T: Bound> Foo<u32> for T {
fn foo() {
println!("u32 foo");
}
}
fn main() {
<() as Foo<_>>::foo();
}
But with two candidate impls, the error message is not as helpful (playground): trait Foo<T> {
fn foo();
}
trait Bound {}
impl<T: Bound> Foo<u32> for T {
fn foo() {
println!("u32 foo");
}
}
impl<T: Bound> Foo<u64> for T {
fn foo() {
println!("u64 foo");
}
}
fn main() {
<() as Foo<_>>::foo();
}
|
I would love some help coming up with a plan for how to improve this. I'm thinking I could do one of two things:
Or perhaps a secret third option where the trait selection cache is able to cache a set of candidates for an obligation. |
@BGR360 Hey there, I'd like to come and help with this task, but I'm not quite sure how to start, is there some documentation about this module, or rfc of related functions that I can quickly understand. |
Hi @devillove084. Have you read that Zulip thread? The consensus seemed to be that we maybe shouldn't poke at it too much quite yet:
See also #103911 |
@BGR360 Yes, I did read what you said, and I decided to try to modify it according to what was said. |
EDIT this was originally reported as a problem specific to auto-traits, but I don't think it actually is. See the comment below.
EDIT 2: It's actually not specific to specialization either. See this comment
This is spun off from #90601.
Given the following code (playground):
The current (good) output is:
But if you add a specialized impl of
Foo
(playground):Then the error message loses all of the information regarding the unimplemented auto trait:
So there is something about the presence of a specialized impl that causes trait selection to not know that there's an unimplemented auto trait obligation. I have confirmed this by exploring the debug logging of rustc a little bit:
If you take a look at Example 4 in #90601, you can see that this can result in detrimentally unhelpful error messages in more complex cases.
cc #13231 #31844 #68970
@rustbot label +A-specialization +A-traits +D-confusing +D-terse +F-auto_traits +F-specialization
The text was updated successfully, but these errors were encountered: