Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fca5c64
Point at arguments or output when fn obligations come from them, or i…
estebank Jan 18, 2020
1c9242f
Point at `Sized` bound
estebank Jan 19, 2020
d72bcdb
When object unsafe trait uses itself in associated item suggest using…
estebank Jan 20, 2020
0eb29d1
fix test
estebank Jan 20, 2020
d137b7a
review comments
estebank Jan 25, 2020
4b2f1db
Tweak `Self: Sized` restriction diagnostic output
estebank Jan 29, 2020
972ae5a
Point at the `Sized` obligation in `where` clauses
estebank Jan 29, 2020
8d48597
Point at return type obligations instead of at `fn` ident
estebank Jan 29, 2020
6870f79
Use more accurate failed predicate spans
estebank Jan 30, 2020
144e259
Slight rewording of diagnostic message
estebank Jan 30, 2020
132921b
Remove duplicated code
estebank Jan 30, 2020
06fea92
review comments
estebank Jan 31, 2020
3ca1c5d
Point at `Sized` requirements
estebank Jan 31, 2020
413bfa4
Wording changes to object unsafe trait errors
estebank Feb 1, 2020
a52ec87
Use more appropriate spans on object unsafe traits and provide struct…
estebank Feb 1, 2020
542130b
add tests for structured suggestion
estebank Feb 1, 2020
cb6dfea
Suggest `?Sized` on type parameters
estebank Feb 2, 2020
d216b73
Remove duplicated code
estebank Feb 2, 2020
342db71
Account for `?Sized` type parameter bounds
estebank Feb 2, 2020
16d935e
fix rebase
estebank Feb 2, 2020
865216b
Point at reason in object unsafe trait with `Self` in supertraits or …
estebank Feb 2, 2020
b9c125a
Deal with spans showing `std` lib
estebank Feb 2, 2020
0e58411
Change wording for object unsafe because of assoc const
estebank Feb 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Point at Sized bound
  • Loading branch information
estebank committed Feb 2, 2020
commit 1c9242f83fdea3e4c7a452d1453370ee81a900af
40 changes: 33 additions & 7 deletions src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::iter::{self};
#[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>`).
Expand All @@ -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 => {
Expand Down Expand Up @@ -80,6 +80,7 @@ impl ObjectSafetyViolation {
// diagnostics use a `note` instead of a `span_label`.
match *self {
ObjectSafetyViolation::AssocConst(_, span)
| ObjectSafetyViolation::SizedSelf(span)
| ObjectSafetyViolation::Method(_, _, span)
if span != DUMMY_SP =>
{
Expand Down Expand Up @@ -179,17 +180,20 @@ 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,
&format!(
"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
Expand All @@ -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);
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
|
Expand Down Expand Up @@ -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
|
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/issues/issue-20692.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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
|
Expand Down
3 changes: 1 addition & 2 deletions src/test/ui/issues/issue-50781.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

3 changes: 3 additions & 0 deletions src/test/ui/object-safety/object-safety-sized.curr.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand Down
Original file line number Diff line number Diff line change
@@ -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
|
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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
|
Expand All @@ -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
|
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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
|
Expand All @@ -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
|
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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
|
Expand Down