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

correctly dedup ExistentialPredicates #73815

Closed
wants to merge 4 commits into from

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented Jun 27, 2020

fixes the underlying issue of the regression in #59326 and removes the stopgap added in #73485.

r? @nikomatsakis cc @estebank

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 27, 2020
#![feature(trait_alias)]

trait I32Iterator = Iterator<Item = i32>;

fn main() {
let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
//~^ ERROR type mismatch
Copy link
Contributor Author

@lcnr lcnr Jun 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test changes because ExistentialPredicate::stable_cmp doesn't actually look at its substs. This seems kind of incorrect to me 🤔

@@ -1814,7 +1815,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here we need to look for conflicting existential_projections and emit an error like E0271. I think the change to dedup below makes it consider two projections on the same associated type but with different values to be the same.

I would also imagine that if you try this code out you will also get a "successful" compilation.

Copy link
Contributor Author

@lcnr lcnr Jun 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also imagine that if you try this code out you will also get a "successful" compilation.

That code compiles correctly errors, added it as a test. I still fear that the current dedup ends up being unsound though 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what's happening. In the type test that is now passing we probably shouldn't allow people to override the type params that are set in the type, and error when that happens. @nikomatsakis might have better insight on what we should continue to do, but the more I look at how we treat type aliases the more I want to revamp them.

(I failed to publish this back on the 28th)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you think it's unsound?

Copy link
Contributor Author

@lcnr lcnr Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List<ExistentialPredicate> for dyn A + B previously was [Trait(A), Trait(B)] and this PR changes this to just [Trait(A)]. This made me slightly worried as I wasn't sure how we handle wf for trait objects.

I spend a bit more time looking at this and strongly believe that this PR is not concerning here
as we emit the errors before using stable_cmp, so anything we may "incorrectly" dedup here
already caused an error.

Added a comment summarizing my current understanding

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I guess I better look at how stable_cmp is defined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, yeah, this seems like not what I expected. =)

Copy link
Contributor Author

@lcnr lcnr Jul 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so I've rebased this, I think the current state is sound, if somewhat 👻 spooky 👻 Not
sure what's the least invasive way to clean this up though...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'll try to give useful feedback as soon as I can ...

@lcnr lcnr force-pushed the existential-pred branch 2 times, most recently from 93a48f6 to 7d09fdb Compare June 29, 2020 19:34
@bors
Copy link
Contributor

bors commented Jul 1, 2020

☔ The latest upstream changes (presumably #73924) made this pull request unmergeable. Please resolve the merge conflicts.

@bors
Copy link
Contributor

bors commented Jul 6, 2020

☔ The latest upstream changes (presumably #74073) made this pull request unmergeable. Please resolve the merge conflicts.

@crlf0710 crlf0710 added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 24, 2020
@crlf0710 crlf0710 added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 21, 2020
@bors
Copy link
Contributor

bors commented Aug 22, 2020

☔ The latest upstream changes (presumably #75797) made this pull request unmergeable. Please resolve the merge conflicts.

@crlf0710 crlf0710 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 12, 2020
@crlf0710
Copy link
Member

Ping from triage, there's merge conflicts now.

@lcnr
Copy link
Contributor Author

lcnr commented Sep 18, 2020

This is the only relevant test which fails if we check that stable_cmp doesn't remove unique predicates:

// check-pass
trait Service {
    type S;
}

trait Framing {
    type F;
}

impl Framing for () {
    type F = ();
}

trait HttpService<F: Framing>: Service<S = F::F> {}

type BoxService = Box<dyn HttpService<(), S = ()>>;

fn build_server<F: FnOnce() -> BoxService>(_: F) {}

fn make_server<F: Framing>() -> Box<dyn HttpService<F, S = F::F>> {
    unimplemented!()
}

fn main() {
    build_server(|| make_server())
}

It fails with

error: internal compiler error: unexpected existential predicates: ExistentialProjection { item_def_id: DefId(0:4 ~ issue_59326_compile_run[317d]::Service[0]::S[0]), substs: [], ty: <() as Framing>::F }, ExistentialProjection { item_def_id: DefId(0:4 ~ issue_59326_compile_run[317d]::Service[0]::S[0]), substs: [], ty: () }
   |
   = note: delayed at compiler/rustc_middle/src/ty/sty.rs:695:30

i.e. one of the predicates is not normalized enough.

Tbh I think that we should slowly start to emit a future compat lint and then error here, as dyn HttpService should not be able set the associated type of Service here IMO, considering that it is already set once by HttpService itself.

IMO we are getting dangerously close to being unsound here:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=20ba57f1c6c3bcca62b495a871ff3743

trait Foo {
    type F;
}

impl<T> Foo for T {
    type F = T;
}

trait Bar: Foo<F = u32> {}
impl<T: Foo<F = u32>> Bar for T {}

fn main() {
    let y: i32 = 7;
    let z: Box<dyn Bar<F = i32>> = Box::new(y);
}

luckily results in

error[E0271]: type mismatch resolving `<i32 as Foo>::F == u32`
  --> src/main.rs:14:36
   |
14 |     let z: Box<dyn Bar<F = i32>> = Box::new(y);
   |                                    ^^^^^^^^^^^ expected `u32`, found `i32`
   |
   = note: required for the cast to the object type `dyn Bar<F = i32, F = u32>`

@bors
Copy link
Contributor

bors commented Sep 20, 2020

☔ The latest upstream changes (presumably #76964) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@lcnr
Copy link
Contributor Author

lcnr commented Oct 6, 2020

closing this for now, I feel like we probably should instead try to change the way existential types are handled in a more fundamental way which means that keeping this PR open isn't really too helpful.

@lcnr lcnr closed this Oct 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants