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.
This commit is contained in:
parent
fb4bca04fa
commit
09f16b596d
@ -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,
|
||||
|
12
tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
Normal file
12
tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
Normal file
@ -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>(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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
@ -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>(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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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: Copy>(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>(f: impl Copy) -> usize {
|
||||
| ++++
|
||||
LL | fn id<F>(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>(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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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: Copy>(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>(f: impl Copy) -> usize {
|
||||
| ++++
|
||||
LL | fn id<F>(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>(f: Copy) -> usize {
|
||||
| ^^^^ `Copy` cannot be made into an object
|
@ -1,9 +1,12 @@
|
||||
// revisions: old new
|
||||
//[old] edition:2015
|
||||
//[new] edition:2021
|
||||
fn id<F>(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() {}
|
||||
|
47
tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr
Normal file
47
tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr
Normal file
@ -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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $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`.
|
@ -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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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<T: B>(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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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<T: A>(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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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<T: A>(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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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<T: B>(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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $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
|
@ -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() {}
|
||||
|
15
tests/ui/object-safety/avoid-ice-on-warning.new.stderr
Normal file
15
tests/ui/object-safety/avoid-ice-on-warning.new.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error: return types are denoted using `->`
|
||||
--> $DIR/avoid-ice-on-warning.rs:4:23
|
||||
|
|
||||
LL | fn call_this<F>(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: 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`.
|
@ -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: 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: 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: F) : Fn(&str) + call_that {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
@ -19,10 +19,10 @@ LL | fn call_this<F>(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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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: F) : impl Fn(&str) + call_that {}
|
||||
| ++++
|
||||
LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
|
||||
| +++
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
@ -1,6 +1,9 @@
|
||||
// revisions: old new
|
||||
//[old] edition:2015
|
||||
//[new] edition:2021
|
||||
fn call_this<F>(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() {}
|
||||
|
@ -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());
|
||||
}
|
16
tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed
Normal file
16
tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed
Normal file
@ -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());
|
||||
}
|
@ -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
|
@ -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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $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`.
|
@ -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() {
|
||||
|
@ -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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= 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<T: Foo + Send>(_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
|
||||
|
Loading…
Reference in New Issue
Block a user