Skip to content

Commit 270e0c5

Browse files
authored
Rollup merge of #103283 - nbarrios1337:unsafe-impl-suggestions, r=cjgillot
Add suggestions for unsafe impl error codes Adds suggestions for users to add `unsafe` to trait impls that should be `unsafe`, and remove `unsafe` from trait impls that do not require `unsafe` With the folllowing code: ```rust struct Foo {} struct Bar {} trait Safe {} unsafe trait Unsafe {} impl Safe for Foo {} // ok impl Unsafe for Foo {} // E0200 unsafe impl Safe for Bar {} // E0199 unsafe impl Unsafe for Bar {} // ok // omitted empty main fn ``` The current rustc output is: ``` error[E0199]: implementing the trait `Safe` is not unsafe --> e0200.rs:13:1 | 13 | unsafe impl Safe for Bar {} // E0199 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0200]: the trait `Unsafe` requires an `unsafe impl` declaration --> e0200.rs:11:1 | 11 | impl Unsafe for Foo {} // E0200 | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors Some errors have detailed explanations: E0199, E0200. For more information about an error, try `rustc --explain E0199`. ``` With this PR, the future rustc output would be: ``` error[E0199]: implementing the trait `Safe` is not unsafe --> ../../temp/e0200.rs:13:1 | 13 | unsafe impl Safe for Bar {} // E0199 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove `unsafe` from this trait implementation | 13 - unsafe impl Safe for Bar {} // E0199 13 + impl Safe for Bar {} // E0199 | error[E0200]: the trait `Unsafe` requires an `unsafe impl` declaration --> ../../temp/e0200.rs:11:1 | 11 | impl Unsafe for Foo {} // E0200 | ^^^^^^^^^^^^^^^^^^^^^^ | = note: the trait `Unsafe` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation | 11 | unsafe impl Unsafe for Foo {} // E0200 | ++++++ error: aborting due to 2 previous errors Some errors have detailed explanations: E0199, E0200. For more information about an error, try `rustc --explain E0199`. ``` ``@rustbot`` label +T-compiler +A-diagnostics +A-suggestion-diagnostics
2 parents c404092 + 770538e commit 270e0c5

File tree

7 files changed

+84
-0
lines changed

7 files changed

+84
-0
lines changed

compiler/rustc_hir_analysis/src/coherence/unsafety.rs

+30
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
2626
"implementing the trait `{}` is not unsafe",
2727
trait_ref.print_only_trait_path()
2828
)
29+
.span_suggestion_verbose(
30+
item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)),
31+
"remove `unsafe` from this trait implementation",
32+
"",
33+
rustc_errors::Applicability::MachineApplicable,
34+
)
2935
.emit();
3036
}
3137

@@ -37,6 +43,18 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
3743
"the trait `{}` requires an `unsafe impl` declaration",
3844
trait_ref.print_only_trait_path()
3945
)
46+
.note(format!(
47+
"the trait `{}` enforces invariants that the compiler can't check. \
48+
Review the trait documentation and make sure this implementation \
49+
upholds those invariants before adding the `unsafe` keyword",
50+
trait_ref.print_only_trait_path()
51+
))
52+
.span_suggestion_verbose(
53+
item.span.shrink_to_lo(),
54+
"add `unsafe` to this trait implementation",
55+
"unsafe ",
56+
rustc_errors::Applicability::MaybeIncorrect,
57+
)
4058
.emit();
4159
}
4260

@@ -48,6 +66,18 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
4866
"requires an `unsafe impl` declaration due to `#[{}]` attribute",
4967
attr_name
5068
)
69+
.note(format!(
70+
"the trait `{}` enforces invariants that the compiler can't check. \
71+
Review the trait documentation and make sure this implementation \
72+
upholds those invariants before adding the `unsafe` keyword",
73+
trait_ref.print_only_trait_path()
74+
))
75+
.span_suggestion_verbose(
76+
item.span.shrink_to_lo(),
77+
"add `unsafe` to this trait implementation",
78+
"unsafe ",
79+
rustc_errors::Applicability::MaybeIncorrect,
80+
)
5181
.emit();
5282
}
5383

src/test/ui/coherence/coherence-default-trait-impl.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ error[E0199]: implementing the trait `MySafeTrait` is not unsafe
33
|
44
LL | unsafe impl MySafeTrait for Foo {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
help: remove `unsafe` from this trait implementation
8+
|
9+
LL - unsafe impl MySafeTrait for Foo {}
10+
LL + impl MySafeTrait for Foo {}
11+
|
612

713
error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
814
--> $DIR/coherence-default-trait-impl.rs:13:1
915
|
1016
LL | impl MyUnsafeTrait for Foo {}
1117
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
|
19+
= note: the trait `MyUnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
20+
help: add `unsafe` to this trait implementation
21+
|
22+
LL | unsafe impl MyUnsafeTrait for Foo {}
23+
| ++++++
1224

1325
error: aborting due to 2 previous errors
1426

src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ LL | | // (unsafe to access self.1 due to #[may_dangle] on A)
88
LL | | fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); }
99
LL | | }
1010
| |_^
11+
|
12+
= note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
13+
help: add `unsafe` to this trait implementation
14+
|
15+
LL | unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt<A, B> {
16+
| ++++++
1117

1218
error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute
1319
--> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:27:1
@@ -19,6 +25,12 @@ LL | | // (unsafe to access self.1 due to #[may_dangle] on 'a)
1925
LL | | fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); }
2026
LL | | }
2127
| |_^
28+
|
29+
= note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
30+
help: add `unsafe` to this trait implementation
31+
|
32+
LL | unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> {
33+
| ++++++
2234

2335
error: aborting due to 2 previous errors
2436

src/test/ui/error-codes/E0199.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ error[E0199]: implementing the trait `Bar` is not unsafe
33
|
44
LL | unsafe impl Bar for Foo { }
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
help: remove `unsafe` from this trait implementation
8+
|
9+
LL - unsafe impl Bar for Foo { }
10+
LL + impl Bar for Foo { }
11+
|
612

713
error: aborting due to previous error
814

src/test/ui/error-codes/E0200.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ error[E0200]: the trait `Bar` requires an `unsafe impl` declaration
33
|
44
LL | impl Bar for Foo { }
55
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: the trait `Bar` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
8+
help: add `unsafe` to this trait implementation
9+
|
10+
LL | unsafe impl Bar for Foo { }
11+
| ++++++
612

713
error: aborting due to previous error
814

src/test/ui/traits/safety-trait-impl-cc.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ LL | | panic!();
77
LL | | }
88
LL | | }
99
| |_^
10+
|
11+
= note: the trait `Foo` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
12+
help: add `unsafe` to this trait implementation
13+
|
14+
LL | unsafe impl lib::Foo for Bar {
15+
| ++++++
1016

1117
error: aborting due to previous error
1218

src/test/ui/traits/safety-trait-impl.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ error[E0200]: the trait `UnsafeTrait` requires an `unsafe impl` declaration
33
|
44
LL | impl UnsafeTrait for u16 { }
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: the trait `UnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
8+
help: add `unsafe` to this trait implementation
9+
|
10+
LL | unsafe impl UnsafeTrait for u16 { }
11+
| ++++++
612

713
error[E0199]: implementing the trait `SafeTrait` is not unsafe
814
--> $DIR/safety-trait-impl.rs:16:1
915
|
1016
LL | unsafe impl SafeTrait for u32 { }
1117
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
|
19+
help: remove `unsafe` from this trait implementation
20+
|
21+
LL - unsafe impl SafeTrait for u32 { }
22+
LL + impl SafeTrait for u32 { }
23+
|
1224

1325
error: aborting due to 2 previous errors
1426

0 commit comments

Comments
 (0)