Skip to content

Commit 30f74ff

Browse files
committedMar 14, 2024
Auto merge of #122497 - matthiaskrgr:rollup-pg9ux4r, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #119029 (Avoid closing invalid handles) - #122238 (Document some builtin impls in the next solver) - #122247 (rustdoc-search: depth limit `T<U>` -> `U` unboxing) - #122287 (add test ensuring simd codegen checks don't run when a static assertion failed) - #122368 (chore: remove repetitive words) - #122397 (Various cleanups around the const eval query providers) - #122406 (Fix WF for `AsyncFnKindHelper` in new trait solver) - #122477 (Change some attribute to only_local) - #122482 (Ungate the `UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES` lint) - #122490 (Update build instructions for OpenHarmony) Failed merges: - #122471 (preserve span when evaluating mir::ConstOperand) r? `@ghost` `@rustbot` modify labels: rollup
·
1.88.01.78.0
2 parents fe61575 + 02b1a91 commit 30f74ff

File tree

33 files changed

+729
-254
lines changed

33 files changed

+729
-254
lines changed
 

‎compiler/rustc_codegen_cranelift/src/constant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
7171
// This cannot fail because we checked all required_consts in advance.
7272
let val = cv
7373
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
74-
.expect("erroneous constant not captured by required_consts");
74+
.expect("erroneous constant missed by mono item collection");
7575
(val, cv.ty())
7676
}
7777

‎compiler/rustc_codegen_ssa/src/mir/constant.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2121
}
2222

2323
pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue<'tcx> {
24-
// `MirUsedCollector` visited all constants before codegen began, so if we got here there
25-
// can be no more constants that fail to evaluate.
24+
// `MirUsedCollector` visited all required_consts before codegen began, so if we got here
25+
// there can be no more constants that fail to evaluate.
2626
self.monomorphize(constant.const_)
2727
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
28-
.expect("erroneous constant not captured by required_consts")
28+
.expect("erroneous constant missed by mono item collection")
2929
}
3030

3131
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition

‎compiler/rustc_codegen_ssa/src/mir/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
211211

212212
// It may seem like we should iterate over `required_consts` to ensure they all successfully
213213
// evaluate; however, the `MirUsedCollector` already did that during the collection phase of
214-
// monomorphization so we don't have to do it again.
214+
// monomorphization, and if there is an error during collection then codegen never starts -- so
215+
// we don't have to do it again.
215216

216217
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
217218

‎compiler/rustc_const_eval/messages.ftl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,6 @@ const_eval_unallowed_op_in_const_context =
374374
const_eval_unavailable_target_features_for_fn =
375375
calling a function that requires unavailable target features: {$unavailable_feats}
376376
377-
const_eval_undefined_behavior =
378-
it is undefined behavior to use this value
379-
380-
const_eval_undefined_behavior_note =
381-
The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
382-
383377
const_eval_uninhabited_enum_variant_read =
384378
read discriminant of an uninhabited enum variant
385379
const_eval_uninhabited_enum_variant_written =
@@ -434,6 +428,12 @@ const_eval_validation_expected_raw_ptr = expected a raw pointer
434428
const_eval_validation_expected_ref = expected a reference
435429
const_eval_validation_expected_str = expected a string
436430
431+
const_eval_validation_failure =
432+
it is undefined behavior to use this value
433+
434+
const_eval_validation_failure_note =
435+
The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
436+
437437
const_eval_validation_front_matter_invalid_value = constructing invalid value
438438
const_eval_validation_front_matter_invalid_value_with_path = constructing invalid value at {$path}
439439

‎compiler/rustc_const_eval/src/const_eval/error.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ use std::mem;
22

33
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, Diagnostic, IntoDiagArg};
44
use rustc_hir::CRATE_HIR_ID;
5+
use rustc_middle::mir::interpret::Provenance;
56
use rustc_middle::mir::AssertKind;
67
use rustc_middle::query::TyCtxtAt;
78
use rustc_middle::ty::TyCtxt;
89
use rustc_middle::ty::{layout::LayoutError, ConstInt};
910
use rustc_span::{Span, Symbol, DUMMY_SP};
1011

11-
use super::{CompileTimeInterpreter, InterpCx};
12+
use super::CompileTimeInterpreter;
1213
use crate::errors::{self, FrameNote, ReportErrorExt};
13-
use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, MachineStopType};
14+
use crate::interpret::{ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType};
1415

1516
/// The CTFE machine has some custom error kinds.
1617
#[derive(Clone, Debug)]
@@ -58,15 +59,12 @@ impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
5859

5960
pub fn get_span_and_frames<'tcx, 'mir>(
6061
tcx: TyCtxtAt<'tcx>,
61-
machine: &CompileTimeInterpreter<'mir, 'tcx>,
62+
stack: &[Frame<'mir, 'tcx, impl Provenance, impl Sized>],
6263
) -> (Span, Vec<errors::FrameNote>)
6364
where
6465
'tcx: 'mir,
6566
{
66-
let mut stacktrace =
67-
InterpCx::<CompileTimeInterpreter<'mir, 'tcx>>::generate_stacktrace_from_stack(
68-
&machine.stack,
69-
);
67+
let mut stacktrace = Frame::generate_stacktrace_from_stack(stack);
7068
// Filter out `requires_caller_location` frames.
7169
stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx));
7270
let span = stacktrace.first().map(|f| f.span).unwrap_or(tcx.span);
@@ -170,7 +168,7 @@ pub(super) fn lint<'tcx, 'mir, L>(
170168
) where
171169
L: for<'a> rustc_errors::LintDiagnostic<'a, ()>,
172170
{
173-
let (span, frames) = get_span_and_frames(tcx, machine);
171+
let (span, frames) = get_span_and_frames(tcx, &machine.stack);
174172

175173
tcx.emit_node_span_lint(
176174
lint,

‎compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 74 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ use crate::errors;
1818
use crate::errors::ConstEvalError;
1919
use crate::interpret::eval_nullary_intrinsic;
2020
use crate::interpret::{
21-
create_static_alloc, intern_const_alloc_recursive, take_static_root_alloc, CtfeValidationMode,
22-
GlobalId, Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind,
23-
OpTy, RefTracking, StackPopCleanup,
21+
create_static_alloc, intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate,
22+
InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
23+
StackPopCleanup,
2424
};
2525

2626
// Returns a pointer to where the result lives
27-
#[instrument(level = "trace", skip(ecx, body), ret)]
28-
fn eval_body_using_ecx<'mir, 'tcx>(
27+
#[instrument(level = "trace", skip(ecx, body))]
28+
fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>(
2929
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
3030
cid: GlobalId<'tcx>,
3131
body: &'mir mir::Body<'tcx>,
32-
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
32+
) -> InterpResult<'tcx, R> {
3333
trace!(?ecx.param_env);
3434
let tcx = *ecx.tcx;
3535
assert!(
@@ -84,7 +84,10 @@ fn eval_body_using_ecx<'mir, 'tcx>(
8484
// Intern the result
8585
intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
8686

87-
Ok(ret)
87+
// Since evaluation had no errors, validate the resulting constant.
88+
const_validate_mplace(&ecx, &ret, cid)?;
89+
90+
Ok(R::make_result(ret, ecx))
8891
}
8992

9093
/// The `InterpCx` is only meant to be used to do field and index projections into constants for
@@ -282,18 +285,26 @@ pub fn eval_static_initializer_provider<'tcx>(
282285

283286
let instance = ty::Instance::mono(tcx, def_id.to_def_id());
284287
let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
285-
let mut ecx = InterpCx::new(
286-
tcx,
287-
tcx.def_span(def_id),
288-
ty::ParamEnv::reveal_all(),
289-
// Statics (and promoteds inside statics) may access other statics, because unlike consts
290-
// they do not have to behave "as if" they were evaluated at runtime.
291-
CompileTimeInterpreter::new(CanAccessMutGlobal::Yes, CheckAlignment::Error),
292-
);
293-
let alloc_id = eval_in_interpreter(&mut ecx, cid, true)?.alloc_id;
294-
let alloc = take_static_root_alloc(&mut ecx, alloc_id);
295-
let alloc = tcx.mk_const_alloc(alloc);
296-
Ok(alloc)
288+
eval_in_interpreter(tcx, cid, ty::ParamEnv::reveal_all())
289+
}
290+
291+
pub trait InterpretationResult<'tcx> {
292+
/// This function takes the place where the result of the evaluation is stored
293+
/// and prepares it for returning it in the appropriate format needed by the specific
294+
/// evaluation query.
295+
fn make_result<'mir>(
296+
mplace: MPlaceTy<'tcx>,
297+
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
298+
) -> Self;
299+
}
300+
301+
impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
302+
fn make_result<'mir>(
303+
mplace: MPlaceTy<'tcx>,
304+
_ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
305+
) -> Self {
306+
ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
307+
}
297308
}
298309

299310
#[instrument(skip(tcx), level = "debug")]
@@ -319,92 +330,64 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
319330
trace!("const eval: {:?} ({})", key, instance);
320331
}
321332

322-
let cid = key.value;
333+
eval_in_interpreter(tcx, key.value, key.param_env)
334+
}
335+
336+
fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
337+
tcx: TyCtxt<'tcx>,
338+
cid: GlobalId<'tcx>,
339+
param_env: ty::ParamEnv<'tcx>,
340+
) -> Result<R, ErrorHandled> {
323341
let def = cid.instance.def.def_id();
324342
let is_static = tcx.is_static(def);
325343

326344
let mut ecx = InterpCx::new(
327345
tcx,
328346
tcx.def_span(def),
329-
key.param_env,
347+
param_env,
330348
// Statics (and promoteds inside statics) may access mutable global memory, because unlike consts
331349
// they do not have to behave "as if" they were evaluated at runtime.
332350
// For consts however we want to ensure they behave "as if" they were evaluated at runtime,
333351
// so we have to reject reading mutable global memory.
334352
CompileTimeInterpreter::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
335353
);
336-
eval_in_interpreter(&mut ecx, cid, is_static)
337-
}
338-
339-
pub fn eval_in_interpreter<'mir, 'tcx>(
340-
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
341-
cid: GlobalId<'tcx>,
342-
is_static: bool,
343-
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
344-
// `is_static` just means "in static", it could still be a promoted!
345-
debug_assert_eq!(is_static, ecx.tcx.static_mutability(cid.instance.def_id()).is_some());
346-
347354
let res = ecx.load_mir(cid.instance.def, cid.promoted);
348-
match res.and_then(|body| eval_body_using_ecx(ecx, cid, body)) {
349-
Err(error) => {
350-
let (error, backtrace) = error.into_parts();
351-
backtrace.print_backtrace();
352-
353-
let (kind, instance) = if is_static {
354-
("static", String::new())
355-
} else {
356-
// If the current item has generics, we'd like to enrich the message with the
357-
// instance and its args: to show the actual compile-time values, in addition to
358-
// the expression, leading to the const eval error.
359-
let instance = &cid.instance;
360-
if !instance.args.is_empty() {
361-
let instance = with_no_trimmed_paths!(instance.to_string());
362-
("const_with_path", instance)
363-
} else {
364-
("const", String::new())
365-
}
366-
};
367-
368-
Err(super::report(
369-
*ecx.tcx,
370-
error,
371-
None,
372-
|| super::get_span_and_frames(ecx.tcx, &ecx.machine),
373-
|span, frames| ConstEvalError {
374-
span,
375-
error_kind: kind,
376-
instance,
377-
frame_notes: frames,
378-
},
379-
))
380-
}
381-
Ok(mplace) => {
382-
// Since evaluation had no errors, validate the resulting constant.
383-
384-
// Temporarily allow access to the static_root_ids for the purpose of validation.
385-
let static_root_ids = ecx.machine.static_root_ids.take();
386-
let res = const_validate_mplace(&ecx, &mplace, cid);
387-
ecx.machine.static_root_ids = static_root_ids;
388-
389-
let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
390-
391-
// Validation failed, report an error.
392-
if let Err(error) = res {
393-
Err(const_report_error(&ecx, error, alloc_id))
355+
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)).map_err(|error| {
356+
let (error, backtrace) = error.into_parts();
357+
backtrace.print_backtrace();
358+
359+
let (kind, instance) = if ecx.tcx.is_static(cid.instance.def_id()) {
360+
("static", String::new())
361+
} else {
362+
// If the current item has generics, we'd like to enrich the message with the
363+
// instance and its args: to show the actual compile-time values, in addition to
364+
// the expression, leading to the const eval error.
365+
let instance = &cid.instance;
366+
if !instance.args.is_empty() {
367+
let instance = with_no_trimmed_paths!(instance.to_string());
368+
("const_with_path", instance)
394369
} else {
395-
// Convert to raw constant
396-
Ok(ConstAlloc { alloc_id, ty: mplace.layout.ty })
370+
("const", String::new())
397371
}
398-
}
399-
}
372+
};
373+
374+
super::report(
375+
*ecx.tcx,
376+
error,
377+
None,
378+
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
379+
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
380+
)
381+
})
400382
}
401383

402384
#[inline(always)]
403-
pub fn const_validate_mplace<'mir, 'tcx>(
385+
fn const_validate_mplace<'mir, 'tcx>(
404386
ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
405387
mplace: &MPlaceTy<'tcx>,
406388
cid: GlobalId<'tcx>,
407-
) -> InterpResult<'tcx> {
389+
) -> Result<(), ErrorHandled> {
390+
let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
408391
let mut ref_tracking = RefTracking::new(mplace.clone());
409392
let mut inner = false;
410393
while let Some((mplace, path)) = ref_tracking.todo.pop() {
@@ -418,15 +401,18 @@ pub fn const_validate_mplace<'mir, 'tcx>(
418401
CtfeValidationMode::Const { allow_immutable_unsafe_cell: !inner }
419402
}
420403
};
421-
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?;
404+
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
405+
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targetted
406+
// error about the validation failure.
407+
.map_err(|error| report_validation_error(&ecx, error, alloc_id))?;
422408
inner = true;
423409
}
424410

425411
Ok(())
426412
}
427413

428414
#[inline(always)]
429-
pub fn const_report_error<'mir, 'tcx>(
415+
fn report_validation_error<'mir, 'tcx>(
430416
ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
431417
error: InterpErrorInfo<'tcx>,
432418
alloc_id: AllocId,
@@ -444,7 +430,7 @@ pub fn const_report_error<'mir, 'tcx>(
444430
*ecx.tcx,
445431
error,
446432
None,
447-
|| crate::const_eval::get_span_and_frames(ecx.tcx, &ecx.machine),
448-
move |span, frames| errors::UndefinedBehavior { span, ub_note, frames, raw_bytes },
433+
|| crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
434+
move |span, frames| errors::ValidationFailure { span, ub_note, frames, raw_bytes },
449435
)
450436
}

‎compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::mir::interpret::InterpErrorInfo;
55
use rustc_middle::query::TyCtxtAt;
66
use rustc_middle::ty::{self, Ty};
77

8-
use crate::interpret::{format_interp_error, InterpCx};
8+
use crate::interpret::format_interp_error;
99

1010
mod error;
1111
mod eval_queries;

‎compiler/rustc_const_eval/src/errors.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,11 @@ pub struct NullaryIntrinsicError {
412412
}
413413

414414
#[derive(Diagnostic)]
415-
#[diag(const_eval_undefined_behavior, code = E0080)]
416-
pub struct UndefinedBehavior {
415+
#[diag(const_eval_validation_failure, code = E0080)]
416+
pub struct ValidationFailure {
417417
#[primary_span]
418418
pub span: Span,
419-
#[note(const_eval_undefined_behavior_note)]
419+
#[note(const_eval_validation_failure_note)]
420420
pub ub_note: Option<()>,
421421
#[subdiagnostic]
422422
pub frames: Vec<FrameNote>,

‎compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,32 @@ impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> {
283283
pub(super) fn locals_addr(&self) -> usize {
284284
self.locals.raw.as_ptr().addr()
285285
}
286+
287+
#[must_use]
288+
pub fn generate_stacktrace_from_stack(stack: &[Self]) -> Vec<FrameInfo<'tcx>> {
289+
let mut frames = Vec::new();
290+
// This deliberately does *not* honor `requires_caller_location` since it is used for much
291+
// more than just panics.
292+
for frame in stack.iter().rev() {
293+
let span = match frame.loc {
294+
Left(loc) => {
295+
// If the stacktrace passes through MIR-inlined source scopes, add them.
296+
let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
297+
let mut scope_data = &frame.body.source_scopes[scope];
298+
while let Some((instance, call_span)) = scope_data.inlined {
299+
frames.push(FrameInfo { span, instance });
300+
span = call_span;
301+
scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
302+
}
303+
span
304+
}
305+
Right(span) => span,
306+
};
307+
frames.push(FrameInfo { span, instance: frame.instance });
308+
}
309+
trace!("generate stacktrace: {:#?}", frames);
310+
frames
311+
}
286312
}
287313

288314
// FIXME: only used by miri, should be removed once translatable.
@@ -1170,37 +1196,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
11701196
PlacePrinter { ecx: self, place: *place.place() }
11711197
}
11721198

1173-
#[must_use]
1174-
pub fn generate_stacktrace_from_stack(
1175-
stack: &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>],
1176-
) -> Vec<FrameInfo<'tcx>> {
1177-
let mut frames = Vec::new();
1178-
// This deliberately does *not* honor `requires_caller_location` since it is used for much
1179-
// more than just panics.
1180-
for frame in stack.iter().rev() {
1181-
let span = match frame.loc {
1182-
Left(loc) => {
1183-
// If the stacktrace passes through MIR-inlined source scopes, add them.
1184-
let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
1185-
let mut scope_data = &frame.body.source_scopes[scope];
1186-
while let Some((instance, call_span)) = scope_data.inlined {
1187-
frames.push(FrameInfo { span, instance });
1188-
span = call_span;
1189-
scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
1190-
}
1191-
span
1192-
}
1193-
Right(span) => span,
1194-
};
1195-
frames.push(FrameInfo { span, instance: frame.instance });
1196-
}
1197-
trace!("generate stacktrace: {:#?}", frames);
1198-
frames
1199-
}
1200-
12011199
#[must_use]
12021200
pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
1203-
Self::generate_stacktrace_from_stack(self.stack())
1201+
Frame::generate_stacktrace_from_stack(self.stack())
12041202
}
12051203
}
12061204

‎compiler/rustc_const_eval/src/interpret/intern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ pub fn intern_const_alloc_recursive<
176176
// This gives us the initial set of nested allocations, which will then all be processed
177177
// recursively in the loop below.
178178
let mut todo: Vec<_> = if is_static {
179-
// Do not steal the root allocation, we need it later for `take_static_root_alloc`
179+
// Do not steal the root allocation, we need it later to create the return value of `eval_static_initializer`.
180180
// But still change its mutability to match the requested one.
181181
let alloc = ecx.memory.alloc_map.get_mut(&base_alloc_id).unwrap();
182182
alloc.1.mutability = base_mutability;

‎compiler/rustc_const_eval/src/interpret/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@ use self::{
3939
};
4040

4141
pub(crate) use self::intrinsics::eval_nullary_intrinsic;
42-
pub(crate) use self::util::{create_static_alloc, take_static_root_alloc};
42+
pub(crate) use self::util::create_static_alloc;
4343
use eval_context::{from_known_layout, mir_assign_valid_types};

‎compiler/rustc_const_eval/src/interpret/util.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
use crate::const_eval::CompileTimeEvalContext;
1+
use crate::const_eval::{CompileTimeEvalContext, CompileTimeInterpreter, InterpretationResult};
22
use crate::interpret::{MemPlaceMeta, MemoryKind};
33
use rustc_hir::def_id::LocalDefId;
4-
use rustc_middle::mir::interpret::{AllocId, Allocation, InterpResult, Pointer};
4+
use rustc_middle::mir;
5+
use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer};
56
use rustc_middle::ty::layout::TyAndLayout;
67
use rustc_middle::ty::{
78
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
89
};
910
use std::ops::ControlFlow;
1011

11-
use super::MPlaceTy;
12+
use super::{InterpCx, MPlaceTy};
1213

1314
/// Checks whether a type contains generic parameters which must be instantiated.
1415
///
@@ -80,11 +81,15 @@ where
8081
}
8182
}
8283

83-
pub(crate) fn take_static_root_alloc<'mir, 'tcx: 'mir>(
84-
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
85-
alloc_id: AllocId,
86-
) -> Allocation {
87-
ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1
84+
impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> {
85+
fn make_result<'mir>(
86+
mplace: MPlaceTy<'tcx>,
87+
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
88+
) -> Self {
89+
let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
90+
let alloc = ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1;
91+
ecx.tcx.mk_const_alloc(alloc)
92+
}
8893
}
8994

9095
pub(crate) fn create_static_alloc<'mir, 'tcx: 'mir>(

‎compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -894,56 +894,93 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
894894
),
895895
rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing),
896896
rustc_attr!(TEST, rustc_strict_coherence, Normal, template!(Word), WarnFollowing),
897-
rustc_attr!(TEST, rustc_variance, Normal, template!(Word), WarnFollowing),
898-
rustc_attr!(TEST, rustc_variance_of_opaques, Normal, template!(Word), WarnFollowing),
899-
rustc_attr!(TEST, rustc_hidden_type_of_opaques, Normal, template!(Word), WarnFollowing),
897+
rustc_attr!(TEST, rustc_variance, Normal, template!(Word), WarnFollowing, @only_local: true),
898+
rustc_attr!(
899+
TEST, rustc_variance_of_opaques, Normal, template!(Word),
900+
WarnFollowing, @only_local: true
901+
),
902+
rustc_attr!(
903+
TEST, rustc_hidden_type_of_opaques, Normal, template!(Word),
904+
WarnFollowing, @only_local: true),
900905
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
901-
rustc_attr!(TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
902-
rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),
906+
rustc_attr!(
907+
TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."),
908+
WarnFollowing, @only_local: true
909+
),
910+
rustc_attr!(
911+
TEST, rustc_regions, Normal, template!(Word),
912+
WarnFollowing, @only_local: true
913+
),
903914
rustc_attr!(
904915
TEST, rustc_error, Normal,
905916
template!(Word, List: "delayed_bug_from_inside_query"), WarnFollowingWordOnly
906917
),
907-
rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing),
918+
rustc_attr!(
919+
TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing,
920+
@only_local: true
921+
),
908922
rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
909923
rustc_attr!(
910-
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk
924+
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"),
925+
DuplicatesOk, @only_local: true
911926
),
912927
rustc_attr!(
913-
TEST, rustc_then_this_would_need, Normal, template!(List: "DepNode"), DuplicatesOk
928+
TEST, rustc_then_this_would_need, Normal, template!(List: "DepNode"),
929+
DuplicatesOk, @only_local: true
914930
),
915931
rustc_attr!(
916932
TEST, rustc_clean, Normal,
917933
template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
918-
DuplicatesOk,
934+
DuplicatesOk, @only_local: true
919935
),
920936
rustc_attr!(
921937
TEST, rustc_partition_reused, Normal,
922-
template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk,
938+
template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk, @only_local: true
923939
),
924940
rustc_attr!(
925941
TEST, rustc_partition_codegened, Normal,
926-
template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk,
942+
template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk, @only_local: true
927943
),
928944
rustc_attr!(
929945
TEST, rustc_expected_cgu_reuse, Normal,
930946
template!(List: r#"cfg = "...", module = "...", kind = "...""#), DuplicatesOk,
947+
@only_local: true
948+
),
949+
rustc_attr!(
950+
TEST, rustc_symbol_name, Normal, template!(Word), WarnFollowing,
951+
@only_local: true
931952
),
932-
rustc_attr!(TEST, rustc_symbol_name, Normal, template!(Word), WarnFollowing),
933953
rustc_attr!(TEST, rustc_polymorphize_error, Normal, template!(Word), WarnFollowing),
934-
rustc_attr!(TEST, rustc_def_path, Normal, template!(Word), WarnFollowing),
954+
rustc_attr!(
955+
TEST, rustc_def_path, Normal, template!(Word), WarnFollowing,
956+
@only_local: true
957+
),
935958
rustc_attr!(TEST, rustc_mir, Normal, template!(List: "arg1, arg2, ..."), DuplicatesOk),
936959
gated!(
937960
custom_mir, Normal, template!(List: r#"dialect = "...", phase = "...""#),
938-
ErrorFollowing, "the `#[custom_mir]` attribute is just used for the Rust test suite",
961+
ErrorFollowing, @only_local: true,
962+
"the `#[custom_mir]` attribute is just used for the Rust test suite",
963+
),
964+
rustc_attr!(
965+
TEST, rustc_dump_program_clauses, Normal, template!(Word), WarnFollowing,
966+
@only_local: true
967+
),
968+
rustc_attr!(
969+
TEST, rustc_dump_env_program_clauses, Normal, template!(Word), WarnFollowing,
970+
@only_local: true
971+
),
972+
rustc_attr!(
973+
TEST, rustc_object_lifetime_default, Normal, template!(Word), WarnFollowing,
974+
@only_local: true
939975
),
940-
rustc_attr!(TEST, rustc_dump_program_clauses, Normal, template!(Word), WarnFollowing),
941-
rustc_attr!(TEST, rustc_dump_env_program_clauses, Normal, template!(Word), WarnFollowing),
942-
rustc_attr!(TEST, rustc_object_lifetime_default, Normal, template!(Word), WarnFollowing),
943976
rustc_attr!(TEST, rustc_dump_vtable, Normal, template!(Word), WarnFollowing),
944-
rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/), DuplicatesOk),
977+
rustc_attr!(
978+
TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/), DuplicatesOk,
979+
@only_local: true
980+
),
945981
gated!(
946982
omit_gdb_pretty_printer_section, Normal, template!(Word), WarnFollowing,
983+
@only_local: true,
947984
"the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
948985
),
949986
rustc_attr!(

‎compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4355,7 +4355,6 @@ declare_lint! {
43554355
pub UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
43564356
Warn,
43574357
"unrecognized or malformed diagnostic attribute",
4358-
@feature_gate = sym::diagnostic_namespace;
43594358
}
43604359

43614360
declare_lint! {

‎compiler/rustc_middle/src/ty/sty.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,9 @@ impl<'tcx> Ty<'tcx> {
24362436
},
24372437

24382438
// "Bound" types appear in canonical queries when the
2439-
// closure type is not yet known
2440-
Bound(..) | Param(_) | Infer(_) => None,
2439+
// closure type is not yet known, and `Placeholder` and `Param`
2440+
// may be encountered in generic `AsyncFnKindHelper` goals.
2441+
Bound(..) | Placeholder(_) | Param(_) | Infer(_) => None,
24412442

24422443
Error(_) => Some(ty::ClosureKind::Fn),
24432444

‎compiler/rustc_mir_transform/src/ffi_unwind_calls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_target::spec::PanicStrategy;
1111
use crate::errors;
1212

1313
/// Some of the functions declared as "may unwind" by `fn_can_unwind` can't actually unwind. In
14-
/// particular, `extern "C"` is still considered as can-unwind on stable, but we need to to consider
14+
/// particular, `extern "C"` is still considered as can-unwind on stable, but we need to consider
1515
/// it cannot-unwind here. So below we check `fn_can_unwind() && abi_can_unwind()` before concluding
1616
/// that a function call can unwind.
1717
fn abi_can_unwind(abi: Abi) -> bool {

‎compiler/rustc_monomorphize/src/collector.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,13 +818,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
818818
self.super_rvalue(rvalue, location);
819819
}
820820

821-
/// This does not walk the constant, as it has been handled entirely here and trying
822-
/// to walk it would attempt to evaluate the `ty::Const` inside, which doesn't necessarily
823-
/// work, as some constants cannot be represented in the type system.
821+
/// This does not walk the MIR of the constant as that is not needed for codegen, all we need is
822+
/// to ensure that the constant evaluates successfully and walk the result.
824823
#[instrument(skip(self), level = "debug")]
825824
fn visit_constant(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) {
826825
let const_ = self.monomorphize(constant.const_);
827826
let param_env = ty::ParamEnv::reveal_all();
827+
// Evaluate the constant. This makes const eval failure a collection-time error (rather than
828+
// a codegen-time error). rustc stops after collection if there was an error, so this
829+
// ensures codegen never has to worry about failing consts.
830+
// (codegen relies on this and ICEs will happen if this is violated.)
828831
let val = match const_.eval(self.tcx, param_env, None) {
829832
Ok(v) => v,
830833
Err(ErrorHandled::Reported(..)) => return,

‎compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,9 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
11121112

11131113
let (items, usage_map) = collector::collect_crate_mono_items(tcx, collection_mode);
11141114

1115+
// If there was an error during collection (e.g. from one of the constants we evaluated),
1116+
// then we stop here. This way codegen does not have to worry about failing constants.
1117+
// (codegen relies on this and ICEs will happen if this is violated.)
11151118
tcx.dcx().abort_if_errors();
11161119

11171120
let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {

‎compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
120120
ty: Ty<'tcx>,
121121
) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
122122
match *ty.kind() {
123+
// impl Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, !
124+
// impl Sized for Coroutine, CoroutineWitness, Closure, CoroutineClosure
123125
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
124126
| ty::Uint(_)
125127
| ty::Int(_)
@@ -152,8 +154,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
152154
bug!("unexpected type `{ty}`")
153155
}
154156

157+
// impl Sized for (T1, T2, .., Tn) where T1: Sized, T2: Sized, .. Tn: Sized
155158
ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
156159

160+
// impl Sized for Adt where T: Sized forall T in field types
157161
ty::Adt(def, args) => {
158162
let sized_crit = def.sized_constraint(ecx.tcx());
159163
Ok(sized_crit.iter_instantiated(ecx.tcx(), args).map(ty::Binder::dummy).collect())
@@ -167,6 +171,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
167171
ty: Ty<'tcx>,
168172
) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
169173
match *ty.kind() {
174+
// impl Copy/Clone for FnDef, FnPtr
170175
ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Ok(vec![]),
171176

172177
// Implementations are provided in core
@@ -196,12 +201,16 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
196201
bug!("unexpected type `{ty}`")
197202
}
198203

204+
// impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone
199205
ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
200206

207+
// impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone
201208
ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
202209

203210
ty::CoroutineClosure(..) => Err(NoSolution),
204211

212+
// only when `coroutine_clone` is enabled and the coroutine is movable
213+
// impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses)
205214
ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) {
206215
Movability::Static => Err(NoSolution),
207216
Movability::Movable => {
@@ -217,6 +226,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
217226
}
218227
},
219228

229+
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
220230
ty::CoroutineWitness(def_id, args) => Ok(ecx
221231
.tcx()
222232
.coroutine_hidden_types(def_id)

‎compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
250250
) -> QueryResult<'tcx> {
251251
let self_ty = goal.predicate.self_ty();
252252
match goal.predicate.polarity {
253+
// impl FnPtr for FnPtr {}
253254
ty::ImplPolarity::Positive => {
254255
if self_ty.is_fn_ptr() {
255256
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
256257
} else {
257258
Err(NoSolution)
258259
}
259260
}
261+
// impl !FnPtr for T where T != FnPtr && T is rigid {}
260262
ty::ImplPolarity::Negative => {
261263
// If a type is rigid and not a fn ptr, then we know for certain
262264
// that it does *not* implement `FnPtr`.
@@ -374,6 +376,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
374376
}
375377
}
376378

379+
/// ```rust, ignore (not valid rust syntax)
380+
/// impl Tuple for () {}
381+
/// impl Tuple for (T1,) {}
382+
/// impl Tuple for (T1, T2) {}
383+
/// impl Tuple for (T1, .., Tn) {}
384+
/// ```
377385
fn consider_builtin_tuple_candidate(
378386
ecx: &mut EvalCtxt<'_, 'tcx>,
379387
goal: Goal<'tcx, Self>,

‎library/std/src/os/windows/io/handle.rs

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::fmt;
77
use crate::fs;
88
use crate::io;
99
use crate::marker::PhantomData;
10-
use crate::mem::forget;
10+
use crate::mem::{forget, ManuallyDrop};
1111
use crate::ptr;
1212
use crate::sys;
1313
use crate::sys::cvt;
@@ -91,7 +91,7 @@ pub struct OwnedHandle {
9191
#[repr(transparent)]
9292
#[stable(feature = "io_safety", since = "1.63.0")]
9393
#[derive(Debug)]
94-
pub struct HandleOrNull(OwnedHandle);
94+
pub struct HandleOrNull(RawHandle);
9595

9696
/// FFI type for handles in return values or out parameters, where `INVALID_HANDLE_VALUE` is used
9797
/// as a sentry value to indicate errors, such as in the return value of `CreateFileW`. This uses
@@ -110,7 +110,7 @@ pub struct HandleOrNull(OwnedHandle);
110110
#[repr(transparent)]
111111
#[stable(feature = "io_safety", since = "1.63.0")]
112112
#[derive(Debug)]
113-
pub struct HandleOrInvalid(OwnedHandle);
113+
pub struct HandleOrInvalid(RawHandle);
114114

115115
// The Windows [`HANDLE`] type may be transferred across and shared between
116116
// thread boundaries (despite containing a `*mut void`, which in general isn't
@@ -163,15 +163,24 @@ impl TryFrom<HandleOrNull> for OwnedHandle {
163163

164164
#[inline]
165165
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
166-
let owned_handle = handle_or_null.0;
167-
if owned_handle.handle.is_null() {
168-
// Don't call `CloseHandle`; it'd be harmless, except that it could
169-
// overwrite the `GetLastError` error.
170-
forget(owned_handle);
171-
172-
Err(NullHandleError(()))
166+
let handle_or_null = ManuallyDrop::new(handle_or_null);
167+
if handle_or_null.is_valid() {
168+
// SAFETY: The handle is not null.
169+
Ok(unsafe { OwnedHandle::from_raw_handle(handle_or_null.0) })
173170
} else {
174-
Ok(owned_handle)
171+
Err(NullHandleError(()))
172+
}
173+
}
174+
}
175+
176+
#[stable(feature = "io_safety", since = "1.63.0")]
177+
impl Drop for HandleOrNull {
178+
#[inline]
179+
fn drop(&mut self) {
180+
if self.is_valid() {
181+
unsafe {
182+
let _ = sys::c::CloseHandle(self.0);
183+
}
175184
}
176185
}
177186
}
@@ -232,15 +241,24 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
232241

233242
#[inline]
234243
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
235-
let owned_handle = handle_or_invalid.0;
236-
if owned_handle.handle == sys::c::INVALID_HANDLE_VALUE {
237-
// Don't call `CloseHandle`; it'd be harmless, except that it could
238-
// overwrite the `GetLastError` error.
239-
forget(owned_handle);
240-
241-
Err(InvalidHandleError(()))
244+
let handle_or_invalid = ManuallyDrop::new(handle_or_invalid);
245+
if handle_or_invalid.is_valid() {
246+
// SAFETY: The handle is not invalid.
247+
Ok(unsafe { OwnedHandle::from_raw_handle(handle_or_invalid.0) })
242248
} else {
243-
Ok(owned_handle)
249+
Err(InvalidHandleError(()))
250+
}
251+
}
252+
}
253+
254+
#[stable(feature = "io_safety", since = "1.63.0")]
255+
impl Drop for HandleOrInvalid {
256+
#[inline]
257+
fn drop(&mut self) {
258+
if self.is_valid() {
259+
unsafe {
260+
let _ = sys::c::CloseHandle(self.0);
261+
}
244262
}
245263
}
246264
}
@@ -333,7 +351,11 @@ impl HandleOrNull {
333351
#[stable(feature = "io_safety", since = "1.63.0")]
334352
#[inline]
335353
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
336-
Self(OwnedHandle::from_raw_handle(handle))
354+
Self(handle)
355+
}
356+
357+
fn is_valid(&self) -> bool {
358+
!self.0.is_null()
337359
}
338360
}
339361

@@ -356,7 +378,11 @@ impl HandleOrInvalid {
356378
#[stable(feature = "io_safety", since = "1.63.0")]
357379
#[inline]
358380
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
359-
Self(OwnedHandle::from_raw_handle(handle))
381+
Self(handle)
382+
}
383+
384+
fn is_valid(&self) -> bool {
385+
self.0 != sys::c::INVALID_HANDLE_VALUE
360386
}
361387
}
362388

‎src/doc/rustc/src/platform-support/openharmony.md

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,34 @@ exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
9696

9797
Future versions of the OpenHarmony SDK will avoid the need for this process.
9898

99-
## Building the target
99+
## Building Rust programs
100+
101+
Rustup ships pre-compiled artifacts for this target, which you can install with:
102+
```sh
103+
rustup target add aarch64-unknown-linux-ohos
104+
rustup target add armv7-unknown-linux-ohos
105+
rustup target add x86_64-unknown-linux-ohos
106+
```
107+
108+
You will need to configure the linker to use in `~/.cargo/config.toml`:
109+
```toml
110+
[target.aarch64-unknown-linux-ohos]
111+
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
112+
linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh"
113+
114+
[target.armv7-unknown-linux-ohos]
115+
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
116+
linker = "/path/to/armv7-unknown-linux-ohos-clang.sh"
117+
118+
[target.x86_64-unknown-linux-ohos]
119+
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
120+
linker = "/path/to/x86_64-unknown-linux-ohos-clang.sh"
121+
```
100122

101-
To build a rust toolchain, create a `config.toml` with the following contents:
123+
## Building the target from source
124+
125+
Instead of using `rustup`, you can instead build a rust toolchain from source.
126+
Create a `config.toml` with the following contents:
102127

103128
```toml
104129
profile = "compiler"
@@ -130,28 +155,6 @@ ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
130155
linker = "/path/to/x86_64-unknown-linux-ohos-clang.sh"
131156
```
132157

133-
## Building Rust programs
134-
135-
Rust does not yet ship pre-compiled artifacts for this target. To compile for
136-
this target, you will either need to build Rust with the target enabled (see
137-
"Building the target" above), or build your own copy of `core` by using
138-
`build-std` or similar.
139-
140-
You will need to configure the linker to use in `~/.cargo/config`:
141-
```toml
142-
[target.aarch64-unknown-linux-ohos]
143-
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
144-
linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh"
145-
146-
[target.armv7-unknown-linux-ohos]
147-
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
148-
linker = "/path/to/armv7-unknown-linux-ohos-clang.sh"
149-
150-
[target.x86_64-unknown-linux-ohos]
151-
ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
152-
linker = "/path/to/x86_64-unknown-linux-ohos-clang.sh"
153-
```
154-
155158
## Testing
156159

157160
Running the Rust testsuite is possible, but currently difficult due to the way

‎src/doc/rustc/src/platform-support/unknown-uefi.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ single stack.
5151
By default, the UEFI targets use the `link`-flavor of the LLVM linker `lld` to
5252
link binaries into the final PE32+ file suffixed with `*.efi`. The PE subsystem
5353
is set to `EFI_APPLICATION`, but can be modified by passing `/subsystem:<...>`
54-
to the linker. Similarly, the entry-point is to to `efi_main` but can be
54+
to the linker. Similarly, the entry-point is set to `efi_main` but can be
5555
changed via `/entry:<...>`. The panic-strategy is set to `abort`,
5656

5757
The UEFI specification is available online for free:

‎src/librustdoc/html/static/js/search.js

Lines changed: 107 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ const longItemTypes = [
8181
const TY_GENERIC = itemTypes.indexOf("generic");
8282
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
8383

84+
// Hard limit on how deep to recurse into generics when doing type-driven search.
85+
// This needs limited, partially because
86+
// a search for `Ty` shouldn't match `WithInfcx<ParamEnvAnd<Vec<ConstTy<Interner<Ty=Ty>>>>>`,
87+
// but mostly because this is the simplest and most principled way to limit the number
88+
// of permutations we need to check.
89+
const UNBOXING_LIMIT = 5;
90+
8491
// In the search display, allows to switch between tabs.
8592
function printTab(nb) {
8693
let iter = 0;
@@ -1458,10 +1465,23 @@ function initSearch(rawSearchIndex) {
14581465
* @param {Map<number,number>|null} mgensIn
14591466
* - Map functions generics to query generics (never modified).
14601467
* @param {null|Map<number,number> -> bool} solutionCb - Called for each `mgens` solution.
1468+
* @param {number} unboxingDepth
1469+
* - Limit checks that Ty matches Vec<Ty>,
1470+
* but not Vec<ParamEnvAnd<WithInfcx<ConstTy<Interner<Ty=Ty>>>>>
14611471
*
14621472
* @return {boolean} - Returns true if a match, false otherwise.
14631473
*/
1464-
function unifyFunctionTypes(fnTypesIn, queryElems, whereClause, mgensIn, solutionCb) {
1474+
function unifyFunctionTypes(
1475+
fnTypesIn,
1476+
queryElems,
1477+
whereClause,
1478+
mgensIn,
1479+
solutionCb,
1480+
unboxingDepth
1481+
) {
1482+
if (unboxingDepth >= UNBOXING_LIMIT) {
1483+
return false;
1484+
}
14651485
/**
14661486
* @type Map<integer, integer>|null
14671487
*/
@@ -1480,7 +1500,7 @@ function initSearch(rawSearchIndex) {
14801500
&& queryElems[0].bindings.size === 0) {
14811501
const queryElem = queryElems[0];
14821502
for (const fnType of fnTypesIn) {
1483-
if (!unifyFunctionTypeIsMatchCandidate(fnType, queryElem, whereClause, mgens)) {
1503+
if (!unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgens)) {
14841504
continue;
14851505
}
14861506
if (fnType.id < 0 && queryElem.id < 0) {
@@ -1499,7 +1519,13 @@ function initSearch(rawSearchIndex) {
14991519
}
15001520
}
15011521
for (const fnType of fnTypesIn) {
1502-
if (!unifyFunctionTypeIsUnboxCandidate(fnType, queryElem, whereClause, mgens)) {
1522+
if (!unifyFunctionTypeIsUnboxCandidate(
1523+
fnType,
1524+
queryElem,
1525+
whereClause,
1526+
mgens,
1527+
unboxingDepth + 1
1528+
)) {
15031529
continue;
15041530
}
15051531
if (fnType.id < 0) {
@@ -1514,7 +1540,8 @@ function initSearch(rawSearchIndex) {
15141540
queryElems,
15151541
whereClause,
15161542
mgensScratch,
1517-
solutionCb
1543+
solutionCb,
1544+
unboxingDepth + 1
15181545
)) {
15191546
return true;
15201547
}
@@ -1523,7 +1550,8 @@ function initSearch(rawSearchIndex) {
15231550
queryElems,
15241551
whereClause,
15251552
mgens ? new Map(mgens) : null,
1526-
solutionCb
1553+
solutionCb,
1554+
unboxingDepth + 1
15271555
)) {
15281556
return true;
15291557
}
@@ -1559,7 +1587,7 @@ function initSearch(rawSearchIndex) {
15591587
let queryElemsTmp = null;
15601588
for (let i = flast; i >= 0; i -= 1) {
15611589
const fnType = fnTypes[i];
1562-
if (!unifyFunctionTypeIsMatchCandidate(fnType, queryElem, whereClause, mgens)) {
1590+
if (!unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgens)) {
15631591
continue;
15641592
}
15651593
let mgensScratch;
@@ -1596,7 +1624,8 @@ function initSearch(rawSearchIndex) {
15961624
fnType,
15971625
queryElem,
15981626
whereClause,
1599-
mgensScratch
1627+
mgensScratch,
1628+
unboxingDepth
16001629
);
16011630
if (!solution) {
16021631
return false;
@@ -1608,14 +1637,16 @@ function initSearch(rawSearchIndex) {
16081637
queryElem.generics,
16091638
whereClause,
16101639
simplifiedMgens,
1611-
solutionCb
1640+
solutionCb,
1641+
unboxingDepth
16121642
);
16131643
if (passesUnification) {
16141644
return true;
16151645
}
16161646
}
16171647
return false;
1618-
}
1648+
},
1649+
unboxingDepth
16191650
);
16201651
if (passesUnification) {
16211652
return true;
@@ -1627,7 +1658,13 @@ function initSearch(rawSearchIndex) {
16271658
}
16281659
for (let i = flast; i >= 0; i -= 1) {
16291660
const fnType = fnTypes[i];
1630-
if (!unifyFunctionTypeIsUnboxCandidate(fnType, queryElem, whereClause, mgens)) {
1661+
if (!unifyFunctionTypeIsUnboxCandidate(
1662+
fnType,
1663+
queryElem,
1664+
whereClause,
1665+
mgens,
1666+
unboxingDepth + 1
1667+
)) {
16311668
continue;
16321669
}
16331670
let mgensScratch;
@@ -1651,7 +1688,8 @@ function initSearch(rawSearchIndex) {
16511688
queryElems,
16521689
whereClause,
16531690
mgensScratch,
1654-
solutionCb
1691+
solutionCb,
1692+
unboxingDepth + 1
16551693
);
16561694
if (passesUnification) {
16571695
return true;
@@ -1670,11 +1708,10 @@ function initSearch(rawSearchIndex) {
16701708
*
16711709
* @param {FunctionType} fnType
16721710
* @param {QueryElement} queryElem
1673-
* @param {[FunctionSearchType]} whereClause - Trait bounds for generic items.
16741711
* @param {Map<number,number>|null} mgensIn - Map functions generics to query generics.
16751712
* @returns {boolean}
16761713
*/
1677-
function unifyFunctionTypeIsMatchCandidate(fnType, queryElem, whereClause, mgensIn) {
1714+
function unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgensIn) {
16781715
// type filters look like `trait:Read` or `enum:Result`
16791716
if (!typePassesFilter(queryElem.typeFilter, fnType.ty)) {
16801717
return false;
@@ -1775,9 +1812,16 @@ function initSearch(rawSearchIndex) {
17751812
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
17761813
* @param {Map<number,number>} mgensIn - Map functions generics to query generics.
17771814
* Never modified.
1815+
* @param {number} unboxingDepth
17781816
* @returns {false|{mgens: [Map<number,number>], simplifiedGenerics: [FunctionType]}}
17791817
*/
1780-
function unifyFunctionTypeCheckBindings(fnType, queryElem, whereClause, mgensIn) {
1818+
function unifyFunctionTypeCheckBindings(
1819+
fnType,
1820+
queryElem,
1821+
whereClause,
1822+
mgensIn,
1823+
unboxingDepth
1824+
) {
17811825
if (fnType.bindings.size < queryElem.bindings.size) {
17821826
return false;
17831827
}
@@ -1804,7 +1848,8 @@ function initSearch(rawSearchIndex) {
18041848
// return `false` makes unifyFunctionTypes return the full set of
18051849
// possible solutions
18061850
return false;
1807-
}
1851+
},
1852+
unboxingDepth
18081853
);
18091854
return newSolutions;
18101855
});
@@ -1834,9 +1879,19 @@ function initSearch(rawSearchIndex) {
18341879
* @param {QueryElement} queryElem
18351880
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
18361881
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
1882+
* @param {number} unboxingDepth
18371883
* @returns {boolean}
18381884
*/
1839-
function unifyFunctionTypeIsUnboxCandidate(fnType, queryElem, whereClause, mgens) {
1885+
function unifyFunctionTypeIsUnboxCandidate(
1886+
fnType,
1887+
queryElem,
1888+
whereClause,
1889+
mgens,
1890+
unboxingDepth
1891+
) {
1892+
if (unboxingDepth >= UNBOXING_LIMIT) {
1893+
return false;
1894+
}
18401895
if (fnType.id < 0 && queryElem.id >= 0) {
18411896
if (!whereClause) {
18421897
return false;
@@ -1858,14 +1913,21 @@ function initSearch(rawSearchIndex) {
18581913
whereClause[(-fnType.id) - 1],
18591914
queryElem,
18601915
whereClause,
1861-
mgensTmp
1916+
mgensTmp,
1917+
unboxingDepth
18621918
);
18631919
} else if (fnType.generics.length > 0 || fnType.bindings.size > 0) {
18641920
const simplifiedGenerics = [
18651921
...fnType.generics,
18661922
...Array.from(fnType.bindings.values()).flat(),
18671923
];
1868-
return checkIfInList(simplifiedGenerics, queryElem, whereClause, mgens);
1924+
return checkIfInList(
1925+
simplifiedGenerics,
1926+
queryElem,
1927+
whereClause,
1928+
mgens,
1929+
unboxingDepth
1930+
);
18691931
}
18701932
return false;
18711933
}
@@ -1877,13 +1939,14 @@ function initSearch(rawSearchIndex) {
18771939
* @param {Array<FunctionType>} list
18781940
* @param {QueryElement} elem - The element from the parsed query.
18791941
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
1880-
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
1942+
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
1943+
* @param {number} unboxingDepth
18811944
*
18821945
* @return {boolean} - Returns true if found, false otherwise.
18831946
*/
1884-
function checkIfInList(list, elem, whereClause, mgens) {
1947+
function checkIfInList(list, elem, whereClause, mgens, unboxingDepth) {
18851948
for (const entry of list) {
1886-
if (checkType(entry, elem, whereClause, mgens)) {
1949+
if (checkType(entry, elem, whereClause, mgens, unboxingDepth)) {
18871950
return true;
18881951
}
18891952
}
@@ -1897,14 +1960,23 @@ function initSearch(rawSearchIndex) {
18971960
* @param {Row} row
18981961
* @param {QueryElement} elem - The element from the parsed query.
18991962
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
1900-
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
1963+
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
19011964
*
19021965
* @return {boolean} - Returns true if the type matches, false otherwise.
19031966
*/
1904-
function checkType(row, elem, whereClause, mgens) {
1967+
function checkType(row, elem, whereClause, mgens, unboxingDepth) {
1968+
if (unboxingDepth >= UNBOXING_LIMIT) {
1969+
return false;
1970+
}
19051971
if (row.bindings.size === 0 && elem.bindings.size === 0) {
1906-
if (elem.id < 0) {
1907-
return row.id < 0 || checkIfInList(row.generics, elem, whereClause, mgens);
1972+
if (elem.id < 0 && mgens === null) {
1973+
return row.id < 0 || checkIfInList(
1974+
row.generics,
1975+
elem,
1976+
whereClause,
1977+
mgens,
1978+
unboxingDepth + 1
1979+
);
19081980
}
19091981
if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 &&
19101982
typePassesFilter(elem.typeFilter, row.ty) && elem.generics.length === 0 &&
@@ -1916,11 +1988,12 @@ function initSearch(rawSearchIndex) {
19161988
row.generics,
19171989
elem,
19181990
whereClause,
1919-
mgens
1991+
mgens,
1992+
unboxingDepth
19201993
);
19211994
}
19221995
}
1923-
return unifyFunctionTypes([row], [elem], whereClause, mgens);
1996+
return unifyFunctionTypes([row], [elem], whereClause, mgens, null, unboxingDepth);
19241997
}
19251998

19261999
/**
@@ -2135,9 +2208,9 @@ function initSearch(rawSearchIndex) {
21352208
);
21362209
if (tfpDist !== null) {
21372210
const in_args = row.type && row.type.inputs
2138-
&& checkIfInList(row.type.inputs, elem, row.type.where_clause);
2211+
&& checkIfInList(row.type.inputs, elem, row.type.where_clause, null, 0);
21392212
const returned = row.type && row.type.output
2140-
&& checkIfInList(row.type.output, elem, row.type.where_clause);
2213+
&& checkIfInList(row.type.output, elem, row.type.where_clause, null, 0);
21412214
if (in_args) {
21422215
results_in_args.max_dist = Math.max(results_in_args.max_dist || 0, tfpDist);
21432216
const maxDist = results_in_args.size < MAX_RESULTS ?
@@ -2223,9 +2296,12 @@ function initSearch(rawSearchIndex) {
22232296
row.type.output,
22242297
parsedQuery.returned,
22252298
row.type.where_clause,
2226-
mgens
2299+
mgens,
2300+
null,
2301+
0 // unboxing depth
22272302
);
2228-
}
2303+
},
2304+
0 // unboxing depth
22292305
)) {
22302306
return;
22312307
}

‎src/tools/miri/src/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
528528
use NonHaltingDiagnostic::*;
529529

530530
let stacktrace =
531-
MiriInterpCx::generate_stacktrace_from_stack(self.threads.active_thread_stack());
531+
Frame::generate_stacktrace_from_stack(self.threads.active_thread_stack());
532532
let (stacktrace, _was_pruned) = prune_stacktrace(stacktrace, self);
533533

534534
let (title, diag_level) = match &e {
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
#![feature(associated_type_defaults)]
2+
3+
use std::cmp::Ord;
4+
use std::fmt::{Debug, Formatter};
5+
use std::hash::Hash;
6+
use std::ops::ControlFlow;
7+
8+
pub trait Interner: Sized {
9+
type DefId: Copy + Debug + Hash + Ord;
10+
type AdtDef: Copy + Debug + Hash + Ord;
11+
type GenericArgs: Copy
12+
+ DebugWithInfcx<Self>
13+
+ Hash
14+
+ Ord
15+
+ IntoIterator<Item = Self::GenericArg>;
16+
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
17+
type Term: Copy + Debug + Hash + Ord;
18+
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
19+
type BoundVars: IntoIterator<Item = Self::BoundVar>;
20+
type BoundVar;
21+
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
22+
type Ty: Copy
23+
+ DebugWithInfcx<Self>
24+
+ Hash
25+
+ Ord
26+
+ Into<Self::GenericArg>
27+
+ IntoKind<Kind = TyKind<Self>>
28+
+ TypeSuperVisitable<Self>
29+
+ Flags
30+
+ Ty<Self>;
31+
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
32+
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
33+
type ParamTy: Copy + Debug + Hash + Ord;
34+
type BoundTy: Copy + Debug + Hash + Ord;
35+
type PlaceholderTy: Copy + Debug + Hash + Ord + PlaceholderLike;
36+
type ErrorGuaranteed: Copy + Debug + Hash + Ord;
37+
type BoundExistentialPredicates: Copy + DebugWithInfcx<Self> + Hash + Ord;
38+
type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Ord;
39+
type AllocId: Copy + Debug + Hash + Ord;
40+
type Const: Copy
41+
+ DebugWithInfcx<Self>
42+
+ Hash
43+
+ Ord
44+
+ Into<Self::GenericArg>
45+
+ IntoKind<Kind = ConstKind<Self>>
46+
+ ConstTy<Self>
47+
+ TypeSuperVisitable<Self>
48+
+ Flags
49+
+ Const<Self>;
50+
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
51+
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
52+
type ParamConst: Copy + Debug + Hash + Ord;
53+
type BoundConst: Copy + Debug + Hash + Ord;
54+
type ValueConst: Copy + Debug + Hash + Ord;
55+
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
56+
type Region: Copy
57+
+ DebugWithInfcx<Self>
58+
+ Hash
59+
+ Ord
60+
+ Into<Self::GenericArg>
61+
+ IntoKind<Kind = RegionKind<Self>>
62+
+ Flags
63+
+ Region<Self>;
64+
type EarlyParamRegion: Copy + Debug + Hash + Ord;
65+
type LateParamRegion: Copy + Debug + Hash + Ord;
66+
type BoundRegion: Copy + Debug + Hash + Ord;
67+
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Ord;
68+
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
69+
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
70+
type TraitPredicate: Copy + Debug + Hash + Eq;
71+
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
72+
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
73+
type ProjectionPredicate: Copy + Debug + Hash + Eq;
74+
type NormalizesTo: Copy + Debug + Hash + Eq;
75+
type SubtypePredicate: Copy + Debug + Hash + Eq;
76+
type CoercePredicate: Copy + Debug + Hash + Eq;
77+
type ClosureKind: Copy + Debug + Hash + Eq;
78+
79+
// Required method
80+
fn mk_canonical_var_infos(
81+
self,
82+
infos: &[CanonicalVarInfo<Self>]
83+
) -> Self::CanonicalVars;
84+
}
85+
86+
pub trait DebugWithInfcx<I: Interner>: Debug {
87+
// Required method
88+
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
89+
this: WithInfcx<'_, Infcx, &Self>,
90+
f: &mut Formatter<'_>
91+
) -> std::fmt::Result;
92+
}
93+
94+
pub trait TypeVisitable<I: Interner>: Debug + Clone {
95+
// Required method
96+
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result;
97+
}
98+
99+
pub trait BoundVars<I: Interner> {
100+
// Required methods
101+
fn bound_vars(&self) -> I::BoundVars;
102+
fn has_no_bound_vars(&self) -> bool;
103+
}
104+
105+
pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> {
106+
// Required method
107+
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result;
108+
}
109+
110+
pub struct CanonicalVarInfo<I: Interner> {
111+
pub kind: CanonicalVarKind<I>,
112+
}
113+
114+
pub struct CanonicalVarKind<I>(std::marker::PhantomData<I>);
115+
116+
pub struct TyKind<I>(std::marker::PhantomData<I>);
117+
118+
pub trait IntoKind {
119+
type Kind;
120+
121+
// Required method
122+
fn kind(self) -> Self::Kind;
123+
}
124+
pub trait Flags {
125+
// Required methods
126+
fn flags(&self) -> TypeFlags;
127+
fn outer_exclusive_binder(&self) -> DebruijnIndex;
128+
}
129+
pub struct TypeFlags;
130+
131+
pub trait Ty<I: Interner<Ty = Self>> {
132+
// Required method
133+
fn new_anon_bound(
134+
interner: I,
135+
debruijn: DebruijnIndex,
136+
var: BoundVar
137+
) -> Self;
138+
}
139+
140+
pub trait PlaceholderLike {
141+
// Required methods
142+
fn universe(self) -> UniverseIndex;
143+
fn var(self) -> BoundVar;
144+
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
145+
fn new(ui: UniverseIndex, var: BoundVar) -> Self;
146+
}
147+
148+
pub struct UniverseIndex;
149+
150+
pub struct BoundVar;
151+
152+
pub struct ConstKind<I>(std::marker::PhantomData<I>);
153+
pub trait Const<I: Interner<Const = Self>> {
154+
// Required method
155+
fn new_anon_bound(
156+
interner: I,
157+
debruijn: DebruijnIndex,
158+
var: BoundVar,
159+
ty: I::Ty
160+
) -> Self;
161+
}
162+
163+
pub trait ConstTy<I: Interner> {
164+
// Required method
165+
fn ty(self) -> I::Ty;
166+
}
167+
168+
pub struct DebruijnIndex;
169+
170+
pub struct RegionKind<I>(std::marker::PhantomData<I>);
171+
pub trait Region<I: Interner<Region = Self>> {
172+
// Required method
173+
fn new_anon_bound(
174+
interner: I,
175+
debruijn: DebruijnIndex,
176+
var: BoundVar
177+
) -> Self;
178+
}
179+
180+
pub trait TypeVisitor<I: Interner>: Sized {
181+
type Result: VisitorResult = ();
182+
183+
// Provided methods
184+
fn visit_binder<T: TypeVisitable<I>>(
185+
&mut self,
186+
t: &I::Binder<T>
187+
) -> Self::Result { unimplemented!() }
188+
fn visit_ty(&mut self, t: I::Ty) -> Self::Result { unimplemented!() }
189+
fn visit_region(&mut self, _r: I::Region) -> Self::Result { unimplemented!() }
190+
fn visit_const(&mut self, c: I::Const) -> Self::Result { unimplemented!() }
191+
fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result { unimplemented!() }
192+
}
193+
194+
pub trait VisitorResult {
195+
type Residual;
196+
197+
// Required methods
198+
fn output() -> Self;
199+
fn from_residual(residual: Self::Residual) -> Self;
200+
fn from_branch(b: ControlFlow<Self::Residual>) -> Self;
201+
fn branch(self) -> ControlFlow<Self::Residual>;
202+
}
203+
204+
impl VisitorResult for () {
205+
type Residual = ();
206+
fn output() -> Self {}
207+
fn from_residual(_: Self::Residual) -> Self {}
208+
fn from_branch(_: ControlFlow<Self::Residual>) -> Self {}
209+
fn branch(self) -> ControlFlow<Self::Residual> { ControlFlow::Continue(()) }
210+
}
211+
212+
pub struct WithInfcx<'a, Infcx: InferCtxtLike, T> {
213+
pub data: T,
214+
pub infcx: &'a Infcx,
215+
}
216+
217+
pub trait InferCtxtLike {
218+
type Interner: Interner;
219+
220+
// Required methods
221+
fn interner(&self) -> Self::Interner;
222+
fn universe_of_ty(&self, ty: TyVid) -> Option<UniverseIndex>;
223+
fn root_ty_var(&self, vid: TyVid) -> TyVid;
224+
fn probe_ty_var(
225+
&self,
226+
vid: TyVid
227+
) -> Option<<Self::Interner as Interner>::Ty>;
228+
fn universe_of_lt(
229+
&self,
230+
lt: <Self::Interner as Interner>::InferRegion
231+
) -> Option<UniverseIndex>;
232+
fn opportunistic_resolve_lt_var(
233+
&self,
234+
vid: <Self::Interner as Interner>::InferRegion
235+
) -> Option<<Self::Interner as Interner>::Region>;
236+
fn universe_of_ct(&self, ct: ConstVid) -> Option<UniverseIndex>;
237+
fn root_ct_var(&self, vid: ConstVid) -> ConstVid;
238+
fn probe_ct_var(
239+
&self,
240+
vid: ConstVid
241+
) -> Option<<Self::Interner as Interner>::Const>;
242+
}
243+
244+
pub struct TyVid;
245+
pub struct ConstVid;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// https://github.com/rust-lang/rust/pull/122247
2+
// exact-check
3+
4+
const EXPECTED = {
5+
'query': 'canonicalvarinfo, intoiterator -> intoiterator',
6+
'others': [
7+
{ 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' },
8+
],
9+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//@ aux-crate:interner=interner.rs
2+
// https://github.com/rust-lang/rust/pull/122247
3+
extern crate interner;
4+
#[doc(inline)]
5+
pub use interner::*;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![deny(unknown_or_malformed_diagnostic_attributes)]
2+
3+
#[diagnostic::unknown_attribute]
4+
//~^ERROR unknown diagnostic attribute
5+
struct Foo;
6+
7+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unknown diagnostic attribute
2+
--> $DIR/deny_malformed_attribute.rs:3:15
3+
|
4+
LL | #[diagnostic::unknown_attribute]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/deny_malformed_attribute.rs:1:9
9+
|
10+
LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@build-fail
2+
//! Make sure that monomorphization-time const errors from `static_assert` take priority over the
3+
//! error from simd_extract. Basically this checks that if a const fails to evaluate in some
4+
//! function, we don't bother codegen'ing the function.
5+
#![feature(generic_arg_infer)]
6+
#![feature(core_intrinsics)]
7+
#![feature(repr_simd)]
8+
#![feature(inline_const)]
9+
use std::intrinsics::simd::*;
10+
11+
#[repr(simd)]
12+
#[allow(non_camel_case_types)]
13+
struct int8x4_t(u8,u8,u8,u8);
14+
15+
fn get_elem<const LANE: u32>(a: int8x4_t) -> u8 {
16+
const { assert!(LANE < 4); } // the error should be here...
17+
//~^ ERROR failed
18+
//~| assertion failed
19+
unsafe { simd_extract(a, LANE) } // ...not here
20+
}
21+
22+
fn main() {
23+
get_elem::<4>(int8x4_t(0,0,0,0));
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0080]: evaluation of `get_elem::<4>::{constant#0}` failed
2+
--> $DIR/const-err-trumps-simd-err.rs:16:13
3+
|
4+
LL | const { assert!(LANE < 4); } // the error should be here...
5+
| ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: LANE < 4', $DIR/const-err-trumps-simd-err.rs:16:13
6+
|
7+
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
note: the above error was encountered while instantiating `fn get_elem::<4>`
10+
--> $DIR/const-err-trumps-simd-err.rs:23:5
11+
|
12+
LL | get_elem::<4>(int8x4_t(0,0,0,0));
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0080`.

‎tests/ui/type-alias-impl-trait/in-where-clause.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! We evaluate `1 + 2` with `Reveal::All` during typeck, causing
2-
//! us to to get the concrete type of `Bar` while computing it.
2+
//! us to get the concrete type of `Bar` while computing it.
33
//! This again requires type checking `foo`.
44
#![feature(type_alias_impl_trait)]
55
type Bar = impl Sized;

0 commit comments

Comments
 (0)
Please sign in to comment.