X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_trait_selection%2Fsrc%2Ftraits%2Fobject_safety.rs;h=565cfca9090e19c2c5e41d7d24fd0eb874661733;hb=b3b9383f8d1324ca2fd34a34cdd026ba40c2e935;hp=c9121212cd8f16b9b115ab1ac703b7895d793790;hpb=a5fa99eed20a46a88c0c85eed6552a94b6656634;p=rust.git diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index c9121212cd8..565cfca9090 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -62,6 +62,37 @@ fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &'_ [Object ) } +fn check_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 /// object. Note that object-safe traits can have some /// 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) .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(); // Check the trait itself. @@ -395,7 +413,7 @@ fn virtual_call_violation_for_method<'tcx>( trait_def_id: DefId, method: &ty::AssocItem, ) -> Option { - let sig = tcx.fn_sig(method.def_id); + let sig = tcx.fn_sig(method.def_id).subst_identity(); // The method's first parameter must be named `self` if !method.fn_has_self_parameter { @@ -866,5 +884,6 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>( } pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { object_safety_violations, ..*providers }; + *providers = + ty::query::Providers { object_safety_violations, check_is_object_safe, ..*providers }; }