diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 38e928145a816..9a740b15d7c42 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -230,7 +230,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) { let check = match terminator.kind { - mir::TerminatorKind::Call { func: mir::Operand::Constant(ref c), ref args, .. } => { + mir::TerminatorKind::Call { func: mir::Operand::Constant(box(_, ref c)), ref args, .. } => { match *c.ty().kind() { ty::FnDef(did, _) => Some((did, args)), _ => None, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index fd3f89a2aee96..f27502a135b10 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -633,10 +633,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checked by const-qualification, which also // promotes any complex rvalues to constants. if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") { - if let mir::Operand::Constant(constant) = arg { - let c = self.eval_mir_constant(constant); + if let mir::Operand::Constant(box(span, constant)) = arg { + let c = self.eval_mir_constant(*span, constant); let (llval, ty) = - self.simd_shuffle_indices(&bx, constant.span, constant.ty(), c); + self.simd_shuffle_indices(&bx, *span, constant.ty(), c); return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty), @@ -821,9 +821,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { out_place.map(|out_place| self.codegen_place(&mut bx, out_place.as_ref())); InlineAsmOperandRef::InOut { reg, late, in_value, out_place } } - mir::InlineAsmOperand::Const { ref value } => { + mir::InlineAsmOperand::Const { span, ref value } => { let const_value = self - .eval_mir_constant(value) + .eval_mir_constant(span, value) .unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved")); let ty = value.ty(); let size = bx.layout_of(ty).size; diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index fa8a53e60b169..9486a5917950a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -13,15 +13,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_mir_constant_to_operand( &self, bx: &mut Bx, + span: Span, constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { - let val = self.eval_mir_constant(constant)?; + let val = self.eval_mir_constant(span, constant)?; let ty = self.monomorphize(constant.ty()); Ok(OperandRef::from_const(bx, val, ty)) } pub fn eval_mir_constant( &self, + span: Span, constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { let ct = self.monomorphize(constant.literal); @@ -35,12 +37,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None) .map_err(|err| { - self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); + self.cx.tcx().sess.span_err(span, "erroneous constant encountered"); err }), ty::ConstKind::Value(value) => Ok(value), err => span_bug!( - constant.span, + span, "encountered bad ConstKind after monomorphizing: {:?}", err ), diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 6bb20545f07be..20da3a796f129 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -420,7 +420,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None => continue, }; - if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) { + if let Ok(operand) = self.eval_mir_constant_to_operand(bx, var.source_info.span, &c) { let base = Self::spill_operand_to_stack( &operand, Some(var.name.to_string()), diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 91df67b53d21f..072d902d33ce2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -188,14 +188,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Evaluate all required consts; codegen later assumes that CTFE will never fail. let mut all_consts_ok = true; - for const_ in &mir.required_consts { - if let Err(err) = fx.eval_mir_constant(const_) { + for (span, const_) in &mir.required_consts { + if let Err(err) = fx.eval_mir_constant(*span, const_) { all_consts_ok = false; match err { // errored or at least linted ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {} ErrorHandled::TooGeneric => { - span_bug!(const_.span, "codgen encountered polymorphic constant: {:?}", err) + span_bug!(*span, "codgen encountered polymorphic constant: {:?}", err) } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 25e84c38ed315..6a16c3bc46115 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -437,10 +437,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_consume(bx, place.as_ref()) } - mir::Operand::Constant(ref constant) => { + mir::Operand::Constant(box(span, ref constant)) => { // This cannot fail because we checked all required_consts in advance. - self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| { - span_bug!(constant.span, "erroneous constant not captured by required_consts") + self.eval_mir_constant_to_operand(bx, span, constant).unwrap_or_else(|_err| { + span_bug!(span, "erroneous constant not captured by required_consts") }) } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index de0c4f2e30e8b..e978307d7032e 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -217,7 +217,7 @@ pub struct Body<'tcx> { /// Constants that are required to evaluate successfully for this MIR to be well-formed. /// We hold in this field all the constants we are not able to evaluate yet. - pub required_consts: Vec>, + pub required_consts: Vec<(Span, Constant<'tcx>)>, /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check. /// @@ -1222,6 +1222,7 @@ pub enum InlineAsmOperand<'tcx> { out_place: Option>, }, Const { + span: Span, value: Box>, }, SymFn { @@ -2029,7 +2030,7 @@ pub enum Operand<'tcx> { Move(Place<'tcx>), /// Synthesizes a constant value. - Constant(Box>), + Constant(Box<(Span, Constant<'tcx>)>), } #[cfg(target_arch = "x86_64")] @@ -2057,11 +2058,10 @@ impl<'tcx> Operand<'tcx> { span: Span, ) -> Self { let ty = tcx.type_of(def_id).subst(tcx, substs); - Operand::Constant(box Constant { - span, + Operand::Constant(box (span, Constant { user_ty: None, literal: ConstantKind::Ty(ty::Const::zero_sized(tcx, ty)), - }) + })) } pub fn is_move(&self) -> bool { @@ -2088,11 +2088,10 @@ impl<'tcx> Operand<'tcx> { }; scalar_size == type_size }); - Operand::Constant(box Constant { - span, + Operand::Constant(box (span, Constant { user_ty: None, literal: ConstantKind::Val(val.into(), ty), - }) + })) } pub fn to_copy(&self) -> Self { @@ -2113,9 +2112,9 @@ impl<'tcx> Operand<'tcx> { /// Returns the `Constant` that is the target of this `Operand`, or `None` if this `Operand` is a /// place. - pub fn constant(&self) -> Option<&Constant<'tcx>> { + pub fn constant(&self) -> Option<(&Span, &Constant<'tcx>)> { match self { - Operand::Constant(x) => Some(&**x), + Operand::Constant(box(span, c)) => Some((span, c)), Operand::Copy(_) | Operand::Move(_) => None, } } @@ -2426,8 +2425,6 @@ impl<'tcx> Debug for Rvalue<'tcx> { #[derive(Clone, Copy, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable)] pub struct Constant<'tcx> { - pub span: Span, - /// Optional user-given type: for something like /// `collect::>`, this would be present and would /// indicate that `Vec<_>` was explicitly specified. diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 6e81914597698..739c924afaa17 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -227,7 +227,7 @@ impl<'tcx> Operand<'tcx> { { match self { &Operand::Copy(ref l) | &Operand::Move(ref l) => l.ty(local_decls, tcx).ty, - &Operand::Constant(ref c) => c.literal.ty(), + &Operand::Constant(box (_, ref c)) => c.literal.ty(), } } } diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index c8db4aeb449b8..6b484f7135359 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -527,7 +527,8 @@ impl<'tcx> TerminatorKind<'tcx> { InlineAsmOperand::InOut { reg, late, in_value, out_place: None } => { write!(fmt, "in{}out({}) {:?} => _", print_late(late), reg, in_value)?; } - InlineAsmOperand::Const { value } => { + InlineAsmOperand::Const { span, value } => { + write!(fmt, "span {:?}", span)?; write!(fmt, "const {:?}", value)?; } InlineAsmOperand::SymFn { value } => { diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index f3124e5bf424e..e0887e342c916 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -336,7 +336,6 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { fn super_fold_with>(self, folder: &mut F) -> Self { Constant { - span: self.span, user_ty: self.user_ty.fold_with(folder), literal: self.literal.fold_with(folder), } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 5516a045c1db0..25362e1761676 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -291,8 +291,9 @@ macro_rules! make_mir_visitor { self.visit_span(&$($mutability)? body.span); - for const_ in &$($mutability)? body.required_consts { + for (span, const_) in &$($mutability)? body.required_consts { let location = START_BLOCK.start_location(); + self.visit_span(span); self.visit_constant(const_, location); } } @@ -606,8 +607,11 @@ macro_rules! make_mir_visitor { ); } } - InlineAsmOperand::Const { value } - | InlineAsmOperand::SymFn { value } => { + InlineAsmOperand::Const { value, span } => { + self.visit_span(span); + self.visit_constant(value, location); + } + InlineAsmOperand::SymFn { value } => { self.visit_constant(value, location); } InlineAsmOperand::SymStatic { def_id: _ } => {} @@ -775,7 +779,8 @@ macro_rules! make_mir_visitor { location ); } - Operand::Constant(constant) => { + Operand::Constant(box(span, constant)) => { + self.visit_span(span); self.visit_constant(constant, location); } } @@ -864,12 +869,10 @@ macro_rules! make_mir_visitor { constant: & $($mutability)? Constant<'tcx>, location: Location) { let Constant { - span, user_ty, literal, } = constant; - self.visit_span(span); drop(user_ty); // no visit method for this match literal { ConstantKind::Ty(ct) => self.visit_const(ct, location), diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index 1b0cae51d585d..d271711f25537 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs @@ -565,7 +565,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { { // Just point to the function, to reduce the chance of overlapping spans. let function_span = match func { - Operand::Constant(c) => c.span, + Operand::Constant(box (span, _)) => *span, Operand::Copy(place) | Operand::Move(place) => { if let Some(l) = place.as_local() { let local_decl = &self.body.local_decls[l]; diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index 1bb8c7ebe5afd..05c08c5b0073d 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -81,7 +81,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let terminator = self.body[location.block].terminator(); debug!("add_moved_or_invoked_closure_note: terminator={:?}", terminator); if let TerminatorKind::Call { - func: Operand::Constant(box Constant { literal, .. }), + func: Operand::Constant(box (_, Constant { literal, .. })), args, .. } = &terminator.kind diff --git a/compiler/rustc_mir/src/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs index e621bafb671bb..ab706bfc1ead4 100644 --- a/compiler/rustc_mir/src/borrow_check/invalidation.rs +++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs @@ -218,7 +218,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.mutate_place(location, out_place, Shallow(None), JustWrite); } } - InlineAsmOperand::Const { value: _ } + InlineAsmOperand::Const { span: _, value: _ } | InlineAsmOperand::SymFn { value: _ } | InlineAsmOperand::SymStatic { def_id: _ } => {} } diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 4c35be39a3d33..7247e2169507a 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -756,7 +756,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc ); } } - InlineAsmOperand::Const { value: _ } + InlineAsmOperand::Const { span: _, value: _ } | InlineAsmOperand::SymFn { value: _ } | InlineAsmOperand::SymStatic { def_id: _ } => {} } diff --git a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs index 994b403abf3bc..2079fb0b3098a 100644 --- a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs @@ -441,7 +441,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.gather_init(out_place.as_ref(), InitKind::Deep); } } - InlineAsmOperand::Const { value: _ } + InlineAsmOperand::Const { span: _, value: _ } | InlineAsmOperand::SymFn { value: _ } | InlineAsmOperand::SymStatic { def_id: _ } => {} } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 2d83d6cfbdc5e..4a206d91783ce 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -683,14 +683,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.stack_mut().push(frame); // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). - for const_ in &body.required_consts { - let span = const_.span; + for (span, const_) in &body.required_consts { let const_ = self.subst_from_current_frame_and_normalize_erasing_regions(const_.literal); self.mir_const_to_op(&const_, None).map_err(|err| { // If there was an error, set the span of the current frame to this constant. // Avoiding doing this when evaluation succeeds. - self.frame_mut().loc = Err(span); + self.frame_mut().loc = Err(*span); err })?; } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index e5bc9320260c6..b3b5acd8685bc 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -517,7 +517,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: do some more logic on `move` to invalidate the old location Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?, - Constant(ref constant) => { + Constant(box (_, ref constant)) => { let val = self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal); // This can still fail: diff --git a/compiler/rustc_mir/src/shim.rs b/compiler/rustc_mir/src/shim.rs index 796d024771d7f..7534329b079d8 100644 --- a/compiler/rustc_mir/src/shim.rs +++ b/compiler/rustc_mir/src/shim.rs @@ -418,11 +418,10 @@ impl CloneShimBuilder<'tcx> { // `func == Clone::clone(&ty) -> ty` let func_ty = tcx.mk_fn_def(self.def_id, substs); - let func = Operand::Constant(box Constant { - span: self.span, + let func = Operand::Constant(box (self.span, Constant { user_ty: None, literal: ty::Const::zero_sized(tcx, func_ty).into(), - }); + })); let ref_loc = self.make_place( Mutability::Not, @@ -474,12 +473,11 @@ impl CloneShimBuilder<'tcx> { ); } - fn make_usize(&self, value: u64) -> Box> { - box Constant { - span: self.span, + fn make_usize(&self, value: u64) -> Box<(Span, Constant<'tcx>)> { + box (self.span, Constant { user_ty: None, literal: ty::Const::from_usize(self.tcx, value).into(), - } + }) } fn array_shim( @@ -506,11 +504,10 @@ impl CloneShimBuilder<'tcx> { ))), self.make_statement(StatementKind::Assign(box ( end, - Rvalue::Use(Operand::Constant(box Constant { - span: self.span, + Rvalue::Use(Operand::Constant(box (self.span, Constant { user_ty: None, literal: len.into(), - })), + }))), ))), ]; self.block(inits, TerminatorKind::Goto { target: BasicBlock::new(1) }, false); @@ -765,11 +762,10 @@ fn build_call_shim<'tcx>( CallKind::Direct(def_id) => { let ty = tcx.type_of(def_id); ( - Operand::Constant(box Constant { - span, + Operand::Constant(box (span, Constant { user_ty: None, literal: ty::Const::zero_sized(tcx, ty).into(), - }), + })), rcvr.into_iter().collect::>(), ) } diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index ac8c748ea8571..bfb20fabd6317 100644 --- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs @@ -237,7 +237,7 @@ where Q: Qualif, F: FnMut(Local) -> bool, { - let constant = match operand { + let box (span, constant) = match operand { Operand::Copy(place) | Operand::Move(place) => { return in_place::(cx, in_local, place.as_ref()); } @@ -252,9 +252,9 @@ where // Don't peek inside trait associated constants. if cx.tcx.trait_of_item(def.did).is_none() { let qualifs = if let Some((did, param_did)) = def.as_const_arg() { - cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did)) + cx.tcx.at(*span).mir_const_qualif_const_arg((did, param_did)) } else { - cx.tcx.at(constant.span).mir_const_qualif(def.did) + cx.tcx.at(*span).mir_const_qualif(def.did) }; if !Q::in_qualifs(&qualifs) { diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 63fc66f2b9f16..ea476dfa836db 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -709,7 +709,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { self.super_operand(op, location); - if let Operand::Constant(c) = op { + if let Operand::Constant(box (_, c)) = op { if let Some(def_id) = c.check_static_ptr(self.tcx) { self.check_static(def_id, self.span); } diff --git a/compiler/rustc_mir/src/transform/const_debuginfo.rs b/compiler/rustc_mir/src/transform/const_debuginfo.rs index 3cdaf4c7dcd47..5b283f8ecfbaf 100644 --- a/compiler/rustc_mir/src/transform/const_debuginfo.rs +++ b/compiler/rustc_mir/src/transform/const_debuginfo.rs @@ -76,7 +76,7 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta continue; } - if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(box c)))) = + if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(box (_, c))))) = &bb.statements[location.statement_index].kind { if let Some(local) = p.as_local() { diff --git a/compiler/rustc_mir/src/transform/const_goto.rs b/compiler/rustc_mir/src/transform/const_goto.rs index ba10b54c5ae2e..ca38469fdb2bd 100644 --- a/compiler/rustc_mir/src/transform/const_goto.rs +++ b/compiler/rustc_mir/src/transform/const_goto.rs @@ -60,7 +60,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'a, 'tcx> { // We only apply this optimization if the last statement is a const assignment let last_statement = self.body.basic_blocks()[location.block].statements.last()?; - if let (place, Rvalue::Use(Operand::Constant(_const))) = + if let (place, Rvalue::Use(Operand::Constant(box (_, _const)))) = last_statement.kind.as_assign()? { // We found a constant being assigned to `place`. diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 5968bbbfca7f3..5491d6b027b2a 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -474,8 +474,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { match self.ecx.mir_const_to_op(&c.literal, None) { Ok(op) => Some(op), Err(error) => { - let tcx = self.ecx.tcx.at(c.span); - let err = ConstEvalErr::new(&self.ecx, error, Some(c.span)); + let span = source_info.span; + let tcx = self.ecx.tcx.at(span); + let err = ConstEvalErr::new(&self.ecx, error, Some(span)); if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal { ConstantKind::Ty(ct) => match ct.val { @@ -494,7 +495,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if lint_only { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. - err.report_as_lint(tcx, "erroneous constant used", lint_root, Some(c.span)); + err.report_as_lint(tcx, "erroneous constant used", lint_root, Some(span)); } else { err.report_as_error(tcx, "erroneous constant used"); } @@ -516,7 +517,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// or `eval_place`, depending on the variant of `Operand` used. fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { - Operand::Constant(ref c) => self.eval_constant(c, source_info), + Operand::Constant(box (_, ref c)) => self.eval_constant(c, source_info), Operand::Move(place) | Operand::Copy(place) => self.eval_place(place), } } @@ -796,11 +797,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Creates a new `Operand::Constant` from a `Scalar` value fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Operand<'tcx> { - Operand::Constant(Box::new(Constant { - span, + Operand::Constant(Box::new((span, Constant { user_ty: None, literal: ty::Const::from_scalar(self.tcx, scalar, ty).into(), - })) + }))) } fn replace_with_const( @@ -809,7 +809,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { value: &OpTy<'tcx>, source_info: SourceInfo, ) { - if let Rvalue::Use(Operand::Constant(c)) = rval { + if let Rvalue::Use(Operand::Constant(box(_, c))) = rval { match c.literal { ConstantKind::Ty(c) if matches!(c.val, ConstKind::Unevaluated(..)) => {} _ => { @@ -879,8 +879,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if let Some(Some(alloc)) = alloc { // Assign entire constant in a single statement. // We can't use aggregates, as we run after the aggregate-lowering `MirPhase`. - *rval = Rvalue::Use(Operand::Constant(Box::new(Constant { - span: source_info.span, + *rval = Rvalue::Use(Operand::Constant(Box::new((source_info.span, Constant { user_ty: None, literal: self .ecx @@ -893,7 +892,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { }), }) .into(), - }))); + })))); } } } @@ -1085,7 +1084,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { trace!("visit_constant: {:?}", constant); self.super_constant(constant, location); - self.eval_constant(constant, self.source_info.unwrap()); + let mut source_info = self.source_info.unwrap(); + self.visit_span(&mut source_info.span); + self.eval_constant(constant, source_info); } fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index b3fc2a0cb5e90..082da6594a1cf 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -865,9 +865,9 @@ pub(super) fn filtered_terminator_span( // Call `func` operand can have a more specific span when part of a chain of calls | TerminatorKind::Call { ref func, .. } => { let mut span = terminator.source_info.span; - if let mir::Operand::Constant(box constant) = func { - if constant.span.lo() > span.lo() { - span = span.with_lo(constant.span.lo()); + if let mir::Operand::Constant(box (c_span, _)) = func { + if c_span.lo() > span.lo() { + span = span.with_lo(c_span.lo()); } } Some(function_source_span(span, body_span)) diff --git a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs index 912505c65983e..c455a08800319 100644 --- a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs +++ b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs @@ -150,7 +150,7 @@ fn rvalue_hash(hasher: &mut H, rvalue: &Rvalue<'tcx>) { fn operand_hash(hasher: &mut H, operand: &Operand<'tcx>) { match operand { - Operand::Constant(box Constant { user_ty: _, literal, span: _ }) => literal.hash(hasher), + Operand::Constant(box (_, Constant { user_ty: _, literal })) => literal.hash(hasher), x => x.hash(hasher), }; } @@ -179,8 +179,8 @@ fn rvalue_eq(lhs: &Rvalue<'tcx>, rhs: &Rvalue<'tcx>) -> bool { fn operand_eq(lhs: &Operand<'tcx>, rhs: &Operand<'tcx>) -> bool { let res = match (lhs, rhs) { ( - Operand::Constant(box Constant { user_ty: _, literal, span: _ }), - Operand::Constant(box Constant { user_ty: _, literal: literal2, span: _ }), + Operand::Constant(box (_, Constant { user_ty: _, literal })), + Operand::Constant(box (_, Constant { user_ty: _, literal: literal2 })), ) => literal == literal2, (x, y) => x == y, }; diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs index 29df86ca6cdb7..f00060961dd5a 100644 --- a/compiler/rustc_mir/src/transform/dest_prop.rs +++ b/compiler/rustc_mir/src/transform/dest_prop.rs @@ -714,7 +714,7 @@ impl Conflicts<'a> { } } InlineAsmOperand::Out { reg: _, late: _, place: None } - | InlineAsmOperand::Const { value: _ } + | InlineAsmOperand::Const { span: _, value: _ } | InlineAsmOperand::SymFn { value: _ } | InlineAsmOperand::SymStatic { def_id: _ } => {} } @@ -728,7 +728,7 @@ impl Conflicts<'a> { } | InlineAsmOperand::In { reg: _, value: _ } | InlineAsmOperand::Out { reg: _, late: _, place: None } - | InlineAsmOperand::Const { value: _ } + | InlineAsmOperand::Const { span: _, value: _ } | InlineAsmOperand::SymFn { value: _ } | InlineAsmOperand::SymStatic { def_id: _ } => {} } diff --git a/compiler/rustc_mir/src/transform/elaborate_drops.rs b/compiler/rustc_mir/src/transform/elaborate_drops.rs index c0fcfb620ff76..37dc0a3cb7c11 100644 --- a/compiler/rustc_mir/src/transform/elaborate_drops.rs +++ b/compiler/rustc_mir/src/transform/elaborate_drops.rs @@ -468,11 +468,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> { - Rvalue::Use(Operand::Constant(Box::new(Constant { - span, + Rvalue::Use(Operand::Constant(Box::new((span, Constant { user_ty: None, literal: ty::Const::from_bool(self.tcx, val).into(), - }))) + })))) } fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagState) { diff --git a/compiler/rustc_mir/src/transform/function_item_references.rs b/compiler/rustc_mir/src/transform/function_item_references.rs index 8d02ac6d9b774..90b46b156d2d6 100644 --- a/compiler/rustc_mir/src/transform/function_item_references.rs +++ b/compiler/rustc_mir/src/transform/function_item_references.rs @@ -167,7 +167,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> { Operand::Copy(place) | Operand::Move(place) => { self.body.local_decls[place.local].source_info.span } - Operand::Constant(constant) => constant.span, + Operand::Constant(box (span, _)) => *span, } } diff --git a/compiler/rustc_mir/src/transform/generator.rs b/compiler/rustc_mir/src/transform/generator.rs index 3560b4b1e8645..9a7a9c90eaaec 100644 --- a/compiler/rustc_mir/src/transform/generator.rs +++ b/compiler/rustc_mir/src/transform/generator.rs @@ -987,11 +987,10 @@ fn insert_panic_block<'tcx>( ) -> BasicBlock { let assert_block = BasicBlock::new(body.basic_blocks().len()); let term = TerminatorKind::Assert { - cond: Operand::Constant(box Constant { - span: body.span, + cond: Operand::Constant(box (body.span, Constant { user_ty: None, literal: ty::Const::from_bool(tcx, false).into(), - }), + })), expected: true, msg: message, target: assert_block, diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index f1c95a84ade85..05283a70ef1bf 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -405,7 +405,7 @@ impl Inliner<'tcx> { threshold = 0; } - TerminatorKind::Call { func: Operand::Constant(ref f), cleanup, .. } => { + TerminatorKind::Call { func: Operand::Constant(box (_, ref f)), cleanup, .. } => { if let ty::FnDef(def_id, substs) = *callsite.callee.subst_mir(self.tcx, &f.literal.ty()).kind() { @@ -628,7 +628,7 @@ impl Inliner<'tcx> { // `required_consts`, here we may not only have `ConstKind::Unevaluated` // because we are calling `subst_and_normalize_erasing_regions`. caller_body.required_consts.extend( - callee_body.required_consts.iter().copied().filter(|&ct| { + callee_body.required_consts.iter().copied().filter(|(_, ct)| { match ct.literal.const_for_ty() { Some(ct) => matches!(ct.val, ConstKind::Unevaluated(_)), None => true, diff --git a/compiler/rustc_mir/src/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs index 7aaf0224164c6..b01b4ec9cd593 100644 --- a/compiler/rustc_mir/src/transform/instcombine.rs +++ b/compiler/rustc_mir/src/transform/instcombine.rs @@ -78,7 +78,7 @@ impl<'tcx, 'a> InstCombineContext<'tcx, 'a> { } fn try_eval_bool(&self, a: &Operand<'_>) -> Option { - let a = a.constant()?; + let (_, a) = a.constant()?; if a.literal.ty().is_bool() { a.literal.try_to_bool() } else { None } } @@ -116,8 +116,8 @@ impl<'tcx, 'a> InstCombineContext<'tcx, 'a> { } let constant = - Constant { span: source_info.span, literal: len.into(), user_ty: None }; - *rvalue = Rvalue::Use(Operand::Constant(box constant)); + Constant { literal: len.into(), user_ty: None }; + *rvalue = Rvalue::Use(Operand::Constant(box (source_info.span, constant))); } } } diff --git a/compiler/rustc_mir/src/transform/lower_intrinsics.rs b/compiler/rustc_mir/src/transform/lower_intrinsics.rs index e6ee474285ec1..c6a410e75ed5c 100644 --- a/compiler/rustc_mir/src/transform/lower_intrinsics.rs +++ b/compiler/rustc_mir/src/transform/lower_intrinsics.rs @@ -30,11 +30,10 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { source_info: terminator.source_info, kind: StatementKind::Assign(box ( destination, - Rvalue::Use(Operand::Constant(box Constant { - span: terminator.source_info.span, + Rvalue::Use(Operand::Constant(box (terminator.source_info.span, Constant { user_ty: None, literal: ty::Const::zero_sized(tcx, tcx.types.unit).into(), - })), + }))), )), }); terminator.kind = TerminatorKind::Goto { target }; diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index 21b208a08c2dc..c061553df3f09 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -91,8 +91,8 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { // If two statements are const bool assignments to the same place, we can optimize. ( - StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(f_c)))), - StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))), + StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(box (_, f_c))))), + StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(box (_, s_c))))), ) if lhs_f == lhs_s && f_c.literal.ty().is_bool() && s_c.literal.ty().is_bool() @@ -119,8 +119,8 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { (f_s, s_s) if f_s == s_s => (*f).clone(), ( - StatementKind::Assign(box (lhs, Rvalue::Use(Operand::Constant(f_c)))), - StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(s_c)))), + StatementKind::Assign(box (lhs, Rvalue::Use(Operand::Constant(box (_, f_c))))), + StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(box (_, s_c))))), ) => { // From earlier loop we know that we are dealing with bool constants only: let f_b = f_c.literal.try_eval_bool(tcx, param_env).unwrap(); diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index 1bbaf833c4fd9..43e66c5f74ffc 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -418,7 +418,7 @@ impl<'tcx> Validator<'_, 'tcx> { kind: StatementKind::Assign(box ( _, - Rvalue::Use(Operand::Constant(c)), + Rvalue::Use(Operand::Constant(box (_, c))), )), .. }) = def_stmt @@ -460,7 +460,7 @@ impl<'tcx> Validator<'_, 'tcx> { match &statement.kind { StatementKind::Assign(box ( _, - Rvalue::Use(Operand::Constant(c)), + Rvalue::Use(Operand::Constant(box (_, c))), )) => c.literal.try_eval_usize(self.tcx, self.param_env), _ => None, } @@ -517,7 +517,7 @@ impl<'tcx> Validator<'_, 'tcx> { // The qualifs for a constant (e.g. `HasMutInterior`) are checked in // `validate_rvalue` upon access. - Operand::Constant(c) => { + Operand::Constant(box (_, c)) => { if let Some(def_id) = c.check_static_ptr(self.tcx) { // Only allow statics (not consts) to refer to other statics. // FIXME(eddyb) does this matter at all for promotion? @@ -639,7 +639,7 @@ impl<'tcx> Validator<'_, 'tcx> { if !self.explicit && lhs_ty.is_integral() { // Integer division: the RHS must be a non-zero const. let const_val = match rhs { - Operand::Constant(c) => { + Operand::Constant(box (_, c)) => { c.literal.try_eval_bits(self.tcx, self.param_env, lhs_ty) } _ => None, @@ -888,11 +888,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { if self.keep_original { rhs.clone() } else { - let unit = Rvalue::Use(Operand::Constant(box Constant { - span: statement.source_info.span, + let unit = Rvalue::Use(Operand::Constant(box (statement.source_info.span, Constant { user_ty: None, literal: ty::Const::zero_sized(self.tcx, self.tcx.types.unit).into(), - })); + }))); mem::replace(rhs, unit) }, statement.source_info, @@ -965,8 +964,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); - Operand::Constant(Box::new(Constant { - span, + Operand::Constant(Box::new((span, Constant { user_ty: None, literal: tcx .mk_const(ty::Const { @@ -984,7 +982,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { }), }) .into(), - })) + }))) }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { @@ -1204,7 +1202,7 @@ crate fn is_const_fn_in_array_repeat_expression<'tcx>( if let Some(Terminator { kind: TerminatorKind::Call { func, destination, .. }, .. }) = &block.terminator { - if let Operand::Constant(box Constant { literal, .. }) = func { + if let Operand::Constant(box (_, Constant { literal, .. })) = func { if let ty::FnDef(def_id, _) = *literal.ty().kind() { if let Some((destination_place, _)) = destination { if destination_place == place { diff --git a/compiler/rustc_mir/src/transform/required_consts.rs b/compiler/rustc_mir/src/transform/required_consts.rs index 8b64ad65ab35c..e85dcf2ad20d1 100644 --- a/compiler/rustc_mir/src/transform/required_consts.rs +++ b/compiler/rustc_mir/src/transform/required_consts.rs @@ -1,22 +1,27 @@ use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{Constant, Location}; +use rustc_middle::mir::{Constant, Location, Operand}; use rustc_middle::ty::ConstKind; +use rustc_span::Span; pub struct RequiredConstsVisitor<'a, 'tcx> { - required_consts: &'a mut Vec>, + required_consts: &'a mut Vec<(Span, Constant<'tcx>)>, } impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { - pub fn new(required_consts: &'a mut Vec>) -> Self { + pub fn new(required_consts: &'a mut Vec<(Span, Constant<'tcx>)>) -> Self { RequiredConstsVisitor { required_consts } } } impl<'a, 'tcx> Visitor<'tcx> for RequiredConstsVisitor<'a, 'tcx> { - fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) { - if let Some(ct) = constant.literal.const_for_ty() { - if let ConstKind::Unevaluated(_) = ct.val { - self.required_consts.push(*constant); + fn visit_operand(&mut self, + operand: &Operand<'tcx>, + _: Location) { + if let Operand::Constant(box(span, constant)) = operand { + if let Some(ct) = constant.literal.const_for_ty() { + if let ConstKind::Unevaluated(_) = ct.val { + self.required_consts.push((*span, *constant)); + } } } } diff --git a/compiler/rustc_mir/src/transform/rustc_peek.rs b/compiler/rustc_mir/src/transform/rustc_peek.rs index a6b8f20f6d449..43461c9c20600 100644 --- a/compiler/rustc_mir/src/transform/rustc_peek.rs +++ b/compiler/rustc_mir/src/transform/rustc_peek.rs @@ -202,7 +202,7 @@ impl PeekCall { use mir::Operand; let span = terminator.source_info.span; - if let mir::TerminatorKind::Call { func: Operand::Constant(func), args, .. } = + if let mir::TerminatorKind::Call { func: Operand::Constant(box (_, func)), args, .. } = &terminator.kind { if let ty::FnDef(def_id, substs) = *func.literal.ty().kind() { diff --git a/compiler/rustc_mir/src/transform/simplify_branches.rs b/compiler/rustc_mir/src/transform/simplify_branches.rs index a9a45e61a38cb..510c803ee3ef5 100644 --- a/compiler/rustc_mir/src/transform/simplify_branches.rs +++ b/compiler/rustc_mir/src/transform/simplify_branches.rs @@ -27,7 +27,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { TerminatorKind::SwitchInt { - discr: Operand::Constant(ref c), + discr: Operand::Constant(box (_, ref c)), switch_ty, ref targets, .. @@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches { } } TerminatorKind::Assert { - target, cond: Operand::Constant(ref c), expected, .. + target, cond: Operand::Constant(box (_, ref c)), expected, .. } => match c.literal.try_eval_bool(tcx, param_env) { Some(v) if v == expected => TerminatorKind::Goto { target }, _ => continue, diff --git a/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs index 9f473f3bae534..1d9dc715511cb 100644 --- a/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs +++ b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs @@ -203,8 +203,8 @@ fn find_branch_value_info<'tcx>( // if any are, we can use the other to switch on, and the constant as a value in a switch use Operand::*; match (left, right) { - (Constant(branch_value), Copy(to_switch_on) | Move(to_switch_on)) - | (Copy(to_switch_on) | Move(to_switch_on), Constant(branch_value)) => { + (Constant(box (_, branch_value)), Copy(to_switch_on) | Move(to_switch_on)) + | (Copy(to_switch_on) | Move(to_switch_on), Constant(box (_, branch_value))) => { let branch_value_ty = branch_value.literal.ty(); // we only want to apply this optimization if we are matching on integrals (and chars), as it is not possible to switch on floats if !branch_value_ty.is_integral() && !branch_value_ty.is_char() { diff --git a/compiler/rustc_mir/src/util/elaborate_drops.rs b/compiler/rustc_mir/src/util/elaborate_drops.rs index e9190d7ebef8b..1e2854515d2f6 100644 --- a/compiler/rustc_mir/src/util/elaborate_drops.rs +++ b/compiler/rustc_mir/src/util/elaborate_drops.rs @@ -1032,11 +1032,10 @@ where } fn constant_usize(&self, val: u16) -> Operand<'tcx> { - Operand::Constant(box Constant { - span: self.source_info.span, + Operand::Constant(box (self.source_info.span, Constant { user_ty: None, literal: ty::Const::from_usize(self.tcx(), val.into()).into(), - }) + })) } fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { diff --git a/compiler/rustc_mir/src/util/find_self_call.rs b/compiler/rustc_mir/src/util/find_self_call.rs index 33ad128eeeb75..6995578dd1b45 100644 --- a/compiler/rustc_mir/src/util/find_self_call.rs +++ b/compiler/rustc_mir/src/util/find_self_call.rs @@ -17,7 +17,7 @@ pub fn find_self_call<'tcx>( &body[block].terminator { debug!("find_self_call: func={:?}", func); - if let Operand::Constant(box Constant { literal, .. }) = func { + if let Operand::Constant(box (_, Constant { literal, .. })) = func { if let ty::FnDef(def_id, substs) = *literal.ty().kind() { if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) = tcx.opt_associated_item(def_id) diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 3b88aec16b26a..5e1e827a4e39c 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -436,27 +436,29 @@ fn use_verbose(ty: &&TyS<'tcx>) -> bool { } impl Visitor<'tcx> for ExtraComments<'tcx> { - fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { - self.super_constant(constant, location); - let Constant { span, user_ty, literal } = constant; - match literal.ty().kind() { - ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char => {} - // Unit type - ty::Tuple(tys) if tys.is_empty() => {} - _ => { - self.push("mir::Constant"); - self.push(&format!("+ span: {}", self.tcx.sess.source_map().span_to_string(*span))); - if let Some(user_ty) = user_ty { - self.push(&format!("+ user_ty: {:?}", user_ty)); - } - match literal { - ConstantKind::Ty(literal) => self.push(&format!("+ literal: {:?}", literal)), - ConstantKind::Val(val, ty) => { - // To keep the diffs small, we render this almost like we render ty::Const - self.push(&format!( - "+ literal: Const {{ ty: {}, val: Value({:?}) }}", - ty, val - )) + fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { + self.super_operand(operand, location); + if let Operand::Constant(box (span, constant)) = operand { + let Constant { user_ty, literal } = constant; + match literal.ty().kind() { + ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char => {} + // Unit type + ty::Tuple(tys) if tys.is_empty() => {} + _ => { + self.push("mir::Constant"); + self.push(&format!("+ span: {}", self.tcx.sess.source_map().span_to_string(*span))); + if let Some(user_ty) = user_ty { + self.push(&format!("+ user_ty: {:?}", user_ty)); + } + match literal { + ConstantKind::Ty(literal) => self.push(&format!("+ literal: {:?}", literal)), + ConstantKind::Val(val, ty) => { + // To keep the diffs small, we render this almost like we render ty::Const + self.push(&format!( + "+ literal: Const {{ ty: {}, val: Value({:?}) }}", + ty, val + )) + } } } } diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index fd4a783d12a00..abbb3d66e718d 100644 --- a/compiler/rustc_mir_build/src/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs @@ -3,6 +3,7 @@ use crate::build::CFG; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; +use rustc_span::Span; impl<'tcx> CFG<'tcx> { crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { @@ -49,9 +50,10 @@ impl<'tcx> CFG<'tcx> { block: BasicBlock, source_info: SourceInfo, temp: Place<'tcx>, + span: Span, constant: Constant<'tcx>, ) { - self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant))); + self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box (span, constant)))); } crate fn push_assign_unit( @@ -65,11 +67,10 @@ impl<'tcx> CFG<'tcx> { block, source_info, place, - Rvalue::Use(Operand::Constant(box Constant { - span: source_info.span, + Rvalue::Use(Operand::Constant(box(source_info.span, Constant { user_ty: None, literal: ty::Const::zero_sized(tcx, tcx.types.unit).into(), - })), + }))), ); } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 57f56e2d09227..32b17b048d7f7 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -4,11 +4,12 @@ use crate::build::Builder; use crate::thir::*; use rustc_middle::mir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; +use rustc_span::Span; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! - crate fn as_constant(&mut self, expr: &Expr<'_, 'tcx>) -> Constant<'tcx> { + crate fn as_constant(&mut self, expr: &Expr<'_, 'tcx>) -> (Span, Constant<'tcx>) { let this = self; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; match *kind { @@ -22,13 +23,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) }); assert_eq!(literal.ty, ty); - Constant { span, user_ty, literal: literal.into() } + (span, Constant { user_ty, literal: literal.into() }) } ExprKind::StaticRef { literal, .. } => { - Constant { span, user_ty: None, literal: literal.into() } + (span, Constant { user_ty: None, literal: literal.into() }) } ExprKind::ConstBlock { value } => { - Constant { span: span, user_ty: None, literal: value.into() } + (span, Constant { user_ty: None, literal: value.into() }) } _ => span_bug!(span, "expression is not a valid constant {:?}", kind), } diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index c393878e0b995..e94ef60f222f2 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -109,8 +109,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("as_operand: category={:?} for={:?}", category, expr.kind); match category { Category::Constant => { - let constant = this.as_constant(expr); - block.and(Operand::Constant(box constant)) + let span_and_constant = this.as_constant(expr); + block.and(Operand::Constant(box span_and_constant)) } Category::Place | Category::Rvalue(..) => { let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut)); diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 822fbd91c947e..09c8309104745 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -248,11 +248,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { block = unpack!(this.stmt_expr(block, expr, None)); - block.and(Rvalue::Use(Operand::Constant(box Constant { - span: expr_span, + block.and(Rvalue::Use(Operand::Constant(box(expr_span, Constant { user_ty: None, literal: ty::Const::zero_sized(this.tcx, this.tcx.types.unit).into(), - }))) + })))) } ExprKind::Yield { .. } | ExprKind::Literal { .. } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 1e7ed3d95d236..ae9a7f4189a43 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -139,8 +139,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { shortcircuit_block, source_info, destination, + expr_span, Constant { - span: expr_span, user_ty: None, literal: match op { LogicalOp::And => ty::Const::from_bool(this.tcx, false).into(), @@ -357,11 +357,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } thir::InlineAsmOperand::Const { value, span } => { mir::InlineAsmOperand::Const { - value: box Constant { span, user_ty: None, literal: value.into() }, + span, + value: box Constant { user_ty: None, literal: value.into() }, } } thir::InlineAsmOperand::SymFn { expr } => { - mir::InlineAsmOperand::SymFn { value: box this.as_constant(expr) } + let (_, constant) = this.as_constant(expr); + mir::InlineAsmOperand::SymFn { value: box constant } } thir::InlineAsmOperand::SymStatic { def_id } => { mir::InlineAsmOperand::SymStatic { def_id } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index b082169cd63c1..ea849b3c9fbd1 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -429,9 +429,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, TerminatorKind::Call { - func: Operand::Constant(box Constant { - span: source_info.span, - + func: Operand::Constant(box (source_info.span, Constant { // FIXME(#54571): This constant comes from user input (a // constant in a pattern). Are there forms where users can add // type annotations here? For example, an associated constant? @@ -439,7 +437,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { user_ty: None, literal: method.into(), - }), + })), args: vec![val, expect], destination: Some((eq_result, eq_block)), cleanup: None, diff --git a/compiler/rustc_mir_build/src/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs index a1126d1c3d529..645e27a882dbb 100644 --- a/compiler/rustc_mir_build/src/build/misc.rs +++ b/compiler/rustc_mir_build/src/build/misc.rs @@ -31,7 +31,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { literal: &'tcx ty::Const<'tcx>, ) -> Operand<'tcx> { let literal = literal.into(); - let constant = box Constant { span, user_ty: None, literal }; + let constant = box (span, Constant { user_ty: None, literal }); Operand::Constant(constant) } @@ -55,8 +55,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, temp, + source_info.span, Constant { - span: source_info.span, user_ty: None, literal: ty::Const::from_usize(self.tcx, value).into(), }, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 8961cdaebf345..b0a2259f5ceab 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -347,9 +347,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { let local = self.place_to_local(span, p)?; Ok(self.locals[local]) } - mir::Operand::Constant(ct) => match ct.literal { - mir::ConstantKind::Ty(ct) => Ok(self.add_node(Node::Leaf(ct), span)), - mir::ConstantKind::Val(..) => self.error(Some(span), "unsupported constant")?, + mir::Operand::Constant(box(span, ct)) => match ct.literal { + mir::ConstantKind::Ty(ct) => Ok(self.add_node(Node::Leaf(ct), *span)), + mir::ConstantKind::Val(..) => self.error(Some(*span), "unsupported constant")?, }, } } diff --git a/src/test/ui/consts/const-err.stderr b/src/test/ui/consts/const-err.stderr index 0c963874a8496..5bb97f38b1383 100644 --- a/src/test/ui/consts/const-err.stderr +++ b/src/test/ui/consts/const-err.stderr @@ -15,16 +15,16 @@ LL | #![warn(const_err)] = note: for more information, see issue #71800 error[E0080]: erroneous constant used - --> $DIR/const-err.rs:16:16 + --> $DIR/const-err.rs:16:15 | LL | black_box((FOO, FOO)); - | ^^^ referenced constant has errors + | ^^^^^^^^^^ referenced constant has errors error[E0080]: erroneous constant used - --> $DIR/const-err.rs:16:21 + --> $DIR/const-err.rs:16:15 | LL | black_box((FOO, FOO)); - | ^^^ referenced constant has errors + | ^^^^^^^^^^ referenced constant has errors error: aborting due to 2 previous errors; 1 warning emitted