Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 28e6f1f

Browse files
committed
Suggest boxing or borrowing unsized fields
1 parent a15bda4 commit 28e6f1f

30 files changed

+424
-106
lines changed

src/librustc_middle/traits/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ pub enum ObligationCauseCode<'tcx> {
229229
/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
230230
FieldSized {
231231
adt_kind: AdtKind,
232+
span: Span,
232233
last: bool,
233234
},
234235

src/librustc_middle/traits/structural_impls.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
156156
super::SizedYieldType => Some(super::SizedYieldType),
157157
super::InlineAsmSized => Some(super::InlineAsmSized),
158158
super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)),
159-
super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
159+
super::FieldSized { adt_kind, span, last } => {
160+
Some(super::FieldSized { adt_kind, span, last })
161+
}
160162
super::ConstSized => Some(super::ConstSized),
161163
super::ConstPatternStructural => Some(super::ConstPatternStructural),
162164
super::SharedStatic => Some(super::SharedStatic),

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,26 +1856,43 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18561856
ObligationCauseCode::StructInitializerSized => {
18571857
err.note("structs must have a statically known size to be initialized");
18581858
}
1859-
ObligationCauseCode::FieldSized { adt_kind: ref item, last } => match *item {
1860-
AdtKind::Struct => {
1861-
if last {
1862-
err.note(
1863-
"the last field of a packed struct may only have a \
1864-
dynamically sized type if it does not need drop to be run",
1865-
);
1866-
} else {
1867-
err.note(
1868-
"only the last field of a struct may have a dynamically sized type",
1869-
);
1859+
ObligationCauseCode::FieldSized { adt_kind: ref item, last, span } => {
1860+
match *item {
1861+
AdtKind::Struct => {
1862+
if last {
1863+
err.note(
1864+
"the last field of a packed struct may only have a \
1865+
dynamically sized type if it does not need drop to be run",
1866+
);
1867+
} else {
1868+
err.note(
1869+
"only the last field of a struct may have a dynamically sized type",
1870+
);
1871+
}
1872+
}
1873+
AdtKind::Union => {
1874+
err.note("no field of a union may have a dynamically sized type");
1875+
}
1876+
AdtKind::Enum => {
1877+
err.note("no field of an enum variant may have a dynamically sized type");
18701878
}
18711879
}
1872-
AdtKind::Union => {
1873-
err.note("no field of a union may have a dynamically sized type");
1874-
}
1875-
AdtKind::Enum => {
1876-
err.note("no field of an enum variant may have a dynamically sized type");
1877-
}
1878-
},
1880+
err.help("change the field's type to have a statically known size");
1881+
err.span_suggestion(
1882+
span.shrink_to_lo(),
1883+
"borrowed types always have a statically known size",
1884+
"&".to_string(),
1885+
Applicability::MachineApplicable,
1886+
);
1887+
err.multipart_suggestion(
1888+
"heap allocated types always have a statically known size",
1889+
vec![
1890+
(span.shrink_to_lo(), "Box<".to_string()),
1891+
(span.shrink_to_hi(), ">".to_string()),
1892+
],
1893+
Applicability::MachineApplicable,
1894+
);
1895+
}
18791896
ObligationCauseCode::ConstSized => {
18801897
err.note("constant expressions must have a statically known size");
18811898
}

src/librustc_typeck/check/wfcheck.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ fn check_type_defn<'tcx, F>(
394394
Some(i) => i,
395395
None => bug!(),
396396
},
397+
span: field.span,
397398
last,
398399
},
399400
),
@@ -1329,7 +1330,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13291330
let field_ty = self.normalize_associated_types_in(field.ty.span, &field_ty);
13301331
let field_ty = self.resolve_vars_if_possible(&field_ty);
13311332
debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty);
1332-
AdtField { ty: field_ty, span: field.span }
1333+
AdtField { ty: field_ty, span: field.ty.span }
13331334
})
13341335
.collect();
13351336
AdtVariant { fields, explicit_discr: None }

src/test/ui/const-generics/array-size-in-generic-struct-param.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
1616
= note: this may fail depending on what value the parameter takes
1717

1818
error: constant expression depends on a generic parameter
19-
--> $DIR/array-size-in-generic-struct-param.rs:14:5
19+
--> $DIR/array-size-in-generic-struct-param.rs:14:10
2020
|
2121
LL | arr: [u8; CFG.arr_size],
22-
| ^^^^^^^^^^^^^^^^^^^^^^^
22+
| ^^^^^^^^^^^^^^^^^^
2323
|
2424
= note: this may fail depending on what value the parameter takes
2525

src/test/ui/error-codes/E0478.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0478]: lifetime bound not satisfied
2-
--> $DIR/E0478.rs:4:5
2+
--> $DIR/E0478.rs:4:12
33
|
44
LL | child: Box<dyn Wedding<'kiss> + 'SnowWhite>,
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: lifetime parameter instantiated with the lifetime `'SnowWhite` as defined on the struct at 3:22
88
--> $DIR/E0478.rs:3:22

src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
error[E0310]: the parameter type `U` may not live long enough
2-
--> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:5
2+
--> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:10
33
|
44
LL | struct Foo<U> {
55
| - help: consider adding an explicit lifetime bound...: `U: 'static`
66
LL | bar: Bar<U>
7-
| ^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds
7+
| ^^^^^^ ...so that the type `U` will meet its required lifetime bounds
88

99
error: aborting due to previous error
1010

src/test/ui/issues/issue-19380.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0038]: the trait `Qiz` cannot be made into an object
2-
--> $DIR/issue-19380.rs:11:3
2+
--> $DIR/issue-19380.rs:11:9
33
|
44
LL | trait Qiz {
55
| --- this trait cannot be made into an object...
66
LL | fn qiz();
77
| --- ...because associated function `qiz` has no `self` parameter
88
...
99
LL | foos: &'static [&'static (dyn Qiz + 'static)]
10-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
10+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
1111
|
1212
help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
1313
|

src/test/ui/issues/issue-22874.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `[std::string::String]` cannot be known at compilation time
2-
--> $DIR/issue-22874.rs:2:5
2+
--> $DIR/issue-22874.rs:2:11
33
|
44
LL | rows: [[String]],
5-
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
5+
| ^^^^^^^^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `[std::string::String]`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/issues/issue-27060-2.stderr

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
error[E0277]: the size for values of type `T` cannot be known at compilation time
2-
--> $DIR/issue-27060-2.rs:3:5
2+
--> $DIR/issue-27060-2.rs:3:11
33
|
44
LL | pub struct Bad<T: ?Sized> {
55
| - this type parameter needs to be `std::marker::Sized`
66
LL | data: T,
7-
| ^^^^^^^ doesn't have a size known at compile-time
7+
| ^ doesn't have a size known at compile-time
88
|
99
= help: the trait `std::marker::Sized` is not implemented for `T`
1010
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
1111
= note: the last field of a packed struct may only have a dynamically sized type if it does not need drop to be run
12+
= help: change the field's type to have a statically known size
13+
help: borrowed types always have a statically known size
14+
|
15+
LL | data: &T,
16+
| ^
17+
help: heap allocated types always have a statically known size
18+
|
19+
LL | data: Box<T>,
20+
| ^^^^ ^
1221

1322
error: aborting due to previous error
1423

0 commit comments

Comments
 (0)