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

[WIP] reject more impossible trivial bounds (HRTBs and trivial after normalization) #95611

Closed

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Apr 3, 2022

We really should be rejecting bounds that are global, even if they have higher-ranked lifetimes. We have the ability to prove whether for<'a> &'a mut String: Clone is true or not, so there's no reason to silently allow this to typecheck, especially because it's inconsistent with a non-HRTB like &'static mut String: Clone and is the source of ICEs

For now, though, just add a warning that it may be denied in the future.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 3, 2022
@compiler-errors
Copy link
Member Author

@bors try

@bors
Copy link
Contributor

bors commented Apr 3, 2022

⌛ Trying commit 2d05446c6dd15d6df2efbbbbd2e586666055b281 with merge eeb2054ba7aab4629538fba83b4971e554d70ee9...

@compiler-errors compiler-errors added the S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. label Apr 3, 2022
@rust-log-analyzer

This comment was marked as outdated.

@bors
Copy link
Contributor

bors commented Apr 3, 2022

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

@compiler-errors
Copy link
Member Author

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-95611 created and queued.
🤖 Automatically detected try build eeb2054ba7aab4629538fba83b4971e554d70ee9
🔍 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-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. labels Apr 3, 2022
@jackh726
Copy link
Member

jackh726 commented Apr 3, 2022

I don't think a crater run makes sense for just a warning. (It won't cause crates to not compile.)
If you want to know the impact, I would use an error for a crater run.

@compiler-errors
Copy link
Member Author

compiler-errors commented Apr 3, 2022

Good point. Totally forgot that this needs to filter out crates for the signal to be visible lol

@compiler-errors
Copy link
Member Author

@craterbot cancel

@craterbot
Copy link
Collaborator

🚨 Error: failed to parse the command

🆘 If you have any trouble with Crater please ping @rust-lang/infra!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@compiler-errors
Copy link
Member Author

@craterbot abort

@craterbot
Copy link
Collaborator

🗑️ Experiment pr-95611 deleted!

ℹ️ 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 Apr 3, 2022
@compiler-errors
Copy link
Member Author

@bors try

@bors
Copy link
Contributor

bors commented Apr 3, 2022

⌛ Trying commit e23c11b4384d3f6ab0f21ac0ca9e75febd006be2 with merge 751cdbaf3a893bc71b2c617bb7be22dfea5f0862...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Apr 3, 2022

☀️ Try build successful - checks-actions
Build commit: 751cdbaf3a893bc71b2c617bb7be22dfea5f0862 (751cdbaf3a893bc71b2c617bb7be22dfea5f0862)

@compiler-errors
Copy link
Member Author

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-95611 created and queued.
🤖 Automatically detected try build 751cdbaf3a893bc71b2c617bb7be22dfea5f0862
🔍 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 Apr 3, 2022
@craterbot
Copy link
Collaborator

🚧 Experiment pr-95611 is now running

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

@craterbot
Copy link
Collaborator

🎉 Experiment pr-95611 is completed!
📊 15 regressed and 5 fixed (223759 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 Apr 10, 2022
@compiler-errors
Copy link
Member Author

This crater run looks relatively clean. In fact, there are only a few relevant failure cases I could find.


The first is in utter-step/advent-utils:

pub fn parse_file<P, T>(p: P) -> Result<Vec<T>, Box<dyn Error>>
where
    P: AsRef<Path>,
    T: FromStr<Err = Box<dyn Error>>,
    <T as FromStr>::Err: Error + 'static,
{
    let contents = read_file(p)?;

    parse_raw_data(contents)
}

This is because Box<dyn Error> does not implement Error, so this method is un-callable. This trivial bound is only revealed when we normalize <T as FromStr>::Err: Error + 'static.


Another failure is in one of the amadeus tests. Specifically, one of the generated methods:

#[derive(Data, Clone, PartialEq, Serialize, Deserialize, Debug)]
struct Row {
	a: String,
	b: u64,
	c: f64,
	// d: List<Row>,
	e: List<Value>,
}

#[inline(always)]
fn hash_a<H>(&self, _state: &mut H)
where
    H: __::Hasher,
    for<'a> __::Wrapper<'a, Row>: __::Hash,
{ ... }

Is not satisfied because Wrapper<'a, T>: Hash only if T: Hash, and Row is not Hash (and, in fact, can't derive Hash because of the f64 member, lol).

This API isn't even fleshed out in the Amadeus API: constellation-rs/amadeus#69
(see: some functionality -- hashing -- isn't fully implemented)


The rest of the crates are due to derive macros hiding unsatisfisable for<'a> &'a Struct: diesel::Identifiable bound, since they have #[derive(Associations)], and the docs for the macro say:

Both the parent and child must implement Identifiable.

Adding derive(Identifiable) to those structs fixes the errors here. Again, we're probably unable to actually use this derived trait due to the bound being unsatisfiable.

@compiler-errors compiler-errors marked this pull request as ready for review April 10, 2022 22:32
@compiler-errors
Copy link
Member Author

r? @nikomatsakis (feel free to redirect)

Also, does this need T-lang sign-off?

@nikomatsakis
Copy link
Contributor

We really should be rejecting bounds that are global, even if they have higher-ranked lifetimes.

I'm somewhat surprised by this statement. I actually think the opposite! I expect us to move towards permitting any where-clause, no matter how nonsensical.

@compiler-errors
Copy link
Member Author

@nikomatsakis: Hm. I actually am a fan of warning the user early if their WC is nonsense, since except for macro-generated code, they're very unlikely to have written something like this. And even in macro-generated code, it sometimes reveals something that the user of the macro forgot to do, like implementing another trait they were required to implement in tandem with a derive.

It feels strange that the user would have to wait until the function/impl is used to receive feedback that their code is wrong, and somewhat inconsistent, too, since this only currently happens when HRTBs are involved.

but if not, then what's the alternative? like, should we be making the places that assume these bounds hold (after erasing lifetimes) fallible so they can bubble up errors when evaluated during codegen (or suppress them)? should we be avoiding generating MIR at all, since some MIR construction steps and optimizations ICE when given bounds like this?

Or maybe we should remove this delay_span_bug and be more careful about unwrapping the result from codegen_fulfill_obligation... 🤔

Anywho, I'd still like to fix ICEs like #94651 somehow, and remove special-casing from specific MIR optimizations like in #95398. Thoughts would be appreciated.

@nikomatsakis
Copy link
Contributor

@compiler-errors

Warning early is one thing, errors are another.

Note though that with approaches like this it might be less clear whether a where-clause is actually wrong.

@nikomatsakis
Copy link
Contributor

since this only currently happens when HRTBs are involved.

Yes, I would change that so that the code is always accepted. I do thing a warning is a good idea, just not hard errors.

@nikomatsakis
Copy link
Contributor

Anywho, I'd still like to fix ICEs like #94651 somehow, and remove special-casing from specific MIR optimizations like in #95398. Thoughts would be appreciated.

Now this is a good question! I'd like to dig into this a bit more. I agree we should not ICE! If I recall, was part of the problem having to do with MIR inlining into a context where those where clauses were not available? We talked about this at some point.

@compiler-errors
Copy link
Member Author

was part of the problem having to do with MIR inlining into a context where those where clauses were not available?

Not exactly. This is due to the fact when we have a WC like for<'a> &mut 'a (): Clone, then we try to use that to select &ReErased mut () in a RevealAll param-env, we fail a codegen_fulfill_obligation call, because the param-env gets removed due to this optimization that throws away the caller bounds.

And ICEs of this nature can show up in many different places. MIR inlining is one, but #95398 shows that it also manifests in the NoopMethodCall lint, the ConstProp MIR pass. In #94651, it's due to the MIR ElaborateDrops step. So it feels somewhat hacky to fix up all these spots, just for more to be added later.

@bors
Copy link
Contributor

bors commented Apr 30, 2022

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

@compiler-errors compiler-errors added S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 19, 2022
@pnkfelix
Copy link
Member

compiler-errors says that this is still in development and should be tagged as either S-experimental or S-blocked.

@rustbot label: -S-waiting-on-review +S-experimental

@pnkfelix pnkfelix changed the title reject more impossible trivial bounds (HRTBs and trivial after normalization) [WIP] reject more impossible trivial bounds (HRTBs and trivial after normalization) May 19, 2022
@pnkfelix pnkfelix marked this pull request as draft May 19, 2022 14:56
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Oct 4, 2022
…i-obk

Don't ICE when trying to copy unsized value in const prop

When we have a trivially false where-clause predicate like `Self: Sized` where `Self = dyn Trait`, we sometimes don't throw an error during typeck for an illegal operation such as copying an unsized type.

This, unfortunately, cannot be made into an error (at least not without some migration -- see rust-lang#95611 for example), but we should at least not ICE, since this function will never actually be reachable from main, for example.

r? `@RalfJung` since I think you added these assertions? but feel free to reassign.

Fixes rust-lang#102553
@compiler-errors compiler-errors deleted the hrtb-impossible branch August 11, 2023 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants