diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-08-09 06:18:00 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-08-24 13:27:38 -0400 |
| commit | e23ad83fbc3afdde5f931d976a6d8592c3550e46 (patch) | |
| tree | 7628fc6eca60b93d21a7915cc9155ab3b86acd93 | |
| parent | d7d4d7c8d5620b7b120304cc5eecf25b499e394a (diff) | |
| download | rust-e23ad83fbc3afdde5f931d976a6d8592c3550e46.tar.gz rust-e23ad83fbc3afdde5f931d976a6d8592c3550e46.zip | |
add a `user_ty` annotation to `Constant`
| -rw-r--r-- | src/librustc/ich/impls_mir.rs | 2 | ||||
| -rw-r--r-- | src/librustc/mir/mod.rs | 16 | ||||
| -rw-r--r-- | src/librustc/mir/visit.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/as_constant.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/as_rvalue.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/into.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/build/matches/test.rs | 3 | ||||
| -rw-r--r-- | src/librustc_mir/build/misc.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/expr.rs | 7 | ||||
| -rw-r--r-- | src/librustc_mir/hair/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc_mir/shim.rs | 3 | ||||
| -rw-r--r-- | src/librustc_mir/transform/elaborate_drops.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/transform/generator.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/transform/instcombine.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/util/elaborate_drops.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/util/pretty.rs | 5 |
16 files changed, 65 insertions, 9 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 38ea536b4ee..ad20bab2b87 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -528,7 +528,7 @@ impl_stable_hash_for!(enum mir::NullOp { SizeOf }); -impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal }); +impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, user_ty, literal }); impl_stable_hash_for!(struct mir::Location { block, statement_index }); diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 14981a700a3..efe2e352138 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1888,12 +1888,15 @@ pub enum Operand<'tcx> { /// This implies that the type of the place must be `Copy`; this is true /// by construction during build, but also checked by the MIR type checker. Copy(Place<'tcx>), + /// Move: The value (including old borrows of it) will not be used again. /// /// Safe for values of all types (modulo future developments towards `?Move`). /// Correct usage patterns are enforced by the borrow checker for safe code. /// `Copy` may be converted to `Move` to enable "last-use" optimizations. Move(Place<'tcx>), + + /// Synthesizes a constant value. Constant(Box<Constant<'tcx>>), } @@ -1909,6 +1912,9 @@ impl<'tcx> Debug for Operand<'tcx> { } impl<'tcx> Operand<'tcx> { + /// Convenience helper to make a constant that refers to the fn + /// with given def-id and substs. Since this is used to synthesize + /// MIR, assumes `user_ty` is None. pub fn function_handle<'a>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, @@ -1919,6 +1925,7 @@ impl<'tcx> Operand<'tcx> { Operand::Constant(box Constant { span, ty, + user_ty: None, literal: ty::Const::zero_sized(tcx, ty), }) } @@ -2207,6 +2214,14 @@ impl<'tcx> Debug for Rvalue<'tcx> { pub struct Constant<'tcx> { pub span: Span, pub ty: Ty<'tcx>, + + /// Optional user-given type: for something like + /// `collect::<Vec<_>>`, this would be present and would + /// indicate that `Vec<_>` was explicitly specified. + /// + /// Needed for NLL to impose user-given type constraints. + pub user_ty: Option<CanonicalTy<'tcx>>, + pub literal: &'tcx ty::Const<'tcx>, } @@ -2902,6 +2917,7 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { Constant { span: self.span.clone(), ty: self.ty.fold_with(folder), + user_ty: self.user_ty.fold_with(folder), literal: self.literal.fold_with(folder), } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index cab6ed0c122..1eaecf7a522 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -213,6 +213,10 @@ macro_rules! make_mir_visitor { self.super_ty(ty); } + fn visit_canonical_ty(&mut self, ty: & $($mutability)* CanonicalTy<'tcx>) { + self.super_canonical_ty(ty); + } + fn visit_region(&mut self, region: & $($mutability)* ty::Region<'tcx>, _: Location) { @@ -625,9 +629,10 @@ macro_rules! make_mir_visitor { } fn super_user_assert_ty(&mut self, - _c_ty: & $($mutability)* CanonicalTy<'tcx>, + c_ty: & $($mutability)* CanonicalTy<'tcx>, local: & $($mutability)* Local, location: Location) { + self.visit_canonical_ty(c_ty); self.visit_local(local, PlaceContext::Validate, location); } @@ -740,11 +745,13 @@ macro_rules! make_mir_visitor { let Constant { ref $($mutability)* span, ref $($mutability)* ty, + ref $($mutability)* user_ty, ref $($mutability)* literal, } = *constant; self.visit_span(span); self.visit_ty(ty, TyContext::Location(location)); + drop(user_ty); // no visit method for this self.visit_const(literal, location); } @@ -764,6 +771,9 @@ macro_rules! make_mir_visitor { self.visit_source_scope(scope); } + fn super_canonical_ty(&mut self, _ty: & $($mutability)* CanonicalTy<'tcx>) { + } + fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) { } diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index a57f1b95494..1106f750d6d 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -31,8 +31,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match kind { ExprKind::Scope { region_scope: _, lint_level: _, value } => this.as_constant(value), - ExprKind::Literal { literal } => - Constant { span: span, ty: ty, literal: literal }, + ExprKind::Literal { literal, user_ty } => + Constant { span, ty, user_ty, literal }, _ => span_bug!( span, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 68009e962a3..fab4f77a095 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -239,6 +239,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { operands.push(Operand::Constant(box Constant { span: expr_span, ty: this.hir.tcx().types.u32, + user_ty: None, literal: ty::Const::from_bits( this.hir.tcx(), 0, diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 2b05e2c023a..3cd1270d7ef 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -128,6 +128,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Constant { span: expr_span, ty: this.hir.bool_ty(), + user_ty: None, literal: this.hir.true_literal(), }); @@ -136,6 +137,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Constant { span: expr_span, ty: this.hir.bool_ty(), + user_ty: None, literal: this.hir.false_literal(), }); diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 15a983635f7..2baefc47f8e 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -344,7 +344,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { func: Operand::Constant(box Constant { span: test.span, ty: mty, - literal: method + user_ty: None, // FIXME + literal: method, }), args: vec![val, expect], destination: Some((eq_result.clone(), eq_block)), diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index ae8070698c2..9405f43c056 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -32,6 +32,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { place } + /// Convenience function for creating a literal operand, one + /// without any user type annotation. pub fn literal_operand(&mut self, span: Span, ty: Ty<'tcx>, @@ -40,6 +42,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let constant = box Constant { span, ty, + user_ty: None, literal, }; Operand::Constant(constant) @@ -69,6 +72,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Constant { span: source_info.span, ty: self.hir.usize_ty(), + user_ty: None, literal: self.hir.usize_literal(value), }); temp diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 04a3b5c115f..00b2bcd486b 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -317,6 +317,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprKind::Lit(ref lit) => ExprKind::Literal { literal: cx.const_eval_literal(&lit.node, expr_ty, lit.span, false), + user_ty: None, }, hir::ExprKind::Binary(op, ref lhs, ref rhs) => { @@ -406,6 +407,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, if let hir::ExprKind::Lit(ref lit) = arg.node { ExprKind::Literal { literal: cx.const_eval_literal(&lit.node, expr_ty, lit.span, true), + user_ty: None, } } else { ExprKind::Unary { @@ -631,7 +633,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, temp_lifetime, ty, span: expr.span, - kind: ExprKind::Literal { literal }, + kind: ExprKind::Literal { literal, user_ty: None }, }.to_ref(); let offset = mk_const(ty::Const::from_bits( cx.tcx, @@ -703,6 +705,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, span: expr.span, kind: ExprKind::Literal { literal: ty::Const::zero_sized(cx.tcx(), ty), + user_ty: None, // TODO }, } } @@ -758,6 +761,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, cx.tcx, cx.tables().node_id_to_type(expr.hir_id), ), + user_ty: None, // TODO }, Def::Const(def_id) | @@ -768,6 +772,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, substs, cx.tables().node_id_to_type(expr.hir_id), ), + user_ty: None, // TODO? }, Def::StructCtor(def_id, CtorKind::Const) | diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index c39aa9ca780..5539db609c4 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -18,7 +18,7 @@ use rustc::mir::{BinOp, BorrowKind, Field, UnOp}; use rustc::hir::def_id::DefId; use rustc::middle::region; use rustc::ty::subst::Substs; -use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const}; +use rustc::ty::{AdtDef, CanonicalTy, UpvarSubsts, Region, Ty, Const}; use rustc::hir; use syntax::ast; use syntax_pos::Span; @@ -272,6 +272,13 @@ pub enum ExprKind<'tcx> { }, Literal { literal: &'tcx Const<'tcx>, + + /// Optional user-given type: for something like + /// `collect::<Vec<_>>`, this would be present and would + /// indicate that `Vec<_>` was explicitly specified. + /// + /// Needed for NLL to impose user-given type constraints. + user_ty: Option<CanonicalTy<'tcx>>, }, InlineAsm { asm: &'tcx hir::InlineAsm, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 765a47e729e..e6b480a27d1 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -440,6 +440,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let func = Operand::Constant(box Constant { span: self.span, ty: func_ty, + user_ty: None, literal: ty::Const::zero_sized(self.tcx, func_ty), }); @@ -498,6 +499,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { box Constant { span: self.span, ty: self.tcx.types.usize, + user_ty: None, literal: ty::Const::from_usize(self.tcx, value), } } @@ -725,6 +727,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (Operand::Constant(box Constant { span, ty, + user_ty: None, literal: ty::Const::zero_sized(tcx, ty), }), vec![rcvr]) diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index bbf896e624f..225de03a329 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -543,6 +543,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { Rvalue::Use(Operand::Constant(Box::new(Constant { span, ty: self.tcx.types.bool, + user_ty: None, literal: ty::Const::from_bool(self.tcx, val), }))) } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index dc657f228c9..a7d6c08ec1f 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -177,6 +177,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { let val = Operand::Constant(box Constant { span: source_info.span, ty: self.tcx.types.u32, + user_ty: None, literal: ty::Const::from_bits( self.tcx, state_disc.into(), @@ -710,6 +711,7 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cond: Operand::Constant(box Constant { span: mir.span, ty: tcx.types.bool, + user_ty: None, literal: ty::Const::from_bool(tcx, false), }), expected: true, diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 4cf4a8f23a4..12780ef8be9 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -103,7 +103,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> { if let TyKind::Array(_, len) = place_ty.sty { let span = self.mir.source_info(location).span; let ty = self.tcx.types.usize; - let constant = Constant { span, ty, literal: len }; + let constant = Constant { span, ty, literal: len, user_ty: None }; self.optimizations.arrays_lengths.insert(location, constant); } } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 45e405cb55e..1c0c98d621c 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -969,6 +969,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> Operand::Constant(box Constant { span: self.source_info.span, ty: self.tcx().types.usize, + user_ty: None, literal: ty::Const::from_usize(self.tcx(), val.into()), }) } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 886f83b8f2f..51834d4bd84 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -397,10 +397,13 @@ impl<'cx, 'gcx, 'tcx> ExtraComments<'cx, 'gcx, 'tcx> { impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { self.super_constant(constant, location); - let Constant { span, ty, literal } = constant; + let Constant { span, ty, user_ty, literal } = constant; self.push("mir::Constant"); self.push(&format!("+ span: {:?}", span)); self.push(&format!("+ ty: {:?}", ty)); + if let Some(user_ty) = user_ty { + self.push(&format!("+ user_ty: {:?}", user_ty)); + } self.push(&format!("+ literal: {:?}", literal)); } |
