use crate::infer::{self, SuppressRegionErrors};
use crate::middle::region;
use crate::traits::error_reporting::report_object_safety_error;
+use crate::traits::object_safety_violations;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
};
let failure_code = trace.cause.as_failure_code(terr);
let mut diag = match failure_code {
FailureCode::Error0038(did) => {
- let violations = self.tcx.object_safety_violations(did);
+ let violations = object_safety_violations(self.tcx, did);
report_object_safety_error(self.tcx, span, did, violations)
}
FailureCode::Error0317(failure_str) => {
use crate::infer::{self, InferCtxt};
use crate::mir::interpret::ErrorHandled;
use crate::session::DiagnosticMessageId;
+use crate::traits::object_safety_violations;
use crate::ty::error::ExpectedFound;
use crate::ty::fast_reject;
use crate::ty::fold::TypeFolder;
}
ty::Predicate::ObjectSafe(trait_def_id) => {
- let violations = self.tcx.object_safety_violations(trait_def_id);
+ let violations = object_safety_violations(self.tcx, trait_def_id);
report_object_safety_error(self.tcx, span, trait_def_id, violations)
}
}
TraitNotObjectSafe(did) => {
- let violations = self.tcx.object_safety_violations(did);
+ let violations = object_safety_violations(self.tcx, did);
report_object_safety_error(self.tcx, span, did, violations)
}
pub use self::coherence::{OrphanCheckErr, OverlapResult};
pub use self::engine::{TraitEngine, TraitEngineExt};
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
+pub use self::object_safety::astconv_object_safety_violations;
+pub use self::object_safety::is_vtable_safe_method;
+pub use self::object_safety::object_safety_violations;
pub use self::object_safety::MethodViolationCode;
pub use self::object_safety::ObjectSafetyViolation;
pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
let def_id = trait_method.def_id;
// Some methods cannot be called on an object; skip those.
- if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
+ if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) {
debug!("vtable_methods: not vtable safe");
return None;
}
UndispatchableReceiver,
}
-impl<'tcx> TyCtxt<'tcx> {
- /// Returns the object safety violations that affect
- /// astconv -- currently, `Self` in supertraits. This is needed
- /// because `object_safety_violations` can't be used during
- /// type collection.
- pub fn astconv_object_safety_violations(
- self,
- trait_def_id: DefId,
- ) -> Vec<ObjectSafetyViolation> {
- debug_assert!(self.generics_of(trait_def_id).has_self);
- let violations = traits::supertrait_def_ids(self, trait_def_id)
- .filter(|&def_id| predicates_reference_self(self, def_id, true))
- .map(|_| ObjectSafetyViolation::SupertraitSelf)
- .collect();
+/// Returns the object safety violations that affect
+/// astconv -- currently, `Self` in supertraits. This is needed
+/// because `object_safety_violations` can't be used during
+/// type collection.
+pub fn astconv_object_safety_violations(
+ tcx: TyCtxt<'_>,
+ trait_def_id: DefId,
+) -> Vec<ObjectSafetyViolation> {
+ debug_assert!(tcx.generics_of(trait_def_id).has_self);
+ let violations = traits::supertrait_def_ids(tcx, trait_def_id)
+ .filter(|&def_id| predicates_reference_self(tcx, def_id, true))
+ .map(|_| ObjectSafetyViolation::SupertraitSelf)
+ .collect();
- debug!(
- "astconv_object_safety_violations(trait_def_id={:?}) = {:?}",
- trait_def_id, violations
- );
+ debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, violations);
- violations
- }
+ violations
+}
+
+pub fn object_safety_violations(
+ tcx: TyCtxt<'_>,
+ trait_def_id: DefId,
+) -> Vec<ObjectSafetyViolation> {
+ debug_assert!(tcx.generics_of(trait_def_id).has_self);
+ debug!("object_safety_violations: {:?}", trait_def_id);
- pub fn object_safety_violations(self, trait_def_id: DefId) -> Vec<ObjectSafetyViolation> {
- debug_assert!(self.generics_of(trait_def_id).has_self);
- debug!("object_safety_violations: {:?}", trait_def_id);
+ traits::supertrait_def_ids(tcx, trait_def_id)
+ .flat_map(|def_id| object_safety_violations_for_trait(tcx, def_id))
+ .collect()
+}
- traits::supertrait_def_ids(self, trait_def_id)
- .flat_map(|def_id| object_safety_violations_for_trait(self, def_id))
- .collect()
+/// 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
+/// otherwise ensure that they cannot be used when `Self = Trait`.
+pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: &ty::AssocItem) -> bool {
+ debug_assert!(tcx.generics_of(trait_def_id).has_self);
+ debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
+ // Any method that has a `Self: Sized` bound cannot be called.
+ if generics_require_sized_self(tcx, method.def_id) {
+ return 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
- /// otherwise ensure that they cannot be used when `Self = Trait`.
- pub fn is_vtable_safe_method(self, trait_def_id: DefId, method: &ty::AssocItem) -> bool {
- debug_assert!(self.generics_of(trait_def_id).has_self);
- debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
- // Any method that has a `Self: Sized` bound cannot be called.
- if generics_require_sized_self(self, method.def_id) {
- return false;
- }
-
- match virtual_call_violation_for_method(self, trait_def_id, method) {
- None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
- Some(_) => false,
- }
+ match virtual_call_violation_for_method(tcx, trait_def_id, method) {
+ None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
+ Some(_) => false,
}
}
}
pub(super) fn is_object_safe_provider(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
- tcx.object_safety_violations(trait_def_id).is_empty()
+ object_safety_violations(tcx, trait_def_id).is_empty()
}