@@ -24,6 +24,7 @@ use std::fmt;
24
24
use syntax:: ast;
25
25
use syntax_pos:: { Span , DUMMY_SP } ;
26
26
27
+ use rustc_data_structures:: fx:: FxHashSet ;
27
28
use rustc_data_structures:: indexed_vec:: Idx ;
28
29
29
30
fn mirbug ( tcx : TyCtxt , span : Span , msg : & str ) {
@@ -87,6 +88,11 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
87
88
self . sanitize_type ( rvalue, rval_ty) ;
88
89
}
89
90
91
+ fn visit_local_decl ( & mut self , local_decl : & LocalDecl < ' tcx > ) {
92
+ self . super_local_decl ( local_decl) ;
93
+ self . sanitize_type ( local_decl, local_decl. ty ) ;
94
+ }
95
+
90
96
fn visit_mir ( & mut self , mir : & Mir < ' tcx > ) {
91
97
self . sanitize_type ( & "return type" , mir. return_ty ) ;
92
98
for local_decl in & mir. local_decls {
@@ -317,6 +323,7 @@ pub struct TypeChecker<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
317
323
fulfillment_cx : traits:: FulfillmentContext < ' tcx > ,
318
324
last_span : Span ,
319
325
body_id : ast:: NodeId ,
326
+ reported_errors : FxHashSet < ( Ty < ' tcx > , Span ) > ,
320
327
}
321
328
322
329
impl < ' a , ' gcx , ' tcx > TypeChecker < ' a , ' gcx , ' tcx > {
@@ -326,6 +333,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
326
333
fulfillment_cx : traits:: FulfillmentContext :: new ( ) ,
327
334
last_span : DUMMY_SP ,
328
335
body_id : body_id,
336
+ reported_errors : FxHashSet ( ) ,
329
337
}
330
338
}
331
339
@@ -641,9 +649,39 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
641
649
}
642
650
}
643
651
644
- fn typeck_mir ( & mut self , mir : & Mir < ' tcx > ) {
652
+ fn check_local ( & mut self , mir : & Mir < ' gcx > , local : Local , local_decl : & LocalDecl < ' gcx > ) {
653
+ match mir. local_kind ( local) {
654
+ LocalKind :: ReturnPointer | LocalKind :: Arg => {
655
+ // return values of normal functions are required to be
656
+ // sized by typeck, but return values of ADT constructors are
657
+ // not because we don't include a `Self: Sized` bounds on them.
658
+ //
659
+ // Unbound parts of arguments were never required to be Sized
660
+ // - maybe we should make that a warning.
661
+ return
662
+ }
663
+ LocalKind :: Var | LocalKind :: Temp => { }
664
+ }
665
+
666
+ let span = local_decl. source_info . span ;
667
+ let ty = local_decl. ty ;
668
+ if !ty. is_sized ( self . tcx ( ) . global_tcx ( ) , self . infcx . param_env ( ) , span) {
669
+ if let None = self . reported_errors . replace ( ( ty, span) ) {
670
+ span_err ! ( self . tcx( ) . sess, span, E0161 ,
671
+ "cannot move a value of type {0}: the size of {0} \
672
+ cannot be statically determined", ty) ;
673
+ }
674
+ }
675
+ }
676
+
677
+ fn typeck_mir ( & mut self , mir : & Mir < ' gcx > ) {
645
678
self . last_span = mir. span ;
646
679
debug ! ( "run_on_mir: {:?}" , mir. span) ;
680
+
681
+ for ( local, local_decl) in mir. local_decls . iter_enumerated ( ) {
682
+ self . check_local ( mir, local, local_decl) ;
683
+ }
684
+
647
685
for block in mir. basic_blocks ( ) {
648
686
for stmt in & block. statements {
649
687
if stmt. source_info . span != DUMMY_SP {
@@ -698,16 +736,18 @@ impl TypeckMir {
698
736
impl < ' tcx > MirPass < ' tcx > for TypeckMir {
699
737
fn run_pass < ' a > ( & mut self , tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
700
738
src : MirSource , mir : & mut Mir < ' tcx > ) {
701
- debug ! ( "run_pass: {}" , tcx. node_path_str( src. item_id( ) ) ) ;
739
+ let item_id = src. item_id ( ) ;
740
+ let def_id = tcx. hir . local_def_id ( item_id) ;
741
+ debug ! ( "run_pass: {}" , tcx. item_path_str( def_id) ) ;
702
742
703
743
if tcx. sess . err_count ( ) > 0 {
704
744
// compiling a broken program can obviously result in a
705
745
// broken MIR, so try not to report duplicate errors.
706
746
return ;
707
747
}
708
- let param_env = ty:: ParameterEnvironment :: for_item ( tcx, src . item_id ( ) ) ;
748
+ let param_env = ty:: ParameterEnvironment :: for_item ( tcx, item_id) ;
709
749
tcx. infer_ctxt ( param_env, Reveal :: UserFacing ) . enter ( |infcx| {
710
- let mut checker = TypeChecker :: new ( & infcx, src . item_id ( ) ) ;
750
+ let mut checker = TypeChecker :: new ( & infcx, item_id) ;
711
751
{
712
752
let mut verifier = TypeVerifier :: new ( & mut checker, mir) ;
713
753
verifier. visit_mir ( mir) ;
0 commit comments