Skip to content

Commit 77bc26f

Browse files
committed
Require yield types to be sized
1 parent 7a6f68c commit 77bc26f

File tree

6 files changed

+55
-1
lines changed

6 files changed

+55
-1
lines changed

src/librustc/traits/error_reporting.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12611261
err.note("the return type of a function must have a \
12621262
statically known size");
12631263
}
1264+
ObligationCauseCode::SizedYieldType => {
1265+
err.note("the yield type of a generator must have a \
1266+
statically known size");
1267+
}
12641268
ObligationCauseCode::AssignmentLhsSized => {
12651269
err.note("the left-hand-side of an assignment must have a statically known size");
12661270
}

src/librustc/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ pub enum ObligationCauseCode<'tcx> {
138138
VariableType(ast::NodeId),
139139
/// Return type must be Sized
140140
SizedReturnType,
141+
/// Yield type must be Sized
142+
SizedYieldType,
141143
/// [T,..n] --> T must be Copy
142144
RepeatVec,
143145

src/librustc/traits/structural_impls.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
209209
super::VariableType(id) => Some(super::VariableType(id)),
210210
super::ReturnType(id) => Some(super::ReturnType(id)),
211211
super::SizedReturnType => Some(super::SizedReturnType),
212+
super::SizedYieldType => Some(super::SizedYieldType),
212213
super::RepeatVec => Some(super::RepeatVec),
213214
super::FieldSized(item) => Some(super::FieldSized(item)),
214215
super::ConstSized => Some(super::ConstSized),
@@ -526,6 +527,7 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
526527
super::VariableType(_) |
527528
super::ReturnType(_) |
528529
super::SizedReturnType |
530+
super::SizedYieldType |
529531
super::ReturnNoExpression |
530532
super::RepeatVec |
531533
super::FieldSized(_) |
@@ -574,6 +576,7 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
574576
super::VariableType(_) |
575577
super::ReturnType(_) |
576578
super::SizedReturnType |
579+
super::SizedYieldType |
577580
super::ReturnNoExpression |
578581
super::RepeatVec |
579582
super::FieldSized(_) |

src/librustc_typeck/check/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
10011001
let span = body.value.span;
10021002

10031003
if body.is_generator && can_be_generator.is_some() {
1004-
fcx.yield_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
1004+
let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
1005+
fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1006+
fcx.yield_ty = Some(yield_ty);
10051007
}
10061008

10071009
GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);

src/test/ui/generator/sized-yield.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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(generators, generator_trait)]
12+
13+
use std::ops::Generator;
14+
15+
fn main() {
16+
let s = String::from("foo");
17+
let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
18+
yield s[..];
19+
};
20+
gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
2+
--> $DIR/sized-yield.rs:17:26
3+
|
4+
17 | let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
5+
| __________________________^
6+
18 | | yield s[..];
7+
19 | | };
8+
| |____^ `str` does not have a constant size known at compile-time
9+
|
10+
= help: the trait `std::marker::Sized` is not implemented for `str`
11+
= note: the yield type of a generator must have a statically known size
12+
13+
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
14+
--> $DIR/sized-yield.rs:20:8
15+
|
16+
20 | gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
17+
| ^^^^^^ `str` does not have a constant size known at compile-time
18+
|
19+
= help: the trait `std::marker::Sized` is not implemented for `str`
20+
21+
error: aborting due to 2 previous errors
22+

0 commit comments

Comments
 (0)