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 impls cause problems with type inference #74383

Closed
lcnr opened this issue Jul 15, 2020 · 4 comments
Closed

negative impls cause problems with type inference #74383

lcnr opened this issue Jul 15, 2020 · 4 comments
Labels
A-inference Area: Type inference C-bug Category: This is a bug. F-negative_impls #![feature(negative_impls)] requires-nightly This issue requires a nightly compiler in some way.

Comments

@lcnr
Copy link
Contributor

lcnr commented Jul 15, 2020

#![feature(negative_impls)]

struct Foo<T>(T);

impl !Send for Foo<()> {}

fn test<T>() -> T where Foo<T>: Send { todo!() }

fn main() {
    let _: u8 = test();
}

Fails with

error[E0277]: `Foo<_>` cannot be sent between threads safely
  --> $DIR/fk.rs:10:17
   |
LL | fn test<T>() -> T where Foo<T>: Send { todo!() }
   |                                 ---- required by this bound in `test`
...
LL |     let _: u8 = test();
   |                 ^^^^ `Foo<_>` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `Foo<_>`

Explicitly specifying test::<u8>() works though.

@lcnr lcnr added A-inference Area: Type inference C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. F-negative_impls #![feature(negative_impls)] labels Jul 15, 2020
@eddyb
Copy link
Member

eddyb commented Jul 15, 2020

cc @nikomatsakis @matthewjasper (I suspect this might actually be expected, but I'm not sure)

@lcnr
Copy link
Contributor Author

lcnr commented Jul 16, 2020

Treat negative impls as unimplemented, and reservation impls as ambiguity.

Seems like this is caused by a mixture of

// Auto implementations have lower priority, so we only
// consider triggering a default if there is no other impl that can apply.
if candidates.vec.is_empty() {
self.assemble_candidates_from_auto_impls(obligation, &mut candidates)?;
}

and
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
fn filter_negative_and_reservation_impls(
&mut self,
candidate: SelectionCandidate<'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {

We might be able to deal with this by also updating candidate_should_be_dropped_in_favor_of.
Let's see if the current behavior is expected before looking deeper into this.

@nikomatsakis
Copy link
Contributor

Hmm I don't think this is expected, though I still don't quite understand how it happens.

@lcnr
Copy link
Contributor Author

lcnr commented Jul 21, 2020

closing as intended behavior, see #74525 (comment) for more details

It looks to me like preventing the impl for Foo<()> is directly tracked in #13231.

@lcnr lcnr closed this as completed Jul 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference C-bug Category: This is a bug. F-negative_impls #![feature(negative_impls)] requires-nightly This issue requires a nightly compiler in some way.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants