From dfd243e27c5f3e169511cf300b61928ecd31db5c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Jul 2022 11:27:54 -0400 Subject: [PATCH 1/4] add track_caller to some interpreter functions --- compiler/rustc_const_eval/src/interpret/operand.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index d48f6521ba2aa..47d128307d3b9 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -71,6 +71,7 @@ impl<'tcx, Tag: Provenance> Immediate { } #[inline] + #[track_caller] pub fn to_scalar_or_uninit(self) -> ScalarMaybeUninit { match self { Immediate::Scalar(val) => val, @@ -79,11 +80,13 @@ impl<'tcx, Tag: Provenance> Immediate { } #[inline] + #[track_caller] pub fn to_scalar(self) -> InterpResult<'tcx, Scalar> { self.to_scalar_or_uninit().check_init() } #[inline] + #[track_caller] pub fn to_scalar_or_uninit_pair(self) -> (ScalarMaybeUninit, ScalarMaybeUninit) { match self { Immediate::ScalarPair(val1, val2) => (val1, val2), @@ -92,6 +95,7 @@ impl<'tcx, Tag: Provenance> Immediate { } #[inline] + #[track_caller] pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar, Scalar)> { let (val1, val2) = self.to_scalar_or_uninit_pair(); Ok((val1.check_init()?, val2.check_init()?)) From a73e2557c7ba25ddbc886ad9085a3025db51ceb3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Jul 2022 11:44:35 -0400 Subject: [PATCH 2/4] fix ICE in ConstProp --- .../rustc_const_eval/src/interpret/machine.rs | 10 +++++----- compiler/rustc_mir_transform/src/const_prop.rs | 11 ++++++++--- src/test/ui/consts/issue-96169.rs | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/consts/issue-96169.rs diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 54c9e99cf97c8..cb5634b771484 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -10,7 +10,7 @@ use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi; +use rustc_target::spec::abi::Abi as FnAbi; use super::{ AllocId, AllocRange, Allocation, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult, @@ -139,7 +139,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Whether to enforce integers and floats not having provenance. fn enforce_number_no_provenance(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; - /// Whether function calls should be [ABI](Abi)-checked. + /// Whether function calls should be [ABI](FnAbi)-checked. fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { true } @@ -170,7 +170,7 @@ pub trait Machine<'mir, 'tcx>: Sized { fn find_mir_or_eval_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, - abi: Abi, + abi: FnAbi, args: &[OpTy<'tcx, Self::PointerTag>], destination: &PlaceTy<'tcx, Self::PointerTag>, target: Option, @@ -182,7 +182,7 @@ pub trait Machine<'mir, 'tcx>: Sized { fn call_extra_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, fn_val: Self::ExtraFnVal, - abi: Abi, + abi: FnAbi, args: &[OpTy<'tcx, Self::PointerTag>], destination: &PlaceTy<'tcx, Self::PointerTag>, target: Option, @@ -480,7 +480,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { fn call_extra_fn( _ecx: &mut InterpCx<$mir, $tcx, Self>, fn_val: !, - _abi: Abi, + _abi: FnAbi, _args: &[OpTy<$tcx>], _destination: &PlaceTy<$tcx, Self::PointerTag>, _target: Option, diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 070e563f39631..4cc722353e64c 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -22,8 +22,8 @@ use rustc_middle::ty::{ self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable, }; use rustc_span::{def_id::DefId, Span}; -use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; -use rustc_target::spec::abi::Abi; +use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout}; +use rustc_target::spec::abi::Abi as FnAbi; use rustc_trait_selection::traits; use crate::MirPass; @@ -199,7 +199,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _instance: ty::Instance<'tcx>, - _abi: Abi, + _abi: FnAbi, _args: &[OpTy<'tcx>], _destination: &PlaceTy<'tcx>, _target: Option, @@ -654,6 +654,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { (Ok(_), Ok(_)) => return this.ecx.eval_rvalue_into_place(rvalue, place), }; + if !matches!(const_arg.layout.abi, abi::Abi::Scalar(..)) { + // We cannot handle Scalar Pair stuff. + return this.ecx.eval_rvalue_into_place(rvalue, place); + } + let arg_value = const_arg.to_scalar()?.to_bits(const_arg.layout.size)?; let dest = this.ecx.eval_place(place)?; diff --git a/src/test/ui/consts/issue-96169.rs b/src/test/ui/consts/issue-96169.rs new file mode 100644 index 0000000000000..14c0a1399a00e --- /dev/null +++ b/src/test/ui/consts/issue-96169.rs @@ -0,0 +1,18 @@ +// check-pass +// compile-flags: -Zmir-opt-level=4 --emit=mir +#![allow(unused)] +fn a() -> usize { 0 } + +fn bar(_: u32) {} + +fn baz() -> *const dyn Fn(u32) { unimplemented!() } + +fn foo() { + match () { + _ if baz() == &bar as &dyn Fn(u32) => (), + () => (), + } +} + +fn main() { +} From 1e0f3cb56606e4e7e136b46b7461ddecb89e3527 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 7 Jul 2022 12:01:36 -0400 Subject: [PATCH 3/4] make a name less ambiguous --- compiler/rustc_const_eval/src/const_eval/machine.rs | 4 ++-- compiler/rustc_const_eval/src/interpret/machine.rs | 10 +++++----- compiler/rustc_mir_transform/src/const_prop.rs | 4 ++-- compiler/rustc_mir_transform/src/const_prop_lint.rs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index ac529bf152f2b..29ab1d187719c 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -14,7 +14,7 @@ use rustc_middle::mir::AssertMessage; use rustc_session::Limit; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{Align, Size}; -use rustc_target::spec::abi::Abi; +use rustc_target::spec::abi::Abi as CallAbi; use crate::interpret::{ self, compile_time_machine, AllocId, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult, @@ -263,7 +263,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, fn find_mir_or_eval_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, - _abi: Abi, + _abi: CallAbi, args: &[OpTy<'tcx>], _dest: &PlaceTy<'tcx>, _ret: Option, diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index cb5634b771484..720f4379847f8 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -10,7 +10,7 @@ use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi as FnAbi; +use rustc_target::spec::abi::Abi as CallAbi; use super::{ AllocId, AllocRange, Allocation, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult, @@ -139,7 +139,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Whether to enforce integers and floats not having provenance. fn enforce_number_no_provenance(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; - /// Whether function calls should be [ABI](FnAbi)-checked. + /// Whether function calls should be [ABI](CallAbi)-checked. fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { true } @@ -170,7 +170,7 @@ pub trait Machine<'mir, 'tcx>: Sized { fn find_mir_or_eval_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, - abi: FnAbi, + abi: CallAbi, args: &[OpTy<'tcx, Self::PointerTag>], destination: &PlaceTy<'tcx, Self::PointerTag>, target: Option, @@ -182,7 +182,7 @@ pub trait Machine<'mir, 'tcx>: Sized { fn call_extra_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, fn_val: Self::ExtraFnVal, - abi: FnAbi, + abi: CallAbi, args: &[OpTy<'tcx, Self::PointerTag>], destination: &PlaceTy<'tcx, Self::PointerTag>, target: Option, @@ -480,7 +480,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { fn call_extra_fn( _ecx: &mut InterpCx<$mir, $tcx, Self>, fn_val: !, - _abi: FnAbi, + _abi: CallAbi, _args: &[OpTy<$tcx>], _destination: &PlaceTy<$tcx, Self::PointerTag>, _target: Option, diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 4cc722353e64c..572c44622f1da 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ }; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout}; -use rustc_target::spec::abi::Abi as FnAbi; +use rustc_target::spec::abi::Abi as CallAbi; use rustc_trait_selection::traits; use crate::MirPass; @@ -199,7 +199,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _instance: ty::Instance<'tcx>, - _abi: FnAbi, + _abi: CallAbi, _args: &[OpTy<'tcx>], _destination: &PlaceTy<'tcx>, _target: Option, diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index e3ab42d09efff..7527bf20c1f1a 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::{ use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; -use rustc_target::spec::abi::Abi; +use rustc_target::spec::abi::Abi as CallAbi; use rustc_trait_selection::traits; use crate::MirLint; @@ -191,7 +191,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _instance: ty::Instance<'tcx>, - _abi: Abi, + _abi: CallAbi, _args: &[OpTy<'tcx>], _destination: &PlaceTy<'tcx>, _target: Option, From cf9186ec69ecdc138ab692c36b0c2509a72d0b4f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 8 Jul 2022 07:33:19 -0400 Subject: [PATCH 4/4] interpret: only to track_caller in debug builds due to perf --- compiler/rustc_const_eval/src/interpret/operand.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 47d128307d3b9..75d987b655366 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -71,7 +71,7 @@ impl<'tcx, Tag: Provenance> Immediate { } #[inline] - #[track_caller] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar_or_uninit(self) -> ScalarMaybeUninit { match self { Immediate::Scalar(val) => val, @@ -80,13 +80,13 @@ impl<'tcx, Tag: Provenance> Immediate { } #[inline] - #[track_caller] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar(self) -> InterpResult<'tcx, Scalar> { self.to_scalar_or_uninit().check_init() } #[inline] - #[track_caller] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar_or_uninit_pair(self) -> (ScalarMaybeUninit, ScalarMaybeUninit) { match self { Immediate::ScalarPair(val1, val2) => (val1, val2), @@ -95,7 +95,7 @@ impl<'tcx, Tag: Provenance> Immediate { } #[inline] - #[track_caller] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar, Scalar)> { let (val1, val2) = self.to_scalar_or_uninit_pair(); Ok((val1.check_init()?, val2.check_init()?))