@@ -146,13 +146,13 @@ impl<'tcx> ProjectedPlace<'tcx> {
146
146
}
147
147
}
148
148
149
- pub fn new (
149
+ pub fn try_new (
150
150
goto_expr : Expr ,
151
151
mir_typ_or_variant : TypeOrVariant < ' tcx > ,
152
152
fat_ptr_goto_expr : Option < Expr > ,
153
153
fat_ptr_mir_typ : Option < Ty < ' tcx > > ,
154
154
ctx : & mut GotocCtx < ' tcx > ,
155
- ) -> Self {
155
+ ) -> Result < Self , UnimplementedData > {
156
156
let mir_typ_or_variant = mir_typ_or_variant. monomorphize ( ctx) ;
157
157
let fat_ptr_mir_typ = fat_ptr_mir_typ. map ( |t| ctx. monomorphize ( t) ) ;
158
158
if let Some ( fat_ptr) = & fat_ptr_goto_expr {
@@ -173,6 +173,12 @@ impl<'tcx> ProjectedPlace<'tcx> {
173
173
"Unexpected type mismatch in projection:\n {:?}\n Expr type\n {:?}\n Type from MIR\n {:?}" ,
174
174
goto_expr, expr_ty, ty_from_mir
175
175
) ;
176
+ return Err ( UnimplementedData :: new (
177
+ "Projection mismatch" ,
178
+ "https://github.com/model-checking/kani/issues/277" ,
179
+ ty_from_mir,
180
+ * goto_expr. location ( ) ,
181
+ ) ) ;
176
182
}
177
183
178
184
assert ! (
@@ -181,7 +187,7 @@ impl<'tcx> ProjectedPlace<'tcx> {
181
187
& fat_ptr_goto_expr,
182
188
& fat_ptr_mir_typ
183
189
) ;
184
- ProjectedPlace { goto_expr, mir_typ_or_variant, fat_ptr_goto_expr, fat_ptr_mir_typ }
190
+ Ok ( ProjectedPlace { goto_expr, mir_typ_or_variant, fat_ptr_goto_expr, fat_ptr_mir_typ } )
185
191
}
186
192
}
187
193
@@ -395,18 +401,18 @@ impl<'tcx> GotocCtx<'tcx> {
395
401
_ => inner_goto_expr. dereference ( ) ,
396
402
} ;
397
403
let typ = TypeOrVariant :: Type ( inner_mir_typ) ;
398
- Ok ( ProjectedPlace :: new ( expr, typ, fat_ptr_goto_expr, fat_ptr_mir_typ, self ) )
404
+ ProjectedPlace :: try_new ( expr, typ, fat_ptr_goto_expr, fat_ptr_mir_typ, self )
399
405
}
400
406
ProjectionElem :: Field ( f, t) => {
401
407
let typ = TypeOrVariant :: Type ( t) ;
402
408
let expr = self . codegen_field ( before. goto_expr , before. mir_typ_or_variant , & f) ?;
403
- Ok ( ProjectedPlace :: new (
409
+ ProjectedPlace :: try_new (
404
410
expr,
405
411
typ,
406
412
before. fat_ptr_goto_expr ,
407
413
before. fat_ptr_mir_typ ,
408
414
self ,
409
- ) )
415
+ )
410
416
}
411
417
ProjectionElem :: Index ( i) => {
412
418
let base_type = before. mir_typ ( ) ;
@@ -420,16 +426,16 @@ impl<'tcx> GotocCtx<'tcx> {
420
426
ty:: Slice ( ..) => before. goto_expr . index ( idxe) ,
421
427
_ => unreachable ! ( "must index an array" ) ,
422
428
} ;
423
- Ok ( ProjectedPlace :: new (
429
+ ProjectedPlace :: try_new (
424
430
expr,
425
431
typ,
426
432
before. fat_ptr_goto_expr ,
427
433
before. fat_ptr_mir_typ ,
428
434
self ,
429
- ) )
435
+ )
430
436
}
431
437
ProjectionElem :: ConstantIndex { offset, min_length, from_end } => {
432
- Ok ( self . codegen_constant_index ( before, offset, min_length, from_end) )
438
+ self . codegen_constant_index ( before, offset, min_length, from_end)
433
439
}
434
440
// Best effort to codegen subslice projection.
435
441
// Full support to be added in
@@ -476,13 +482,13 @@ impl<'tcx> GotocCtx<'tcx> {
476
482
let from_elem = before. goto_expr . index ( index) ;
477
483
let data = from_elem. address_of ( ) ;
478
484
let fat_ptr = slice_fat_ptr ( goto_type, data, len, & self . symbol_table ) ;
479
- Ok ( ProjectedPlace :: new (
485
+ ProjectedPlace :: try_new (
480
486
fat_ptr. clone ( ) ,
481
487
TypeOrVariant :: Type ( ptr_typ) ,
482
488
Some ( fat_ptr) ,
483
489
Some ( ptr_typ) ,
484
490
self ,
485
- ) )
491
+ )
486
492
}
487
493
_ => unreachable ! ( "must be array or slice" ) ,
488
494
}
@@ -507,13 +513,13 @@ impl<'tcx> GotocCtx<'tcx> {
507
513
TagEncoding :: Niche { .. } => before. goto_expr ,
508
514
} ,
509
515
} ;
510
- Ok ( ProjectedPlace :: new (
516
+ ProjectedPlace :: try_new (
511
517
expr,
512
518
typ,
513
519
before. fat_ptr_goto_expr ,
514
520
before. fat_ptr_mir_typ ,
515
521
self ,
516
- ) )
522
+ )
517
523
}
518
524
_ => unreachable ! ( "it's a bug to reach here!" ) ,
519
525
}
@@ -535,10 +541,21 @@ impl<'tcx> GotocCtx<'tcx> {
535
541
let initial_expr = self . codegen_local ( p. local ) ;
536
542
let initial_typ = TypeOrVariant :: Type ( self . local_ty ( p. local ) ) ;
537
543
debug ! ( ?initial_typ, ?initial_expr, "codegen_place" ) ;
538
- let initial_projection = ProjectedPlace :: new ( initial_expr, initial_typ, None , None , self ) ;
539
- p. projection
544
+ let initial_projection =
545
+ ProjectedPlace :: try_new ( initial_expr, initial_typ, None , None , self ) ;
546
+ let result = p
547
+ . projection
540
548
. iter ( )
541
- . fold ( Ok ( initial_projection) , |accum, proj| self . codegen_projection ( accum, proj) )
549
+ . fold ( initial_projection, |accum, proj| self . codegen_projection ( accum, proj) ) ;
550
+ match result {
551
+ Err ( data) => Err ( UnimplementedData :: new (
552
+ & data. operation ,
553
+ & data. bug_url ,
554
+ self . codegen_ty ( self . place_ty ( p) ) ,
555
+ data. loc ,
556
+ ) ) ,
557
+ _ => result,
558
+ }
542
559
}
543
560
544
561
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.ProjectionElem.html
@@ -555,7 +572,7 @@ impl<'tcx> GotocCtx<'tcx> {
555
572
offset : u64 ,
556
573
min_length : u64 ,
557
574
from_end : bool ,
558
- ) -> ProjectedPlace < ' tcx > {
575
+ ) -> Result < ProjectedPlace < ' tcx > , UnimplementedData > {
559
576
match before. mir_typ ( ) . kind ( ) {
560
577
//TODO, ask on zulip if we can ever have from_end here?
561
578
ty:: Array ( elemt, length) => {
@@ -565,7 +582,7 @@ impl<'tcx> GotocCtx<'tcx> {
565
582
let idxe = Expr :: int_constant ( idx, Type :: ssize_t ( ) ) ;
566
583
let expr = self . codegen_idx_array ( before. goto_expr , idxe) ;
567
584
let typ = TypeOrVariant :: Type ( * elemt) ;
568
- ProjectedPlace :: new (
585
+ ProjectedPlace :: try_new (
569
586
expr,
570
587
typ,
571
588
before. fat_ptr_goto_expr ,
@@ -585,7 +602,7 @@ impl<'tcx> GotocCtx<'tcx> {
585
602
} ;
586
603
let expr = before. goto_expr . plus ( idxe) . dereference ( ) ;
587
604
let typ = TypeOrVariant :: Type ( * elemt) ;
588
- ProjectedPlace :: new (
605
+ ProjectedPlace :: try_new (
589
606
expr,
590
607
typ,
591
608
before. fat_ptr_goto_expr ,
0 commit comments