Skip to content

Commit 4910206

Browse files
authoredJun 19, 2020
Rollup merge of rust-lang#73261 - estebank:generics-sized, r=nikomatsakis
Suggest `?Sized` when applicable for ADTs Address rust-lang#71790, fix rust-lang#27964.
2 parents 17064da + 40b27ff commit 4910206

17 files changed

+352
-34
lines changed
 

‎src/librustc_hir/hir.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -2741,14 +2741,8 @@ impl Node<'_> {
27412741
pub fn generics(&self) -> Option<&Generics<'_>> {
27422742
match self {
27432743
Node::TraitItem(TraitItem { generics, .. })
2744-
| Node::ImplItem(ImplItem { generics, .. })
2745-
| Node::Item(Item {
2746-
kind:
2747-
ItemKind::Trait(_, _, generics, ..)
2748-
| ItemKind::Impl { generics, .. }
2749-
| ItemKind::Fn(_, generics, _),
2750-
..
2751-
}) => Some(generics),
2744+
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
2745+
Node::Item(item) => item.kind.generics(),
27522746
_ => None,
27532747
}
27542748
}

‎src/librustc_trait_selection/traits/error_reporting/mod.rs

+130-26
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxHashMap;
1515
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
1616
use rustc_hir as hir;
1717
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
18+
use rustc_hir::intravisit::Visitor;
1819
use rustc_hir::Node;
1920
use rustc_middle::mir::interpret::ErrorHandled;
2021
use rustc_middle::ty::error::ExpectedFound;
@@ -25,7 +26,7 @@ use rustc_middle::ty::{
2526
TypeFoldable, WithConstness,
2627
};
2728
use rustc_session::DiagnosticMessageId;
28-
use rustc_span::{ExpnKind, Span, DUMMY_SP};
29+
use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP};
2930
use std::fmt;
3031

3132
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -1695,36 +1696,95 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
16951696
err: &mut DiagnosticBuilder<'tcx>,
16961697
obligation: &PredicateObligation<'tcx>,
16971698
) {
1698-
if let (
1699-
ty::PredicateKind::Trait(pred, _),
1700-
ObligationCauseCode::BindingObligation(item_def_id, span),
1701-
) = (obligation.predicate.kind(), &obligation.cause.code)
1702-
{
1703-
if let (Some(generics), true) = (
1704-
self.tcx.hir().get_if_local(*item_def_id).as_ref().and_then(|n| n.generics()),
1705-
Some(pred.def_id()) == self.tcx.lang_items().sized_trait(),
1706-
) {
1707-
for param in generics.params {
1708-
if param.span == *span
1709-
&& !param.bounds.iter().any(|bound| {
1710-
bound.trait_ref().and_then(|trait_ref| trait_ref.trait_def_id())
1711-
== self.tcx.lang_items().sized_trait()
1712-
})
1713-
{
1714-
let (span, separator) = match param.bounds {
1715-
[] => (span.shrink_to_hi(), ":"),
1716-
[.., bound] => (bound.span().shrink_to_hi(), " +"),
1717-
};
1718-
err.span_suggestion_verbose(
1719-
span,
1720-
"consider relaxing the implicit `Sized` restriction",
1721-
format!("{} ?Sized", separator),
1722-
Applicability::MachineApplicable,
1699+
let (pred, item_def_id, span) =
1700+
match (obligation.predicate.kind(), &obligation.cause.code.peel_derives()) {
1701+
(
1702+
ty::PredicateKind::Trait(pred, _),
1703+
ObligationCauseCode::BindingObligation(item_def_id, span),
1704+
) => (pred, item_def_id, span),
1705+
_ => return,
1706+
};
1707+
1708+
let node = match (
1709+
self.tcx.hir().get_if_local(*item_def_id),
1710+
Some(pred.def_id()) == self.tcx.lang_items().sized_trait(),
1711+
) {
1712+
(Some(node), true) => node,
1713+
_ => return,
1714+
};
1715+
let generics = match node.generics() {
1716+
Some(generics) => generics,
1717+
None => return,
1718+
};
1719+
for param in generics.params {
1720+
if param.span != *span
1721+
|| param.bounds.iter().any(|bound| {
1722+
bound.trait_ref().and_then(|trait_ref| trait_ref.trait_def_id())
1723+
== self.tcx.lang_items().sized_trait()
1724+
})
1725+
{
1726+
continue;
1727+
}
1728+
match node {
1729+
hir::Node::Item(
1730+
item
1731+
@
1732+
hir::Item {
1733+
kind:
1734+
hir::ItemKind::Enum(..)
1735+
| hir::ItemKind::Struct(..)
1736+
| hir::ItemKind::Union(..),
1737+
..
1738+
},
1739+
) => {
1740+
// Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a
1741+
// borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S<T: ?Sized>(T);`
1742+
// is not.
1743+
let mut visitor = FindTypeParam {
1744+
param: param.name.ident().name,
1745+
invalid_spans: vec![],
1746+
nested: false,
1747+
};
1748+
visitor.visit_item(item);
1749+
if !visitor.invalid_spans.is_empty() {
1750+
let mut multispan: MultiSpan = param.span.into();
1751+
multispan.push_span_label(
1752+
param.span,
1753+
format!("this could be changed to `{}: ?Sized`...", param.name.ident()),
1754+
);
1755+
for sp in visitor.invalid_spans {
1756+
multispan.push_span_label(
1757+
sp,
1758+
format!(
1759+
"...if indirection was used here: `Box<{}>`",
1760+
param.name.ident(),
1761+
),
1762+
);
1763+
}
1764+
err.span_help(
1765+
multispan,
1766+
&format!(
1767+
"you could relax the implicit `Sized` bound on `{T}` if it were \
1768+
used through indirection like `&{T}` or `Box<{T}>`",
1769+
T = param.name.ident(),
1770+
),
17231771
);
17241772
return;
17251773
}
17261774
}
1775+
_ => {}
17271776
}
1777+
let (span, separator) = match param.bounds {
1778+
[] => (span.shrink_to_hi(), ":"),
1779+
[.., bound] => (bound.span().shrink_to_hi(), " +"),
1780+
};
1781+
err.span_suggestion_verbose(
1782+
span,
1783+
"consider relaxing the implicit `Sized` restriction",
1784+
format!("{} ?Sized", separator),
1785+
Applicability::MachineApplicable,
1786+
);
1787+
return;
17281788
}
17291789
}
17301790

@@ -1744,6 +1804,50 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
17441804
}
17451805
}
17461806

1807+
/// Look for type `param` in an ADT being used only through a reference to confirm that suggesting
1808+
/// `param: ?Sized` would be a valid constraint.
1809+
struct FindTypeParam {
1810+
param: rustc_span::Symbol,
1811+
invalid_spans: Vec<Span>,
1812+
nested: bool,
1813+
}
1814+
1815+
impl<'v> Visitor<'v> for FindTypeParam {
1816+
type Map = rustc_hir::intravisit::ErasedMap<'v>;
1817+
1818+
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
1819+
hir::intravisit::NestedVisitorMap::None
1820+
}
1821+
1822+
fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
1823+
// We collect the spans of all uses of the "bare" type param, like in `field: T` or
1824+
// `field: (T, T)` where we could make `T: ?Sized` while skipping cases that are known to be
1825+
// valid like `field: &'a T` or `field: *mut T` and cases that *might* have further `Sized`
1826+
// obligations like `Box<T>` and `Vec<T>`, but we perform no extra analysis for those cases
1827+
// and suggest `T: ?Sized` regardless of their obligations. This is fine because the errors
1828+
// in that case should make what happened clear enough.
1829+
match ty.kind {
1830+
hir::TyKind::Ptr(_) | hir::TyKind::Rptr(..) | hir::TyKind::TraitObject(..) => {}
1831+
hir::TyKind::Path(hir::QPath::Resolved(None, path))
1832+
if path.segments.len() == 1 && path.segments[0].ident.name == self.param =>
1833+
{
1834+
if !self.nested {
1835+
self.invalid_spans.push(ty.span);
1836+
}
1837+
}
1838+
hir::TyKind::Path(_) => {
1839+
let prev = self.nested;
1840+
self.nested = true;
1841+
hir::intravisit::walk_ty(self, ty);
1842+
self.nested = prev;
1843+
}
1844+
_ => {
1845+
hir::intravisit::walk_ty(self, ty);
1846+
}
1847+
}
1848+
}
1849+
}
1850+
17471851
pub fn recursive_type_with_infinite_size_error(
17481852
tcx: TyCtxt<'tcx>,
17491853
type_def_id: DefId,

‎src/test/ui/dst/dst-sized-trait-param.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ LL | impl Foo<[isize]> for usize { }
99
|
1010
= help: the trait `std::marker::Sized` is not implemented for `[isize]`
1111
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12+
help: consider relaxing the implicit `Sized` restriction
13+
|
14+
LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is sized
15+
| ^^^^^^^^
1216

1317
error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
1418
--> $DIR/dst-sized-trait-param.rs:10:6

‎src/test/ui/extern/extern-types-unsized.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ LL | assert_sized::<Foo>();
2626
= help: within `Foo`, the trait `std::marker::Sized` is not implemented for `A`
2727
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
2828
= note: required because it appears within the type `Foo`
29+
help: consider relaxing the implicit `Sized` restriction
30+
|
31+
LL | fn assert_sized<T: ?Sized>() { }
32+
| ^^^^^^^^
2933

3034
error[E0277]: the size for values of type `A` cannot be known at compilation time
3135
--> $DIR/extern-types-unsized.rs:28:5
@@ -39,6 +43,10 @@ LL | assert_sized::<Bar<A>>();
3943
= help: within `Bar<A>`, the trait `std::marker::Sized` is not implemented for `A`
4044
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
4145
= note: required because it appears within the type `Bar<A>`
46+
help: consider relaxing the implicit `Sized` restriction
47+
|
48+
LL | fn assert_sized<T: ?Sized>() { }
49+
| ^^^^^^^^
4250

4351
error[E0277]: the size for values of type `A` cannot be known at compilation time
4452
--> $DIR/extern-types-unsized.rs:31:5
@@ -53,6 +61,10 @@ LL | assert_sized::<Bar<Bar<A>>>();
5361
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
5462
= note: required because it appears within the type `Bar<A>`
5563
= note: required because it appears within the type `Bar<Bar<A>>`
64+
help: consider relaxing the implicit `Sized` restriction
65+
|
66+
LL | fn assert_sized<T: ?Sized>() { }
67+
| ^^^^^^^^
5668

5769
error: aborting due to 4 previous errors
5870

‎src/test/ui/issues/issue-10412.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ LL | impl<'self> Serializable<str> for &'self str {
5757
|
5858
= help: the trait `std::marker::Sized` is not implemented for `str`
5959
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
60+
help: consider relaxing the implicit `Sized` restriction
61+
|
62+
LL | trait Serializable<'self, T: ?Sized> {
63+
| ^^^^^^^^
6064

6165
error: aborting due to 9 previous errors
6266

‎src/test/ui/issues/issue-18919.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ LL | enum Option<T> {
99
|
1010
= help: the trait `std::marker::Sized` is not implemented for `dyn for<'r> std::ops::Fn(&'r isize) -> isize`
1111
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
13+
--> $DIR/issue-18919.rs:7:13
14+
|
15+
LL | enum Option<T> {
16+
| ^ this could be changed to `T: ?Sized`...
17+
LL | Some(T),
18+
| - ...if indirection was used here: `Box<T>`
1219

1320
error: aborting due to previous error
1421

‎src/test/ui/issues/issue-23281.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ LL | struct Vec<T> {
99
|
1010
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::Fn() + 'static)`
1111
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
13+
--> $DIR/issue-23281.rs:8:12
14+
|
15+
LL | struct Vec<T> {
16+
| ^ this could be changed to `T: ?Sized`...
17+
LL | t: T,
18+
| - ...if indirection was used here: `Box<T>`
1219

1320
error: aborting due to previous error
1421

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
trait Trait {
2+
fn func1() -> Struct1<Self>; //~ ERROR E0277
3+
fn func2<'a>() -> Struct2<'a, Self>; //~ ERROR E0277
4+
fn func3() -> Struct3<Self>; //~ ERROR E0277
5+
fn func4() -> Struct4<Self>; //~ ERROR E0277
6+
}
7+
8+
struct Struct1<T>{
9+
_t: std::marker::PhantomData<*const T>,
10+
}
11+
struct Struct2<'a, T>{
12+
_t: &'a T,
13+
}
14+
struct Struct3<T>{
15+
_t: T,
16+
}
17+
18+
struct X<T>(T);
19+
20+
struct Struct4<T>{
21+
_t: X<T>,
22+
}
23+
24+
struct Struct5<T: ?Sized>{
25+
_t: X<T>, //~ ERROR E0277
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
error[E0277]: the size for values of type `T` cannot be known at compilation time
2+
--> $DIR/adt-param-with-implicit-sized-bound.rs:25:5
3+
|
4+
LL | struct X<T>(T);
5+
| - required by this bound in `X`
6+
...
7+
LL | struct Struct5<T: ?Sized>{
8+
| - this type parameter needs to be `std::marker::Sized`
9+
LL | _t: X<T>,
10+
| ^^^^^^^^ doesn't have a size known at compile-time
11+
|
12+
= help: the trait `std::marker::Sized` is not implemented for `T`
13+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
15+
--> $DIR/adt-param-with-implicit-sized-bound.rs:18:10
16+
|
17+
LL | struct X<T>(T);
18+
| ^ - ...if indirection was used here: `Box<T>`
19+
| |
20+
| this could be changed to `T: ?Sized`...
21+
22+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
23+
--> $DIR/adt-param-with-implicit-sized-bound.rs:2:19
24+
|
25+
LL | fn func1() -> Struct1<Self>;
26+
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
27+
...
28+
LL | struct Struct1<T>{
29+
| - required by this bound in `Struct1`
30+
|
31+
= help: the trait `std::marker::Sized` is not implemented for `Self`
32+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
33+
help: consider further restricting `Self`
34+
|
35+
LL | fn func1() -> Struct1<Self> where Self: std::marker::Sized;
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
help: consider relaxing the implicit `Sized` restriction
38+
|
39+
LL | struct Struct1<T: ?Sized>{
40+
| ^^^^^^^^
41+
42+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
43+
--> $DIR/adt-param-with-implicit-sized-bound.rs:3:23
44+
|
45+
LL | fn func2<'a>() -> Struct2<'a, Self>;
46+
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
47+
...
48+
LL | struct Struct2<'a, T>{
49+
| - required by this bound in `Struct2`
50+
|
51+
= help: the trait `std::marker::Sized` is not implemented for `Self`
52+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
53+
help: consider further restricting `Self`
54+
|
55+
LL | fn func2<'a>() -> Struct2<'a, Self> where Self: std::marker::Sized;
56+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57+
help: consider relaxing the implicit `Sized` restriction
58+
|
59+
LL | struct Struct2<'a, T: ?Sized>{
60+
| ^^^^^^^^
61+
62+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
63+
--> $DIR/adt-param-with-implicit-sized-bound.rs:4:19
64+
|
65+
LL | fn func3() -> Struct3<Self>;
66+
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
67+
...
68+
LL | struct Struct3<T>{
69+
| - required by this bound in `Struct3`
70+
|
71+
= help: the trait `std::marker::Sized` is not implemented for `Self`
72+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
73+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
74+
--> $DIR/adt-param-with-implicit-sized-bound.rs:14:16
75+
|
76+
LL | struct Struct3<T>{
77+
| ^ this could be changed to `T: ?Sized`...
78+
LL | _t: T,
79+
| - ...if indirection was used here: `Box<T>`
80+
help: consider further restricting `Self`
81+
|
82+
LL | fn func3() -> Struct3<Self> where Self: std::marker::Sized;
83+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84+
85+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
86+
--> $DIR/adt-param-with-implicit-sized-bound.rs:5:19
87+
|
88+
LL | fn func4() -> Struct4<Self>;
89+
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
90+
...
91+
LL | struct Struct4<T>{
92+
| - required by this bound in `Struct4`
93+
|
94+
= help: the trait `std::marker::Sized` is not implemented for `Self`
95+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
96+
help: consider further restricting `Self`
97+
|
98+
LL | fn func4() -> Struct4<Self> where Self: std::marker::Sized;
99+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
100+
help: consider relaxing the implicit `Sized` restriction
101+
|
102+
LL | struct Struct4<T: ?Sized>{
103+
| ^^^^^^^^
104+
105+
error: aborting due to 5 previous errors
106+
107+
For more information about this error, try `rustc --explain E0277`.

‎src/test/ui/unsized/unsized-enum.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `T`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: you could relax the implicit `Sized` bound on `U` if it were used through indirection like `&U` or `Box<U>`
15+
--> $DIR/unsized-enum.rs:4:10
16+
|
17+
LL | enum Foo<U> { FooSome(U), FooNone }
18+
| ^ - ...if indirection was used here: `Box<U>`
19+
| |
20+
| this could be changed to `U: ?Sized`...
1421

1522
error: aborting due to previous error
1623

‎src/test/ui/unsized/unsized-inherent-impl-self-type.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ LL | impl<X: ?Sized> S5<X> {
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `X`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box<Y>`
15+
--> $DIR/unsized-inherent-impl-self-type.rs:5:11
16+
|
17+
LL | struct S5<Y>(Y);
18+
| ^ - ...if indirection was used here: `Box<Y>`
19+
| |
20+
| this could be changed to `Y: ?Sized`...
1421

1522
error: aborting due to previous error
1623

‎src/test/ui/unsized/unsized-struct.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `T`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
15+
--> $DIR/unsized-struct.rs:4:12
16+
|
17+
LL | struct Foo<T> { data: T }
18+
| ^ - ...if indirection was used here: `Box<T>`
19+
| |
20+
| this could be changed to `T: ?Sized`...
1421

1522
error[E0277]: the size for values of type `T` cannot be known at compilation time
1623
--> $DIR/unsized-struct.rs:13:24

‎src/test/ui/unsized/unsized-trait-impl-self-type.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ LL | impl<X: ?Sized> T3<X> for S5<X> {
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `X`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box<Y>`
15+
--> $DIR/unsized-trait-impl-self-type.rs:8:11
16+
|
17+
LL | struct S5<Y>(Y);
18+
| ^ - ...if indirection was used here: `Box<Y>`
19+
| |
20+
| this could be changed to `Y: ?Sized`...
1421

1522
error: aborting due to previous error
1623

‎src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ LL | impl<X: ?Sized> T2<X> for S4<X> {
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `X`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: consider relaxing the implicit `Sized` restriction
15+
|
16+
LL | trait T2<Z: ?Sized> {
17+
| ^^^^^^^^
1418

1519
error: aborting due to previous error
1620

‎src/test/ui/unsized3.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ LL | f5(x1);
4848
= help: within `S<X>`, the trait `std::marker::Sized` is not implemented for `X`
4949
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
5050
= note: required because it appears within the type `S<X>`
51+
help: consider relaxing the implicit `Sized` restriction
52+
|
53+
LL | fn f5<Y: ?Sized>(x: &Y) {}
54+
| ^^^^^^^^
5155

5256
error[E0277]: the size for values of type `X` cannot be known at compilation time
5357
--> $DIR/unsized3.rs:40:8
@@ -91,6 +95,10 @@ LL | f5(&(32, *x1));
9195
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9296
= note: required because it appears within the type `S<X>`
9397
= note: required because it appears within the type `({integer}, S<X>)`
98+
help: consider relaxing the implicit `Sized` restriction
99+
|
100+
LL | fn f5<Y: ?Sized>(x: &Y) {}
101+
| ^^^^^^^^
94102

95103
error: aborting due to 6 previous errors
96104

‎src/test/ui/unsized7.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ LL | impl<X: ?Sized + T> T1<X> for S3<X> {
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `X`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
help: consider relaxing the implicit `Sized` restriction
15+
|
16+
LL | trait T1<Z: T + ?Sized> {
17+
| ^^^^^^^^
1418

1519
error: aborting due to previous error
1620

‎src/test/ui/wf/wf-fn-where-clause.stderr

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ LL | struct Vec<T> {
2323
|
2424
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::marker::Copy + 'static)`
2525
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
26+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
27+
--> $DIR/wf-fn-where-clause.rs:16:12
28+
|
29+
LL | struct Vec<T> {
30+
| ^ this could be changed to `T: ?Sized`...
31+
LL | t: T,
32+
| - ...if indirection was used here: `Box<T>`
2633

2734
error[E0038]: the trait `std::marker::Copy` cannot be made into an object
2835
--> $DIR/wf-fn-where-clause.rs:12:16

0 commit comments

Comments
 (0)
Please sign in to comment.