]> git.lizzy.rs Git - rust.git/commitdiff
Point at `Sized` bound
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 19 Jan 2020 22:53:37 +0000 (14:53 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Sun, 2 Feb 2020 19:52:34 +0000 (11:52 -0800)
src/librustc/traits/object_safety.rs
src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
src/test/ui/issues/issue-20692.stderr
src/test/ui/issues/issue-50781.stderr
src/test/ui/object-safety/object-safety-sized.curr.stderr
src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
src/test/ui/wf/wf-unsafe-trait-obj-match.stderr

index 15f81bb3f47ed5e3e33d707d82e42a9d47291306..bca0ecb1e79dc24f8c99616b8dbcf5dd129703b5 100644 (file)
@@ -26,7 +26,7 @@
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation {
     /// `Self: Sized` declared on the trait.
-    SizedSelf,
+    SizedSelf(Span),
 
     /// Supertrait reference references `Self` an in illegal location
     /// (e.g., `trait Foo : Bar<Self>`).
@@ -42,7 +42,7 @@ pub enum ObjectSafetyViolation {
 impl ObjectSafetyViolation {
     pub fn error_msg(&self) -> Cow<'static, str> {
         match *self {
-            ObjectSafetyViolation::SizedSelf => {
+            ObjectSafetyViolation::SizedSelf(_) => {
                 "the trait cannot require that `Self : Sized`".into()
             }
             ObjectSafetyViolation::SupertraitSelf => {
@@ -80,6 +80,7 @@ pub fn span(&self) -> Option<Span> {
         // diagnostics use a `note` instead of a `span_label`.
         match *self {
             ObjectSafetyViolation::AssocConst(_, span)
+            | ObjectSafetyViolation::SizedSelf(span)
             | ObjectSafetyViolation::Method(_, _, span)
                 if span != DUMMY_SP =>
             {
@@ -179,7 +180,7 @@ 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.struct_span_lint_hir(
+                let mut err = tcx.struct_span_lint_hir(
                     WHERE_CLAUSES_OBJECT_SAFETY,
                     hir::CRATE_HIR_ID,
                     *span,
@@ -187,9 +188,12 @@ fn object_safety_violations_for_trait(
                         "the trait `{}` cannot be made into an object",
                         tcx.def_path_str(trait_def_id)
                     ),
-                )
-                .note(&violation.error_msg())
-                .emit();
+                );
+                match violation.span() {
+                    Some(span) => err.span_label(span, violation.error_msg()),
+                    None => err.note(&violation.error_msg()),
+                };
+                err.emit();
                 false
             } else {
                 true
@@ -199,7 +203,8 @@ fn object_safety_violations_for_trait(
 
     // Check the trait itself.
     if trait_has_sized_self(tcx, trait_def_id) {
-        violations.push(ObjectSafetyViolation::SizedSelf);
+        let span = get_sized_bound(tcx, trait_def_id);
+        violations.push(ObjectSafetyViolation::SizedSelf(span));
     }
     if predicates_reference_self(tcx, trait_def_id, false) {
         violations.push(ObjectSafetyViolation::SupertraitSelf);
@@ -219,6 +224,27 @@ fn object_safety_violations_for_trait(
     violations
 }
 
+fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span {
+    tcx.hir()
+        .get_if_local(trait_def_id)
+        .and_then(|node| match node {
+            hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds
+                .iter()
+                .filter_map(|b| match b {
+                    hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None)
+                        if Some(trait_ref.trait_ref.trait_def_id())
+                            == tcx.lang_items().sized_trait() =>
+                    {
+                        Some(trait_ref.span)
+                    }
+                    _ => None,
+                })
+                .next(),
+            _ => None,
+        })
+        .unwrap_or(DUMMY_SP)
+}
+
 fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool {
     let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
     let predicates = if supertraits_only {
index a2409621db310add50056be747f0eba4cb96cd31..de362e1cef0fd182631547e23b6c4f44dcc65ff1 100644 (file)
@@ -1,6 +1,9 @@
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
    |
+LL | trait NonObjectSafe1: Sized {}
+   |                       ----- the trait cannot require that `Self : Sized`
+...
 LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
    |                                      ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
    |
@@ -36,6 +39,9 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
    |
+LL | trait NonObjectSafe1: Sized {}
+   |                       ----- the trait cannot require that `Self : Sized`
+...
 LL | impl Trait for dyn NonObjectSafe1 {}
    |      ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
    |
index 06c83f65be26c7b01fd3e26d9a11533097a44eca..4757742a707b18f389a6c3adb17eac0c3188cf52 100644 (file)
@@ -1,6 +1,9 @@
 error[E0038]: the trait `Array` cannot be made into an object
   --> $DIR/issue-20692.rs:7:5
    |
+LL | trait Array: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     &dyn Array;
    |     ^^^^^^^^^^ the trait `Array` cannot be made into an object
    |
@@ -9,6 +12,9 @@ LL |     &dyn Array;
 error[E0038]: the trait `Array` cannot be made into an object
   --> $DIR/issue-20692.rs:4:13
    |
+LL | trait Array: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     let _ = x
    |             ^ the trait `Array` cannot be made into an object
    |
index cb6ca24c7124aa4087f2d8fab90be5775e86f35f..c161e9efd1261330955af821da3d69d11af5a5cd 100644 (file)
@@ -2,7 +2,7 @@ error: the trait `X` cannot be made into an object
   --> $DIR/issue-50781.rs:6:8
    |
 LL |     fn foo(&self) where Self: Trait;
-   |        ^^^
+   |        ^^^ method `foo` references the `Self` type in where clauses
    |
 note: the lint level is defined here
   --> $DIR/issue-50781.rs:1:9
@@ -11,7 +11,6 @@ LL | #![deny(where_clauses_object_safety)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
-   = note: method `foo` references the `Self` type in where clauses
 
 error: aborting due to previous error
 
index 0f284fc85073ebf0726cd7fc0ca131bdb69b3bc4..be0a2519a469b362acae628c1660c5ce4bfaed03 100644 (file)
@@ -1,6 +1,9 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized.rs:12:30
    |
+LL | trait Bar : Sized {
+   |             ----- the trait cannot require that `Self : Sized`
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
    |
index 3d88dfc40ed385eb40eda611c9f8d7e6744b0740..c20ddee54c07ece43b394fd955c3c41204e65672 100644 (file)
@@ -1,6 +1,9 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized.rs:14:5
    |
+LL | trait Bar : Sized {
+   |             ----- the trait cannot require that `Self : Sized`
+...
 LL |     t
    |     ^ the trait `Bar` cannot be made into an object
    |
index 0b63aef2bce1077110a722478c4f15c60b0124f1..4c033cfcd898bac34a329ad3991d8baf729f2b24 100644 (file)
@@ -1,6 +1,9 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     let t_box: Box<dyn Trait> = Box::new(S);
    |                                 ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
    |
@@ -11,6 +14,9 @@ LL |     let t_box: Box<dyn Trait> = Box::new(S);
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     takes_box(Box::new(S));
    |               ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
    |
@@ -21,6 +27,9 @@ LL |     takes_box(Box::new(S));
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     Box::new(S) as Box<dyn Trait>;
    |     ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
    |
index 7aeefd731fb28d6afbcbb997201edf4612167e6b..ba3792c362e86d7fb9ab9f65d4c48afc9460581e 100644 (file)
@@ -1,6 +1,9 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     let t: &dyn Trait = &S;
    |                         ^^ the trait `Trait` cannot be made into an object
    |
@@ -11,6 +14,9 @@ LL |     let t: &dyn Trait = &S;
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     takes_trait(&S);
    |                 ^^ the trait `Trait` cannot be made into an object
    |
@@ -21,6 +27,9 @@ LL |     takes_trait(&S);
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     &S as &dyn Trait;
    |     ^^ the trait `Trait` cannot be made into an object
    |
index 594fad4138505fcfb0e28b2ec430d370894a59ff..a0082578d4d068d09447ea32e989acf3061d35aa 100644 (file)
@@ -15,6 +15,9 @@ LL | |     }
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-unsafe-trait-obj-match.rs:26:21
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |         Some(()) => &S,
    |                     ^^ the trait `Trait` cannot be made into an object
    |
@@ -25,6 +28,9 @@ LL |         Some(()) => &S,
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-unsafe-trait-obj-match.rs:25:25
    |
+LL | trait Trait: Sized {}
+   |              ----- the trait cannot require that `Self : Sized`
+...
 LL |     let t: &dyn Trait = match opt() {
    |                         ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
    |