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

Missing dyn keyword in bare_trait_objects with Rust 2015 edition produces faulty error instead of warnings #98726

Closed
yanchen4791 opened this issue Jun 30, 2022 · 7 comments · Fixed by #98637
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. P-critical Critical priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@yanchen4791
Copy link
Contributor

yanchen4791 commented Jun 30, 2022

Code

I tried this code with edition = "2015":

fn a<F>(_f: F) where F: FnMut(&i32) {}

fn b<F>(_f: F) where F: FnMut(&mut FnMut(&i32)) {}

fn main()
{
    b(|f| {
        a(|v| f(v))
    });
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2015&gist=40892217ad5a83b67570be18e19a43c4

I expected to see only warning without error, like this:

warning: trait objects without an explicit `dyn` are deprecated
 --> src/main.rs:3:36
  |
3 | fn b<F>(_f: F) where F: FnMut(&mut FnMut(&i32)) {}
  |                                    ^^^^^^^^^^^
  |
  = note: `#[warn(bare_trait_objects)]` on by default
  = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
  = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
  |
3 - fn b<F>(_f: F) where F: FnMut(&mut FnMut(&i32)) {}
3 + fn b<F>(_f: F) where F: FnMut(&mut dyn FnMut(&i32)) {}
  | 

warning: `playground` (bin "playground") generated 1 warning

Instead, this happened (extra error E0521 emitted, which is incorrect):

warning: trait objects without an explicit `dyn` are deprecated
 --> src/main.rs:3:36
  |
3 | fn b<F>(_f: F) where F: FnMut(&mut FnMut(&i32)) {}
  |                                    ^^^^^^^^^^^
  |
  = note: `#[warn(bare_trait_objects)]` on by default
  = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
  = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
  |
3 - fn b<F>(_f: F) where F: FnMut(&mut FnMut(&i32)) {}
3 + fn b<F>(_f: F) where F: FnMut(&mut dyn FnMut(&i32)) {}
  |

error[[E0521]](https://doc.rust-lang.org/nightly/error-index.html#E0521): borrowed data escapes outside of closure
 --> src/main.rs:8:15
  |
7 |     b(|f| {
  |        - `f` declared here, outside of the closure body
8 |         a(|v| f(v))
  |            -  ^^^^ `v` escapes the closure body here
  |            |
  |            `v` is a reference that is only valid in the closure body

For more information about this error, try `rustc --explain E0521`.
warning: `playground` (bin "playground") generated 1 warning
error: could not compile `playground` due to previous error; 1 warning emitted

If I add dyn in line 3, it compiles without any error or warning:

fn b<F>(_f: F) where F: FnMut(&mut dyn FnMut(&i32)) {}

So the E0521 error emitted by the compiler is incorrect. The test code using Rust=2015 should only produce warnings without an error.

Version it worked on

It most recently worked on: 1.63.0-nightly (a4c1cd0eb 2022-05-18)

Version with regression

rustc 1.64.0-nightly (830880640 2022-06-28)
binary: rustc
commit-hash: 830880640304ba8699c5f9a0c4665c38a3271963
commit-date: 2022-06-28
host: x86_64-unknown-linux-gnu
release: 1.64.0-nightly
LLVM version: 14.0.6

@yanchen4791 yanchen4791 added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Jun 30, 2022
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jun 30, 2022
@yanchen4791
Copy link
Contributor Author

@rustbot labels:+T-compiler

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 30, 2022
@Rageking8
Copy link
Contributor

@rustbot label A-diagnostics

@rustbot rustbot added the A-diagnostics Area: Messages for errors, warnings, and lints label Jun 30, 2022
@yanchen4791
Copy link
Contributor Author

@rustbot labels: +regression-from-stable-to-nightly

@rustbot rustbot added the regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. label Jun 30, 2022
@steffahn
Copy link
Member

@rustbot label -regression-untriaged

Bisection:
regressed nightly: nightly-2022-06-23
searched commit range: dc80ca7...10f4ce3
regressed commit: 10f4ce3

that’s #98279, cc @cjgillot

@rustbot rustbot removed the regression-untriaged Untriaged performance or correctness regression. label Jun 30, 2022
@steffahn
Copy link
Member

steffahn commented Jun 30, 2022

Seems like, possibly, the code without the explicit dyn (incorrectly) desugars to

fn a<F>(_f: F) where F: FnMut(&i32) {}

fn b<'a, F>(_f: F) where F: FnMut(&mut FnMut(&'a i32)) {}

fn main()
{
    b(|f| {
        a(|v| f(v))
    });
}

rather than

fn a<F>(_f: F) where F: FnMut(&i32) {}

fn b<F>(_f: F) where F: FnMut(&mut for<'a> FnMut(&'a i32)) {}

fn main()
{
    b(|f| {
        a(|v| f(v))
    });
}

Edit: Or perhaps it incorrectly desugars to

fn a<F>(_f: F) where F: FnMut(&i32) {}

fn b<F>(_f: F) where F: for<'a> FnMut(&mut FnMut(&'a i32)) {}

fn main()
{
    b(|f| {
        a(|v| f(v))
    });
}

@steffahn
Copy link
Member

steffahn commented Jun 30, 2022

Here’s another kind of code example that reproduces the issue

fn f<F>()
where
    F: FnOnce() -> Box<FnOnce(&())>,
{
}
error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
 --> src/lib.rs:3:20
  |
3 |     F: FnOnce() -> Box<FnOnce(&())>,
  |                    ^^^^^^^^^^^^^^^^
  |
  = note: lifetimes appearing in an associated type are not considered constrained

Which does confirm the idea that this appears to be interpreted like F: for<'a> FnOnce() -> Box<FnOnce(&'a ())>, rather than F: FnOnce() -> Box<for<'a> FnOnce(&'a ())> which would be correct.

@apiraino
Copy link
Contributor

apiraino commented Jul 1, 2022

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-critical

@rustbot rustbot added P-critical Critical priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jul 1, 2022
@cjgillot cjgillot self-assigned this Jul 1, 2022
@bors bors closed this as completed in 38b7215 Jul 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. P-critical Critical priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. 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