Rollup merge of #98980 - RalfJung:const-prop-ice, r=oli-obk
fix ICE in ConstProp Fixes https://github.com/rust-lang/rust/issues/96169
This commit is contained in:
commit
a6c6166d7b
6 changed files with 39 additions and 12 deletions
|
@ -14,7 +14,7 @@ use rustc_middle::mir::AssertMessage;
|
||||||
use rustc_session::Limit;
|
use rustc_session::Limit;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_target::abi::{Align, Size};
|
use rustc_target::abi::{Align, Size};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi as CallAbi;
|
||||||
|
|
||||||
use crate::interpret::{
|
use crate::interpret::{
|
||||||
self, compile_time_machine, AllocId, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult,
|
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(
|
fn find_mir_or_eval_fn(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
_abi: Abi,
|
_abi: CallAbi,
|
||||||
args: &[OpTy<'tcx>],
|
args: &[OpTy<'tcx>],
|
||||||
_dest: &PlaceTy<'tcx>,
|
_dest: &PlaceTy<'tcx>,
|
||||||
_ret: Option<mir::BasicBlock>,
|
_ret: Option<mir::BasicBlock>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_middle::mir;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi as CallAbi;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AllocId, AllocRange, Allocation, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult,
|
AllocId, AllocRange, Allocation, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult,
|
||||||
|
@ -138,7 +138,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
/// Whether to enforce integers and floats not having provenance.
|
/// Whether to enforce integers and floats not having provenance.
|
||||||
fn enforce_number_no_provenance(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
|
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](CallAbi)-checked.
|
||||||
fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
fn find_mir_or_eval_fn(
|
fn find_mir_or_eval_fn(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
abi: Abi,
|
abi: CallAbi,
|
||||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
args: &[OpTy<'tcx, Self::PointerTag>],
|
||||||
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
||||||
target: Option<mir::BasicBlock>,
|
target: Option<mir::BasicBlock>,
|
||||||
|
@ -181,7 +181,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
fn call_extra_fn(
|
fn call_extra_fn(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
fn_val: Self::ExtraFnVal,
|
fn_val: Self::ExtraFnVal,
|
||||||
abi: Abi,
|
abi: CallAbi,
|
||||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
args: &[OpTy<'tcx, Self::PointerTag>],
|
||||||
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
||||||
target: Option<mir::BasicBlock>,
|
target: Option<mir::BasicBlock>,
|
||||||
|
@ -483,7 +483,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||||
fn call_extra_fn(
|
fn call_extra_fn(
|
||||||
_ecx: &mut InterpCx<$mir, $tcx, Self>,
|
_ecx: &mut InterpCx<$mir, $tcx, Self>,
|
||||||
fn_val: !,
|
fn_val: !,
|
||||||
_abi: Abi,
|
_abi: CallAbi,
|
||||||
_args: &[OpTy<$tcx>],
|
_args: &[OpTy<$tcx>],
|
||||||
_destination: &PlaceTy<$tcx, Self::PointerTag>,
|
_destination: &PlaceTy<$tcx, Self::PointerTag>,
|
||||||
_target: Option<mir::BasicBlock>,
|
_target: Option<mir::BasicBlock>,
|
||||||
|
|
|
@ -78,6 +78,7 @@ impl<'tcx, Tag: Provenance> Immediate<Tag> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||||
pub fn to_scalar_or_uninit(self) -> ScalarMaybeUninit<Tag> {
|
pub fn to_scalar_or_uninit(self) -> ScalarMaybeUninit<Tag> {
|
||||||
match self {
|
match self {
|
||||||
Immediate::Scalar(val) => val,
|
Immediate::Scalar(val) => val,
|
||||||
|
@ -87,11 +88,13 @@ impl<'tcx, Tag: Provenance> Immediate<Tag> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||||
pub fn to_scalar(self) -> InterpResult<'tcx, Scalar<Tag>> {
|
pub fn to_scalar(self) -> InterpResult<'tcx, Scalar<Tag>> {
|
||||||
self.to_scalar_or_uninit().check_init()
|
self.to_scalar_or_uninit().check_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||||
pub fn to_scalar_or_uninit_pair(self) -> (ScalarMaybeUninit<Tag>, ScalarMaybeUninit<Tag>) {
|
pub fn to_scalar_or_uninit_pair(self) -> (ScalarMaybeUninit<Tag>, ScalarMaybeUninit<Tag>) {
|
||||||
match self {
|
match self {
|
||||||
Immediate::ScalarPair(val1, val2) => (val1, val2),
|
Immediate::ScalarPair(val1, val2) => (val1, val2),
|
||||||
|
@ -101,6 +104,7 @@ impl<'tcx, Tag: Provenance> Immediate<Tag> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||||
pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar<Tag>, Scalar<Tag>)> {
|
pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar<Tag>, Scalar<Tag>)> {
|
||||||
let (val1, val2) = self.to_scalar_or_uninit_pair();
|
let (val1, val2) = self.to_scalar_or_uninit_pair();
|
||||||
Ok((val1.check_init()?, val2.check_init()?))
|
Ok((val1.check_init()?, val2.check_init()?))
|
||||||
|
|
|
@ -22,8 +22,8 @@ use rustc_middle::ty::{
|
||||||
self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable,
|
self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable,
|
||||||
};
|
};
|
||||||
use rustc_span::{def_id::DefId, Span};
|
use rustc_span::{def_id::DefId, Span};
|
||||||
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
|
use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi as CallAbi;
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
|
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
|
@ -195,7 +195,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
||||||
fn find_mir_or_eval_fn(
|
fn find_mir_or_eval_fn(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_instance: ty::Instance<'tcx>,
|
_instance: ty::Instance<'tcx>,
|
||||||
_abi: Abi,
|
_abi: CallAbi,
|
||||||
_args: &[OpTy<'tcx>],
|
_args: &[OpTy<'tcx>],
|
||||||
_destination: &PlaceTy<'tcx>,
|
_destination: &PlaceTy<'tcx>,
|
||||||
_target: Option<BasicBlock>,
|
_target: Option<BasicBlock>,
|
||||||
|
@ -659,6 +659,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
(Ok(_), Ok(_)) => return this.ecx.eval_rvalue_into_place(rvalue, place),
|
(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 arg_value = const_arg.to_scalar()?.to_bits(const_arg.layout.size)?;
|
||||||
let dest = this.ecx.eval_place(place)?;
|
let dest = this.ecx.eval_place(place)?;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ use rustc_middle::ty::{
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::{def_id::DefId, Span};
|
use rustc_span::{def_id::DefId, Span};
|
||||||
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
|
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 rustc_trait_selection::traits;
|
||||||
|
|
||||||
use crate::MirLint;
|
use crate::MirLint;
|
||||||
|
@ -191,7 +191,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
||||||
fn find_mir_or_eval_fn(
|
fn find_mir_or_eval_fn(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_instance: ty::Instance<'tcx>,
|
_instance: ty::Instance<'tcx>,
|
||||||
_abi: Abi,
|
_abi: CallAbi,
|
||||||
_args: &[OpTy<'tcx>],
|
_args: &[OpTy<'tcx>],
|
||||||
_destination: &PlaceTy<'tcx>,
|
_destination: &PlaceTy<'tcx>,
|
||||||
_target: Option<BasicBlock>,
|
_target: Option<BasicBlock>,
|
||||||
|
|
18
src/test/ui/consts/issue-96169.rs
Normal file
18
src/test/ui/consts/issue-96169.rs
Normal file
|
@ -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() {
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue