]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/traits/object_safety.rs
Revert previous attempt at detecting unsatisfiable predicates
[rust.git] / src / librustc / traits / object_safety.rs
index 3c64a46661d05302601f88f1db0b9c10eaa6d8f7..ce57fb8110496036f86b0109aa636336a5f04f61 100644 (file)
 
 use super::elaborate_predicates;
 
-use crate::lint;
 use crate::traits::{self, Obligation, ObligationCause};
 use crate::ty::subst::{InternalSubsts, Subst};
 use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
+use syntax::ast;
+
 use std::borrow::Cow;
 use std::iter::{self};
-use syntax::ast::{self};
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation {
@@ -108,54 +109,52 @@ pub enum MethodViolationCode {
     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(self, trait_def_id: DefId) -> Vec<ObjectSafetyViolation> {
-        debug_assert!(self.generics_of(trait_def_id).has_self);
-        debug!("object_safety_violations: {:?}", trait_def_id);
+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);
 
-        traits::supertrait_def_ids(self, trait_def_id)
-            .flat_map(|def_id| object_safety_violations_for_trait(self, def_id))
-            .collect()
-    }
+    traits::supertrait_def_ids(tcx, trait_def_id)
+        .flat_map(|def_id| object_safety_violations_for_trait(tcx, 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(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;
-        }
+/// 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;
+    }
 
-        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,
     }
 }
 
@@ -180,16 +179,17 @@ fn object_safety_violations_for_trait(
             {
                 // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
                 // It's also hard to get a use site span, so we use the method definition span.
-                tcx.lint_node_note(
-                    lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY,
+                tcx.struct_span_lint_hir(
+                    WHERE_CLAUSES_OBJECT_SAFETY,
                     hir::CRATE_HIR_ID,
                     *span,
                     &format!(
                         "the trait `{}` cannot be made into an object",
                         tcx.def_path_str(trait_def_id)
                     ),
-                    &violation.error_msg(),
-                );
+                )
+                .note(&violation.error_msg())
+                .emit();
                 false
             } else {
                 true
@@ -724,5 +724,5 @@ fn contains_illegal_self_type_reference<'tcx>(
 }
 
 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()
 }