Skip to content

Commit d6de40b

Browse files
committed
Make is_object_safe a query and move lint_object_unsafe_trait call there
1 parent e144a13 commit d6de40b

File tree

3 files changed

+35
-18
lines changed

3 files changed

+35
-18
lines changed

compiler/rustc_middle/src/query/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,9 @@ rustc_queries! {
12741274
query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
12751275
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
12761276
}
1277+
query is_object_safe(trait_id: DefId) -> bool {
1278+
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
1279+
}
12771280

12781281
/// Gets the ParameterEnvironment for a given item; this environment
12791282
/// will be in "user-facing" mode, meaning that it is suitable for

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,10 +2471,6 @@ impl<'tcx> TyCtxt<'tcx> {
24712471
}
24722472
}
24732473

2474-
pub fn is_object_safe(self, key: DefId) -> bool {
2475-
self.object_safety_violations(key).is_empty()
2476-
}
2477-
24782474
#[inline]
24792475
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
24802476
matches!(

compiler/rustc_trait_selection/src/traits/object_safety.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,37 @@ fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &'_ [Object
6262
)
6363
}
6464

65+
fn is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
66+
let violations = tcx.object_safety_violations(trait_def_id);
67+
68+
if violations.is_empty() {
69+
return true;
70+
}
71+
72+
// If the trait contains any other violations, then let the error reporting path
73+
// report it instead of emitting a warning here.
74+
if violations.iter().all(|violation| {
75+
matches!(
76+
violation,
77+
ObjectSafetyViolation::Method(_, MethodViolationCode::WhereClauseReferencesSelf, _)
78+
)
79+
}) {
80+
for violation in violations {
81+
if let ObjectSafetyViolation::Method(
82+
_,
83+
MethodViolationCode::WhereClauseReferencesSelf,
84+
span,
85+
) = violation
86+
{
87+
lint_object_unsafe_trait(tcx, *span, trait_def_id, &violation);
88+
}
89+
}
90+
return true;
91+
}
92+
93+
false
94+
}
95+
6596
/// We say a method is *vtable safe* if it can be invoked on a trait
6697
/// object. Note that object-safe traits can have some
6798
/// non-vtable-safe methods, so long as they require `Self: Sized` or
@@ -93,19 +124,6 @@ fn object_safety_violations_for_trait(
93124
object_safety_violation_for_method(tcx, trait_def_id, &item)
94125
.map(|(code, span)| ObjectSafetyViolation::Method(item.name, code, span))
95126
})
96-
.filter(|violation| {
97-
if let ObjectSafetyViolation::Method(
98-
_,
99-
MethodViolationCode::WhereClauseReferencesSelf,
100-
span,
101-
) = violation
102-
{
103-
lint_object_unsafe_trait(tcx, *span, trait_def_id, &violation);
104-
false
105-
} else {
106-
true
107-
}
108-
})
109127
.collect();
110128

111129
// Check the trait itself.
@@ -866,5 +884,5 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
866884
}
867885

868886
pub fn provide(providers: &mut ty::query::Providers) {
869-
*providers = ty::query::Providers { object_safety_violations, ..*providers };
887+
*providers = ty::query::Providers { object_safety_violations, is_object_safe, ..*providers };
870888
}

0 commit comments

Comments
 (0)