Skip to content

Commit e2b95cb

Browse files
committed
Lift some Sized checks.
1 parent 7f05304 commit e2b95cb

File tree

18 files changed

+140
-14
lines changed

18 files changed

+140
-14
lines changed

src/librustc/traits/error_reporting.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,9 +1454,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
14541454
}
14551455
ObligationCauseCode::VariableType(_) => {
14561456
err.note("all local variables must have a statically known size");
1457+
if !self.tcx.features().unsized_locals {
1458+
err.help("unsized locals are gated as an unstable feature");
1459+
}
14571460
}
14581461
ObligationCauseCode::SizedArgumentType => {
14591462
err.note("all function arguments must have a statically known size");
1463+
if !self.tcx.features().unsized_locals {
1464+
err.help("unsized locals are gated as an unstable feature");
1465+
}
14601466
}
14611467
ObligationCauseCode::SizedReturnType => {
14621468
err.note("the return type of a function must have a \

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -903,11 +903,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
903903
);
904904
}
905905
self.check_rvalue(mir, rv, location);
906-
let trait_ref = ty::TraitRef {
907-
def_id: tcx.lang_items().sized_trait().unwrap(),
908-
substs: tcx.mk_substs_trait(place_ty, &[]),
909-
};
910-
self.prove_trait_ref(trait_ref, location.interesting());
906+
if !self.tcx().features().unsized_locals {
907+
let trait_ref = ty::TraitRef {
908+
def_id: tcx.lang_items().sized_trait().unwrap(),
909+
substs: tcx.mk_substs_trait(place_ty, &[]),
910+
};
911+
self.prove_trait_ref(trait_ref, location.interesting());
912+
}
911913
}
912914
StatementKind::SetDiscriminant {
913915
ref place,
@@ -962,6 +964,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
962964
mir: &Mir<'tcx>,
963965
term: &Terminator<'tcx>,
964966
term_location: Location,
967+
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
965968
) {
966969
debug!("check_terminator: {:?}", term);
967970
let tcx = self.tcx();
@@ -1041,7 +1044,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10411044
&sig,
10421045
);
10431046
let sig = self.normalize(sig, term_location);
1044-
self.check_call_dest(mir, term, &sig, destination, term_location);
1047+
self.check_call_dest(mir, term, &sig, destination, term_location, errors_buffer);
10451048

10461049
self.prove_predicates(
10471050
sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
@@ -1115,6 +1118,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11151118
sig: &ty::FnSig<'tcx>,
11161119
destination: &Option<(Place<'tcx>, BasicBlock)>,
11171120
term_location: Location,
1121+
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
11181122
) {
11191123
let tcx = self.tcx();
11201124
match *destination {
@@ -1143,6 +1147,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11431147
terr
11441148
);
11451149
}
1150+
1151+
// When `#![feature(unsized_locals)]` is not enabled,
1152+
// this check is done at `check_local`.
1153+
if self.tcx().features().unsized_locals {
1154+
let span = term.source_info.span;
1155+
self.ensure_place_sized(dest_ty, span, errors_buffer);
1156+
}
11461157
}
11471158
None => {
11481159
// FIXME(canndrew): This is_never should probably be an is_uninhabited
@@ -1309,14 +1320,26 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13091320
LocalKind::Var | LocalKind::Temp => {}
13101321
}
13111322

1312-
let span = local_decl.source_info.span;
1313-
let ty = local_decl.ty;
1323+
// When `#![feature(unsized_locals)]` is enabled, only function calls
1324+
// are checked in `check_call_dest`.
1325+
if !self.tcx().features().unsized_locals {
1326+
let span = local_decl.source_info.span;
1327+
let ty = local_decl.ty;
1328+
self.ensure_place_sized(ty, span, errors_buffer);
1329+
}
1330+
}
1331+
1332+
fn ensure_place_sized(&mut self,
1333+
ty: Ty<'tcx>,
1334+
span: Span,
1335+
errors_buffer: &mut Option<&mut Vec<Diagnostic>>) {
1336+
let tcx = self.tcx();
13141337

13151338
// Erase the regions from `ty` to get a global type. The
13161339
// `Sized` bound in no way depends on precise regions, so this
13171340
// shouldn't affect `is_sized`.
1318-
let gcx = self.tcx().global_tcx();
1319-
let erased_ty = gcx.lift(&self.tcx().erase_regions(&ty)).unwrap();
1341+
let gcx = tcx.global_tcx();
1342+
let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
13201343
if !erased_ty.is_sized(gcx.at(span), self.param_env) {
13211344
// in current MIR construction, all non-control-flow rvalue
13221345
// expressions evaluate through `as_temp` or `into` a return
@@ -1838,7 +1861,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
18381861
location.statement_index += 1;
18391862
}
18401863

1841-
self.check_terminator(mir, block_data.terminator(), location);
1864+
self.check_terminator(mir, block_data.terminator(), location, &mut errors_buffer);
18421865
self.check_iscleanup(mir, block_data);
18431866
}
18441867
}

src/librustc_typeck/check/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -961,8 +961,10 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
961961
if let PatKind::Binding(_, _, ident, _) = p.node {
962962
let var_ty = self.assign(p.span, p.id, None);
963963

964-
self.fcx.require_type_is_sized(var_ty, p.span,
965-
traits::VariableType(p.id));
964+
if !self.fcx.tcx.features().unsized_locals {
965+
self.fcx.require_type_is_sized(var_ty, p.span,
966+
traits::VariableType(p.id));
967+
}
966968

967969
debug!("Pattern binding {} is assigned to {} with type {:?}",
968970
ident,
@@ -1048,7 +1050,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
10481050
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
10491051
// for simple cases like `fn foo(x: Trait)`,
10501052
// where we would error once on the parameter as a whole, and once on the binding `x`.
1051-
if arg.pat.simple_ident().is_none() {
1053+
if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
10521054
fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
10531055
}
10541056

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(unsized_tuple_coercion, unsized_locals)]
12+
13+
struct A<X: ?Sized>(X);
14+
15+
fn udrop<T: ?Sized>(_x: T) {}
16+
fn foo() -> Box<[u8]> {
17+
Box::new(*b"foo")
18+
}
19+
fn tfoo() -> Box<(i32, [u8])> {
20+
Box::new((42, *b"foo"))
21+
}
22+
fn afoo() -> Box<A<[u8]>> {
23+
Box::new(A(*b"foo"))
24+
}
25+
26+
impl std::ops::Add<i32> for A<[u8]> {
27+
type Output = ();
28+
fn add(self, _rhs: i32) -> Self::Output {}
29+
}
30+
31+
fn main() {
32+
udrop::<(i32, [u8])>((42, *foo()));
33+
//~^ERROR E0277
34+
udrop::<A<[u8]>>(A { 0: *foo() });
35+
//~^ERROR E0277
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(unsized_tuple_coercion, unsized_locals)]
12+
13+
struct A<X: ?Sized>(X);
14+
15+
fn udrop<T: ?Sized>(_x: T) {}
16+
fn foo() -> Box<[u8]> {
17+
Box::new(*b"foo")
18+
}
19+
fn tfoo() -> Box<(i32, [u8])> {
20+
Box::new((42, *b"foo"))
21+
}
22+
fn afoo() -> Box<A<[u8]>> {
23+
Box::new(A(*b"foo"))
24+
}
25+
26+
impl std::ops::Add<i32> for A<[u8]> {
27+
type Output = ();
28+
fn add(self, _rhs: i32) -> Self::Output {}
29+
}
30+
31+
fn main() {
32+
udrop::<[u8]>(foo()[..]);
33+
//~^ERROR cannot move out of indexed content
34+
// FIXME: should be error
35+
udrop::<A<[u8]>>(A(*foo()));
36+
}

src/test/ui/associated-types/associated-types-unsized.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | let x = t.get(); //~ ERROR the size for values of type
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= help: consider adding a `where <T as Get>::Value: std::marker::Sized` bound
1010
= note: all local variables must have a statically known size
11+
= help: unsized locals are gated as an unstable feature
1112

1213
error: aborting due to previous error
1314

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | fn f(p: Path) { }
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: required because it appears within the type `std::path::Path`
1010
= note: all local variables must have a statically known size
11+
= help: unsized locals are gated as an unstable feature
1112

1213
error[E0277]: the trait bound `i32: Foo` is not satisfied
1314
--> $DIR/E0277.rs:27:5

src/test/ui/feature-gate-unsized_locals.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | fn f(f: FnOnce()) {}
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce() + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all local variables must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error: aborting due to previous error
1213

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | &mut something
77
= help: the trait `std::marker::Sized` is not implemented for `[T]`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all local variables must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error: aborting due to previous error
1213

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | fn foo(self) -> &'static i32 {
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= help: consider adding a `where Self: std::marker::Sized` bound
1010
= note: all local variables must have a statically known size
11+
= help: unsized locals are gated as an unstable feature
1112

1213
error: aborting due to previous error
1314

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | fn _test(ref _p: str) {}
77
= help: the trait `std::marker::Sized` is not implemented for `str`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all function arguments must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error: aborting due to previous error
1213

src/test/ui/issues/issue-41229-ref-str.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | pub fn example(ref s: str) {}
77
= help: the trait `std::marker::Sized` is not implemented for `str`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all function arguments must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error: aborting due to previous error
1213

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | fn baz(_: Self::Target) where Self: Deref {}
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= help: consider adding a `where <Self as std::ops::Deref>::Target: std::marker::Sized` bound
1010
= note: all function arguments must have a statically known size
11+
= help: unsized locals are gated as an unstable feature
1112

1213
error[E0277]: the size for values of type `(dyn std::string::ToString + 'static)` cannot be known at compilation time
1314
--> $DIR/issue-42312.rs:18:23
@@ -18,6 +19,7 @@ LL | pub fn f(_: ToString) {}
1819
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::string::ToString + 'static)`
1920
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
2021
= note: all function arguments must have a statically known size
22+
= help: unsized locals are gated as an unstable feature
2123

2224
error: aborting due to 2 previous errors
2325

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | fn new_struct(r: A+'static)
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all local variables must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
1213
--> $DIR/issue-5883.rs:18:8

src/test/ui/resolve/issue-5035-2.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | fn foo(_x: K) {}
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all local variables must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error: aborting due to previous error
1213

src/test/ui/str/str-array-assignment.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ LL | let v = s[..2];
3030
= help: the trait `std::marker::Sized` is not implemented for `str`
3131
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
3232
= note: all local variables must have a statically known size
33+
= help: unsized locals are gated as an unstable feature
3334

3435
error[E0308]: mismatched types
3536
--> $DIR/str-array-assignment.rs:19:17

src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | fn foo(_x: Foo + Send) {
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + std::marker::Send + 'static)`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= note: all local variables must have a statically known size
10+
= help: unsized locals are gated as an unstable feature
1011

1112
error: aborting due to previous error
1213

src/test/ui/unsized6.stderr

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | let y: Y;
88
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
99
= help: consider adding a `where Y: std::marker::Sized` bound
1010
= note: all local variables must have a statically known size
11+
= help: unsized locals are gated as an unstable feature
1112

1213
error[E0277]: the size for values of type `X` cannot be known at compilation time
1314
--> $DIR/unsized6.rs:17:12
@@ -41,6 +42,7 @@ LL | let y: X;
4142
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
4243
= help: consider adding a `where X: std::marker::Sized` bound
4344
= note: all local variables must have a statically known size
45+
= help: unsized locals are gated as an unstable feature
4446

4547
error[E0277]: the size for values of type `Y` cannot be known at compilation time
4648
--> $DIR/unsized6.rs:27:12
@@ -63,6 +65,7 @@ LL | let y: X = *x1;
6365
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
6466
= help: consider adding a `where X: std::marker::Sized` bound
6567
= note: all local variables must have a statically known size
68+
= help: unsized locals are gated as an unstable feature
6669

6770
error[E0277]: the size for values of type `X` cannot be known at compilation time
6871
--> $DIR/unsized6.rs:34:9
@@ -74,6 +77,7 @@ LL | let y = *x2;
7477
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
7578
= help: consider adding a `where X: std::marker::Sized` bound
7679
= note: all local variables must have a statically known size
80+
= help: unsized locals are gated as an unstable feature
7781

7882
error[E0277]: the size for values of type `X` cannot be known at compilation time
7983
--> $DIR/unsized6.rs:36:10
@@ -85,6 +89,7 @@ LL | let (y, z) = (*x3, 4);
8589
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
8690
= help: consider adding a `where X: std::marker::Sized` bound
8791
= note: all local variables must have a statically known size
92+
= help: unsized locals are gated as an unstable feature
8893

8994
error[E0277]: the size for values of type `X` cannot be known at compilation time
9095
--> $DIR/unsized6.rs:40:9
@@ -96,6 +101,7 @@ LL | let y: X = *x1;
96101
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
97102
= help: consider adding a `where X: std::marker::Sized` bound
98103
= note: all local variables must have a statically known size
104+
= help: unsized locals are gated as an unstable feature
99105

100106
error[E0277]: the size for values of type `X` cannot be known at compilation time
101107
--> $DIR/unsized6.rs:42:9
@@ -107,6 +113,7 @@ LL | let y = *x2;
107113
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
108114
= help: consider adding a `where X: std::marker::Sized` bound
109115
= note: all local variables must have a statically known size
116+
= help: unsized locals are gated as an unstable feature
110117

111118
error[E0277]: the size for values of type `X` cannot be known at compilation time
112119
--> $DIR/unsized6.rs:44:10
@@ -118,6 +125,7 @@ LL | let (y, z) = (*x3, 4);
118125
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
119126
= help: consider adding a `where X: std::marker::Sized` bound
120127
= note: all local variables must have a statically known size
128+
= help: unsized locals are gated as an unstable feature
121129

122130
error[E0277]: the size for values of type `X` cannot be known at compilation time
123131
--> $DIR/unsized6.rs:48:18
@@ -129,6 +137,7 @@ LL | fn g1<X: ?Sized>(x: X) {}
129137
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
130138
= help: consider adding a `where X: std::marker::Sized` bound
131139
= note: all local variables must have a statically known size
140+
= help: unsized locals are gated as an unstable feature
132141

133142
error[E0277]: the size for values of type `X` cannot be known at compilation time
134143
--> $DIR/unsized6.rs:50:22
@@ -140,6 +149,7 @@ LL | fn g2<X: ?Sized + T>(x: X) {}
140149
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
141150
= help: consider adding a `where X: std::marker::Sized` bound
142151
= note: all local variables must have a statically known size
152+
= help: unsized locals are gated as an unstable feature
143153

144154
error: aborting due to 13 previous errors
145155

0 commit comments

Comments
 (0)