Skip to content

Commit de6b219

Browse files
Make WHERE_CLAUSES_OBJECT_SAFETY a regular object safety violation
1 parent 8768db9 commit de6b219

File tree

13 files changed

+74
-191
lines changed

13 files changed

+74
-191
lines changed

compiler/rustc_lint_defs/src/builtin.rs

-42
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ declare_lint_pass! {
136136
USELESS_DEPRECATED,
137137
WARNINGS,
138138
WASM_C_ABI,
139-
WHERE_CLAUSES_OBJECT_SAFETY,
140139
WRITES_THROUGH_IMMUTABLE_POINTER,
141140
// tidy-alphabetical-end
142141
]
@@ -2093,47 +2092,6 @@ declare_lint! {
20932092
"detects labels that are never used"
20942093
}
20952094

2096-
declare_lint! {
2097-
/// The `where_clauses_object_safety` lint detects for [object safety] of
2098-
/// [where clauses].
2099-
///
2100-
/// [object safety]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
2101-
/// [where clauses]: https://doc.rust-lang.org/reference/items/generics.html#where-clauses
2102-
///
2103-
/// ### Example
2104-
///
2105-
/// ```rust,no_run
2106-
/// trait Trait {}
2107-
///
2108-
/// trait X { fn foo(&self) where Self: Trait; }
2109-
///
2110-
/// impl X for () { fn foo(&self) {} }
2111-
///
2112-
/// impl Trait for dyn X {}
2113-
///
2114-
/// // Segfault at opt-level 0, SIGILL otherwise.
2115-
/// pub fn main() { <dyn X as X>::foo(&()); }
2116-
/// ```
2117-
///
2118-
/// {{produces}}
2119-
///
2120-
/// ### Explanation
2121-
///
2122-
/// The compiler previously allowed these object-unsafe bounds, which was
2123-
/// incorrect. This is a [future-incompatible] lint to transition this to
2124-
/// a hard error in the future. See [issue #51443] for more details.
2125-
///
2126-
/// [issue #51443]: https://github.com/rust-lang/rust/issues/51443
2127-
/// [future-incompatible]: ../index.md#future-incompatible-lints
2128-
pub WHERE_CLAUSES_OBJECT_SAFETY,
2129-
Warn,
2130-
"checks the object safety of where clauses",
2131-
@future_incompatible = FutureIncompatibleInfo {
2132-
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
2133-
reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
2134-
};
2135-
}
2136-
21372095
declare_lint! {
21382096
/// The `proc_macro_derive_resolution_fallback` lint detects proc macro
21392097
/// derives using inaccessible names from parent modules.

compiler/rustc_trait_selection/src/traits/object_safety.rs

+3-78
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::elaborate;
1313
use crate::infer::TyCtxtInferExt;
1414
use crate::traits::query::evaluate_obligation::InferCtxtExt;
1515
use crate::traits::{self, Obligation, ObligationCause};
16-
use rustc_errors::{FatalError, MultiSpan};
16+
use rustc_errors::FatalError;
1717
use rustc_hir as hir;
1818
use rustc_hir::def_id::DefId;
1919
use rustc_middle::query::Providers;
@@ -23,7 +23,6 @@ use rustc_middle::ty::{
2323
};
2424
use rustc_middle::ty::{GenericArg, GenericArgs};
2525
use rustc_middle::ty::{TypeVisitableExt, Upcast};
26-
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
2726
use rustc_span::symbol::Symbol;
2827
use rustc_span::Span;
2928
use rustc_target::abi::Abi;
@@ -66,44 +65,13 @@ fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &'_ [Object
6665
}
6766

6867
fn check_is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
69-
let violations = tcx.object_safety_violations(trait_def_id);
70-
71-
if violations.is_empty() {
72-
return true;
73-
}
74-
75-
// If the trait contains any other violations, then let the error reporting path
76-
// report it instead of emitting a warning here.
77-
if violations.iter().all(|violation| {
78-
matches!(
79-
violation,
80-
ObjectSafetyViolation::Method(_, MethodViolationCode::WhereClauseReferencesSelf, _)
81-
)
82-
}) {
83-
for violation in violations {
84-
if let ObjectSafetyViolation::Method(
85-
_,
86-
MethodViolationCode::WhereClauseReferencesSelf,
87-
span,
88-
) = violation
89-
{
90-
lint_object_unsafe_trait(tcx, *span, trait_def_id, violation);
91-
}
92-
}
93-
return true;
94-
}
95-
96-
false
68+
tcx.object_safety_violations(trait_def_id).is_empty()
9769
}
9870

9971
/// We say a method is *vtable safe* if it can be invoked on a trait
10072
/// object. Note that object-safe traits can have some
10173
/// non-vtable-safe methods, so long as they require `Self: Sized` or
10274
/// otherwise ensure that they cannot be used when `Self = Trait`.
103-
///
104-
/// [`MethodViolationCode::WhereClauseReferencesSelf`] is considered object safe due to backwards
105-
/// compatibility, see <https://github.com/rust-lang/rust/issues/51443> and
106-
/// [`WHERE_CLAUSES_OBJECT_SAFETY`].
10775
pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::AssocItem) -> bool {
10876
debug_assert!(tcx.generics_of(trait_def_id).has_self);
10977
debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
@@ -112,9 +80,7 @@ pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::A
11280
return false;
11381
}
11482

115-
virtual_call_violations_for_method(tcx, trait_def_id, method)
116-
.iter()
117-
.all(|v| matches!(v, MethodViolationCode::WhereClauseReferencesSelf))
83+
virtual_call_violations_for_method(tcx, trait_def_id, method).is_empty()
11884
}
11985

12086
fn object_safety_violations_for_trait(
@@ -163,47 +129,6 @@ fn object_safety_violations_for_trait(
163129
violations
164130
}
165131

166-
/// Lint object-unsafe trait.
167-
fn lint_object_unsafe_trait(
168-
tcx: TyCtxt<'_>,
169-
span: Span,
170-
trait_def_id: DefId,
171-
violation: &ObjectSafetyViolation,
172-
) {
173-
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
174-
// It's also hard to get a use site span, so we use the method definition span.
175-
tcx.node_span_lint(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |err| {
176-
err.primary_message(format!(
177-
"the trait `{}` cannot be made into an object",
178-
tcx.def_path_str(trait_def_id)
179-
));
180-
let node = tcx.hir().get_if_local(trait_def_id);
181-
let mut spans = MultiSpan::from_span(span);
182-
if let Some(hir::Node::Item(item)) = node {
183-
spans.push_span_label(item.ident.span, "this trait cannot be made into an object...");
184-
spans.push_span_label(span, format!("...because {}", violation.error_msg()));
185-
} else {
186-
spans.push_span_label(
187-
span,
188-
format!(
189-
"the trait cannot be made into an object because {}",
190-
violation.error_msg()
191-
),
192-
);
193-
};
194-
err.span_note(
195-
spans,
196-
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the \
197-
call to be resolvable dynamically; for more information visit \
198-
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
199-
);
200-
if node.is_some() {
201-
// Only provide the help if its a local trait, otherwise it's not
202-
violation.solution().add_to(err);
203-
}
204-
});
205-
}
206-
207132
fn sized_trait_bound_spans<'tcx>(
208133
tcx: TyCtxt<'tcx>,
209134
bounds: hir::GenericBounds<'tcx>,

src/tools/miri/tests/fail/issue-miri-2432.rs

-19
This file was deleted.

src/tools/miri/tests/fail/issue-miri-2432.stderr

-15
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
#![feature(generic_const_exprs)]
22
#![allow(incomplete_features)]
3-
#![deny(where_clauses_object_safety)]
43

54

65
const fn bar<T: ?Sized>() -> usize { 7 }
76

87
trait Foo {
98
fn test(&self) where [u8; bar::<Self>()]: Sized;
10-
//~^ ERROR the trait `Foo` cannot be made into an object
11-
//~| WARN this was previously accepted by the compiler but is being phased out
129
}
1310

1411
impl Foo for () {
1512
fn test(&self) where [u8; bar::<Self>()]: Sized {}
1613
}
1714

1815
fn use_dyn(v: &dyn Foo) {
16+
//~^ ERROR the trait `Foo` cannot be made into an object
1917
v.test();
18+
//~^ ERROR the trait `Foo` cannot be made into an object
2019
}
2120

2221
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,35 @@
1-
error: the trait `Foo` cannot be made into an object
2-
--> $DIR/object-safety-err-where-bounds.rs:9:8
1+
error[E0038]: the trait `Foo` cannot be made into an object
2+
--> $DIR/object-safety-err-where-bounds.rs:15:16
33
|
4-
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
5-
| ^^^^
4+
LL | fn use_dyn(v: &dyn Foo) {
5+
| ^^^^^^^ `Foo` cannot be made into an object
66
|
7-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8-
= note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
97
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>
10-
--> $DIR/object-safety-err-where-bounds.rs:9:8
8+
--> $DIR/object-safety-err-where-bounds.rs:8:8
119
|
1210
LL | trait Foo {
1311
| --- this trait cannot be made into an object...
1412
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
1513
| ^^^^ ...because method `test` references the `Self` type in its `where` clause
1614
= help: consider moving `test` to another trait
17-
note: the lint level is defined here
18-
--> $DIR/object-safety-err-where-bounds.rs:3:9
15+
= help: only type `()` implements the trait, consider using it directly instead
16+
17+
error[E0038]: the trait `Foo` cannot be made into an object
18+
--> $DIR/object-safety-err-where-bounds.rs:17:5
19+
|
20+
LL | v.test();
21+
| ^^^^^^^^ `Foo` cannot be made into an object
22+
|
23+
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>
24+
--> $DIR/object-safety-err-where-bounds.rs:8:8
1925
|
20-
LL | #![deny(where_clauses_object_safety)]
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
LL | trait Foo {
27+
| --- this trait cannot be made into an object...
28+
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
29+
| ^^^^ ...because method `test` references the `Self` type in its `where` clause
30+
= help: consider moving `test` to another trait
31+
= help: only type `()` implements the trait, consider using it directly instead
2232

23-
error: aborting due to 1 previous error
33+
error: aborting due to 2 previous errors
2434

35+
For more information about this error, try `rustc --explain E0038`.

tests/ui/issues/issue-50781.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
#![deny(where_clauses_object_safety)]
2-
31
trait Trait {}
42

53
trait X {
6-
fn foo(&self) where Self: Trait; //~ ERROR the trait `X` cannot be made into an object
7-
//~^ WARN this was previously accepted by the compiler but is being phased out
4+
fn foo(&self) where Self: Trait;
85
}
96

107
impl X for () {
118
fn foo(&self) {}
129
}
1310

1411
impl Trait for dyn X {}
12+
//~^ ERROR the trait `X` cannot be made into an object
1513

1614
pub fn main() {
1715
// Check that this does not segfault.
1816
<dyn X as X>::foo(&());
17+
//~^ ERROR the trait `X` cannot be made into an object
18+
//~| ERROR the trait `X` cannot be made into an object
1919
}

tests/ui/issues/issue-50781.stderr

+39-11
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,52 @@
1-
error: the trait `X` cannot be made into an object
2-
--> $DIR/issue-50781.rs:6:8
1+
error[E0038]: the trait `X` cannot be made into an object
2+
--> $DIR/issue-50781.rs:11:16
33
|
4+
LL | impl Trait for dyn X {}
5+
| ^^^^^ `X` cannot be made into an object
6+
|
7+
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>
8+
--> $DIR/issue-50781.rs:4:8
9+
|
10+
LL | trait X {
11+
| - this trait cannot be made into an object...
412
LL | fn foo(&self) where Self: Trait;
5-
| ^^^
13+
| ^^^ ...because method `foo` references the `Self` type in its `where` clause
14+
= help: consider moving `foo` to another trait
15+
= help: only type `()` implements the trait, consider using it directly instead
16+
17+
error[E0038]: the trait `X` cannot be made into an object
18+
--> $DIR/issue-50781.rs:16:23
19+
|
20+
LL | <dyn X as X>::foo(&());
21+
| ^^^ `X` cannot be made into an object
622
|
7-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8-
= note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
923
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>
10-
--> $DIR/issue-50781.rs:6:8
24+
--> $DIR/issue-50781.rs:4:8
1125
|
1226
LL | trait X {
1327
| - this trait cannot be made into an object...
1428
LL | fn foo(&self) where Self: Trait;
1529
| ^^^ ...because method `foo` references the `Self` type in its `where` clause
1630
= help: consider moving `foo` to another trait
17-
note: the lint level is defined here
18-
--> $DIR/issue-50781.rs:1:9
31+
= help: only type `()` implements the trait, consider using it directly instead
32+
= note: required for the cast from `&()` to `&dyn X`
33+
34+
error[E0038]: the trait `X` cannot be made into an object
35+
--> $DIR/issue-50781.rs:16:6
36+
|
37+
LL | <dyn X as X>::foo(&());
38+
| ^^^^^ `X` cannot be made into an object
1939
|
20-
LL | #![deny(where_clauses_object_safety)]
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
40+
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>
41+
--> $DIR/issue-50781.rs:4:8
42+
|
43+
LL | trait X {
44+
| - this trait cannot be made into an object...
45+
LL | fn foo(&self) where Self: Trait;
46+
| ^^^ ...because method `foo` references the `Self` type in its `where` clause
47+
= help: consider moving `foo` to another trait
48+
= help: only type `()` implements the trait, consider using it directly instead
2249

23-
error: aborting due to 1 previous error
50+
error: aborting due to 3 previous errors
2451

52+
For more information about this error, try `rustc --explain E0038`.

tests/ui/object-safety/issue-106247.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//@ check-pass
22

3-
#![deny(where_clauses_object_safety)]
4-
53
pub trait Trait {
64
fn method(&self) where Self: Sync;
75
}

tests/ui/traits/vtable/vtable-vacant.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//@ build-fail
22
#![feature(rustc_attrs)]
33
#![feature(negative_impls)]
4-
#![allow(where_clauses_object_safety)]
54

65
// B --> A
76

tests/ui/traits/vtable/vtable-vacant.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ error: vtable entries for `<S as B>`: [
77
Method(<S as B>::foo_b1),
88
Vacant,
99
]
10-
--> $DIR/vtable-vacant.rs:15:1
10+
--> $DIR/vtable-vacant.rs:14:1
1111
|
1212
LL | trait B: A {
1313
| ^^^^^^^^^^

0 commit comments

Comments
 (0)