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

negative trait bounds give nonsense error #125297

Closed
lolbinarycat opened this issue May 19, 2024 · 4 comments
Closed

negative trait bounds give nonsense error #125297

lolbinarycat opened this issue May 19, 2024 · 4 comments
Labels
requires-internal-features This issue requires the use of internal features

Comments

@lolbinarycat
Copy link

I tried this code:

#![feature(negative_bounds)]

struct Foo<T> {
	v: T,
}

impl<T: SomeTrait + Default> Foo<T> {
	fn new() -> Self {
		Foo{ v: T::default() }
	}
}

trait SomeTrait: !SomeOtherTrait {}
trait SomeOtherTrait {}
impl SomeOtherTrait for u8 {}
impl<T: !SomeOtherTrait> SomeTrait for T {}

fn main() {
    let _ = Foo::<u8>::new();
}

I expected to see this happen: the code should build successfully.
Instead, this happened: nonsense compiler error

also note that if new() is not available due to any trait bounds, the compiler will recommend calling new().

Meta

rustc --version --verbose:

rustc 1.80.0-nightly (b1ec1bd65 2024-05-18)
binary: rustc
commit-hash: b1ec1bd65f89c1375d2cf2fb733a87ef390276d3
commit-date: 2024-05-18
host: x86_64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.4
Backtrace

   Compiling negative-bound-bug v0.1.0 (/home/binarycat/src/rs/negative-bound-bug)
warning: the feature `negative_bounds` is internal to the compiler or standard library
 --> src/main.rs:1:12
  |
1 | #![feature(negative_bounds)]
  |            ^^^^^^^^^^^^^^^
  |
  = note: using it is strongly discouraged
  = note: `#[warn(internal_features)]` on by default

error[E0599]: the function or associated item `new` exists for struct `Foo<u8>`, but its trait bounds were not satisfied
  --> src/main.rs:19:24
   |
3  | struct Foo<T> {
   | ------------- function or associated item `new` not found for this struct
...
19 |     let _ = Foo::<u8>::new();
   |                        ^^^ function or associated item cannot be called on `Foo<u8>` due to unsatisfied trait bounds
   |
note: if you're trying to build a new `Foo<u8>`, consider using `Foo::<T>::new` which returns `Foo<_>`
  --> src/main.rs:8:2
   |
8  |     fn new() -> Self {
   |     ^^^^^^^^^^^^^^^^
note: trait bound `u8: SomeOtherTrait` was not satisfied
  --> src/main.rs:16:9
   |
16 | impl<T: !SomeOtherTrait> SomeTrait for T {}
   |         ^^^^^^^^^^^^^^^  ---------     -
   |         |
   |         unsatisfied trait bound introduced here

For more information about this error, try `rustc --explain E0599`.
warning: `negative-bound-bug` (bin "negative-bound-bug") generated 1 warning
error: could not compile `negative-bound-bug` (bin "negative-bound-bug") due to 1 previous error; 1 warning emitted

@lolbinarycat lolbinarycat added the C-bug Category: This is a bug. label May 19, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 19, 2024
@fmease fmease added requires-internal-features This issue requires the use of internal features and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 20, 2024
@fmease
Copy link
Member

fmease commented May 20, 2024

Thank you for your report. Since negative_bounds is an internal feature as noted by the warning, I'll close this issue as not planned as per MCP 620.

@fmease fmease closed this as not planned Won't fix, can't repro, duplicate, stale May 20, 2024
@fmease
Copy link
Member

fmease commented May 20, 2024

To elaborate, we don't guarantee anything when internal features are “misused” in the broadest of senses of the word. This includes diagnostics.

@fmease
Copy link
Member

fmease commented May 20, 2024

However, if you're just curious about what's going on: Your code should in fact not compile since a negative trait bound T: !Trait doesn't denote the absence of a trait impl (it doesn't mean T doesn't impl Trait) but it denotes the presence of a negative trait impl under feature negative_impls (it means T impls Trait negatively).

The "fix" for your code would be the following: Playground (namely turning the positive SomeOtherTrait impl for u8 into a negative one).

@fmease
Copy link
Member

fmease commented May 20, 2024

I presume these are the steps taken by the trait solver (simplified):

  1. let _ = Foo::<u8>::new();: When confirming the assoc fn new, we need to prove the bounds on the impl (with Tu8), namely u8: Sized + SomeTrait + Default.
  2. We want to prove u8: SomeTrait via the user impl impl<T: !SomeOtherTrait> SomeTrait for T: This requires us to prove u8: !SomeOtherTrait
  3. u8: !SomeOtherTrait doesn't hold (only u8: SomeOtherTrait holds), we therefore reject this code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
requires-internal-features This issue requires the use of internal features
Projects
None yet
Development

No branches or pull requests

3 participants