Auto merge of #122690 - matthiaskrgr:rollup-43fggl0, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #122480 (Avoid various uses of `Option<Span>` in favor of using `DUMMY_SP` in the few cases that used `None`) - #122567 (Remove fixme about LLVM basic block naming) - #122588 (less useless filter calls in imported_source_file) - #122647 (add_retag: ensure box-to-raw-ptr casts are preserved for Miri) - #122649 (Update the minimum external LLVM to 17) - #122680 (Do not eat nested expressions' results in `MayContainYieldPoint` format args visitor) - #122683 (add missing test: expected paren or brace in macro) - #122689 (Add missing `try_visit` calls in visitors.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d31b6fb8c0
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -58,7 +58,7 @@ jobs:
|
||||
- name: mingw-check-tidy
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-llvm-16
|
||||
- name: x86_64-gnu-llvm-17
|
||||
env:
|
||||
ENABLE_GCC_CODEGEN: "1"
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
@ -323,10 +323,6 @@ jobs:
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-llvm-16
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-nopt
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
|
@ -755,7 +755,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
|
||||
}
|
||||
AssocItemKind::Delegation(box Delegation { id, qself, path, body }) => {
|
||||
if let Some(qself) = qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
try_visit!(visitor.visit_ty(&qself.ty));
|
||||
}
|
||||
try_visit!(visitor.visit_path(path, *id));
|
||||
visit_opt!(visitor, visit_block, body);
|
||||
@ -994,7 +994,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
|
||||
ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
|
||||
ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)),
|
||||
ExprKind::OffsetOf(container, fields) => {
|
||||
visitor.visit_ty(container);
|
||||
try_visit!(visitor.visit_ty(container));
|
||||
walk_list!(visitor, visit_ident, fields.iter().copied());
|
||||
}
|
||||
ExprKind::Yield(optional_expression) => {
|
||||
|
@ -604,8 +604,7 @@ fn may_contain_yield_point(e: &ast::Expr) -> bool {
|
||||
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
visit::walk_expr(self, e);
|
||||
ControlFlow::Continue(())
|
||||
visit::walk_expr(self, e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
|
||||
let cv = fx.monomorphize(constant.const_);
|
||||
// This cannot fail because we checked all required_consts in advance.
|
||||
let val = cv
|
||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
|
||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span)
|
||||
.expect("erroneous constant missed by mono item collection");
|
||||
(val, cv.ty())
|
||||
}
|
||||
|
@ -728,8 +728,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
| sym::variant_count => {
|
||||
intrinsic_args!(fx, args => (); intrinsic);
|
||||
|
||||
let const_val =
|
||||
fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap();
|
||||
let const_val = fx
|
||||
.tcx
|
||||
.const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span)
|
||||
.unwrap();
|
||||
let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
|
||||
ret.write_cvalue(fx, val);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
|
||||
let idx = generic_args[2]
|
||||
.expect_const()
|
||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span))
|
||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), span)
|
||||
.unwrap()
|
||||
.unwrap_branch();
|
||||
|
||||
|
@ -126,17 +126,6 @@ pub unsafe fn create_module<'ll>(
|
||||
|
||||
let mut target_data_layout = sess.target.data_layout.to_string();
|
||||
let llvm_version = llvm_util::get_version();
|
||||
if llvm_version < (17, 0, 0) {
|
||||
if sess.target.arch.starts_with("powerpc") {
|
||||
// LLVM 17 specifies function pointer alignment for ppc:
|
||||
// https://reviews.llvm.org/D147016
|
||||
target_data_layout = target_data_layout
|
||||
.replace("-Fn32", "")
|
||||
.replace("-Fi32", "")
|
||||
.replace("-Fn64", "")
|
||||
.replace("-Fi64", "");
|
||||
}
|
||||
}
|
||||
if llvm_version < (18, 0, 0) {
|
||||
if sess.target.arch == "x86" || sess.target.arch == "x86_64" {
|
||||
// LLVM 18 adjusts i128 to be 128-bit aligned on x86 variants.
|
||||
|
@ -1129,7 +1129,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
if name == sym::simd_shuffle_generic {
|
||||
let idx = fn_args[2]
|
||||
.expect_const()
|
||||
.eval(tcx, ty::ParamEnv::reveal_all(), Some(span))
|
||||
.eval(tcx, ty::ParamEnv::reveal_all(), span)
|
||||
.unwrap()
|
||||
.unwrap_branch();
|
||||
let n = idx.len() as u64;
|
||||
|
@ -19,6 +19,7 @@ use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}
|
||||
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
||||
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_target::abi::Integer;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
@ -704,7 +705,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
|
||||
// avoiding collisions and will make the emitted type names shorter.
|
||||
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut hasher = StableHasher::new();
|
||||
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), None).unwrap();
|
||||
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
|
||||
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
|
||||
hasher.finish::<Hash64>()
|
||||
});
|
||||
|
@ -1688,7 +1688,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
pub fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option<Bx::BasicBlock> {
|
||||
match self.cached_llbbs[bb] {
|
||||
CachedLlbb::None => {
|
||||
// FIXME(eddyb) only name the block if `fewer_names` is `false`.
|
||||
let llbb = Bx::append_block(self.cx, self.llfn, &format!("{bb:?}"));
|
||||
self.cached_llbbs[bb] = CachedLlbb::Some(llbb);
|
||||
Some(llbb)
|
||||
|
@ -24,7 +24,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
// `MirUsedCollector` visited all required_consts before codegen began, so if we got here
|
||||
// there can be no more constants that fail to evaluate.
|
||||
self.monomorphize(constant.const_)
|
||||
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
|
||||
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), constant.span)
|
||||
.expect("erroneous constant missed by mono item collection")
|
||||
}
|
||||
|
||||
@ -56,11 +56,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
other => span_bug!(constant.span, "{other:#?}"),
|
||||
};
|
||||
let uv = self.monomorphize(uv);
|
||||
self.cx.tcx().const_eval_resolve_for_typeck(
|
||||
ty::ParamEnv::reveal_all(),
|
||||
uv,
|
||||
Some(constant.span),
|
||||
)
|
||||
self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span)
|
||||
}
|
||||
|
||||
/// process constant containing SIMD shuffle indices
|
||||
|
@ -130,7 +130,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
| sym::variant_count => {
|
||||
let value = bx
|
||||
.tcx()
|
||||
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, None)
|
||||
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, span)
|
||||
.unwrap();
|
||||
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
||||
}
|
||||
|
@ -826,7 +826,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
for &const_ in &body.required_consts {
|
||||
let c = self
|
||||
.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
|
||||
c.eval(*self.tcx, self.param_env, Some(const_.span)).map_err(|err| {
|
||||
c.eval(*self.tcx, self.param_env, const_.span).map_err(|err| {
|
||||
err.emit_note(*self.tcx);
|
||||
err
|
||||
})?;
|
||||
@ -1174,7 +1174,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
pub fn eval_mir_constant(
|
||||
&self,
|
||||
val: &mir::Const<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
|
||||
|
@ -153,9 +153,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::type_name => Ty::new_static_str(self.tcx.tcx),
|
||||
_ => bug!(),
|
||||
};
|
||||
let val = self.ctfe_query(|tcx| {
|
||||
tcx.const_eval_global_id(self.param_env, gid, Some(tcx.span))
|
||||
})?;
|
||||
let val =
|
||||
self.ctfe_query(|tcx| tcx.const_eval_global_id(self.param_env, gid, tcx.span))?;
|
||||
let val = self.const_val_to_op(val, ty, Some(dest.layout))?;
|
||||
self.copy_op(&val, dest)?;
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
||||
fn eval_mir_constant<F>(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
val: mir::Const<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
eval: F,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
|
||||
@ -533,7 +533,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
||||
F: Fn(
|
||||
&InterpCx<'mir, 'tcx, Self>,
|
||||
mir::Const<'tcx>,
|
||||
Option<Span>,
|
||||
Span,
|
||||
Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>,
|
||||
{
|
||||
|
@ -741,7 +741,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
|
||||
// checked yet.
|
||||
// * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
|
||||
self.eval_mir_constant(&c, Some(constant.span), layout)?
|
||||
self.eval_mir_constant(&c, constant.span, layout)?
|
||||
}
|
||||
};
|
||||
trace!("{:?}: {:?}", mir_op, op);
|
||||
|
@ -341,7 +341,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
|
||||
// FIXME(JakobDegen) The validator should check that `self.mir_phase <
|
||||
// DropsLowered`. However, this causes ICEs with generation of drop shims, which
|
||||
// seem to fail to set their `MirPhase` correctly.
|
||||
if matches!(kind, RetagKind::Raw | RetagKind::TwoPhase) {
|
||||
if matches!(kind, RetagKind::TwoPhase) {
|
||||
self.fail(location, format!("explicit `{kind:?}` is forbidden"));
|
||||
}
|
||||
}
|
||||
@ -1272,7 +1272,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
// FIXME(JakobDegen) The validator should check that `self.mir_phase <
|
||||
// DropsLowered`. However, this causes ICEs with generation of drop shims, which
|
||||
// seem to fail to set their `MirPhase` correctly.
|
||||
if matches!(kind, RetagKind::Raw | RetagKind::TwoPhase) {
|
||||
if matches!(kind, RetagKind::TwoPhase) {
|
||||
self.fail(location, format!("explicit `{kind:?}` is forbidden"));
|
||||
}
|
||||
}
|
||||
|
@ -899,7 +899,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(
|
||||
GenericParamKind::Const { ref ty, ref default, is_host_effect: _ } => {
|
||||
try_visit!(visitor.visit_ty(ty));
|
||||
if let Some(ref default) = default {
|
||||
visitor.visit_const_param_default(param.hir_id, default);
|
||||
try_visit!(visitor.visit_const_param_default(param.hir_id, default));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -658,10 +658,6 @@ pub fn check_intrinsic_type(
|
||||
sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
|
||||
sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)),
|
||||
|
||||
sym::retag_box_to_raw => {
|
||||
(2, 0, vec![Ty::new_mut_ptr(tcx, param(0))], Ty::new_mut_ptr(tcx, param(0)))
|
||||
}
|
||||
|
||||
other => {
|
||||
tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
|
||||
return;
|
||||
|
@ -2178,7 +2178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
len: ty::Const<'tcx>,
|
||||
min_len: u64,
|
||||
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
|
||||
let len = match len.eval(self.tcx, self.param_env, None) {
|
||||
let len = match len.eval(self.tcx, self.param_env, span) {
|
||||
Ok(val) => val
|
||||
.try_to_scalar()
|
||||
.and_then(|scalar| scalar.try_to_int().ok())
|
||||
|
@ -1475,7 +1475,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
unevaluated: ty::UnevaluatedConst<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> Result<ty::Const<'tcx>, ErrorHandled> {
|
||||
match self.const_eval_resolve(param_env, unevaluated, span) {
|
||||
Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, ty)),
|
||||
@ -1509,7 +1509,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
&self,
|
||||
mut param_env: ty::ParamEnv<'tcx>,
|
||||
unevaluated: ty::UnevaluatedConst<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
let mut args = self.resolve_vars_if_possible(unevaluated.args);
|
||||
debug!(?args);
|
||||
@ -1521,12 +1521,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
|
||||
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
|
||||
if let Err(e) = ct.error_reported() {
|
||||
return Err(ErrorHandled::Reported(
|
||||
e.into(),
|
||||
span.unwrap_or(rustc_span::DUMMY_SP),
|
||||
));
|
||||
return Err(ErrorHandled::Reported(e.into(), span));
|
||||
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
|
||||
return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP)));
|
||||
return Err(ErrorHandled::TooGeneric(span));
|
||||
} else {
|
||||
args = replace_param_and_infer_args_with_placeholder(tcx, args);
|
||||
}
|
||||
|
@ -24,9 +24,7 @@
|
||||
#include "llvm/Passes/StandardInstrumentations.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#endif
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/IPO/AlwaysInliner.h"
|
||||
#include "llvm/Transforms/IPO/FunctionImport.h"
|
||||
@ -334,14 +332,8 @@ extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM,
|
||||
|
||||
std::ostringstream Buf;
|
||||
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
|
||||
const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions();
|
||||
#else
|
||||
Buf << "Full target CPU help is not supported by this LLVM version.\n\n";
|
||||
SubtargetSubTypeKV TargetCPUKV = { TargetCPU, {{}}, {{}} };
|
||||
const ArrayRef<SubtargetSubTypeKV> CPUTable = TargetCPUKV;
|
||||
#endif
|
||||
unsigned MaxCPULen = getLongestEntryLength(CPUTable);
|
||||
|
||||
Buf << "Available CPUs for this target:\n";
|
||||
@ -476,10 +468,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
Options.RelaxELFRelocations = RelaxELFRelocations;
|
||||
#endif
|
||||
Options.UseInitArray = UseInitArray;
|
||||
|
||||
#if LLVM_VERSION_LT(17, 0)
|
||||
Options.ExplicitEmulatedTLS = true;
|
||||
#endif
|
||||
Options.EmulatedTLS = UseEmulatedTls;
|
||||
|
||||
if (TrapUnreachable) {
|
||||
@ -761,16 +749,10 @@ LLVMRustOptimize(
|
||||
}
|
||||
|
||||
std::optional<PGOOptions> PGOOpt;
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
auto FS = vfs::getRealFileSystem();
|
||||
#endif
|
||||
if (PGOGenPath) {
|
||||
assert(!PGOUsePath && !PGOSampleUsePath);
|
||||
PGOOpt = PGOOptions(PGOGenPath, "", "",
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
"",
|
||||
FS,
|
||||
#endif
|
||||
PGOOpt = PGOOptions(PGOGenPath, "", "", "", FS,
|
||||
PGOOptions::IRInstr, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
@ -778,33 +760,21 @@ LLVMRustOptimize(
|
||||
DebugInfoForProfiling);
|
||||
} else if (PGOUsePath) {
|
||||
assert(!PGOSampleUsePath);
|
||||
PGOOpt = PGOOptions(PGOUsePath, "", "",
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
"",
|
||||
FS,
|
||||
#endif
|
||||
PGOOpt = PGOOptions(PGOUsePath, "", "", "", FS,
|
||||
PGOOptions::IRUse, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
#endif
|
||||
DebugInfoForProfiling);
|
||||
} else if (PGOSampleUsePath) {
|
||||
PGOOpt = PGOOptions(PGOSampleUsePath, "", "",
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
"",
|
||||
FS,
|
||||
#endif
|
||||
PGOOpt = PGOOptions(PGOSampleUsePath, "", "", "", FS,
|
||||
PGOOptions::SampleUse, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
#endif
|
||||
DebugInfoForProfiling);
|
||||
} else if (DebugInfoForProfiling) {
|
||||
PGOOpt = PGOOptions("", "", "",
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
"",
|
||||
FS,
|
||||
#endif
|
||||
PGOOpt = PGOOptions("", "", "", "", FS,
|
||||
PGOOptions::NoAction, PGOOptions::NoCSAction,
|
||||
#if LLVM_VERSION_GE(19, 0)
|
||||
PGOOptions::ColdFuncOpt::Default,
|
||||
@ -1353,9 +1323,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
|
||||
ComputeCrossModuleImport(
|
||||
Ret->Index,
|
||||
Ret->ModuleToDefinedGVSummaries,
|
||||
#if LLVM_VERSION_GE(17, 0)
|
||||
isPrevailing,
|
||||
#endif
|
||||
Ret->ImportLists,
|
||||
Ret->ExportLists
|
||||
);
|
||||
|
@ -2152,19 +2152,3 @@ extern "C" LLVMValueRef LLVMConstStringInContext2(LLVMContextRef C,
|
||||
return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), !DontNullTerminate));
|
||||
}
|
||||
#endif
|
||||
|
||||
// FIXME: Remove when Rust's minimum supported LLVM version reaches 17.
|
||||
// https://github.com/llvm/llvm-project/commit/35276f16e5a2cae0dfb49c0fbf874d4d2f177acc
|
||||
#if LLVM_VERSION_LT(17, 0)
|
||||
extern "C" LLVMValueRef LLVMConstArray2(LLVMTypeRef ElementTy,
|
||||
LLVMValueRef *ConstantVals,
|
||||
uint64_t Length) {
|
||||
ArrayRef<Constant *> V(unwrap<Constant>(ConstantVals, Length), Length);
|
||||
return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V));
|
||||
}
|
||||
|
||||
extern "C" LLVMTypeRef LLVMArrayType2(LLVMTypeRef ElementTy,
|
||||
uint64_t ElementCount) {
|
||||
return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
|
||||
}
|
||||
#endif
|
||||
|
@ -1590,17 +1590,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
// Translate the virtual `/rustc/$hash` prefix back to a real directory
|
||||
// that should hold actual sources, where possible.
|
||||
//
|
||||
// NOTE: if you update this, you might need to also update bootstrap's code for generating
|
||||
// the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
|
||||
let virtual_rust_source_base_dir = [
|
||||
filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)),
|
||||
filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()),
|
||||
];
|
||||
|
||||
let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
|
||||
// Translate the virtual `/rustc/$hash` prefix back to a real directory
|
||||
// that should hold actual sources, where possible.
|
||||
//
|
||||
// NOTE: if you update this, you might need to also update bootstrap's code for generating
|
||||
// the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
|
||||
let virtual_rust_source_base_dir = [
|
||||
filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)),
|
||||
filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()),
|
||||
];
|
||||
|
||||
debug!(
|
||||
"try_to_translate_virtual_to_real(name={:?}): \
|
||||
virtual_rust_source_base_dir={:?}, real_rust_source_base_dir={:?}",
|
||||
|
@ -2,7 +2,7 @@ use std::fmt::{self, Debug, Display, Formatter};
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_session::RemapFileNameExt;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::abi::{HasDataLayout, Size};
|
||||
|
||||
use crate::mir::interpret::{alloc_range, AllocId, ConstAllocation, ErrorHandled, Scalar};
|
||||
@ -273,7 +273,7 @@ impl<'tcx> Const<'tcx> {
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self {
|
||||
Const::Ty(c) => {
|
||||
@ -293,7 +293,7 @@ impl<'tcx> Const<'tcx> {
|
||||
/// Normalizes the constant to a value or an error if possible.
|
||||
#[inline]
|
||||
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
|
||||
match self.eval(tcx, param_env, None) {
|
||||
match self.eval(tcx, param_env, DUMMY_SP) {
|
||||
Ok(val) => Self::Val(val, self.ty()),
|
||||
Err(ErrorHandled::Reported(guar, _span)) => {
|
||||
Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty()))
|
||||
@ -313,10 +313,10 @@ impl<'tcx> Const<'tcx> {
|
||||
// Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
|
||||
// are valtree leaves, and *not* on references. (References should return the
|
||||
// pointer here, which valtrees don't represent.)
|
||||
let val = c.eval(tcx, param_env, None).ok()?;
|
||||
let val = c.eval(tcx, param_env, DUMMY_SP).ok()?;
|
||||
Some(val.unwrap_leaf().into())
|
||||
}
|
||||
_ => self.eval(tcx, param_env, None).ok()?.try_to_scalar(),
|
||||
_ => self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
let instance = ty::Instance::new(def_id, args);
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
|
||||
self.const_eval_global_id(param_env, cid, None)
|
||||
self.const_eval_global_id(param_env, cid, DUMMY_SP)
|
||||
}
|
||||
/// Resolves and evaluates a constant.
|
||||
///
|
||||
@ -40,7 +40,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ct: mir::UnevaluatedConst<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToConstValueResult<'tcx> {
|
||||
// Cannot resolve `Unevaluated` constants that contain inference
|
||||
// variables. We reject those here since `resolve`
|
||||
@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ct: ty::UnevaluatedConst<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
// Cannot resolve `Unevaluated` constants that contain inference
|
||||
// variables. We reject those here since `resolve`
|
||||
@ -130,7 +130,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToConstValueResult<'tcx> {
|
||||
self.const_eval_global_id(param_env, GlobalId { instance, promoted: None }, span)
|
||||
}
|
||||
@ -141,12 +141,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cid: GlobalId<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToConstValueResult<'tcx> {
|
||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||
// improve caching of queries.
|
||||
let inputs = self.erase_regions(param_env.with_reveal_all_normalized(self).and(cid));
|
||||
if let Some(span) = span {
|
||||
if !span.is_dummy() {
|
||||
// The query doesn't know where it is being invoked, so we need to fix the span.
|
||||
self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
|
||||
} else {
|
||||
@ -160,13 +160,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cid: GlobalId<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||
// improve caching of queries.
|
||||
let inputs = self.erase_regions(param_env.with_reveal_all_normalized(self).and(cid));
|
||||
debug!(?inputs);
|
||||
if let Some(span) = span {
|
||||
if !span.is_dummy() {
|
||||
// The query doesn't know where it is being invoked, so we need to fix the span.
|
||||
self.at(span).eval_to_valtree(inputs).map_err(|e| e.with_span(span))
|
||||
} else {
|
||||
|
@ -335,7 +335,7 @@ impl<'tcx> Const<'tcx> {
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> Result<ValTree<'tcx>, ErrorHandled> {
|
||||
assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
|
||||
match self.kind() {
|
||||
@ -349,7 +349,7 @@ impl<'tcx> Const<'tcx> {
|
||||
else {
|
||||
// This can happen when we run on ill-typed code.
|
||||
let e = tcx.dcx().span_delayed_bug(
|
||||
span.unwrap_or(DUMMY_SP),
|
||||
span,
|
||||
"`ty::Const::eval` called on a non-valtree-compatible type",
|
||||
);
|
||||
return Err(e.into());
|
||||
@ -362,14 +362,14 @@ impl<'tcx> Const<'tcx> {
|
||||
| ConstKind::Infer(_)
|
||||
| ConstKind::Bound(_, _)
|
||||
| ConstKind::Placeholder(_)
|
||||
| ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))),
|
||||
| ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric(span)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalizes the constant to a value or an error if possible.
|
||||
#[inline]
|
||||
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
|
||||
match self.eval(tcx, param_env, None) {
|
||||
match self.eval(tcx, param_env, DUMMY_SP) {
|
||||
Ok(val) => Self::new_value(tcx, val, self.ty()),
|
||||
Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into(), self.ty()),
|
||||
Err(ErrorHandled::TooGeneric(_span)) => self,
|
||||
@ -382,7 +382,7 @@ impl<'tcx> Const<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<Scalar> {
|
||||
self.eval(tcx, param_env, None).ok()?.try_to_scalar()
|
||||
self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -524,12 +524,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
// Prefer valtrees over opaque constants.
|
||||
let const_value = self
|
||||
.tcx
|
||||
.const_eval_global_id_for_typeck(param_env_reveal_all, cid, Some(span))
|
||||
.const_eval_global_id_for_typeck(param_env_reveal_all, cid, span)
|
||||
.map(|val| match val {
|
||||
Some(valtree) => mir::Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)),
|
||||
None => mir::Const::Val(
|
||||
self.tcx
|
||||
.const_eval_global_id(param_env_reveal_all, cid, Some(span))
|
||||
.const_eval_global_id(param_env_reveal_all, cid, span)
|
||||
.expect("const_eval_global_id_for_typeck should have already failed"),
|
||||
ty,
|
||||
),
|
||||
@ -627,15 +627,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
// First try using a valtree in order to destructure the constant into a pattern.
|
||||
// FIXME: replace "try to do a thing, then fall back to another thing"
|
||||
// but something more principled, like a trait query checking whether this can be turned into a valtree.
|
||||
if let Ok(Some(valtree)) =
|
||||
self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span))
|
||||
if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span)
|
||||
{
|
||||
let subpattern =
|
||||
self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span);
|
||||
PatKind::InlineConstant { subpattern, def: def_id }
|
||||
} else {
|
||||
// If that fails, convert it to an opaque constant pattern.
|
||||
match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) {
|
||||
match tcx.const_eval_resolve(self.param_env, uneval, span) {
|
||||
Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span).kind,
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
|
||||
|
@ -24,7 +24,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
|
||||
| ty::Str
|
||||
| ty::FnDef(..)
|
||||
| ty::Never => false,
|
||||
// References
|
||||
// References and Boxes (`noalias` sources)
|
||||
ty::Ref(..) => true,
|
||||
ty::Adt(..) if ty.is_box() => true,
|
||||
ty::Adt(adt, _) if Some(adt.did()) == tcx.lang_items().ptr_unique() => true,
|
||||
@ -125,15 +125,39 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
|
||||
for i in (0..block_data.statements.len()).rev() {
|
||||
let (retag_kind, place) = match block_data.statements[i].kind {
|
||||
// Retag after assignments of reference type.
|
||||
StatementKind::Assign(box (ref place, ref rvalue)) if needs_retag(place) => {
|
||||
StatementKind::Assign(box (ref place, ref rvalue)) => {
|
||||
let add_retag = match rvalue {
|
||||
// Ptr-creating operations already do their own internal retagging, no
|
||||
// need to also add a retag statement.
|
||||
Rvalue::Ref(..) | Rvalue::AddressOf(..) => false,
|
||||
_ => true,
|
||||
// *Except* if we are deref'ing a Box, because those get desugared to directly working
|
||||
// with the inner raw pointer! That's relevant for `AddressOf` as Miri otherwise makes it
|
||||
// a NOP when the original pointer is already raw.
|
||||
Rvalue::AddressOf(_mutbl, place) => {
|
||||
// Using `is_box_global` here is a bit sketchy: if this code is
|
||||
// generic over the allocator, we'll not add a retag! This is a hack
|
||||
// to make Stacked Borrows compatible with custom allocator code.
|
||||
// Long-term, we'll want to move to an aliasing model where "cast to
|
||||
// raw pointer" is a complete NOP, and then this will no longer be
|
||||
// an issue.
|
||||
if place.is_indirect_first_projection()
|
||||
&& body.local_decls[place.local].ty.is_box_global(tcx)
|
||||
{
|
||||
Some(RetagKind::Raw)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Rvalue::Ref(..) => None,
|
||||
_ => {
|
||||
if needs_retag(place) {
|
||||
Some(RetagKind::Default)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
if add_retag {
|
||||
(RetagKind::Default, *place)
|
||||
if let Some(kind) = add_retag {
|
||||
(kind, *place)
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
|
||||
}
|
||||
Operand::Constant(box constant) => {
|
||||
if let Ok(constant) =
|
||||
self.ecx.eval_mir_constant(&constant.const_, Some(constant.span), None)
|
||||
self.ecx.eval_mir_constant(&constant.const_, constant.span, None)
|
||||
{
|
||||
self.assign_constant(state, place, constant, &[]);
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
Repeat(..) => return None,
|
||||
|
||||
Constant { ref value, disambiguator: _ } => {
|
||||
self.ecx.eval_mir_constant(value, None, None).ok()?
|
||||
self.ecx.eval_mir_constant(value, DUMMY_SP, None).ok()?
|
||||
}
|
||||
Aggregate(kind, variant, ref fields) => {
|
||||
let fields = fields
|
||||
|
@ -417,7 +417,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
|
||||
// If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
|
||||
Operand::Constant(constant) => {
|
||||
let constant =
|
||||
self.ecx.eval_mir_constant(&constant.const_, Some(constant.span), None).ok()?;
|
||||
self.ecx.eval_mir_constant(&constant.const_, constant.span, None).ok()?;
|
||||
self.process_constant(bb, lhs, constant, state);
|
||||
}
|
||||
// Transfer the conditions on the copied rhs.
|
||||
|
@ -261,7 +261,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
// manually normalized.
|
||||
let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.const_).ok()?;
|
||||
|
||||
self.use_ecx(|this| this.ecx.eval_mir_constant(&val, Some(c.span), None))?
|
||||
self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?
|
||||
.as_mplace_or_imm()
|
||||
.right()
|
||||
}
|
||||
|
@ -529,11 +529,11 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
// AddMovesForPackedDrops needs to run after drop
|
||||
// elaboration.
|
||||
&add_moves_for_packed_drops::AddMovesForPackedDrops,
|
||||
// `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
|
||||
// `AddRetag` needs to run after `ElaborateDrops` but before `ElaborateBoxDerefs`. Otherwise it should run fairly late,
|
||||
// but before optimizations begin.
|
||||
&add_retag::AddRetag,
|
||||
&elaborate_box_derefs::ElaborateBoxDerefs,
|
||||
&coroutine::StateTransform,
|
||||
&add_retag::AddRetag,
|
||||
&Lint(known_panics_lint::KnownPanicsLint),
|
||||
];
|
||||
pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial)));
|
||||
|
@ -828,7 +828,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
||||
// a codegen-time error). rustc stops after collection if there was an error, so this
|
||||
// ensures codegen never has to worry about failing consts.
|
||||
// (codegen relies on this and ICEs will happen if this is violated.)
|
||||
let val = match const_.eval(self.tcx, param_env, Some(constant.span)) {
|
||||
let val = match const_.eval(self.tcx, param_env, constant.span) {
|
||||
Ok(v) => v,
|
||||
Err(ErrorHandled::TooGeneric(..)) => span_bug!(
|
||||
self.body.source_info(location).span,
|
||||
|
@ -56,7 +56,7 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
|
||||
|
||||
fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
|
||||
let const_ = self.monomorphize(constant.const_);
|
||||
let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) {
|
||||
let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), constant.span) {
|
||||
Ok(v) => v,
|
||||
Err(mir::interpret::ErrorHandled::Reported(..)) => return,
|
||||
Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
|
||||
|
@ -566,7 +566,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
let result = tcx.const_eval_instance(
|
||||
ParamEnv::reveal_all(),
|
||||
instance,
|
||||
Some(tcx.def_span(instance.def_id())),
|
||||
tcx.def_span(instance.def_id()),
|
||||
);
|
||||
result
|
||||
.map(|const_val| {
|
||||
|
@ -1463,7 +1463,6 @@ symbols! {
|
||||
residual,
|
||||
result,
|
||||
resume,
|
||||
retag_box_to_raw,
|
||||
return_position_impl_trait_in_trait,
|
||||
return_type_notation,
|
||||
rhs,
|
||||
|
@ -968,7 +968,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<ty::Const<'tcx>> {
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, None) {
|
||||
match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, DUMMY_SP) {
|
||||
Ok(ct) => Some(ct),
|
||||
Err(ErrorHandled::Reported(e, _)) => {
|
||||
Some(ty::Const::new_error(self.tcx(), e.into(), ty))
|
||||
|
@ -786,7 +786,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
match selcx.infcx.const_eval_resolve(
|
||||
obligation.param_env,
|
||||
unevaluated,
|
||||
Some(obligation.cause.span),
|
||||
obligation.cause.span,
|
||||
) {
|
||||
Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, c.ty())),
|
||||
Ok(None) => {
|
||||
|
@ -68,7 +68,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
tcx.dcx().span_bug(span, "evaluating `ConstKind::Expr` is not currently supported");
|
||||
}
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv, span);
|
||||
match concrete {
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug(
|
||||
@ -99,7 +99,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||
// and hopefully soon change this to an error.
|
||||
//
|
||||
// See #74595 for more details about this.
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv, span);
|
||||
match concrete {
|
||||
// If we're evaluating a generic foreign constant, under a nightly compiler while
|
||||
// the current crate does not enable `feature(generic_const_exprs)`, abort
|
||||
|
@ -600,7 +600,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
obligation.param_env,
|
||||
unevaluated,
|
||||
c.ty(),
|
||||
Some(obligation.cause.span),
|
||||
obligation.cause.span,
|
||||
) {
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => {
|
||||
|
@ -949,7 +949,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation.param_env,
|
||||
unevaluated,
|
||||
c.ty(),
|
||||
Some(obligation.cause.span),
|
||||
obligation.cause.span,
|
||||
) {
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => Err(e),
|
||||
|
@ -89,6 +89,7 @@ mod rustc {
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::ValTree;
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
/// The source and destination types of a transmutation.
|
||||
#[derive(TypeVisitable, Debug, Clone, Copy)]
|
||||
@ -135,7 +136,7 @@ mod rustc {
|
||||
use rustc_middle::ty::ScalarInt;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
let Ok(cv) = c.eval(tcx, param_env, None) else {
|
||||
let Ok(cv) = c.eval(tcx, param_env, DUMMY_SP) else {
|
||||
return Some(Self {
|
||||
alignment: true,
|
||||
lifetimes: true,
|
||||
|
@ -155,7 +155,6 @@ use core::error::Error;
|
||||
use core::fmt;
|
||||
use core::future::Future;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::intrinsics::retag_box_to_raw;
|
||||
use core::iter::FusedIterator;
|
||||
use core::marker::Tuple;
|
||||
use core::marker::Unsize;
|
||||
@ -165,7 +164,7 @@ use core::ops::{
|
||||
CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver,
|
||||
};
|
||||
use core::pin::Pin;
|
||||
use core::ptr::{self, NonNull, Unique};
|
||||
use core::ptr::{self, addr_of_mut, NonNull, Unique};
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
@ -1111,16 +1110,12 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
#[inline]
|
||||
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
|
||||
// This is the transition point from `Box` to raw pointers. For Stacked Borrows, these casts
|
||||
// are relevant -- if this is a global allocator Box and we just get the pointer from `b.0`,
|
||||
// it will have `Unique` permission, which is not what we want from a raw pointer. We could
|
||||
// fix that by going through `&mut`, but then if this is *not* a global allocator Box, we'd
|
||||
// be adding uniqueness assertions that we do not want. So for Miri's sake we pass this
|
||||
// pointer through an intrinsic for box-to-raw casts, which can do the right thing wrt the
|
||||
// aliasing model.
|
||||
let b = mem::ManuallyDrop::new(b);
|
||||
let mut b = mem::ManuallyDrop::new(b);
|
||||
// We carefully get the raw pointer out in a way that Miri's aliasing model understands what
|
||||
// is happening: using the primitive "deref" of `Box`.
|
||||
let ptr = addr_of_mut!(**b);
|
||||
let alloc = unsafe { ptr::read(&b.1) };
|
||||
(unsafe { retag_box_to_raw::<T, A>(b.0.as_ptr()) }, alloc)
|
||||
(ptr, alloc)
|
||||
}
|
||||
|
||||
#[unstable(
|
||||
|
@ -2709,19 +2709,6 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
/// Retag a box pointer as part of casting it to a raw pointer. This is the `Box` equivalent of
|
||||
/// `(x: &mut T) as *mut T`. The input pointer must be the pointer of a `Box` (passed as raw pointer
|
||||
/// to avoid all questions around move semantics and custom allocators), and `A` must be the `Box`'s
|
||||
/// allocator.
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[rustc_nounwind]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
|
||||
#[cfg_attr(bootstrap, inline)]
|
||||
pub unsafe fn retag_box_to_raw<T: ?Sized, A>(ptr: *mut T) -> *mut T {
|
||||
// Miri needs to adjust the provenance, but for regular codegen this is not needed
|
||||
ptr
|
||||
}
|
||||
|
||||
// Some functions are defined here because they accidentally got made
|
||||
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
|
||||
// (`transmute` also falls into this category, but it cannot be wrapped due to the
|
||||
|
@ -564,11 +564,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
|
||||
let version = output(cmd.arg("--version"));
|
||||
let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
|
||||
if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
|
||||
if major >= 16 {
|
||||
if major >= 17 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
panic!("\n\nbad LLVM version: {version}, need >=16.0\n\n")
|
||||
panic!("\n\nbad LLVM version: {version}, need >=17.0\n\n")
|
||||
}
|
||||
|
||||
fn configure_cmake(
|
||||
|
@ -1,67 +0,0 @@
|
||||
FROM ubuntu:23.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
gcc-multilib \
|
||||
make \
|
||||
ninja-build \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
git \
|
||||
cmake \
|
||||
sudo \
|
||||
gdb \
|
||||
llvm-16-tools \
|
||||
llvm-16-dev \
|
||||
libedit-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
# libgccjit dependencies
|
||||
flex \
|
||||
libmpfr-dev \
|
||||
libgmp-dev \
|
||||
libmpc3 \
|
||||
libmpc-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Note: libgccjit needs to match the default gcc version for the linker to find it.
|
||||
|
||||
# Install powershell (universal package) so we can test x.ps1 on Linux
|
||||
RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
|
||||
dpkg -i powershell.deb && \
|
||||
rm -f powershell.deb
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
# We are disabling CI LLVM since this builder is intentionally using a host
|
||||
# LLVM, rather than the typical src/llvm-project LLVM.
|
||||
ENV NO_DOWNLOAD_CI_LLVM 1
|
||||
|
||||
# This is not the latest LLVM version, so some components required by tests may
|
||||
# be missing.
|
||||
ENV IS_NOT_LATEST_LLVM 1
|
||||
|
||||
# Using llvm-link-shared due to libffi issues -- see #34486
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=x86_64-unknown-linux-gnu \
|
||||
--llvm-root=/usr/lib/llvm-16 \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/
|
||||
|
||||
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
|
||||
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
|
||||
|
||||
RUN /scripts/build-gccjit.sh /scripts
|
||||
|
||||
ENV SCRIPT /tmp/script.sh
|
@ -56,11 +56,10 @@ ENV RUST_CONFIGURE_ARGS \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/
|
||||
|
||||
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
|
||||
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
|
||||
|
||||
RUN /scripts/build-gccjit.sh /scripts
|
||||
|
||||
COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh
|
||||
ENV SCRIPT /tmp/script.sh
|
||||
|
@ -24,11 +24,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
libgccjit-13-dev \
|
||||
# libgccjit dependencies
|
||||
flex \
|
||||
libmpfr-dev \
|
||||
libgmp-dev \
|
||||
libmpc3 \
|
||||
libmpc-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Note: libgccjit needs to match the default gcc version for the linker to find it.
|
||||
|
||||
# Install powershell (universal package) so we can test x.ps1 on Linux
|
||||
# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep.
|
||||
RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
|
||||
@ -50,6 +53,10 @@ ENV RUST_CONFIGURE_ARGS \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/
|
||||
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
|
||||
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
|
||||
|
||||
RUN /scripts/build-gccjit.sh /scripts
|
||||
|
||||
COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh
|
||||
ENV SCRIPT /tmp/script.sh
|
||||
|
@ -357,7 +357,7 @@ jobs:
|
||||
- name: mingw-check-tidy
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: x86_64-gnu-llvm-16
|
||||
- name: x86_64-gnu-llvm-17
|
||||
env:
|
||||
ENABLE_GCC_CODEGEN: "1"
|
||||
<<: *job-linux-16c
|
||||
@ -520,11 +520,6 @@ jobs:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-llvm-16
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-nopt
|
||||
<<: *job-linux-4c
|
||||
|
||||
|
@ -290,14 +290,14 @@ impl NonCopyConst {
|
||||
promoted: None,
|
||||
};
|
||||
let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
|
||||
let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None);
|
||||
let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, rustc_span::DUMMY_SP);
|
||||
self.is_value_unfrozen_raw(cx, result, ty)
|
||||
}
|
||||
|
||||
fn is_value_unfrozen_expr<'tcx>(&self, cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
|
||||
let args = cx.typeck_results().node_args(hir_id);
|
||||
|
||||
let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), None);
|
||||
let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), rustc_span::DUMMY_SP);
|
||||
self.is_value_unfrozen_raw(cx, result, ty)
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ impl NonCopyConst {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ct: ty::UnevaluatedConst<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
match ty::Instance::resolve(tcx, param_env, ct.def, ct.args) {
|
||||
Ok(Some(instance)) => {
|
||||
@ -315,8 +315,8 @@ impl NonCopyConst {
|
||||
};
|
||||
tcx.const_eval_global_id_for_typeck(param_env, cid, span)
|
||||
},
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(rustc_span::DUMMY_SP))),
|
||||
Ok(None) => Err(ErrorHandled::TooGeneric(span)),
|
||||
Err(err) => Err(ErrorHandled::Reported(err.into(), span)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
|
||||
let result = self
|
||||
.lcx
|
||||
.tcx
|
||||
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None)
|
||||
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span())
|
||||
.ok()
|
||||
.map(|val| rustc_middle::mir::Const::from_value(val, ty))?;
|
||||
let result = mir_to_const(self.lcx, result)?;
|
||||
|
@ -5,7 +5,7 @@ use std::num::NonZero;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_middle::{mir::RetagKind, ty::Ty};
|
||||
use rustc_middle::mir::RetagKind;
|
||||
use rustc_target::abi::Size;
|
||||
|
||||
use crate::*;
|
||||
@ -291,19 +291,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn retag_box_to_raw(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
alloc_ty: Ty<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
|
||||
match method {
|
||||
BorrowTrackerMethod::StackedBorrows => this.sb_retag_box_to_raw(val, alloc_ty),
|
||||
BorrowTrackerMethod::TreeBorrows => this.tb_retag_box_to_raw(val, alloc_ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn retag_place_contents(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
|
@ -865,24 +865,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
this.sb_retag_reference(val, new_perm, RetagInfo { cause, in_field: false })
|
||||
}
|
||||
|
||||
fn sb_retag_box_to_raw(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
alloc_ty: Ty<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
let is_global_alloc = alloc_ty.ty_adt_def().is_some_and(|adt| {
|
||||
let global_alloc = this.tcx.require_lang_item(rustc_hir::LangItem::GlobalAlloc, None);
|
||||
adt.did() == global_alloc
|
||||
});
|
||||
if is_global_alloc {
|
||||
// Retag this as-if it was a mutable reference.
|
||||
this.sb_retag_ptr_value(RetagKind::Raw, val)
|
||||
} else {
|
||||
Ok(val.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn sb_retag_place_contents(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
@ -891,9 +873,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields;
|
||||
let retag_cause = match kind {
|
||||
RetagKind::Raw | RetagKind::TwoPhase { .. } => unreachable!(), // these can only happen in `retag_ptr_value`
|
||||
RetagKind::TwoPhase { .. } => unreachable!(), // can only happen in `retag_ptr_value`
|
||||
RetagKind::FnEntry => RetagCause::FnEntry,
|
||||
RetagKind::Default => RetagCause::Normal,
|
||||
RetagKind::Default | RetagKind::Raw => RetagCause::Normal,
|
||||
};
|
||||
let mut visitor =
|
||||
RetagVisitor { ecx: this, kind, retag_cause, retag_fields, in_field: false };
|
||||
@ -959,14 +941,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
// Check the type of this value to see what to do with it (retag, or recurse).
|
||||
match place.layout.ty.kind() {
|
||||
ty::Ref(..) => {
|
||||
let new_perm =
|
||||
NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx);
|
||||
self.retag_ptr_inplace(place, new_perm)?;
|
||||
}
|
||||
ty::RawPtr(..) => {
|
||||
// We do *not* want to recurse into raw pointers -- wide raw pointers have
|
||||
// fields, and for dyn Trait pointees those can have reference type!
|
||||
ty::Ref(..) | ty::RawPtr(..) => {
|
||||
if matches!(place.layout.ty.kind(), ty::Ref(..))
|
||||
|| self.kind == RetagKind::Raw
|
||||
{
|
||||
let new_perm =
|
||||
NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx);
|
||||
self.retag_ptr_inplace(place, new_perm)?;
|
||||
}
|
||||
}
|
||||
ty::Adt(adt, _) if adt.is_box() => {
|
||||
// Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
|
||||
|
@ -392,15 +392,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn tb_retag_box_to_raw(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
_alloc_ty: Ty<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
// Casts to raw pointers are NOPs in Tree Borrows.
|
||||
Ok(val.clone())
|
||||
}
|
||||
|
||||
/// Retag all pointers that are stored in this place.
|
||||
fn tb_retag_place_contents(
|
||||
&mut self,
|
||||
|
@ -1503,7 +1503,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||
fn eval_mir_constant<F>(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
val: mir::Const<'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
eval: F,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
|
||||
@ -1511,7 +1511,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||
F: Fn(
|
||||
&InterpCx<'mir, 'tcx, Self>,
|
||||
mir::Const<'tcx>,
|
||||
Option<Span>,
|
||||
Span,
|
||||
Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>,
|
||||
{
|
||||
|
@ -140,18 +140,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?;
|
||||
}
|
||||
"retag_box_to_raw" => {
|
||||
let [ptr] = check_arg_count(args)?;
|
||||
let alloc_ty = generic_args[1].expect_ty();
|
||||
|
||||
let val = this.read_immediate(ptr)?;
|
||||
let new_val = if this.machine.borrow_tracker.is_some() {
|
||||
this.retag_box_to_raw(&val, alloc_ty)?
|
||||
} else {
|
||||
val
|
||||
};
|
||||
this.write_immediate(*new_val, dest)?;
|
||||
}
|
||||
|
||||
// We want to return either `true` or `false` at random, or else something like
|
||||
// ```
|
||||
|
@ -549,7 +549,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
let index = generic_args[2]
|
||||
.expect_const()
|
||||
.eval(*this.tcx, this.param_env(), Some(this.tcx.span))
|
||||
.eval(*this.tcx, this.param_env(), this.tcx.span)
|
||||
.unwrap()
|
||||
.unwrap_branch();
|
||||
let index_len = index.len();
|
||||
|
@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
||||
--> $DIR/newtype_pair_retagging.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = Box::into_raw(Box::new(0i32));
|
||||
|
@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
||||
--> $DIR/newtype_retagging.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = Box::into_raw(Box::new(0i32));
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ compile-flags: -O
|
||||
//@ min-llvm-version: 17
|
||||
//@ only-x86_64-unknown-linux-gnu
|
||||
|
||||
// We want to check that this function does not mis-optimize to loop jumping.
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Verify that move before the call of the function with noalias, nocapture, readonly.
|
||||
// #107436
|
||||
//@ compile-flags: -O
|
||||
//@ min-llvm-version: 17
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
//@ compile-flags: -O -Z randomize-layout=no
|
||||
//@ only-x86_64
|
||||
//@ ignore-llvm-version: 16.0.0
|
||||
// ^-- needs https://reviews.llvm.org/D146149 in 16.0.1
|
||||
#![crate_type = "lib"]
|
||||
#![feature(generic_nonzero)]
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ compile-flags: -O
|
||||
//@ min-llvm-version: 17
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
//@ revisions: old new
|
||||
// LLVM 17 realizes double panic is not possible and doesn't generate calls
|
||||
// to panic_cannot_unwind.
|
||||
//@ [old]ignore-llvm-version: 17 - 99
|
||||
//@ [new]min-llvm-version: 17
|
||||
//@ compile-flags: -O
|
||||
//@ ignore-debug: plain old debug assertions
|
||||
//@ needs-unwind
|
||||
@ -22,14 +19,6 @@ pub fn shrink_to_fit(vec: &mut Vec<u32>) {
|
||||
// CHECK-LABEL: @issue71861
|
||||
#[no_mangle]
|
||||
pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> {
|
||||
// CHECK-NOT: panic
|
||||
|
||||
// Call to panic_cannot_unwind in case of double-panic is expected
|
||||
// on LLVM 16 and older, but other panics are not.
|
||||
// old: filter
|
||||
// old-NEXT: ; call core::panicking::panic_cannot_unwind
|
||||
// old-NEXT: panic_cannot_unwind
|
||||
|
||||
// CHECK-NOT: panic
|
||||
vec.into_boxed_slice()
|
||||
}
|
||||
@ -40,6 +29,3 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
|
||||
// CHECK-NOT: panic
|
||||
iter.iter().copied().collect()
|
||||
}
|
||||
|
||||
// old: ; core::panicking::panic_cannot_unwind
|
||||
// old: declare void @{{.*}}panic_cannot_unwind
|
||||
|
@ -0,0 +1,17 @@
|
||||
// MIR for `box_to_raw_mut` after SimplifyCfg-pre-optimizations
|
||||
|
||||
fn box_to_raw_mut(_1: &mut Box<i32>) -> *mut i32 {
|
||||
debug x => _1;
|
||||
let mut _0: *mut i32;
|
||||
let mut _2: std::boxed::Box<i32>;
|
||||
let mut _3: *const i32;
|
||||
|
||||
bb0: {
|
||||
Retag([fn entry] _1);
|
||||
_2 = deref_copy (*_1);
|
||||
_3 = (((_2.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32);
|
||||
_0 = &raw mut (*_3);
|
||||
Retag([raw] _0);
|
||||
return;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
// MIR for `box_to_raw_mut` after SimplifyCfg-pre-optimizations
|
||||
|
||||
fn box_to_raw_mut(_1: &mut Box<i32>) -> *mut i32 {
|
||||
debug x => _1;
|
||||
let mut _0: *mut i32;
|
||||
let mut _2: std::boxed::Box<i32>;
|
||||
let mut _3: *const i32;
|
||||
|
||||
bb0: {
|
||||
Retag([fn entry] _1);
|
||||
_2 = deref_copy (*_1);
|
||||
_3 = (((_2.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32);
|
||||
_0 = &raw mut (*_3);
|
||||
Retag([raw] _0);
|
||||
return;
|
||||
}
|
||||
}
|
@ -65,3 +65,8 @@ fn array_casts() {
|
||||
let p = &x as *const usize;
|
||||
assert_eq!(unsafe { *p.add(1) }, 1);
|
||||
}
|
||||
|
||||
// EMIT_MIR retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.mir
|
||||
fn box_to_raw_mut(x: &mut Box<i32>) -> *mut i32 {
|
||||
std::ptr::addr_of_mut!(**x)
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ include ../tools.mk
|
||||
|
||||
# Verify that the impl_* symbols are preserved. #108030
|
||||
# only-x86_64-unknown-linux-gnu
|
||||
# min-llvm-version: 17
|
||||
|
||||
all:
|
||||
$(RUSTC) -Cdebuginfo=0 -Copt-level=3 lib.rs
|
||||
|
@ -1,4 +1,3 @@
|
||||
//@ needs-llvm-components: webassembly
|
||||
//@ min-llvm-version: 17
|
||||
//@ compile-flags: --print=target-cpus --target=wasm32-unknown-unknown
|
||||
//@ check-pass
|
||||
|
22
tests/ui/fmt/nested-awaits-issue-122674.rs
Normal file
22
tests/ui/fmt/nested-awaits-issue-122674.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Non-regression test for issue #122674: a change in the format args visitor missed nested awaits.
|
||||
|
||||
//@ edition: 2021
|
||||
//@ check-pass
|
||||
|
||||
pub fn f1() -> impl std::future::Future<Output = Result<(), String>> + Send {
|
||||
async {
|
||||
should_work().await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn should_work() -> Result<String, String> {
|
||||
let x = 1;
|
||||
Err(format!("test: {}: {}", x, inner().await?))
|
||||
}
|
||||
|
||||
async fn inner() -> Result<String, String> {
|
||||
Ok("test".to_string())
|
||||
}
|
||||
|
||||
fn main() {}
|
9
tests/ui/macros/paren-or-brace-expected.rs
Normal file
9
tests/ui/macros/paren-or-brace-expected.rs
Normal file
@ -0,0 +1,9 @@
|
||||
macro_rules! foo {
|
||||
( $( $i:ident ),* ) => {
|
||||
$[count($i)]
|
||||
//~^ ERROR expected `(` or `{`, found `[`
|
||||
//~| ERROR
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
14
tests/ui/macros/paren-or-brace-expected.stderr
Normal file
14
tests/ui/macros/paren-or-brace-expected.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: expected `(` or `{`, found `[`
|
||||
--> $DIR/paren-or-brace-expected.rs:3:10
|
||||
|
|
||||
LL | $[count($i)]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: expected one of: `*`, `+`, or `?`
|
||||
--> $DIR/paren-or-brace-expected.rs:3:10
|
||||
|
|
||||
LL | $[count($i)]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user