Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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