Skip to content

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

Closed
@yanchen4791

Description

@yanchen4791

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

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.P-criticalCritical priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions