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

Broken compilation with &(dyn Trait + '_) #103762

Open
Cerber-Ursi opened this issue Oct 30, 2022 · 7 comments
Open

Broken compilation with &(dyn Trait + '_) #103762

Cerber-Ursi opened this issue Oct 30, 2022 · 7 comments
Labels
A-lifetimes Area: Lifetimes / regions A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Cerber-Ursi
Copy link
Contributor

Cerber-Ursi commented Oct 30, 2022

Code

I tried this code:

pub trait AsStr {
    fn as_str(&self) -> &str;
}

fn foo(bar: &(dyn AsStr + '_)) -> &'_ str {
    bar.as_str()
}

I expected to see this happen: code compiles successfully.

Instead, this happened:

error[E0106]: missing lifetime specifier
 --> src/main.rs:5:36
  |
5 | fn foo(bar: &(dyn AsStr + '_)) -> &'_ str {
  |             -----------------      ^^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say which one of `bar`'s 2 lifetimes it is borrowed from
help: consider introducing a named lifetime parameter
  |
5 | fn foo<'a>(bar: &'a (dyn AsStr + 'a)) -> &'a str {
  |       ++++       ++              ~~       ~~

For more information about this error, try `rustc --explain E0106`.

Version it worked on

It most recently worked on Rust 1.63.0.

Version with regression

It is broken on current stable, i.e. 1.64.0.

Here's the output by cargo-bisect-rustc:

searched nightlies: from nightly-2022-06-24 to nightly-2022-08-05
regressed nightly: nightly-2022-07-15
searched commit range: 87588a2...c2f428d
regressed commit: f1a8854

bisected with cargo-bisect-rustc v0.6.4

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --end=1.64.0 -- check 

It seems to have been found previously by gluon developers and fixed in their own code in this commit, and today popped up also on URLO.

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged

@Cerber-Ursi Cerber-Ursi added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Oct 30, 2022
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-untriaged Untriaged performance or correctness regression. labels Oct 30, 2022
@csmoe
Copy link
Member

csmoe commented Oct 31, 2022

Seems related to #97720
cc @cjgillot

@apiraino
Copy link
Contributor

apiraino commented Nov 3, 2022

I think it's very close to #100615, so I'll close this as duplicate. Please feel free to reopen if it's not the case.

@apiraino apiraino closed this as completed Nov 3, 2022
@apiraino apiraino removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Nov 3, 2022
@apiraino
Copy link
Contributor

apiraino commented Nov 3, 2022

Reverting the decision because I misunderstood the context and assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-high

@rustbot rustbot added the P-high High priority label Nov 3, 2022
@apiraino apiraino reopened this Nov 3, 2022
@apiraino apiraino added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Nov 3, 2022
@BGR360
Copy link
Contributor

BGR360 commented Nov 7, 2022

Indeed, from what I can tell, it seems that #97720 regressed this. Specifically, this change here.

My understanding of this change is that it stopped pushing lifetime resolution in function signatures to typeck, and instead made it so that every occurrence of '_, &'_, or & in the function's inputs resulted in a "new" lifetime.

So I guess rustc used to think that the '_ in &(dyn AsStr + '_) was just referring to the same lifetime as the &. But now it is being treated the same way as, e.g., the second & in (a: &str, b: &str) would be treated.

It seems a little unfortunate that we ever accepted this. I say this because having &(dyn Trait + '_) doesn't really seem any different than &Type<'_> to me. Yet we never accepted the latter in previous versions of Rust:

struct Type<'a> { a: &'a () }

fn foo(_: &Type<'_>) -> &'_ str { loop {} }

fn main() {}
$ rustc +1.63.0 test.rs
error[E0106]: missing lifetime specifier
 --> test.rs:3:26
  |
3 | fn foo(_: &Type<'_>) -> &'_ str { loop {} }
  |           ---------      ^^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say which one of argument 1's 2 lifetimes it is borrowed from
help: consider introducing a named lifetime parameter
  |
3 | fn foo<'a>(_: &'a Type<'_>) -> &'a str { loop {} }
  |       ++++     ++               ~~

error: aborting due to previous error

I'm interested in trying to undo the regression, so I'll claim this. It seems like what I'd need to do is make the + '_ resolve the same way the -> &'_ str gets resolved. Unsure how hard that will be yet, I haven't spent much time in rustc_resolve yet.

But perhaps there's someone who thinks we should just let it regress?

@rustbot claim
@rustbot label +A-lifetimes +A-resolve

@rustbot rustbot added A-lifetimes Area: Lifetimes / regions A-resolve Area: Name/path resolution done by `rustc_resolve` specifically labels Nov 7, 2022
@cjgillot
Copy link
Contributor

cjgillot commented Nov 7, 2022

Note this other one is also broken:

pub trait AsStr {
    fn as_str(&self) -> &str;
}

fn foo(bar: &(AsStr + '_)) -> &'_ str {
    bar.as_str()
}

Both cases do not appear at the same place in rustc_resolve::late. These are not the same construct on the AST, even if they are on HIR.

@BGR360
Copy link
Contributor

BGR360 commented Nov 7, 2022

That's valid syntax?

@Cerber-Ursi
Copy link
Contributor Author

That's deprecated syntax, but it's valid, yes - Rust used to have just Trait where it currently has dyn Trait.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants