@@ -67,11 +67,12 @@ pub enum PathElem {
6767 Field ( Symbol ) ,
6868 Variant ( Symbol ) ,
6969 GeneratorState ( VariantIdx ) ,
70- ClosureVar ( Symbol ) ,
70+ CapturedVar ( Symbol ) ,
7171 ArrayElem ( usize ) ,
7272 TupleElem ( usize ) ,
7373 Deref ,
74- Tag ,
74+ EnumTag ,
75+ GeneratorTag ,
7576 DynDowncast ,
7677}
7778
@@ -109,17 +110,18 @@ fn write_path(out: &mut String, path: &Vec<PathElem>) {
109110 for elem in path. iter ( ) {
110111 match elem {
111112 Field ( name) => write ! ( out, ".{}" , name) ,
112- Variant ( name) => write ! ( out, ".<downcast-variant({})>" , name) ,
113+ EnumTag => write ! ( out, ".<enum-tag>" ) ,
114+ Variant ( name) => write ! ( out, ".<enum-variant({})>" , name) ,
115+ GeneratorTag => write ! ( out, ".<generator-tag>" ) ,
113116 GeneratorState ( idx) => write ! ( out, ".<generator-state({})>" , idx. index( ) ) ,
114- ClosureVar ( name) => write ! ( out, ".<closure -var({})>" , name) ,
117+ CapturedVar ( name) => write ! ( out, ".<captured -var({})>" , name) ,
115118 TupleElem ( idx) => write ! ( out, ".{}" , idx) ,
116119 ArrayElem ( idx) => write ! ( out, "[{}]" , idx) ,
117120 // `.<deref>` does not match Rust syntax, but it is more readable for long paths -- and
118121 // some of the other items here also are not Rust syntax. Actually we can't
119122 // even use the usual syntax because we are just showing the projections,
120123 // not the root.
121124 Deref => write ! ( out, ".<deref>" ) ,
122- Tag => write ! ( out, ".<enum-tag>" ) ,
123125 DynDowncast => write ! ( out, ".<dyn-downcast>" ) ,
124126 }
125127 . unwrap ( )
@@ -170,6 +172,21 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
170172
171173impl < ' rt , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > ValidityVisitor < ' rt , ' mir , ' tcx , M > {
172174 fn aggregate_field_path_elem ( & mut self , layout : TyLayout < ' tcx > , field : usize ) -> PathElem {
175+ // First, check if we are projecting to a variant.
176+ match layout. variants {
177+ layout:: Variants :: Multiple { discr_index, .. } => {
178+ if discr_index == field {
179+ return match layout. ty . kind {
180+ ty:: Adt ( def, ..) if def. is_enum ( ) => PathElem :: EnumTag ,
181+ ty:: Generator ( ..) => PathElem :: GeneratorTag ,
182+ _ => bug ! ( "non-variant type {:?}" , layout. ty) ,
183+ } ;
184+ }
185+ }
186+ layout:: Variants :: Single { .. } => { }
187+ }
188+
189+ // Now we know we are projecting to a field, so figure out which one.
173190 match layout. ty . kind {
174191 // generators and closures.
175192 ty:: Closure ( def_id, _) | ty:: Generator ( def_id, _, _) => {
@@ -190,7 +207,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
190207 }
191208 }
192209
193- PathElem :: ClosureVar ( name. unwrap_or_else ( || {
210+ PathElem :: CapturedVar ( name. unwrap_or_else ( || {
194211 // Fall back to showing the field index.
195212 sym:: integer ( field)
196213 } ) )
@@ -207,10 +224,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
207224 // Inside a variant
208225 PathElem :: Field ( def. variants [ index] . fields [ field] . ident . name )
209226 }
210- layout:: Variants :: Multiple { discr_index, .. } => {
211- assert_eq ! ( discr_index, field) ;
212- PathElem :: Tag
213- }
227+ layout:: Variants :: Multiple { .. } => bug ! ( "we handled variants above" ) ,
214228 }
215229 }
216230
@@ -441,11 +455,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
441455 fn visit_scalar (
442456 & mut self ,
443457 op : OpTy < ' tcx , M :: PointerTag > ,
444- layout : & layout:: Scalar ,
458+ scalar_layout : & layout:: Scalar ,
445459 ) -> InterpResult < ' tcx > {
446460 let value = self . ecx . read_scalar ( op) ?;
461+ let valid_range = & scalar_layout. valid_range ;
462+ let ( lo, hi) = valid_range. clone ( ) . into_inner ( ) ;
447463 // Determine the allowed range
448- let ( lo, hi) = layout. valid_range . clone ( ) . into_inner ( ) ;
449464 // `max_hi` is as big as the size fits
450465 let max_hi = u128:: max_value ( ) >> ( 128 - op. layout . size . bits ( ) ) ;
451466 assert ! ( hi <= max_hi) ;
@@ -459,7 +474,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
459474 value. not_undef( ) ,
460475 value,
461476 self . path,
462- format_args!( "something {}" , wrapping_range_format( & layout . valid_range, max_hi) , )
477+ format_args!( "something {}" , wrapping_range_format( valid_range, max_hi) , )
463478 ) ;
464479 let bits = match value. to_bits_or_ptr ( op. layout . size , self . ecx ) {
465480 Err ( ptr) => {
@@ -471,7 +486,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
471486 self . path,
472487 format_args!(
473488 "something that cannot possibly fail to be {}" ,
474- wrapping_range_format( & layout . valid_range, max_hi)
489+ wrapping_range_format( valid_range, max_hi)
475490 )
476491 )
477492 }
@@ -484,21 +499,21 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
484499 self . path,
485500 format_args!(
486501 "something that cannot possibly fail to be {}" ,
487- wrapping_range_format( & layout . valid_range, max_hi)
502+ wrapping_range_format( valid_range, max_hi)
488503 )
489504 )
490505 }
491506 }
492507 Ok ( data) => data,
493508 } ;
494509 // Now compare. This is slightly subtle because this is a special "wrap-around" range.
495- if wrapping_range_contains ( & layout . valid_range , bits) {
510+ if wrapping_range_contains ( & valid_range, bits) {
496511 Ok ( ( ) )
497512 } else {
498513 throw_validation_failure ! (
499514 bits,
500515 self . path,
501- format_args!( "something {}" , wrapping_range_format( & layout . valid_range, max_hi) )
516+ format_args!( "something {}" , wrapping_range_format( valid_range, max_hi) )
502517 )
503518 }
504519 }
@@ -594,7 +609,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
594609
595610 // *After* all of this, check the ABI. We need to check the ABI to handle
596611 // types like `NonNull` where the `Scalar` info is more restrictive than what
597- // the fields say. But in most cases, this will just propagate what the fields say,
612+ // the fields say (`rustc_layout_scalar_valid_range_start`).
613+ // But in most cases, this will just propagate what the fields say,
598614 // and then we want the error to point at the field -- so, first recurse,
599615 // then check ABI.
600616 //
@@ -603,11 +619,18 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
603619 // MyNewtype and then the scalar in there).
604620 match op. layout . abi {
605621 layout:: Abi :: Uninhabited => unreachable ! ( ) , // checked above
606- layout:: Abi :: Scalar ( ref layout) => {
607- self . visit_scalar ( op, layout) ?;
622+ layout:: Abi :: Scalar ( ref scalar_layout) => {
623+ self . visit_scalar ( op, scalar_layout) ?;
624+ }
625+ layout:: Abi :: ScalarPair { .. } | layout:: Abi :: Vector { .. } => {
626+ // These have fields that we already visited above, so we already checked
627+ // all their scalar-level restrictions.
628+ // There is also no equivalent to `rustc_layout_scalar_valid_range_start`
629+ // that would make skipping them here an issue.
630+ }
631+ layout:: Abi :: Aggregate { .. } => {
632+ // Nothing to do.
608633 }
609- // FIXME: Should we do something for ScalarPair? Vector?
610- _ => { }
611634 }
612635
613636 Ok ( ( ) )
0 commit comments