From 09f16b596dce8f584ac070127a07f8fc6775ab30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Jan 2024 18:24:40 +0000 Subject: [PATCH] Avoid ICE in trait without `dyn` lint Do not attempt to provide an accurate suggestion for `impl Trait` in bare trait types when linting. Instead, only do the object safety check when an E0782 is already going to be emitted in the 2021 edition. Fix #120241. --- .../rustc_hir_analysis/src/astconv/lint.rs | 8 +- .../avoid-ice-on-warning-2.new.stderr | 12 ++ ...derr => avoid-ice-on-warning-2.old.stderr} | 28 ++--- .../object-safety/avoid-ice-on-warning-2.rs | 13 +- .../avoid-ice-on-warning-3.new.stderr | 47 ++++++++ ...derr => avoid-ice-on-warning-3.old.stderr} | 114 ++++++++---------- .../object-safety/avoid-ice-on-warning-3.rs | 31 ++--- .../avoid-ice-on-warning.new.stderr | 15 +++ ...stderr => avoid-ice-on-warning.old.stderr} | 12 +- .../ui/object-safety/avoid-ice-on-warning.rs | 7 +- .../bare-trait-dont-suggest-dyn.fixed | 9 -- .../bare-trait-dont-suggest-dyn.new.fixed | 16 +++ ...=> bare-trait-dont-suggest-dyn.new.stderr} | 2 +- .../bare-trait-dont-suggest-dyn.old.stderr | 39 ++++++ .../bare-trait-dont-suggest-dyn.rs | 9 +- .../ui/traits/bound/not-on-bare-trait.stderr | 14 +-- 16 files changed, 236 insertions(+), 140 deletions(-) create mode 100644 tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr rename tests/ui/object-safety/{avoid-ice-on-warning-2.stderr => avoid-ice-on-warning-2.old.stderr} (60%) create mode 100644 tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr rename tests/ui/object-safety/{avoid-ice-on-warning-3.stderr => avoid-ice-on-warning-3.old.stderr} (63%) create mode 100644 tests/ui/object-safety/avoid-ice-on-warning.new.stderr rename tests/ui/object-safety/{avoid-ice-on-warning.stderr => avoid-ice-on-warning.old.stderr} (71%) delete mode 100644 tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed create mode 100644 tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed rename tests/ui/object-safety/{bare-trait-dont-suggest-dyn.stderr => bare-trait-dont-suggest-dyn.new.stderr} (95%) create mode 100644 tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 98cd8a085ba..a6ac8ecd950 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -132,7 +132,7 @@ fn maybe_lint_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) -> ], Applicability::MachineApplicable, ); - } else if diag.is_error() && is_downgradable { + } else if is_downgradable { // We'll emit the object safety error already, with a structured suggestion. diag.downgrade_to_delayed_bug(); } @@ -158,7 +158,7 @@ fn maybe_lint_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) -> } if !is_object_safe { diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`")); - if diag.is_error() && is_downgradable { + if is_downgradable { // We'll emit the object safety error already, with a structured suggestion. diag.downgrade_to_delayed_bug(); } @@ -241,9 +241,7 @@ pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) } else { let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { - if self_ty.span.can_be_used_for_suggestions() - && !self.maybe_lint_impl_trait(self_ty, lint) - { + if self_ty.span.can_be_used_for_suggestions() { lint.multipart_suggestion_verbose( "use `dyn`", sugg, diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr new file mode 100644 index 00000000000..7aec3a73fe9 --- /dev/null +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr @@ -0,0 +1,12 @@ +error[E0038]: the trait `Copy` cannot be made into an object + --> $DIR/avoid-ice-on-warning-2.rs:4:13 + | +LL | fn id(f: Copy) -> usize { + | ^^^^ `Copy` cannot be made into an object + | + = note: the trait cannot be made into an object because it requires `Self: Sized` + = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr similarity index 60% rename from tests/ui/object-safety/avoid-ice-on-warning-2.stderr rename to tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr index 2755eee6f35..41c09b7df62 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr @@ -1,43 +1,33 @@ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-2.rs:1:13 + --> $DIR/avoid-ice-on-warning-2.rs:4:13 | LL | fn id(f: Copy) -> usize { | ^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - = note: `Copy` it is not object safe, so it can't be `dyn` = note: `#[warn(bare_trait_objects)]` on by default -help: use a new generic type parameter, constrained by `Copy` +help: use `dyn` | -LL | fn id(f: T) -> usize { - | +++++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | fn id(f: impl Copy) -> usize { - | ++++ +LL | fn id(f: dyn Copy) -> usize { + | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-2.rs:1:13 + --> $DIR/avoid-ice-on-warning-2.rs:4:13 | LL | fn id(f: Copy) -> usize { | ^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - = note: `Copy` it is not object safe, so it can't be `dyn` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: use a new generic type parameter, constrained by `Copy` +help: use `dyn` | -LL | fn id(f: T) -> usize { - | +++++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | fn id(f: impl Copy) -> usize { - | ++++ +LL | fn id(f: dyn Copy) -> usize { + | +++ error[E0038]: the trait `Copy` cannot be made into an object - --> $DIR/avoid-ice-on-warning-2.rs:1:13 + --> $DIR/avoid-ice-on-warning-2.rs:4:13 | LL | fn id(f: Copy) -> usize { | ^^^^ `Copy` cannot be made into an object diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.rs b/tests/ui/object-safety/avoid-ice-on-warning-2.rs index cd34362d3dd..9a6a4378fa3 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.rs +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.rs @@ -1,9 +1,12 @@ +// revisions: old new +//[old] edition:2015 +//[new] edition:2021 fn id(f: Copy) -> usize { -//~^ WARN trait objects without an explicit `dyn` are deprecated -//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! -//~| ERROR the trait `Copy` cannot be made into an object +//~^ ERROR the trait `Copy` cannot be made into an object +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! f() } fn main() {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr new file mode 100644 index 00000000000..fd92d43ef9a --- /dev/null +++ b/tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr @@ -0,0 +1,47 @@ +error[E0038]: the trait `A` cannot be made into an object + --> $DIR/avoid-ice-on-warning-3.rs:4:19 + | +LL | trait B { fn f(a: A) -> A; } + | ^ `A` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/avoid-ice-on-warning-3.rs:12:14 + | +LL | trait A { fn g(b: B) -> B; } + | - ^ ...because associated function `g` has no `self` parameter + | | + | this trait cannot be made into an object... +help: consider turning `g` into a method by giving it a `&self` argument + | +LL | trait A { fn g(&self, b: B) -> B; } + | ++++++ +help: alternatively, consider constraining `g` so it does not apply to trait objects + | +LL | trait A { fn g(b: B) -> B where Self: Sized; } + | +++++++++++++++++ + +error[E0038]: the trait `B` cannot be made into an object + --> $DIR/avoid-ice-on-warning-3.rs:12:19 + | +LL | trait A { fn g(b: B) -> B; } + | ^ `B` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/avoid-ice-on-warning-3.rs:4:14 + | +LL | trait B { fn f(a: A) -> A; } + | - ^ ...because associated function `f` has no `self` parameter + | | + | this trait cannot be made into an object... +help: consider turning `f` into a method by giving it a `&self` argument + | +LL | trait B { fn f(&self, a: A) -> A; } + | ++++++ +help: alternatively, consider constraining `f` so it does not apply to trait objects + | +LL | trait B { fn f(a: A) -> A where Self: Sized; } + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr similarity index 63% rename from tests/ui/object-safety/avoid-ice-on-warning-3.stderr rename to tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr index 0fc67770b96..a36e2519c80 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-3.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr @@ -1,93 +1,78 @@ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-3.rs:9:19 + --> $DIR/avoid-ice-on-warning-3.rs:4:19 | -LL | trait A { fn g(b: B) -> B; } +LL | trait B { fn f(a: A) -> A; } | ^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - = note: `B` it is not object safe, so it can't be `dyn` = note: `#[warn(bare_trait_objects)]` on by default -help: use a new generic type parameter, constrained by `B` +help: use `dyn` | -LL | trait A { fn g(b: T) -> B; } - | ++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | trait A { fn g(b: impl B) -> B; } - | ++++ +LL | trait B { fn f(a: dyn A) -> A; } + | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-3.rs:9:25 + --> $DIR/avoid-ice-on-warning-3.rs:4:25 + | +LL | trait B { fn f(a: A) -> A; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | trait B { fn f(a: A) -> dyn A; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:12:19 + | +LL | trait A { fn g(b: B) -> B; } + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | trait A { fn g(b: dyn B) -> B; } + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/avoid-ice-on-warning-3.rs:12:25 | LL | trait A { fn g(b: B) -> B; } | ^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see -help: `B` is not object safe, use `impl B` to return an opaque type, as long as you return a single underlying type +help: use `dyn` | -LL | trait A { fn g(b: B) -> impl B; } - | ++++ +LL | trait A { fn g(b: B) -> dyn B; } + | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-3.rs:1:19 + --> $DIR/avoid-ice-on-warning-3.rs:4:19 | LL | trait B { fn f(a: A) -> A; } | ^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - = note: `A` it is not object safe, so it can't be `dyn` -help: use a new generic type parameter, constrained by `A` - | -LL | trait B { fn f(a: T) -> A; } - | ++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | trait B { fn f(a: impl A) -> A; } - | ++++ - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-3.rs:1:25 - | -LL | trait B { fn f(a: A) -> A; } - | ^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see -help: `A` is not object safe, use `impl A` to return an opaque type, as long as you return a single underlying type - | -LL | trait B { fn f(a: A) -> impl A; } - | ++++ - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-3.rs:1:19 - | -LL | trait B { fn f(a: A) -> A; } - | ^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - = note: `A` it is not object safe, so it can't be `dyn` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: use a new generic type parameter, constrained by `A` +help: use `dyn` | -LL | trait B { fn f(a: T) -> A; } - | ++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | trait B { fn f(a: impl A) -> A; } - | ++++ +LL | trait B { fn f(a: dyn A) -> A; } + | +++ error[E0038]: the trait `A` cannot be made into an object - --> $DIR/avoid-ice-on-warning-3.rs:1:19 + --> $DIR/avoid-ice-on-warning-3.rs:4:19 | LL | trait B { fn f(a: A) -> A; } | ^ `A` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/avoid-ice-on-warning-3.rs:9:14 + --> $DIR/avoid-ice-on-warning-3.rs:12:14 | LL | trait A { fn g(b: B) -> B; } | - ^ ...because associated function `g` has no `self` parameter @@ -103,32 +88,27 @@ LL | trait A { fn g(b: B) -> B where Self: Sized; } | +++++++++++++++++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning-3.rs:9:19 + --> $DIR/avoid-ice-on-warning-3.rs:12:19 | LL | trait A { fn g(b: B) -> B; } | ^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - = note: `B` it is not object safe, so it can't be `dyn` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: use a new generic type parameter, constrained by `B` +help: use `dyn` | -LL | trait A { fn g(b: T) -> B; } - | ++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | trait A { fn g(b: impl B) -> B; } - | ++++ +LL | trait A { fn g(b: dyn B) -> B; } + | +++ error[E0038]: the trait `B` cannot be made into an object - --> $DIR/avoid-ice-on-warning-3.rs:9:19 + --> $DIR/avoid-ice-on-warning-3.rs:12:19 | LL | trait A { fn g(b: B) -> B; } | ^ `B` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/avoid-ice-on-warning-3.rs:1:14 + --> $DIR/avoid-ice-on-warning-3.rs:4:14 | LL | trait B { fn f(a: A) -> A; } | - ^ ...because associated function `f` has no `self` parameter diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.rs b/tests/ui/object-safety/avoid-ice-on-warning-3.rs index caaf4d0fd99..40563e233de 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-3.rs +++ b/tests/ui/object-safety/avoid-ice-on-warning-3.rs @@ -1,17 +1,20 @@ +// revisions: old new +//[old] edition:2015 +//[new] edition:2021 trait B { fn f(a: A) -> A; } -//~^ WARN trait objects without an explicit `dyn` are deprecated -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN this is accepted in the current edition -//~| WARN this is accepted in the current edition -//~| WARN this is accepted in the current edition -//~| ERROR the trait `A` cannot be made into an object +//~^ ERROR the trait `A` cannot be made into an object +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition trait A { fn g(b: B) -> B; } -//~^ WARN trait objects without an explicit `dyn` are deprecated -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN this is accepted in the current edition -//~| WARN this is accepted in the current edition -//~| WARN this is accepted in the current edition -//~| ERROR the trait `B` cannot be made into an object +//~^ ERROR the trait `B` cannot be made into an object +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition +//[old]~| WARN this is accepted in the current edition fn main() {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr new file mode 100644 index 00000000000..517f910080d --- /dev/null +++ b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr @@ -0,0 +1,15 @@ +error: return types are denoted using `->` + --> $DIR/avoid-ice-on-warning.rs:4:23 + | +LL | fn call_this(f: F) : Fn(&str) + call_that {} + | ^ help: use `->` instead + +error[E0405]: cannot find trait `call_that` in this scope + --> $DIR/avoid-ice-on-warning.rs:4:36 + | +LL | fn call_this(f: F) : Fn(&str) + call_that {} + | ^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/object-safety/avoid-ice-on-warning.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr similarity index 71% rename from tests/ui/object-safety/avoid-ice-on-warning.stderr rename to tests/ui/object-safety/avoid-ice-on-warning.old.stderr index 1046f177e82..7c7af968280 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr @@ -1,17 +1,17 @@ error: return types are denoted using `->` - --> $DIR/avoid-ice-on-warning.rs:1:23 + --> $DIR/avoid-ice-on-warning.rs:4:23 | LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^ help: use `->` instead error[E0405]: cannot find trait `call_that` in this scope - --> $DIR/avoid-ice-on-warning.rs:1:36 + --> $DIR/avoid-ice-on-warning.rs:4:36 | LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^^^^^^^^^ not found in this scope warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/avoid-ice-on-warning.rs:1:25 + --> $DIR/avoid-ice-on-warning.rs:4:25 | LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^^^^^^^^^^^^^^^^^^^^ @@ -19,10 +19,10 @@ LL | fn call_this(f: F) : Fn(&str) + call_that {} = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see = note: `#[warn(bare_trait_objects)]` on by default -help: `Fn(&str) + call_that` is not object safe, use `impl Fn(&str) + call_that` to return an opaque type, as long as you return a single underlying type +help: use `dyn` | -LL | fn call_this(f: F) : impl Fn(&str) + call_that {} - | ++++ +LL | fn call_this(f: F) : dyn Fn(&str) + call_that {} + | +++ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/object-safety/avoid-ice-on-warning.rs b/tests/ui/object-safety/avoid-ice-on-warning.rs index d2a1eeb5286..5192da94216 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.rs +++ b/tests/ui/object-safety/avoid-ice-on-warning.rs @@ -1,6 +1,9 @@ +// revisions: old new +//[old] edition:2015 +//[new] edition:2021 fn call_this(f: F) : Fn(&str) + call_that {} //~^ ERROR return types are denoted using `->` //~| ERROR cannot find trait `call_that` in this scope -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//[old]~| WARN trait objects without an explicit `dyn` are deprecated +//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! fn main() {} diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed deleted file mode 100644 index e95b982966d..00000000000 --- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed +++ /dev/null @@ -1,9 +0,0 @@ -// run-rustfix -#![deny(bare_trait_objects)] -fn ord_prefer_dot(s: String) -> impl Ord { - //~^ ERROR the trait `Ord` cannot be made into an object - (s.starts_with("."), s) -} -fn main() { - let _ = ord_prefer_dot(String::new()); -} diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed new file mode 100644 index 00000000000..301c36c6191 --- /dev/null +++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed @@ -0,0 +1,16 @@ +// revisions: old new +//[old] edition:2015 +//[new] edition:2021 +//[new] run-rustfix +// FIXME: the test suite tries to create a crate called `bare_trait_dont_suggest_dyn.new` +#![crate_name="bare_trait_dont_suggest_dyn"] +#![deny(bare_trait_objects)] +fn ord_prefer_dot(s: String) -> impl Ord { + //~^ ERROR the trait `Ord` cannot be made into an object + //[old]~| ERROR trait objects without an explicit `dyn` are deprecated + //[old]~| WARNING this is accepted in the current edition (Rust 2015) + (s.starts_with("."), s) +} +fn main() { + let _ = ord_prefer_dot(String::new()); +} diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.stderr similarity index 95% rename from tests/ui/object-safety/bare-trait-dont-suggest-dyn.stderr rename to tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.stderr index 2c499d240ab..52db31d620c 100644 --- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.stderr +++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Ord` cannot be made into an object - --> $DIR/bare-trait-dont-suggest-dyn.rs:3:33 + --> $DIR/bare-trait-dont-suggest-dyn.rs:8:33 | LL | fn ord_prefer_dot(s: String) -> Ord { | ^^^ `Ord` cannot be made into an object diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr new file mode 100644 index 00000000000..274d5a639a4 --- /dev/null +++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr @@ -0,0 +1,39 @@ +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/bare-trait-dont-suggest-dyn.rs:8:33 + | +LL | fn ord_prefer_dot(s: String) -> Ord { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +note: the lint level is defined here + --> $DIR/bare-trait-dont-suggest-dyn.rs:7:9 + | +LL | #![deny(bare_trait_objects)] + | ^^^^^^^^^^^^^^^^^^ +help: use `dyn` + | +LL | fn ord_prefer_dot(s: String) -> dyn Ord { + | +++ + +error[E0038]: the trait `Ord` cannot be made into an object + --> $DIR/bare-trait-dont-suggest-dyn.rs:8:33 + | +LL | fn ord_prefer_dot(s: String) -> Ord { + | ^^^ `Ord` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter +help: consider using an opaque type instead + | +LL | fn ord_prefer_dot(s: String) -> impl Ord { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs index fdf7e0a77aa..64586b77b8c 100644 --- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs +++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs @@ -1,7 +1,14 @@ -// run-rustfix +// revisions: old new +//[old] edition:2015 +//[new] edition:2021 +//[new] run-rustfix +// FIXME: the test suite tries to create a crate called `bare_trait_dont_suggest_dyn.new` +#![crate_name="bare_trait_dont_suggest_dyn"] #![deny(bare_trait_objects)] fn ord_prefer_dot(s: String) -> Ord { //~^ ERROR the trait `Ord` cannot be made into an object + //[old]~| ERROR trait objects without an explicit `dyn` are deprecated + //[old]~| WARNING this is accepted in the current edition (Rust 2015) (s.starts_with("."), s) } fn main() { diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr index 8d0e40be788..6d56851bf34 100644 --- a/tests/ui/traits/bound/not-on-bare-trait.stderr +++ b/tests/ui/traits/bound/not-on-bare-trait.stderr @@ -7,18 +7,10 @@ LL | fn foo(_x: Foo + Send) { = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see = note: `#[warn(bare_trait_objects)]` on by default -help: use a new generic type parameter, constrained by `Foo + Send` +help: use `dyn` | -LL | fn foo(_x: T) { - | +++++++++++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference - | -LL | fn foo(_x: impl Foo + Send) { - | ++++ -help: alternatively, use a trait object to accept any type that implements `Foo + Send`, accessing its methods at runtime using dynamic dispatch - | -LL | fn foo(_x: &(dyn Foo + Send)) { - | +++++ + +LL | fn foo(_x: dyn Foo + Send) { + | +++ error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time --> $DIR/not-on-bare-trait.rs:7:8