Make is_object_safe
a query and move lint_object_unsafe_trait call there
This commit is contained in:
parent
e144a13254
commit
d6de40b536
3 changed files with 35 additions and 18 deletions
|
@ -1274,6 +1274,9 @@ rustc_queries! {
|
||||||
query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
|
query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
|
||||||
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
||||||
}
|
}
|
||||||
|
query is_object_safe(trait_id: DefId) -> bool {
|
||||||
|
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the ParameterEnvironment for a given item; this environment
|
/// Gets the ParameterEnvironment for a given item; this environment
|
||||||
/// will be in "user-facing" mode, meaning that it is suitable for
|
/// will be in "user-facing" mode, meaning that it is suitable for
|
||||||
|
|
|
@ -2471,10 +2471,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_object_safe(self, key: DefId) -> bool {
|
|
||||||
self.object_safety_violations(key).is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
|
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
|
|
|
@ -62,6 +62,37 @@ fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &'_ [Object
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
|
||||||
|
let violations = tcx.object_safety_violations(trait_def_id);
|
||||||
|
|
||||||
|
if violations.is_empty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the trait contains any other violations, then let the error reporting path
|
||||||
|
// report it instead of emitting a warning here.
|
||||||
|
if violations.iter().all(|violation| {
|
||||||
|
matches!(
|
||||||
|
violation,
|
||||||
|
ObjectSafetyViolation::Method(_, MethodViolationCode::WhereClauseReferencesSelf, _)
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
for violation in violations {
|
||||||
|
if let ObjectSafetyViolation::Method(
|
||||||
|
_,
|
||||||
|
MethodViolationCode::WhereClauseReferencesSelf,
|
||||||
|
span,
|
||||||
|
) = violation
|
||||||
|
{
|
||||||
|
lint_object_unsafe_trait(tcx, *span, trait_def_id, &violation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// We say a method is *vtable safe* if it can be invoked on a trait
|
/// We say a method is *vtable safe* if it can be invoked on a trait
|
||||||
/// object. Note that object-safe traits can have some
|
/// object. Note that object-safe traits can have some
|
||||||
/// non-vtable-safe methods, so long as they require `Self: Sized` or
|
/// non-vtable-safe methods, so long as they require `Self: Sized` or
|
||||||
|
@ -93,19 +124,6 @@ fn object_safety_violations_for_trait(
|
||||||
object_safety_violation_for_method(tcx, trait_def_id, &item)
|
object_safety_violation_for_method(tcx, trait_def_id, &item)
|
||||||
.map(|(code, span)| ObjectSafetyViolation::Method(item.name, code, span))
|
.map(|(code, span)| ObjectSafetyViolation::Method(item.name, code, span))
|
||||||
})
|
})
|
||||||
.filter(|violation| {
|
|
||||||
if let ObjectSafetyViolation::Method(
|
|
||||||
_,
|
|
||||||
MethodViolationCode::WhereClauseReferencesSelf,
|
|
||||||
span,
|
|
||||||
) = violation
|
|
||||||
{
|
|
||||||
lint_object_unsafe_trait(tcx, *span, trait_def_id, &violation);
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Check the trait itself.
|
// Check the trait itself.
|
||||||
|
@ -866,5 +884,5 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
*providers = ty::query::Providers { object_safety_violations, ..*providers };
|
*providers = ty::query::Providers { object_safety_violations, is_object_safe, ..*providers };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue