From 58a59e9d231e36e3d39dd398b80c96094de591aa Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 30 Aug 2017 11:13:01 +0200 Subject: Rustup (generator support) --- src/librustc_mir/interpret/eval_context.rs | 27 ++++++++++++++++++++------- src/librustc_mir/interpret/terminator/mod.rs | 9 +++++++-- src/librustc_mir/interpret/validation.rs | 6 ++++-- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b123ad7fd0b..b3d2617c9a3 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -480,15 +480,22 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { // Subtract 1 because `local_decls` includes the ReturnMemoryPointer, but we don't store a local // `Value` for that. - let annotated_locals = collect_storage_annotations(mir); let num_locals = mir.local_decls.len() - 1; - let mut locals = vec![None; num_locals]; - for i in 0..num_locals { - let local = mir::Local::new(i + 1); - if !annotated_locals.contains(&local) { - locals[i] = Some(Value::ByVal(PrimVal::Undef)); + + // FIXME: generators produce broken storage annotations (https://github.com/rust-lang/rust/issues/44179) + let locals = if mir.generator_layout.is_some() { + vec![Some(Value::ByVal(PrimVal::Undef)); num_locals] + } else { + let annotated_locals = collect_storage_annotations(mir); + let mut locals = vec![None; num_locals]; + for i in 0..num_locals { + let local = mir::Local::new(i + 1); + if !annotated_locals.contains(&local) { + locals[i] = Some(Value::ByVal(PrimVal::Undef)); + } } - } + locals + }; self.stack.push(Frame { mir, @@ -2426,6 +2433,12 @@ fn resolve_associated_item<'a, 'tcx>( let substs = tcx.erase_regions(&substs); ty::Instance::new(def_id, substs) } + ::rustc::traits::VtableGenerator(closure_data) => { + ty::Instance { + def: ty::InstanceDef::Item(closure_data.closure_def_id), + substs: closure_data.substs.substs + } + } ::rustc::traits::VtableClosure(closure_data) => { let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap(); resolve_closure( diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index ebd6649c447..bee0fe23f7f 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -137,8 +137,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { if expected == cond_val { self.goto_block(target); } else { + use rustc::mir::AssertMessage::*; return match *msg { - mir::AssertMessage::BoundsCheck { ref len, ref index } => { + BoundsCheck { ref len, ref index } => { let span = terminator.source_info.span; let len = self.eval_operand_to_primval(len) .expect("can't eval len") @@ -148,13 +149,17 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { .to_u64()?; err!(ArrayIndexOutOfBounds(span, len, index)) } - mir::AssertMessage::Math(ref err) => { + Math(ref err) => { err!(Math(terminator.source_info.span, err.clone())) } + GeneratorResumedAfterReturn | + GeneratorResumedAfterPanic => unimplemented!(), }; } } + Yield { .. } => unimplemented!("{:#?}", terminator.kind), + GeneratorDrop => unimplemented!(), DropAndReplace { .. } => unimplemented!(), Resume => unimplemented!(), Unreachable => return err!(Unreachable), diff --git a/src/librustc_mir/interpret/validation.rs b/src/librustc_mir/interpret/validation.rs index 6454e12e037..63872f3c9c6 100644 --- a/src/librustc_mir/interpret/validation.rs +++ b/src/librustc_mir/interpret/validation.rs @@ -355,7 +355,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { TyRef(..) | TyFnPtr(..) | TyFnDef(..) | TyNever => true, TyAdt(adt, _) if adt.is_box() => true, TySlice(_) | TyAdt(_, _) | TyTuple(..) | TyClosure(..) | TyArray(..) | - TyDynamic(..) => false, + TyDynamic(..) | TyGenerator(..) => false, TyParam(_) | TyInfer(_) | TyProjection(_) | TyAnon(..) | TyError => { bug!("I got an incomplete/unnormalized type for validation") } @@ -630,7 +630,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { // Is there other things we can/should check? Like vtable pointers? Ok(()) } - _ => bug!("We already establishd that this is a type we support."), + // FIXME: generators aren't validated right now + TyGenerator(..) => Ok(()), + _ => bug!("We already established that this is a type we support. ({})", query.ty), } } } -- cgit 1.4.1-3-g733a5