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 handle normalization in implied bounds query #109482

Closed
wants to merge 4 commits into from

Conversation

aliemjay
Copy link
Member

@aliemjay aliemjay commented Mar 22, 2023

One subtle bug with the implied_outlives_bounds is that it adds implied bounds from trait impls. Example:

trait Trait { type Ty; }
impl<T: 'static> Trait for T { type Ty = (); }
// implied_outlives_bounds(Vec<<T as Trait>::Ty>) = [T: 'static,]
// note Vec<_> is necessary 

This is not a user-visible bug only because wfcheck currently computes implied bounds for fully normalized types only. (edit: this is not correct unfortunately. See #109628) The only place where we use implied bounds for unnormalized types during HIR analysis is in compare_predicate_entailment.

This PR fixes this by using wf::unnormalized_obligations instead of wf::obligations.

Fixes #109628.
Fixes #109799.

Additional changes :

  • rework to handle inference vars and normalization more explicitly and rigorously.
  • add implied bounds from the input types after normalization.

r? @lcnr

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Mar 22, 2023
@aliemjay aliemjay added T-types Relevant to the types team, which will review and decide on the PR/issue. A-implied-bounds Area: Implied bounds / inferred outlives-bounds and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 22, 2023
@lcnr
Copy link
Contributor

lcnr commented Mar 22, 2023

that's really cool 👍 i remember that we still have that issue during borrowck

use std::any::Any;

trait Trait {
    type Assoc;
}

impl<T: 'static> Trait for T {
    type Assoc = &'static T; 
}

fn implies_t_static<T>(t: T, x: <T as Trait>::Assoc) -> Box<dyn Any> {
    Box::new(t)
}

I forgot why exactly we had to add both the normalized and the unnormalized signature types for implied bounds, maybe that was also an issue solved by opportunistically resolving region vars in the query response?

why is this still a draft?

@lcnr lcnr 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 Mar 22, 2023
@aliemjay aliemjay force-pushed the implied-bounds-normalize branch 2 times, most recently from 5001a41 to 8e4a7e1 Compare March 23, 2023 02:52
@rust-log-analyzer

This comment has been minimized.

@aliemjay
Copy link
Member Author

aliemjay commented Mar 23, 2023

i remember that we still have that issue during borrowck

@lcnr I breaked this code in 00a80b0 only to assess the impact with crater. That said, this only breaks borrowck -- we still accept this in wfcheck:

trait Trait {
    type Assoc;
}

impl<T: 'static> Trait for Box<T> {
    type Assoc = &'static T; 
}

impl<T> Trait for (T, <Box<T> as Trait>::Assoc) {
    type Assoc = &'static T; // We can still assume T: 'static by wfcheck
}

@workingjubilee
Copy link
Member

@bors try

@bors
Copy link
Contributor

bors commented Mar 23, 2023

⌛ Trying commit 00a80b04fd4235d74626d6e7071e4c58803cbd2f with merge 78392dafb07418956e6952e68a24a94edd0c8dc6...

@bors
Copy link
Contributor

bors commented Mar 23, 2023

☀️ Try build successful - checks-actions
Build commit: 78392dafb07418956e6952e68a24a94edd0c8dc6 (78392dafb07418956e6952e68a24a94edd0c8dc6)

@lcnr
Copy link
Contributor

lcnr commented Mar 23, 2023

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-109482 created and queued.
🤖 Automatically detected try build 78392dafb07418956e6952e68a24a94edd0c8dc6
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Mar 23, 2023
@craterbot
Copy link
Collaborator

🚧 Experiment pr-109482 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Mar 23, 2023
@craterbot
Copy link
Collaborator

🎉 Experiment pr-109482 is completed!
📊 2002 regressed and 3 fixed (259262 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the blacklist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Mar 24, 2023
@bors
Copy link
Contributor

bors commented Mar 24, 2023

☀️ Try build successful - checks-actions
Build commit: 38d217432297792fdf0e298115e9fe95b714ee8f (38d217432297792fdf0e298115e9fe95b714ee8f)

@compiler-errors
Copy link
Member

@craterbot
Copy link
Collaborator

👌 Experiment pr-109482-1 created and queued.
🤖 Automatically detected try build 38d217432297792fdf0e298115e9fe95b714ee8f
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 25, 2023
@craterbot
Copy link
Collaborator

🚧 Experiment pr-109482-1 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-109482-1 is completed!
📊 428 regressed and 0 fixed (2002 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the blacklist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Mar 25, 2023
@lcnr lcnr added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Mar 27, 2023
@lcnr
Copy link
Contributor

lcnr commented Mar 27, 2023

We currently consider bounds only on impls used during normalization while computing implied bounds. This means that removing bounds on impls is a theoretical breaking change.

This PR causes us to only consider implied bounds which are from WF requirements directly and stops considering bounds from normalization. This allows users to safely remove (region) bounds from their impls.

The following code currently compiles but will break with this change:

use core::any::Any;

trait Trait {
    type Assoc;
}

impl<X: 'static> Trait for Vec<X> {
    type Assoc = ();
}

struct Foo<T: Trait>(T)
where
    T::Assoc: Clone; // any predicate using `T::Assoc` works here

fn foo<X>(x: X, _: Foo<Vec<X>>) -> Box<dyn Any> {
    Box::new(x) // gets to assume `X: 'static` from the bound on the impl
}

This is relied on by 2 crates:

This breakage is fixing a previously underspecified part of the language and is therefore acceptable. I think we should open PRs for both of these crates as soon as possible, fixing this issue. Maybe even asking the bevy devs to emit point releases for some previous versions, and then land this at the start of the next nightly cycle: April 14th.

going to start a types FCP after we have the PRs up to fix these 2 crates

@lcnr
Copy link
Contributor

lcnr commented Mar 27, 2023

alright, bevy is very annoying to fix. We would have to add 'static bounds to a lot of structs and that also leaks to crates using bevy, so users may also be required to add 'static.

Considering that region bounds on trait definitions are already used as implied bounds somewhere?

use std::any::Any;

trait Trait: 'static {}

fn foo<T: Trait>(x: T) -> Box<dyn Any> {
    Box::new(x)
}

Maybe we should apply this consistently to trait predicates in implied bounds, looking at the nested predicates of trait bounds and considering the outlives predicates... not sure why that isn't currently happening/what exactly is happening here.

With this we should only have to add a 'static bound to trait WorldQuery to bevy and get it implied everywhere else.

@lcnr lcnr 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 Mar 31, 2023
@aliemjay
Copy link
Member Author

aliemjay commented May 6, 2023

closing in favor of the lint version #109763.

@aliemjay aliemjay closed this May 6, 2023
@aliemjay aliemjay deleted the implied-bounds-normalize branch August 14, 2023 18:12
bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 28, 2023
…=<try>

 correctly handle normalization in implied bounds query v2

Revives rust-lang#109482. I've opened a new PR because Github doesn't allow me to reuse the old one.

Updated to refresh the toolchain build in order to test bevy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-implied-bounds Area: Implied bounds / inferred outlives-bounds needs-fcp This change is insta-stable, so needs a completed FCP to proceed. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-types Relevant to the types team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bounds on trait impls are used in implied bounds incomplete normalization in implied bounds
8 participants