authorbors <bors@rust-lang.org> 2024-05-29 03:55:21 UTC
committerbors <bors@rust-lang.org> 2024-05-29 03:55:21 UTC
log751691271d76b8435559200b84d1947c2bd735bd
tree43c1b958190e9e2b87cea232e2f3ac27df9ecaa8
parentda159eb331b27df528185c616b394bb0e1d2a4bd
parent4c1228276b15c50b991d052d9fc682cc62f90881

Auto merge of #125691 - jieyouxu:rollup-0i3wrc4, r=jieyouxu

Rollup of 8 pull requests Successful merges: - #124251 (Add an intrinsic for `ptr::metadata`) - #124320 (Add `--print=check-cfg` to get the expected configs) - #125226 (Make more of the test suite run on Mac Catalyst) - #125381 (Silence some resolve errors when there have been glob import errors) - #125633 (miri: avoid making a full copy of all new allocations) - #125638 (Rewrite `lto-smoke`, `simple-rlib` and `mixing-deps` `run-make` tests in `rmake.rs` format) - #125639 (Support `./x doc run-make-support --open`) - #125664 (Tweak relations to no longer rely on `TypeTrace`) r? `@ghost` `@rustbot` modify labels: rollup

145 files changed, 1347 insertions(+), 534 deletions(-)

compiler/rustc_codegen_cranelift/src/base.rs+25-13
......@@ -616,22 +616,34 @@ fn codegen_stmt<'tcx>(
616616 Rvalue::UnaryOp(un_op, ref operand) => {
617617 let operand = codegen_operand(fx, operand);
618618 let layout = operand.layout();
619 let val = operand.load_scalar(fx);
620619 let res = match un_op {
621 UnOp::Not => match layout.ty.kind() {
622 ty::Bool => {
623 let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
624 CValue::by_val(res, layout)
620 UnOp::Not => {
621 let val = operand.load_scalar(fx);
622 match layout.ty.kind() {
623 ty::Bool => {
624 let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
625 CValue::by_val(res, layout)
626 }
627 ty::Uint(_) | ty::Int(_) => {
628 CValue::by_val(fx.bcx.ins().bnot(val), layout)
629 }
630 _ => unreachable!("un op Not for {:?}", layout.ty),
625631 }
626 ty::Uint(_) | ty::Int(_) => {
627 CValue::by_val(fx.bcx.ins().bnot(val), layout)
632 }
633 UnOp::Neg => {
634 let val = operand.load_scalar(fx);
635 match layout.ty.kind() {
636 ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
637 ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
638 _ => unreachable!("un op Neg for {:?}", layout.ty),
628639 }
629 _ => unreachable!("un op Not for {:?}", layout.ty),
630 },
631 UnOp::Neg => match layout.ty.kind() {
632 ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
633 ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
634 _ => unreachable!("un op Neg for {:?}", layout.ty),
640 }
641 UnOp::PtrMetadata => match layout.abi {
642 Abi::Scalar(_) => CValue::zst(dest_layout),
643 Abi::ScalarPair(_, _) => {
644 CValue::by_val(operand.load_scalar_pair(fx).1, dest_layout)
645 }
646 _ => bug!("Unexpected `PtrToMetadata` operand: {operand:?}"),
635647 },
636648 };
637649 lval.write_cvalue(fx, res);
compiler/rustc_codegen_cranelift/src/constant.rs+1-1
......@@ -100,7 +100,7 @@ pub(crate) fn codegen_const_value<'tcx>(
100100 assert!(layout.is_sized(), "unsized const value");
101101
102102 if layout.is_zst() {
103 return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout);
103 return CValue::zst(layout);
104104 }
105105
106106 match const_val {
compiler/rustc_codegen_cranelift/src/value_and_place.rs+8
......@@ -95,6 +95,14 @@ impl<'tcx> CValue<'tcx> {
9595 CValue(CValueInner::ByValPair(value, extra), layout)
9696 }
9797
98 /// Create an instance of a ZST
99 ///
100 /// The is represented by a dangling pointer of suitable alignment.
101 pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> {
102 assert!(layout.is_zst());
103 CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout)
104 }
105
98106 pub(crate) fn layout(&self) -> TyAndLayout<'tcx> {
99107 self.1
100108 }
compiler/rustc_codegen_ssa/src/mir/operand.rs+5
......@@ -565,6 +565,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
565565 for elem in place_ref.projection.iter() {
566566 match elem {
567567 mir::ProjectionElem::Field(ref f, _) => {
568 debug_assert!(
569 !o.layout.ty.is_any_ptr(),
570 "Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \
571 but tried to access field {f:?} of pointer {o:?}",
572 );
568573 o = o.extract_field(bx, f.index());
569574 }
570575 mir::ProjectionElem::Index(_)
compiler/rustc_codegen_ssa/src/mir/place.rs+5
......@@ -480,6 +480,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
480480 cg_base = match *elem {
481481 mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
482482 mir::ProjectionElem::Field(ref field, _) => {
483 debug_assert!(
484 !cg_base.layout.ty.is_any_ptr(),
485 "Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \
486 but tried to access field {field:?} of pointer {cg_base:?}",
487 );
483488 cg_base.project_field(bx, field.index())
484489 }
485490 mir::ProjectionElem::OpaqueCast(ty) => {
compiler/rustc_codegen_ssa/src/mir/rvalue.rs+26-8
......@@ -623,19 +623,36 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
623623
624624 mir::Rvalue::UnaryOp(op, ref operand) => {
625625 let operand = self.codegen_operand(bx, operand);
626 let lloperand = operand.immediate();
627626 let is_float = operand.layout.ty.is_floating_point();
628 let llval = match op {
629 mir::UnOp::Not => bx.not(lloperand),
627 let (val, layout) = match op {
628 mir::UnOp::Not => {
629 let llval = bx.not(operand.immediate());
630 (OperandValue::Immediate(llval), operand.layout)
631 }
630632 mir::UnOp::Neg => {
631 if is_float {
632 bx.fneg(lloperand)
633 let llval = if is_float {
634 bx.fneg(operand.immediate())
635 } else {
636 bx.neg(operand.immediate())
637 };
638 (OperandValue::Immediate(llval), operand.layout)
639 }
640 mir::UnOp::PtrMetadata => {
641 debug_assert!(operand.layout.ty.is_unsafe_ptr());
642 let (_, meta) = operand.val.pointer_parts();
643 assert_eq!(operand.layout.fields.count() > 1, meta.is_some());
644 if let Some(meta) = meta {
645 (OperandValue::Immediate(meta), operand.layout.field(self.cx, 1))
633646 } else {
634 bx.neg(lloperand)
647 (OperandValue::ZeroSized, bx.cx().layout_of(bx.tcx().types.unit))
635648 }
636649 }
637650 };
638 OperandRef { val: OperandValue::Immediate(llval), layout: operand.layout }
651 debug_assert!(
652 val.is_expected_variant_for_type(self.cx, layout),
653 "Made wrong variant {val:?} for type {layout:?}",
654 );
655 OperandRef { val, layout }
639656 }
640657
641658 mir::Rvalue::Discriminant(ref place) => {
......@@ -718,8 +735,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
718735 let values = op.val.immediates_or_place().left_or_else(|p| {
719736 bug!("Field {field_idx:?} is {p:?} making {layout:?}");
720737 });
721 inputs.extend(values);
722738 let scalars = self.value_kind(op.layout).scalars().unwrap();
739 debug_assert_eq!(values.len(), scalars.len());
740 inputs.extend(values);
723741 input_scalars.extend(scalars);
724742 }
725743
compiler/rustc_const_eval/src/const_eval/dummy_machine.rs+1-1
......@@ -174,7 +174,7 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
174174 unimplemented!()
175175 }
176176
177 fn init_frame_extra(
177 fn init_frame(
178178 _ecx: &mut InterpCx<'tcx, Self>,
179179 _frame: interpret::Frame<'tcx, Self::Provenance>,
180180 ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>
compiler/rustc_const_eval/src/const_eval/machine.rs+1-1
......@@ -643,7 +643,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeInterpreter<'tcx> {
643643 }
644644
645645 #[inline(always)]
646 fn init_frame_extra(
646 fn init_frame(
647647 ecx: &mut InterpCx<'tcx, Self>,
648648 frame: Frame<'tcx>,
649649 ) -> InterpResult<'tcx, Frame<'tcx>> {
compiler/rustc_const_eval/src/interpret/cast.rs+1-1
......@@ -207,7 +207,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
207207 assert!(cast_to.ty.is_unsafe_ptr());
208208 // Handle casting any ptr to raw ptr (might be a fat ptr).
209209 if cast_to.size == src.layout.size {
210 // Thin or fat pointer that just hast the ptr kind of target type changed.
210 // Thin or fat pointer that just has the ptr kind of target type changed.
211211 return Ok(ImmTy::from_immediate(**src, cast_to));
212212 } else {
213213 // Casting the metadata away from a fat ptr.
compiler/rustc_const_eval/src/interpret/eval_context.rs+1-1
......@@ -819,7 +819,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
819819 tracing_span: SpanGuard::new(),
820820 extra: (),
821821 };
822 let frame = M::init_frame_extra(self, pre_frame)?;
822 let frame = M::init_frame(self, pre_frame)?;
823823 self.stack_mut().push(frame);
824824
825825 // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
compiler/rustc_const_eval/src/interpret/machine.rs+41-17
......@@ -329,27 +329,41 @@ pub trait Machine<'tcx>: Sized {
329329 ptr: Pointer<Self::Provenance>,
330330 ) -> Option<(AllocId, Size, Self::ProvenanceExtra)>;
331331
332 /// Called to adjust allocations to the Provenance and AllocExtra of this machine.
332 /// Called to adjust global allocations to the Provenance and AllocExtra of this machine.
333333 ///
334334 /// If `alloc` contains pointers, then they are all pointing to globals.
335335 ///
336 /// The way we construct allocations is to always first construct it without extra and then add
337 /// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
338 /// globals, and allocations created by Miri during evaluation.
339 ///
340 /// `kind` is the kind of the allocation being adjusted; it can be `None` when
341 /// it's a global and `GLOBAL_KIND` is `None`.
342 ///
343336 /// This should avoid copying if no work has to be done! If this returns an owned
344337 /// allocation (because a copy had to be done to adjust things), machine memory will
345338 /// cache the result. (This relies on `AllocMap::get_or` being able to add the
346339 /// owned allocation to the map even when the map is shared.)
347 fn adjust_allocation<'b>(
340 fn adjust_global_allocation<'b>(
348341 ecx: &InterpCx<'tcx, Self>,
349342 id: AllocId,
350 alloc: Cow<'b, Allocation>,
351 kind: Option<MemoryKind<Self::MemoryKind>>,
352 ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
343 alloc: &'b Allocation,
344 ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
345 {
346 // The default implementation does a copy; CTFE machines have a more efficient implementation
347 // based on their particular choice for `Provenance`, `AllocExtra`, and `Bytes`.
348 let kind = Self::GLOBAL_KIND
349 .expect("if GLOBAL_KIND is None, adjust_global_allocation must be overwritten");
350 let alloc = alloc.adjust_from_tcx(&ecx.tcx, |ptr| ecx.global_root_pointer(ptr))?;
351 let extra =
352 Self::init_alloc_extra(ecx, id, MemoryKind::Machine(kind), alloc.size(), alloc.align)?;
353 Ok(Cow::Owned(alloc.with_extra(extra)))
354 }
355
356 /// Initialize the extra state of an allocation.
357 ///
358 /// This is guaranteed to be called exactly once on all allocations that are accessed by the
359 /// program.
360 fn init_alloc_extra(
361 ecx: &InterpCx<'tcx, Self>,
362 id: AllocId,
363 kind: MemoryKind<Self::MemoryKind>,
364 size: Size,
365 align: Align,
366 ) -> InterpResult<'tcx, Self::AllocExtra>;
353367
354368 /// Return a "root" pointer for the given allocation: the one that is used for direct
355369 /// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
......@@ -473,7 +487,7 @@ pub trait Machine<'tcx>: Sized {
473487 }
474488
475489 /// Called immediately before a new stack frame gets pushed.
476 fn init_frame_extra(
490 fn init_frame(
477491 ecx: &mut InterpCx<'tcx, Self>,
478492 frame: Frame<'tcx, Self::Provenance>,
479493 ) -> InterpResult<'tcx, Frame<'tcx, Self::Provenance, Self::FrameExtra>>;
......@@ -590,13 +604,23 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
590604 }
591605
592606 #[inline(always)]
593 fn adjust_allocation<'b>(
607 fn adjust_global_allocation<'b>(
594608 _ecx: &InterpCx<$tcx, Self>,
595609 _id: AllocId,
596 alloc: Cow<'b, Allocation>,
597 _kind: Option<MemoryKind<Self::MemoryKind>>,
610 alloc: &'b Allocation,
598611 ) -> InterpResult<$tcx, Cow<'b, Allocation<Self::Provenance>>> {
599 Ok(alloc)
612 // Overwrite default implementation: no need to adjust anything.
613 Ok(Cow::Borrowed(alloc))
614 }
615
616 fn init_alloc_extra(
617 _ecx: &InterpCx<$tcx, Self>,
618 _id: AllocId,
619 _kind: MemoryKind<Self::MemoryKind>,
620 _size: Size,
621 _align: Align,
622 ) -> InterpResult<$tcx, Self::AllocExtra> {
623 Ok(())
600624 }
601625
602626 fn extern_static_pointer(
compiler/rustc_const_eval/src/interpret/memory.rs+8-6
......@@ -239,7 +239,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
239239
240240 pub fn allocate_raw_ptr(
241241 &mut self,
242 alloc: Allocation,
242 alloc: Allocation<M::Provenance, (), M::Bytes>,
243243 kind: MemoryKind<M::MemoryKind>,
244244 ) -> InterpResult<'tcx, Pointer<M::Provenance>> {
245245 let id = self.tcx.reserve_alloc_id();
......@@ -248,8 +248,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
248248 M::GLOBAL_KIND.map(MemoryKind::Machine),
249249 "dynamically allocating global memory"
250250 );
251 let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
252 self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
251 // We have set things up so we don't need to call `adjust_from_tcx` here,
252 // so we avoid copying the entire allocation contents.
253 let extra = M::init_alloc_extra(self, id, kind, alloc.size(), alloc.align)?;
254 let alloc = alloc.with_extra(extra);
255 self.memory.alloc_map.insert(id, (kind, alloc));
253256 M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
254257 }
255258
......@@ -583,11 +586,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
583586 };
584587 M::before_access_global(self.tcx, &self.machine, id, alloc, def_id, is_write)?;
585588 // We got tcx memory. Let the machine initialize its "extra" stuff.
586 M::adjust_allocation(
589 M::adjust_global_allocation(
587590 self,
588591 id, // always use the ID we got as input, not the "hidden" one.
589 Cow::Borrowed(alloc.inner()),
590 M::GLOBAL_KIND.map(MemoryKind::Machine),
592 alloc.inner(),
591593 )
592594 }
593595
compiler/rustc_const_eval/src/interpret/operator.rs+24-4
......@@ -9,7 +9,7 @@ use rustc_middle::{bug, span_bug};
99use rustc_span::symbol::sym;
1010use tracing::trace;
1111
12use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine};
12use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine, MemPlaceMeta};
1313
1414impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
1515 fn three_way_compare<T: Ord>(&self, lhs: T, rhs: T) -> ImmTy<'tcx, M::Provenance> {
......@@ -415,11 +415,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
415415 use rustc_middle::mir::UnOp::*;
416416
417417 let layout = val.layout;
418 let val = val.to_scalar();
419418 trace!("Running unary op {:?}: {:?} ({})", un_op, val, layout.ty);
420419
421420 match layout.ty.kind() {
422421 ty::Bool => {
422 let val = val.to_scalar();
423423 let val = val.to_bool()?;
424424 let res = match un_op {
425425 Not => !val,
......@@ -428,6 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
428428 Ok(ImmTy::from_bool(res, *self.tcx))
429429 }
430430 ty::Float(fty) => {
431 let val = val.to_scalar();
431432 // No NaN adjustment here, `-` is a bitwise operation!
432433 let res = match (un_op, fty) {
433434 (Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?),
......@@ -436,8 +437,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
436437 };
437438 Ok(ImmTy::from_scalar(res, layout))
438439 }
439 _ => {
440 assert!(layout.ty.is_integral());
440 _ if layout.ty.is_integral() => {
441 let val = val.to_scalar();
441442 let val = val.to_bits(layout.size)?;
442443 let res = match un_op {
443444 Not => self.truncate(!val, layout), // bitwise negation, then truncate
......@@ -450,9 +451,28 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
450451 // Truncate to target type.
451452 self.truncate(res, layout)
452453 }
454 _ => span_bug!(self.cur_span(), "Invalid integer op {:?}", un_op),
453455 };
454456 Ok(ImmTy::from_uint(res, layout))
455457 }
458 ty::RawPtr(..) => {
459 assert_eq!(un_op, PtrMetadata);
460 let (_, meta) = val.to_scalar_and_meta();
461 Ok(match meta {
462 MemPlaceMeta::Meta(scalar) => {
463 let ty = un_op.ty(*self.tcx, val.layout.ty);
464 let layout = self.layout_of(ty)?;
465 ImmTy::from_scalar(scalar, layout)
466 }
467 MemPlaceMeta::None => {
468 let unit_layout = self.layout_of(self.tcx.types.unit)?;
469 ImmTy::uninit(unit_layout)
470 }
471 })
472 }
473 _ => {
474 bug!("Unexpected unary op argument {val:?}")
475 }
456476 }
457477 }
458478}
compiler/rustc_driver_impl/src/lib.rs+33
......@@ -804,6 +804,39 @@ fn print_crate_info(
804804 println_info!("{cfg}");
805805 }
806806 }
807 CheckCfg => {
808 let mut check_cfgs: Vec<String> = Vec::with_capacity(410);
809
810 // INSTABILITY: We are sorting the output below.
811 #[allow(rustc::potential_query_instability)]
812 for (name, expected_values) in &sess.psess.check_config.expecteds {
813 use crate::config::ExpectedValues;
814 match expected_values {
815 ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")),
816 ExpectedValues::Some(values) => {
817 check_cfgs.extend(values.iter().map(|value| {
818 if let Some(value) = value {
819 format!("{name}=\"{value}\"")
820 } else {
821 name.to_string()
822 }
823 }))
824 }
825 }
826 }
827
828 check_cfgs.sort_unstable();
829 if !sess.psess.check_config.exhaustive_names {
830 if !sess.psess.check_config.exhaustive_values {
831 println_info!("any()=any()");
832 } else {
833 println_info!("any()");
834 }
835 }
836 for check_cfg in check_cfgs {
837 println_info!("{check_cfg}");
838 }
839 }
807840 CallingConventions => {
808841 let mut calling_conventions = rustc_target::spec::abi::all_names();
809842 calling_conventions.sort_unstable();
compiler/rustc_hir_analysis/src/check/intrinsic.rs+2
......@@ -130,6 +130,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
130130 | sym::is_val_statically_known
131131 | sym::ptr_mask
132132 | sym::aggregate_raw_ptr
133 | sym::ptr_metadata
133134 | sym::ub_checks
134135 | sym::fadd_algebraic
135136 | sym::fsub_algebraic
......@@ -576,6 +577,7 @@ pub fn check_intrinsic_type(
576577 // This type check is not particularly useful, but the `where` bounds
577578 // on the definition in `core` do the heavy lifting for checking it.
578579 sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)),
580 sym::ptr_metadata => (2, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
579581
580582 sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
581583
compiler/rustc_hir_typeck/src/coercion.rs-1
......@@ -1158,7 +1158,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11581158 let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig));
11591159 let sig = self
11601160 .at(cause, self.param_env)
1161 .trace(prev_ty, new_ty)
11621161 .lub(DefineOpaqueTypes::Yes, a_sig, b_sig)
11631162 .map(|ok| self.register_infer_ok_obligations(ok))?;
11641163
compiler/rustc_infer/src/infer/at.rs+73-122
......@@ -48,11 +48,6 @@ pub struct At<'a, 'tcx> {
4848 pub param_env: ty::ParamEnv<'tcx>,
4949}
5050
51pub struct Trace<'a, 'tcx> {
52 at: At<'a, 'tcx>,
53 trace: TypeTrace<'tcx>,
54}
55
5651impl<'tcx> InferCtxt<'tcx> {
5752 #[inline]
5853 pub fn at<'a>(
......@@ -109,9 +104,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
109104 /// call like `foo(x)`, where `foo: fn(i32)`, you might have
110105 /// `sup(i32, x)`, since the "expected" type is the type that
111106 /// appears in the signature.
112 ///
113 /// See [`At::trace`] and [`Trace::sub`] for a version of
114 /// this method that only requires `T: Relate<'tcx>`
115107 pub fn sup<T>(
116108 self,
117109 define_opaque_types: DefineOpaqueTypes,
......@@ -121,13 +113,19 @@ impl<'a, 'tcx> At<'a, 'tcx> {
121113 where
122114 T: ToTrace<'tcx>,
123115 {
124 self.trace(expected, actual).sup(define_opaque_types, expected, actual)
116 let mut fields = CombineFields::new(
117 self.infcx,
118 ToTrace::to_trace(self.cause, true, expected, actual),
119 self.param_env,
120 define_opaque_types,
121 );
122 fields
123 .sup()
124 .relate(expected, actual)
125 .map(|_| InferOk { value: (), obligations: fields.obligations })
125126 }
126127
127128 /// Makes `expected <: actual`.
128 ///
129 /// See [`At::trace`] and [`Trace::sub`] for a version of
130 /// this method that only requires `T: Relate<'tcx>`
131129 pub fn sub<T>(
132130 self,
133131 define_opaque_types: DefineOpaqueTypes,
......@@ -137,13 +135,19 @@ impl<'a, 'tcx> At<'a, 'tcx> {
137135 where
138136 T: ToTrace<'tcx>,
139137 {
140 self.trace(expected, actual).sub(define_opaque_types, expected, actual)
138 let mut fields = CombineFields::new(
139 self.infcx,
140 ToTrace::to_trace(self.cause, true, expected, actual),
141 self.param_env,
142 define_opaque_types,
143 );
144 fields
145 .sub()
146 .relate(expected, actual)
147 .map(|_| InferOk { value: (), obligations: fields.obligations })
141148 }
142149
143 /// Makes `expected <: actual`.
144 ///
145 /// See [`At::trace`] and [`Trace::eq`] for a version of
146 /// this method that only requires `T: Relate<'tcx>`
150 /// Makes `expected == actual`.
147151 pub fn eq<T>(
148152 self,
149153 define_opaque_types: DefineOpaqueTypes,
......@@ -153,7 +157,40 @@ impl<'a, 'tcx> At<'a, 'tcx> {
153157 where
154158 T: ToTrace<'tcx>,
155159 {
156 self.trace(expected, actual).eq(define_opaque_types, expected, actual)
160 let mut fields = CombineFields::new(
161 self.infcx,
162 ToTrace::to_trace(self.cause, true, expected, actual),
163 self.param_env,
164 define_opaque_types,
165 );
166 fields
167 .equate(StructurallyRelateAliases::No)
168 .relate(expected, actual)
169 .map(|_| InferOk { value: (), obligations: fields.obligations })
170 }
171
172 /// Equates `expected` and `found` while structurally relating aliases.
173 /// This should only be used inside of the next generation trait solver
174 /// when relating rigid aliases.
175 pub fn eq_structurally_relating_aliases<T>(
176 self,
177 expected: T,
178 actual: T,
179 ) -> InferResult<'tcx, ()>
180 where
181 T: ToTrace<'tcx>,
182 {
183 assert!(self.infcx.next_trait_solver());
184 let mut fields = CombineFields::new(
185 self.infcx,
186 ToTrace::to_trace(self.cause, true, expected, actual),
187 self.param_env,
188 DefineOpaqueTypes::Yes,
189 );
190 fields
191 .equate(StructurallyRelateAliases::Yes)
192 .relate(expected, actual)
193 .map(|_| InferOk { value: (), obligations: fields.obligations })
157194 }
158195
159196 pub fn relate<T>(
......@@ -185,9 +222,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
185222 /// this can result in an error (e.g., if asked to compute LUB of
186223 /// u32 and i32), it is meaningful to call one of them the
187224 /// "expected type".
188 ///
189 /// See [`At::trace`] and [`Trace::lub`] for a version of
190 /// this method that only requires `T: Relate<'tcx>`
191225 pub fn lub<T>(
192226 self,
193227 define_opaque_types: DefineOpaqueTypes,
......@@ -197,15 +231,21 @@ impl<'a, 'tcx> At<'a, 'tcx> {
197231 where
198232 T: ToTrace<'tcx>,
199233 {
200 self.trace(expected, actual).lub(define_opaque_types, expected, actual)
234 let mut fields = CombineFields::new(
235 self.infcx,
236 ToTrace::to_trace(self.cause, true, expected, actual),
237 self.param_env,
238 define_opaque_types,
239 );
240 fields
241 .lub()
242 .relate(expected, actual)
243 .map(|value| InferOk { value, obligations: fields.obligations })
201244 }
202245
203246 /// Computes the greatest-lower-bound, or mutual subtype, of two
204247 /// values. As with `lub` order doesn't matter, except for error
205248 /// cases.
206 ///
207 /// See [`At::trace`] and [`Trace::glb`] for a version of
208 /// this method that only requires `T: Relate<'tcx>`
209249 pub fn glb<T>(
210250 self,
211251 define_opaque_types: DefineOpaqueTypes,
......@@ -215,105 +255,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
215255 where
216256 T: ToTrace<'tcx>,
217257 {
218 self.trace(expected, actual).glb(define_opaque_types, expected, actual)
219 }
220
221 /// Sets the "trace" values that will be used for
222 /// error-reporting, but doesn't actually perform any operation
223 /// yet (this is useful when you want to set the trace using
224 /// distinct values from those you wish to operate upon).
225 pub fn trace<T>(self, expected: T, actual: T) -> Trace<'a, 'tcx>
226 where
227 T: ToTrace<'tcx>,
228 {
229 let trace = ToTrace::to_trace(self.cause, true, expected, actual);
230 Trace { at: self, trace }
231 }
232}
233
234impl<'a, 'tcx> Trace<'a, 'tcx> {
235 /// Makes `a <: b`.
236 #[instrument(skip(self), level = "debug")]
237 pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
238 where
239 T: Relate<'tcx>,
240 {
241 let Trace { at, trace } = self;
242 let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
243 fields
244 .sub()
245 .relate(a, b)
246 .map(move |_| InferOk { value: (), obligations: fields.obligations })
247 }
248
249 /// Makes `a :> b`.
250 #[instrument(skip(self), level = "debug")]
251 pub fn sup<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
252 where
253 T: Relate<'tcx>,
254 {
255 let Trace { at, trace } = self;
256 let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
257 fields
258 .sup()
259 .relate(a, b)
260 .map(move |_| InferOk { value: (), obligations: fields.obligations })
261 }
262
263 /// Makes `a == b`.
264 #[instrument(skip(self), level = "debug")]
265 pub fn eq<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
266 where
267 T: Relate<'tcx>,
268 {
269 let Trace { at, trace } = self;
270 let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
271 fields
272 .equate(StructurallyRelateAliases::No)
273 .relate(a, b)
274 .map(move |_| InferOk { value: (), obligations: fields.obligations })
275 }
276
277 /// Equates `a` and `b` while structurally relating aliases. This should only
278 /// be used inside of the next generation trait solver when relating rigid aliases.
279 #[instrument(skip(self), level = "debug")]
280 pub fn eq_structurally_relating_aliases<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
281 where
282 T: Relate<'tcx>,
283 {
284 let Trace { at, trace } = self;
285 debug_assert!(at.infcx.next_trait_solver());
286 let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::Yes);
287 fields
288 .equate(StructurallyRelateAliases::Yes)
289 .relate(a, b)
290 .map(move |_| InferOk { value: (), obligations: fields.obligations })
291 }
292
293 #[instrument(skip(self), level = "debug")]
294 pub fn lub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T>
295 where
296 T: Relate<'tcx>,
297 {
298 let Trace { at, trace } = self;
299 let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
300 fields
301 .lub()
302 .relate(a, b)
303 .map(move |t| InferOk { value: t, obligations: fields.obligations })
304 }
305
306 #[instrument(skip(self), level = "debug")]
307 pub fn glb<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T>
308 where
309 T: Relate<'tcx>,
310 {
311 let Trace { at, trace } = self;
312 let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
258 let mut fields = CombineFields::new(
259 self.infcx,
260 ToTrace::to_trace(self.cause, true, expected, actual),
261 self.param_env,
262 define_opaque_types,
263 );
313264 fields
314265 .glb()
315 .relate(a, b)
316 .map(move |t| InferOk { value: t, obligations: fields.obligations })
266 .relate(expected, actual)
267 .map(|value| InferOk { value, obligations: fields.obligations })
317268 }
318269}
319270
compiler/rustc_infer/src/infer/mod.rs-15
......@@ -836,21 +836,6 @@ impl<'tcx> InferCtxt<'tcx> {
836836 .collect()
837837 }
838838
839 fn combine_fields<'a>(
840 &'a self,
841 trace: TypeTrace<'tcx>,
842 param_env: ty::ParamEnv<'tcx>,
843 define_opaque_types: DefineOpaqueTypes,
844 ) -> CombineFields<'a, 'tcx> {
845 CombineFields {
846 infcx: self,
847 trace,
848 param_env,
849 obligations: PredicateObligations::new(),
850 define_opaque_types,
851 }
852 }
853
854839 pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
855840 where
856841 T: at::ToTrace<'tcx>,
compiler/rustc_infer/src/infer/relate/combine.rs+11
......@@ -42,6 +42,17 @@ pub struct CombineFields<'infcx, 'tcx> {
4242 pub define_opaque_types: DefineOpaqueTypes,
4343}
4444
45impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
46 pub fn new(
47 infcx: &'infcx InferCtxt<'tcx>,
48 trace: TypeTrace<'tcx>,
49 param_env: ty::ParamEnv<'tcx>,
50 define_opaque_types: DefineOpaqueTypes,
51 ) -> Self {
52 Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] }
53 }
54}
55
4556impl<'tcx> InferCtxt<'tcx> {
4657 pub fn super_combine_tys<R>(
4758 &self,
compiler/rustc_middle/src/mir/interpret/allocation.rs+21-22
......@@ -266,19 +266,6 @@ impl AllocRange {
266266
267267// The constructors are all without extra; the extra gets added by a machine hook later.
268268impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
269 /// Creates an allocation from an existing `Bytes` value - this is needed for miri FFI support
270 pub fn from_raw_bytes(bytes: Bytes, align: Align, mutability: Mutability) -> Self {
271 let size = Size::from_bytes(bytes.len());
272 Self {
273 bytes,
274 provenance: ProvenanceMap::new(),
275 init_mask: InitMask::new(size, true),
276 align,
277 mutability,
278 extra: (),
279 }
280 }
281
282269 /// Creates an allocation initialized by the given bytes
283270 pub fn from_bytes<'a>(
284271 slice: impl Into<Cow<'a, [u8]>>,
......@@ -342,18 +329,30 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
342329 Err(x) => x,
343330 }
344331 }
332
333 /// Add the extra.
334 pub fn with_extra<Extra>(self, extra: Extra) -> Allocation<Prov, Extra, Bytes> {
335 Allocation {
336 bytes: self.bytes,
337 provenance: self.provenance,
338 init_mask: self.init_mask,
339 align: self.align,
340 mutability: self.mutability,
341 extra,
342 }
343 }
345344}
346345
347346impl Allocation {
348347 /// Adjust allocation from the ones in `tcx` to a custom Machine instance
349 /// with a different `Provenance`, `Extra` and `Byte` type.
350 pub fn adjust_from_tcx<Prov: Provenance, Extra, Bytes: AllocBytes, Err>(
351 self,
348 /// with a different `Provenance` and `Byte` type.
349 pub fn adjust_from_tcx<Prov: Provenance, Bytes: AllocBytes, Err>(
350 &self,
352351 cx: &impl HasDataLayout,
353 extra: Extra,
354352 mut adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> Result<Pointer<Prov>, Err>,
355 ) -> Result<Allocation<Prov, Extra, Bytes>, Err> {
356 let mut bytes = self.bytes;
353 ) -> Result<Allocation<Prov, (), Bytes>, Err> {
354 // Copy the data.
355 let mut bytes = Bytes::from_bytes(Cow::Borrowed(&*self.bytes), self.align);
357356 // Adjust provenance of pointers stored in this allocation.
358357 let mut new_provenance = Vec::with_capacity(self.provenance.ptrs().len());
359358 let ptr_size = cx.data_layout().pointer_size.bytes_usize();
......@@ -369,12 +368,12 @@ impl Allocation {
369368 }
370369 // Create allocation.
371370 Ok(Allocation {
372 bytes: AllocBytes::from_bytes(Cow::Owned(Vec::from(bytes)), self.align),
371 bytes,
373372 provenance: ProvenanceMap::from_presorted_ptrs(new_provenance),
374 init_mask: self.init_mask,
373 init_mask: self.init_mask.clone(),
375374 align: self.align,
376375 mutability: self.mutability,
377 extra,
376 extra: self.extra,
378377 })
379378 }
380379}
compiler/rustc_middle/src/mir/syntax.rs+7
......@@ -1434,6 +1434,13 @@ pub enum UnOp {
14341434 Not,
14351435 /// The `-` operator for negation
14361436 Neg,
1437 /// Get the metadata `M` from a `*const/mut impl Pointee<Metadata = M>`.
1438 ///
1439 /// For example, this will give a `()` from `*const i32`, a `usize` from
1440 /// `*mut [u8]`, or a pointer to a vtable from a `*const dyn Foo`.
1441 ///
1442 /// Allowed only in [`MirPhase::Runtime`]; earlier it's an intrinsic.
1443 PtrMetadata,
14371444}
14381445
14391446#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
compiler/rustc_middle/src/mir/tcx.rs+25-1
......@@ -180,7 +180,10 @@ impl<'tcx> Rvalue<'tcx> {
180180 let rhs_ty = rhs.ty(local_decls, tcx);
181181 op.ty(tcx, lhs_ty, rhs_ty)
182182 }
183 Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
183 Rvalue::UnaryOp(op, ref operand) => {
184 let arg_ty = operand.ty(local_decls, tcx);
185 op.ty(tcx, arg_ty)
186 }
184187 Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
185188 Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
186189 tcx.types.usize
......@@ -282,6 +285,27 @@ impl<'tcx> BinOp {
282285 }
283286}
284287
288impl<'tcx> UnOp {
289 pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> {
290 match self {
291 UnOp::Not | UnOp::Neg => arg_ty,
292 UnOp::PtrMetadata => {
293 let pointee_ty = arg_ty
294 .builtin_deref(true)
295 .unwrap_or_else(|| bug!("PtrMetadata of non-dereferenceable ty {arg_ty:?}"));
296 if pointee_ty.is_trivially_sized(tcx) {
297 tcx.types.unit
298 } else {
299 let Some(metadata_def_id) = tcx.lang_items().metadata_type() else {
300 bug!("No metadata_type lang item while looking at {arg_ty:?}")
301 };
302 Ty::new_projection(tcx, metadata_def_id, [pointee_ty])
303 }
304 }
305 }
306 }
307}
308
285309impl BorrowKind {
286310 pub fn to_mutbl_lossy(self) -> hir::Mutability {
287311 match self {
compiler/rustc_middle/src/ty/print/pretty.rs+2
......@@ -1579,8 +1579,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
15791579 let formatted_op = match op {
15801580 UnOp::Not => "!",
15811581 UnOp::Neg => "-",
1582 UnOp::PtrMetadata => "PtrMetadata",
15821583 };
15831584 let parenthesized = match ct.kind() {
1585 _ if op == UnOp::PtrMetadata => true,
15841586 ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op,
15851587 ty::ConstKind::Expr(_) => true,
15861588 _ => false,
compiler/rustc_mir_build/src/build/custom/parse/instruction.rs+1
......@@ -212,6 +212,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
212212 Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
213213 },
214214 @call(mir_len, args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
215 @call(mir_ptr_metadata, args) => Ok(Rvalue::UnaryOp(UnOp::PtrMetadata, self.parse_operand(args[0])?)),
215216 @call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
216217 ExprKind::Borrow { borrow_kind, arg } => Ok(
217218 Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
compiler/rustc_mir_transform/src/lower_intrinsics.rs+17
......@@ -316,6 +316,23 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
316316
317317 terminator.kind = TerminatorKind::Goto { target };
318318 }
319 sym::ptr_metadata => {
320 let Ok([ptr]) = <[_; 1]>::try_from(std::mem::take(args)) else {
321 span_bug!(
322 terminator.source_info.span,
323 "Wrong number of arguments for ptr_metadata intrinsic",
324 );
325 };
326 let target = target.unwrap();
327 block.statements.push(Statement {
328 source_info: terminator.source_info,
329 kind: StatementKind::Assign(Box::new((
330 *destination,
331 Rvalue::UnaryOp(UnOp::PtrMetadata, ptr.node),
332 ))),
333 });
334 terminator.kind = TerminatorKind::Goto { target };
335 }
319336 _ => {}
320337 }
321338 }
compiler/rustc_mir_transform/src/promote_consts.rs+1-1
......@@ -464,7 +464,7 @@ impl<'tcx> Validator<'_, 'tcx> {
464464 Rvalue::UnaryOp(op, operand) => {
465465 match op {
466466 // These operations can never fail.
467 UnOp::Neg | UnOp::Not => {}
467 UnOp::Neg | UnOp::Not | UnOp::PtrMetadata => {}
468468 }
469469
470470 self.validate_operand(operand)?;
compiler/rustc_mir_transform/src/validate.rs+10
......@@ -1109,6 +1109,16 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11091109 ty::Int(..) | ty::Uint(..) | ty::Bool
11101110 );
11111111 }
1112 UnOp::PtrMetadata => {
1113 if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
1114 // It would probably be fine to support this in earlier phases,
1115 // but at the time of writing it's only ever introduced from intrinsic lowering,
1116 // so earlier things can just `bug!` on it.
1117 self.fail(location, "PtrMetadata should be in runtime MIR only");
1118 }
1119
1120 check_kinds!(a, "Cannot PtrMetadata non-pointer type {:?}", ty::RawPtr(..));
1121 }
11121122 }
11131123 }
11141124 Rvalue::ShallowInitBox(operand, _) => {
compiler/rustc_resolve/src/imports.rs+15-7
......@@ -537,6 +537,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
537537 let determined_imports = mem::take(&mut self.determined_imports);
538538 let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
539539
540 let mut glob_error = false;
540541 for (is_indeterminate, import) in determined_imports
541542 .iter()
542543 .map(|i| (false, i))
......@@ -548,6 +549,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
548549 self.import_dummy_binding(*import, is_indeterminate);
549550
550551 if let Some(err) = unresolved_import_error {
552 glob_error |= import.is_glob();
553
551554 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
552555 if source.name == kw::SelfLower {
553556 // Silence `unresolved import` error if E0429 is already emitted
......@@ -563,7 +566,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
563566 {
564567 // In the case of a new import line, throw a diagnostic message
565568 // for the previous line.
566 self.throw_unresolved_import_error(errors);
569 self.throw_unresolved_import_error(errors, glob_error);
567570 errors = vec![];
568571 }
569572 if seen_spans.insert(err.span) {
......@@ -574,7 +577,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
574577 }
575578
576579 if !errors.is_empty() {
577 self.throw_unresolved_import_error(errors);
580 self.throw_unresolved_import_error(errors, glob_error);
578581 return;
579582 }
580583
......@@ -600,9 +603,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
600603 }
601604 }
602605
603 if !errors.is_empty() {
604 self.throw_unresolved_import_error(errors);
605 }
606 self.throw_unresolved_import_error(errors, glob_error);
606607 }
607608
608609 pub(crate) fn check_hidden_glob_reexports(
......@@ -672,7 +673,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
672673 }
673674 }
674675
675 fn throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>) {
676 fn throw_unresolved_import_error(
677 &mut self,
678 errors: Vec<(Import<'_>, UnresolvedImportError)>,
679 glob_error: bool,
680 ) {
676681 if errors.is_empty() {
677682 return;
678683 }
......@@ -751,7 +756,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
751756 }
752757 }
753758
754 diag.emit();
759 let guar = diag.emit();
760 if glob_error {
761 self.glob_error = Some(guar);
762 }
755763 }
756764
757765 /// Attempts to resolve the given import, returning:
compiler/rustc_resolve/src/late.rs+4-1
......@@ -4033,9 +4033,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
40334033 }
40344034
40354035 #[inline]
4036 /// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items.
4036 /// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items or
4037 // an invalid `use foo::*;` was found, which can cause unbounded ammounts of "item not found"
4038 // errors. We silence them all.
40374039 fn should_report_errs(&self) -> bool {
40384040 !(self.r.tcx.sess.opts.actually_rustdoc && self.in_func_body)
4041 && !self.r.glob_error.is_some()
40394042 }
40404043
40414044 // Resolve in alternative namespaces if resolution in the primary namespace fails.
compiler/rustc_resolve/src/lib.rs+3-1
......@@ -32,7 +32,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
3232use rustc_data_structures::intern::Interned;
3333use rustc_data_structures::steal::Steal;
3434use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
35use rustc_errors::{Applicability, Diag, ErrCode};
35use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed};
3636use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
3737use rustc_feature::BUILTIN_ATTRIBUTES;
3838use rustc_hir::def::Namespace::{self, *};
......@@ -1048,6 +1048,7 @@ pub struct Resolver<'a, 'tcx> {
10481048
10491049 /// Maps glob imports to the names of items actually imported.
10501050 glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
1051 glob_error: Option<ErrorGuaranteed>,
10511052 visibilities_for_hashing: Vec<(LocalDefId, ty::Visibility)>,
10521053 used_imports: FxHashSet<NodeId>,
10531054 maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
......@@ -1417,6 +1418,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14171418 ast_transform_scopes: FxHashMap::default(),
14181419
14191420 glob_map: Default::default(),
1421 glob_error: None,
14201422 visibilities_for_hashing: Default::default(),
14211423 used_imports: FxHashSet::default(),
14221424 maybe_unused_trait_imports: Default::default(),
compiler/rustc_session/src/config.rs+13-1
......@@ -773,6 +773,7 @@ pub enum PrintKind {
773773 TargetLibdir,
774774 CrateName,
775775 Cfg,
776 CheckCfg,
776777 CallingConventions,
777778 TargetList,
778779 TargetCPUs,
......@@ -1443,7 +1444,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
14431444 "",
14441445 "print",
14451446 "Compiler information to print on stdout",
1446 "[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
1447 "[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
14471448 target-list|target-cpus|target-features|relocation-models|code-models|\
14481449 tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
14491450 stack-protector-strategies|link-args|deployment-target]",
......@@ -1859,6 +1860,7 @@ fn collect_print_requests(
18591860 ("all-target-specs-json", PrintKind::AllTargetSpecs),
18601861 ("calling-conventions", PrintKind::CallingConventions),
18611862 ("cfg", PrintKind::Cfg),
1863 ("check-cfg", PrintKind::CheckCfg),
18621864 ("code-models", PrintKind::CodeModels),
18631865 ("crate-name", PrintKind::CrateName),
18641866 ("deployment-target", PrintKind::DeploymentTarget),
......@@ -1908,6 +1910,16 @@ fn collect_print_requests(
19081910 );
19091911 }
19101912 }
1913 Some((_, PrintKind::CheckCfg)) => {
1914 if unstable_opts.unstable_options {
1915 PrintKind::CheckCfg
1916 } else {
1917 early_dcx.early_fatal(
1918 "the `-Z unstable-options` flag must also be passed to \
1919 enable the check-cfg print option",
1920 );
1921 }
1922 }
19111923 Some(&(_, print_kind)) => print_kind,
19121924 None => {
19131925 let prints =
compiler/rustc_smir/src/rustc_internal/internal.rs+13-1
......@@ -10,7 +10,7 @@ use rustc_span::Symbol;
1010use stable_mir::abi::Layout;
1111use stable_mir::mir::alloc::AllocId;
1212use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
13use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, Safety};
13use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, Safety, UnOp};
1414use stable_mir::ty::{
1515 Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
1616 DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
......@@ -582,6 +582,18 @@ impl RustcInternal for BinOp {
582582 }
583583}
584584
585impl RustcInternal for UnOp {
586 type T<'tcx> = rustc_middle::mir::UnOp;
587
588 fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
589 match self {
590 UnOp::Not => rustc_middle::mir::UnOp::Not,
591 UnOp::Neg => rustc_middle::mir::UnOp::Neg,
592 UnOp::PtrMetadata => rustc_middle::mir::UnOp::PtrMetadata,
593 }
594 }
595}
596
585597impl<T> RustcInternal for &T
586598where
587599 T: RustcInternal,
compiler/rustc_smir/src/rustc_smir/context.rs+9-1
......@@ -19,7 +19,7 @@ use stable_mir::abi::{FnAbi, Layout, LayoutShape};
1919use stable_mir::compiler_interface::Context;
2020use stable_mir::mir::alloc::GlobalAlloc;
2121use stable_mir::mir::mono::{InstanceDef, StaticDef};
22use stable_mir::mir::{BinOp, Body, Place};
22use stable_mir::mir::{BinOp, Body, Place, UnOp};
2323use stable_mir::target::{MachineInfo, MachineSize};
2424use stable_mir::ty::{
2525 AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
......@@ -700,6 +700,14 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
700700 let ty = bin_op.internal(&mut *tables, tcx).ty(tcx, rhs_internal, lhs_internal);
701701 ty.stable(&mut *tables)
702702 }
703
704 fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty {
705 let mut tables = self.0.borrow_mut();
706 let tcx = tables.tcx;
707 let arg_internal = arg.internal(&mut *tables, tcx);
708 let ty = un_op.internal(&mut *tables, tcx).ty(tcx, arg_internal);
709 ty.stable(&mut *tables)
710 }
703711}
704712
705713pub struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
compiler/rustc_smir/src/rustc_smir/convert/mir.rs+1
......@@ -526,6 +526,7 @@ impl<'tcx> Stable<'tcx> for mir::UnOp {
526526 match self {
527527 UnOp::Not => stable_mir::mir::UnOp::Not,
528528 UnOp::Neg => stable_mir::mir::UnOp::Neg,
529 UnOp::PtrMetadata => stable_mir::mir::UnOp::PtrMetadata,
529530 }
530531 }
531532}
compiler/rustc_span/src/symbol.rs+2
......@@ -1179,6 +1179,7 @@ symbols! {
11791179 mir_make_place,
11801180 mir_move,
11811181 mir_offset,
1182 mir_ptr_metadata,
11821183 mir_retag,
11831184 mir_return,
11841185 mir_return_to,
......@@ -1433,6 +1434,7 @@ symbols! {
14331434 ptr_guaranteed_cmp,
14341435 ptr_is_null,
14351436 ptr_mask,
1437 ptr_metadata,
14361438 ptr_null,
14371439 ptr_null_mut,
14381440 ptr_offset_from,
compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs-1
......@@ -363,7 +363,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
363363 for (&orig, response) in iter::zip(original_values, var_values.var_values) {
364364 let InferOk { value: (), obligations } = infcx
365365 .at(&cause, param_env)
366 .trace(orig, response)
367366 .eq_structurally_relating_aliases(orig, response)
368367 .unwrap();
369368 assert!(obligations.is_empty());
compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs+2-6
......@@ -776,7 +776,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
776776 let InferOk { value: (), obligations } = self
777777 .infcx
778778 .at(&ObligationCause::dummy(), param_env)
779 .trace(term, ctor_term)
780779 .eq_structurally_relating_aliases(term, ctor_term)?;
781780 debug_assert!(obligations.is_empty());
782781 self.relate(param_env, alias, variance, rigid_ctor)
......@@ -796,11 +795,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
796795 rhs: T,
797796 ) -> Result<(), NoSolution> {
798797 let cause = ObligationCause::dummy();
799 let InferOk { value: (), obligations } = self
800 .infcx
801 .at(&cause, param_env)
802 .trace(lhs, rhs)
803 .eq_structurally_relating_aliases(lhs, rhs)?;
798 let InferOk { value: (), obligations } =
799 self.infcx.at(&cause, param_env).eq_structurally_relating_aliases(lhs, rhs)?;
804800 assert!(obligations.is_empty());
805801 Ok(())
806802 }
compiler/rustc_trait_selection/src/traits/fulfill.rs+5-2
......@@ -566,10 +566,13 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
566566 {
567567 if let Ok(new_obligations) = infcx
568568 .at(&obligation.cause, obligation.param_env)
569 .trace(c1, c2)
570569 // Can define opaque types as this is only reachable with
571570 // `generic_const_exprs`
572 .eq(DefineOpaqueTypes::Yes, a.args, b.args)
571 .eq(
572 DefineOpaqueTypes::Yes,
573 ty::AliasTerm::from(a),
574 ty::AliasTerm::from(b),
575 )
573576 {
574577 return ProcessResult::Changed(mk_pending(
575578 new_obligations.into_obligations(),
compiler/rustc_trait_selection/src/traits/select/mod.rs+5-2
......@@ -910,10 +910,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
910910 if let Ok(InferOk { obligations, value: () }) = self
911911 .infcx
912912 .at(&obligation.cause, obligation.param_env)
913 .trace(c1, c2)
914913 // Can define opaque types as this is only reachable with
915914 // `generic_const_exprs`
916 .eq(DefineOpaqueTypes::Yes, a.args, b.args)
915 .eq(
916 DefineOpaqueTypes::Yes,
917 ty::AliasTerm::from(a),
918 ty::AliasTerm::from(b),
919 )
917920 {
918921 return self.evaluate_predicates_recursively(
919922 previous_stack,
compiler/rustc_ty_utils/src/consts.rs+1-1
......@@ -94,7 +94,7 @@ fn check_binop(op: mir::BinOp) -> bool {
9494fn check_unop(op: mir::UnOp) -> bool {
9595 use mir::UnOp::*;
9696 match op {
97 Not | Neg => true,
97 Not | Neg | PtrMetadata => true,
9898 }
9999}
100100
compiler/stable_mir/src/compiler_interface.rs+4-1
......@@ -8,7 +8,7 @@ use std::cell::Cell;
88use crate::abi::{FnAbi, Layout, LayoutShape};
99use crate::mir::alloc::{AllocId, GlobalAlloc};
1010use crate::mir::mono::{Instance, InstanceDef, StaticDef};
11use crate::mir::{BinOp, Body, Place};
11use crate::mir::{BinOp, Body, Place, UnOp};
1212use crate::target::MachineInfo;
1313use crate::ty::{
1414 AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
......@@ -226,6 +226,9 @@ pub trait Context {
226226
227227 /// Get the resulting type of binary operation.
228228 fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty;
229
230 /// Get the resulting type of unary operation.
231 fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty;
229232}
230233
231234// A thread local variable that stores a pointer to the tables mapping between TyCtxt
compiler/stable_mir/src/mir/body.rs+13-1
......@@ -346,6 +346,15 @@ impl BinOp {
346346pub enum UnOp {
347347 Not,
348348 Neg,
349 PtrMetadata,
350}
351
352impl UnOp {
353 /// Return the type of this operation for the given input Ty.
354 /// This function does not perform type checking, and it currently doesn't handle SIMD.
355 pub fn ty(&self, arg_ty: Ty) -> Ty {
356 with(|ctx| ctx.unop_ty(*self, arg_ty))
357 }
349358}
350359
351360#[derive(Clone, Debug, Eq, PartialEq)]
......@@ -580,7 +589,10 @@ impl Rvalue {
580589 let ty = op.ty(lhs_ty, rhs_ty);
581590 Ok(Ty::new_tuple(&[ty, Ty::bool_ty()]))
582591 }
583 Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, operand) => operand.ty(locals),
592 Rvalue::UnaryOp(op, operand) => {
593 let arg_ty = operand.ty(locals)?;
594 Ok(op.ty(arg_ty))
595 }
584596 Rvalue::Discriminant(place) => {
585597 let place_ty = place.ty(locals)?;
586598 place_ty
library/core/src/intrinsics.rs+15
......@@ -2821,6 +2821,21 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
28212821 type Metadata = <P as ptr::Pointee>::Metadata;
28222822}
28232823
2824/// Lowers in MIR to `Rvalue::UnaryOp` with `UnOp::PtrMetadata`.
2825///
2826/// This is used to implement functions like `ptr::metadata`.
2827#[rustc_nounwind]
2828#[unstable(feature = "core_intrinsics", issue = "none")]
2829#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
2830#[rustc_intrinsic]
2831#[rustc_intrinsic_must_be_overridden]
2832#[cfg(not(bootstrap))]
2833pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *const P) -> M {
2834 // To implement a fallback we'd have to assume the layout of the pointer,
2835 // but the whole point of this intrinsic is that we shouldn't do that.
2836 unreachable!()
2837}
2838
28242839// Some functions are defined here because they accidentally got made
28252840// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
28262841// (`transmute` also falls into this category, but it cannot be wrapped due to the
library/core/src/intrinsics/mir.rs+4
......@@ -360,6 +360,10 @@ define!("mir_assume", fn Assume(operand: bool));
360360define!("mir_deinit", fn Deinit<T>(place: T));
361361define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
362362define!("mir_len", fn Len<T>(place: T) -> usize);
363define!(
364 "mir_ptr_metadata",
365 fn PtrMetadata<P: ?Sized>(place: *const P) -> <P as ::core::ptr::Pointee>::Metadata
366);
363367define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T);
364368define!("mir_retag", fn Retag<T>(place: T));
365369define!("mir_move", fn Move<T>(place: T) -> T);
library/core/src/ptr/metadata.rs+17-4
......@@ -3,6 +3,8 @@
33use crate::fmt;
44use crate::hash::{Hash, Hasher};
55use crate::intrinsics::aggregate_raw_ptr;
6#[cfg(not(bootstrap))]
7use crate::intrinsics::ptr_metadata;
68use crate::marker::Freeze;
79
810/// Provides the pointer metadata type of any pointed-to type.
......@@ -94,10 +96,17 @@ pub trait Thin = Pointee<Metadata = ()>;
9496#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
9597#[inline]
9698pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
97 // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
98 // and PtrComponents<T> have the same memory layouts. Only std can make this
99 // guarantee.
100 unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
99 #[cfg(bootstrap)]
100 {
101 // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
102 // and PtrComponents<T> have the same memory layouts. Only std can make this
103 // guarantee.
104 unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
105 }
106 #[cfg(not(bootstrap))]
107 {
108 ptr_metadata(ptr)
109 }
101110}
102111
103112/// Forms a (possibly-wide) raw pointer from a data pointer and metadata.
......@@ -132,6 +141,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
132141}
133142
134143#[repr(C)]
144#[cfg(bootstrap)]
135145union PtrRepr<T: ?Sized> {
136146 const_ptr: *const T,
137147 mut_ptr: *mut T,
......@@ -139,15 +149,18 @@ union PtrRepr<T: ?Sized> {
139149}
140150
141151#[repr(C)]
152#[cfg(bootstrap)]
142153struct PtrComponents<T: ?Sized> {
143154 data_pointer: *const (),
144155 metadata: <T as Pointee>::Metadata,
145156}
146157
147158// Manual impl needed to avoid `T: Copy` bound.
159#[cfg(bootstrap)]
148160impl<T: ?Sized> Copy for PtrComponents<T> {}
149161
150162// Manual impl needed to avoid `T: Clone` bound.
163#[cfg(bootstrap)]
151164impl<T: ?Sized> Clone for PtrComponents<T> {
152165 fn clone(&self) -> Self {
153166 *self
library/core/tests/ptr.rs+12
......@@ -1171,3 +1171,15 @@ fn test_ptr_from_raw_parts_in_const() {
11711171 assert_eq!(EMPTY_SLICE_PTR.addr(), 123);
11721172 assert_eq!(EMPTY_SLICE_PTR.len(), 456);
11731173}
1174
1175#[test]
1176fn test_ptr_metadata_in_const() {
1177 use std::fmt::Debug;
1178
1179 const ARRAY_META: () = std::ptr::metadata::<[u16; 3]>(&[1, 2, 3]);
1180 const SLICE_META: usize = std::ptr::metadata::<[u16]>(&[1, 2, 3]);
1181 const DYN_META: DynMetadata<dyn Debug> = std::ptr::metadata::<dyn Debug>(&[0_u8; 42]);
1182 assert_eq!(ARRAY_META, ());
1183 assert_eq!(SLICE_META, 3);
1184 assert_eq!(DYN_META.size_of(), 42);
1185}
library/std/src/fs/tests.rs+1-1
......@@ -1431,7 +1431,7 @@ fn metadata_access_times() {
14311431 assert_eq!(check!(a.modified()), check!(a.modified()));
14321432 assert_eq!(check!(b.accessed()), check!(b.modified()));
14331433
1434 if cfg!(target_os = "macos") || cfg!(target_os = "windows") {
1434 if cfg!(target_vendor = "apple") || cfg!(target_os = "windows") {
14351435 check!(a.created());
14361436 check!(b.created());
14371437 }
library/std/src/sys/pal/unix/stack_overflow.rs+8
......@@ -491,6 +491,14 @@ mod imp {
491491 }
492492}
493493
494// This is intentionally not enabled on iOS/tvOS/watchOS/visionOS, as it uses
495// several symbols that might lead to rejections from the App Store, namely
496// `sigaction`, `sigaltstack`, `sysctlbyname`, `mmap`, `munmap` and `mprotect`.
497//
498// This might be overly cautious, though it is also what Swift does (and they
499// usually have fewer qualms about forwards compatibility, since the runtime
500// is shipped with the OS):
501// <https://github.com/apple/swift/blob/swift-5.10-RELEASE/stdlib/public/runtime/CrashHandlerMacOS.cpp>
494502#[cfg(not(any(
495503 target_os = "linux",
496504 target_os = "freebsd",
src/bootstrap/src/core/build_steps/doc.rs+8
......@@ -1028,6 +1028,14 @@ tool_doc!(
10281028 is_library = true,
10291029 crates = ["bootstrap"]
10301030);
1031tool_doc!(
1032 RunMakeSupport,
1033 "run_make_support",
1034 "src/tools/run-make-support",
1035 rustc_tool = false,
1036 is_library = true,
1037 crates = ["run_make_support"]
1038);
10311039
10321040#[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)]
10331041pub struct ErrorIndex {
src/bootstrap/src/core/builder.rs+1
......@@ -888,6 +888,7 @@ impl<'a> Builder<'a> {
888888 doc::Tidy,
889889 doc::Bootstrap,
890890 doc::Releases,
891 doc::RunMakeSupport,
891892 ),
892893 Kind::Dist => describe!(
893894 dist::Docs,
src/bootstrap/src/utils/dylib.rs+1-1
......@@ -5,7 +5,7 @@
55pub fn dylib_path_var() -> &'static str {
66 if cfg!(target_os = "windows") {
77 "PATH"
8 } else if cfg!(target_os = "macos") {
8 } else if cfg!(target_vendor = "apple") {
99 "DYLD_LIBRARY_PATH"
1010 } else if cfg!(target_os = "haiku") {
1111 "LIBRARY_PATH"
src/doc/unstable-book/src/compiler-flags/print-check-cfg.md created+25
......@@ -0,0 +1,25 @@
1# `print=check-cfg`
2
3The tracking issue for this feature is: [#XXXXXX](https://github.com/rust-lang/rust/issues/XXXXXX).
4
5------------------------
6
7This option of the `--print` flag print the list of expected cfgs.
8
9This is related to the `--check-cfg` flag which allows specifying arbitrary expected
10names and values.
11
12This print option works similarly to `--print=cfg` (modulo check-cfg specifics):
13 - *check_cfg syntax*: *output of --print=check-cfg*
14 - `cfg(windows)`: `windows`
15 - `cfg(feature, values("foo", "bar"))`: `feature="foo"` and `feature="bar"`
16 - `cfg(feature, values(none(), ""))`: `feature` and `feature=""`
17 - `cfg(feature, values(any()))`: `feature=any()`
18 - `cfg(any())`: `any()`
19 - *nothing*: `any()=any()`
20
21To be used like this:
22
23```bash
24rustc --print=check-cfg -Zunstable-options lib.rs
25```
src/tools/compiletest/src/header.rs+2-1
......@@ -747,6 +747,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
747747 "ignore-aarch64",
748748 "ignore-aarch64-unknown-linux-gnu",
749749 "ignore-android",
750 "ignore-apple",
750751 "ignore-arm",
751752 "ignore-avr",
752753 "ignore-beta",
......@@ -829,7 +830,6 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
829830 "ignore-x32",
830831 "ignore-x86",
831832 "ignore-x86_64",
832 "ignore-x86_64-apple-darwin",
833833 "ignore-x86_64-unknown-linux-gnu",
834834 "incremental",
835835 "known-bug",
......@@ -876,6 +876,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
876876 "only-32bit",
877877 "only-64bit",
878878 "only-aarch64",
879 "only-apple",
879880 "only-arm",
880881 "only-avr",
881882 "only-beta",
src/tools/compiletest/src/header/cfg.rs+6
......@@ -159,6 +159,12 @@ pub(super) fn parse_cfg_name_directive<'a>(
159159 message: "when the architecture is part of the Thumb family"
160160 }
161161
162 condition! {
163 name: "apple",
164 condition: config.target.contains("apple"),
165 message: "when the target vendor is Apple"
166 }
167
162168 // Technically the locally built compiler uses the "dev" channel rather than the "nightly"
163169 // channel, even though most people don't know or won't care about it. To avoid confusion, we
164170 // treat the "dev" channel as the "nightly" channel when processing the directive.
src/tools/compiletest/src/runtest.rs+1-1
......@@ -98,7 +98,7 @@ fn get_lib_name(lib: &str, aux_type: AuxType) -> Option<String> {
9898 AuxType::Lib => Some(format!("lib{}.rlib", lib)),
9999 AuxType::Dylib => Some(if cfg!(windows) {
100100 format!("{}.dll", lib)
101 } else if cfg!(target_os = "macos") {
101 } else if cfg!(target_vendor = "apple") {
102102 format!("lib{}.dylib", lib)
103103 } else {
104104 format!("lib{}.so", lib)
src/tools/compiletest/src/util.rs+1-1
......@@ -57,7 +57,7 @@ impl PathBufExt for PathBuf {
5757pub fn dylib_env_var() -> &'static str {
5858 if cfg!(windows) {
5959 "PATH"
60 } else if cfg!(target_os = "macos") {
60 } else if cfg!(target_vendor = "apple") {
6161 "DYLD_LIBRARY_PATH"
6262 } else if cfg!(target_os = "haiku") {
6363 "LIBRARY_PATH"
src/tools/miri/src/concurrency/thread.rs+7-6
......@@ -862,14 +862,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
862862 if tcx.is_foreign_item(def_id) {
863863 throw_unsup_format!("foreign thread-local statics are not supported");
864864 }
865 let allocation = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
866 let mut allocation = allocation.inner().clone();
865 let alloc = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
866 // We make a full copy of this allocation.
867 let mut alloc = alloc.inner().adjust_from_tcx(&this.tcx, |ptr| this.global_root_pointer(ptr))?;
867868 // This allocation will be deallocated when the thread dies, so it is not in read-only memory.
868 allocation.mutability = Mutability::Mut;
869 alloc.mutability = Mutability::Mut;
869870 // Create a fresh allocation with this content.
870 let new_alloc = this.allocate_raw_ptr(allocation, MiriMemoryKind::Tls.into())?;
871 this.machine.threads.set_thread_local_alloc(def_id, new_alloc);
872 Ok(new_alloc)
871 let ptr = this.allocate_raw_ptr(alloc, MiriMemoryKind::Tls.into())?;
872 this.machine.threads.set_thread_local_alloc(def_id, ptr);
873 Ok(ptr)
873874 }
874875 }
875876
src/tools/miri/src/machine.rs+12-31
......@@ -1,7 +1,6 @@
11//! Global machine state as well as implementation of the interpreter engine
22//! `Machine` trait.
33
4use std::borrow::Cow;
54use std::cell::RefCell;
65use std::collections::hash_map::Entry;
76use std::fmt;
......@@ -1086,40 +1085,33 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
10861085 }
10871086 }
10881087
1089 fn adjust_allocation<'b>(
1088 fn init_alloc_extra(
10901089 ecx: &MiriInterpCx<'tcx>,
10911090 id: AllocId,
1092 alloc: Cow<'b, Allocation>,
1093 kind: Option<MemoryKind>,
1094 ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
1095 {
1096 let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
1091 kind: MemoryKind,
1092 size: Size,
1093 align: Align,
1094 ) -> InterpResult<'tcx, Self::AllocExtra> {
10971095 if ecx.machine.tracked_alloc_ids.contains(&id) {
1098 ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
1099 id,
1100 alloc.size(),
1101 alloc.align,
1102 kind,
1103 ));
1096 ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id, size, align, kind));
11041097 }
11051098
1106 let alloc = alloc.into_owned();
11071099 let borrow_tracker = ecx
11081100 .machine
11091101 .borrow_tracker
11101102 .as_ref()
1111 .map(|bt| bt.borrow_mut().new_allocation(id, alloc.size(), kind, &ecx.machine));
1103 .map(|bt| bt.borrow_mut().new_allocation(id, size, kind, &ecx.machine));
11121104
1113 let race_alloc = ecx.machine.data_race.as_ref().map(|data_race| {
1105 let data_race = ecx.machine.data_race.as_ref().map(|data_race| {
11141106 data_race::AllocState::new_allocation(
11151107 data_race,
11161108 &ecx.machine.threads,
1117 alloc.size(),
1109 size,
11181110 kind,
11191111 ecx.machine.current_span(),
11201112 )
11211113 });
1122 let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
1114 let weak_memory = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
11231115
11241116 // If an allocation is leaked, we want to report a backtrace to indicate where it was
11251117 // allocated. We don't need to record a backtrace for allocations which are allowed to
......@@ -1130,17 +1122,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
11301122 Some(ecx.generate_stacktrace())
11311123 };
11321124
1133 let alloc: Allocation<Provenance, Self::AllocExtra, Self::Bytes> = alloc.adjust_from_tcx(
1134 &ecx.tcx,
1135 AllocExtra {
1136 borrow_tracker,
1137 data_race: race_alloc,
1138 weak_memory: buffer_alloc,
1139 backtrace,
1140 },
1141 |ptr| ecx.global_root_pointer(ptr),
1142 )?;
1143
11441125 if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
11451126 ecx.machine
11461127 .allocation_spans
......@@ -1148,7 +1129,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
11481129 .insert(id, (ecx.machine.current_span(), None));
11491130 }
11501131
1151 Ok(Cow::Owned(alloc))
1132 Ok(AllocExtra { borrow_tracker, data_race, weak_memory, backtrace })
11521133 }
11531134
11541135 fn adjust_alloc_root_pointer(
......@@ -1357,7 +1338,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
13571338 }
13581339
13591340 #[inline(always)]
1360 fn init_frame_extra(
1341 fn init_frame(
13611342 ecx: &mut InterpCx<'tcx, Self>,
13621343 frame: Frame<'tcx, Provenance>,
13631344 ) -> InterpResult<'tcx, Frame<'tcx, Provenance, FrameExtra<'tcx>>> {
src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs created+22
......@@ -0,0 +1,22 @@
1//@compile-flags: -Zmiri-disable-validation
2#![feature(core_intrinsics, custom_mir)]
3use std::intrinsics::mir::*;
4
5// This disables validation and uses custom MIR hit exactly the UB in the intrinsic,
6// rather than getting UB from the typed load or parameter passing.
7
8#[custom_mir(dialect = "runtime")]
9pub unsafe fn deref_meta(p: *const *const [i32]) -> usize {
10 mir!({
11 RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data
12 Return()
13 })
14}
15
16fn main() {
17 let mut p = std::mem::MaybeUninit::<*const [i32]>::uninit();
18 unsafe {
19 (*p.as_mut_ptr().cast::<[usize; 2]>())[1] = 4;
20 let _meta = deref_meta(p.as_ptr().cast());
21 }
22}
src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr created+20
......@@ -0,0 +1,20 @@
1error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
2 --> $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC
3 |
4LL | RET = PtrMetadata(*p);
5 | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
6 |
7 = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8 = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9 = note: BACKTRACE:
10 = note: inside `deref_meta` at $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC
11note: inside `main`
12 --> $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC
13 |
14LL | let _meta = deref_meta(p.as_ptr().cast());
15 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16
17note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
18
19error: aborting due to 1 previous error
20
src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs created+22
......@@ -0,0 +1,22 @@
1//@compile-flags: -Zmiri-disable-validation
2#![feature(core_intrinsics, custom_mir)]
3use std::intrinsics::mir::*;
4
5// This disables validation and uses custom MIR hit exactly the UB in the intrinsic,
6// rather than getting UB from the typed load or parameter passing.
7
8#[custom_mir(dialect = "runtime")]
9pub unsafe fn deref_meta(p: *const *const [i32]) -> usize {
10 mir!({
11 RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data
12 Return()
13 })
14}
15
16fn main() {
17 let mut p = std::mem::MaybeUninit::<*const [i32]>::uninit();
18 unsafe {
19 (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32;
20 let _meta = deref_meta(p.as_ptr().cast());
21 }
22}
src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr created+35
......@@ -0,0 +1,35 @@
1warning: integer-to-pointer cast
2 --> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
3 |
4LL | (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
6 |
7 = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`,
8 = help: which means that Miri might miss pointer bugs in this program.
9 = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
10 = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead.
11 = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics.
12 = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning.
13 = note: BACKTRACE:
14 = note: inside `main` at $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
15
16error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
17 --> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
18 |
19LL | RET = PtrMetadata(*p);
20 | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
21 |
22 = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
23 = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
24 = note: BACKTRACE:
25 = note: inside `deref_meta` at $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
26note: inside `main`
27 --> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
28 |
29LL | let _meta = deref_meta(p.as_ptr().cast());
30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31
32note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
33
34error: aborting due to 1 previous error; 1 warning emitted
35
src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.rs created+23
......@@ -0,0 +1,23 @@
1//@compile-flags: -Zmiri-disable-validation
2#![feature(core_intrinsics, custom_mir)]
3use std::intrinsics::mir::*;
4
5// This disables validation and uses custom MIR hit exactly the UB in the intrinsic,
6// rather than getting UB from the typed load or parameter passing.
7
8#[custom_mir(dialect = "runtime")]
9pub unsafe fn deref_meta(p: *const *const i32) -> () {
10 mir!({
11 RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data
12 Return()
13 })
14}
15
16fn main() {
17 // Even though the meta is the trivially-valid `()`, this is still UB
18
19 let p = std::mem::MaybeUninit::<*const i32>::uninit();
20 unsafe {
21 let _meta = deref_meta(p.as_ptr());
22 }
23}
src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr created+20
......@@ -0,0 +1,20 @@
1error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
2 --> $DIR/ptr_metadata_uninit_thin.rs:LL:CC
3 |
4LL | RET = PtrMetadata(*p);
5 | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
6 |
7 = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8 = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9 = note: BACKTRACE:
10 = note: inside `deref_meta` at $DIR/ptr_metadata_uninit_thin.rs:LL:CC
11note: inside `main`
12 --> $DIR/ptr_metadata_uninit_thin.rs:LL:CC
13 |
14LL | let _meta = deref_meta(p.as_ptr());
15 | ^^^^^^^^^^^^^^^^^^^^^^
16
17note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
18
19error: aborting due to 1 previous error
20
src/tools/miri/tests/pass/intrinsics/intrinsics.rs+7-1
......@@ -1,5 +1,5 @@
11//@compile-flags: -Zmiri-permissive-provenance
2#![feature(core_intrinsics, layout_for_ptr)]
2#![feature(core_intrinsics, layout_for_ptr, ptr_metadata)]
33//! Tests for various intrinsics that do not fit anywhere else.
44
55use std::intrinsics;
......@@ -57,4 +57,10 @@ fn main() {
5757 // Make sure that even if the discriminant is stored together with data, the intrinsic returns
5858 // only the discriminant, nothing about the data.
5959 assert_eq!(discriminant(&Some(false)), discriminant(&Some(true)));
60
61 let () = intrinsics::ptr_metadata(&[1, 2, 3]);
62 let len = intrinsics::ptr_metadata(&[1, 2, 3][..]);
63 assert_eq!(len, 3);
64 let dyn_meta = intrinsics::ptr_metadata(&[1, 2, 3] as &dyn std::fmt::Debug);
65 assert_eq!(dyn_meta.size_of(), 12);
6066}
src/tools/run-make-support/src/lib.rs+1-1
......@@ -362,7 +362,7 @@ macro_rules! impl_common_helpers {
362362 self
363363 }
364364
365 /// Inspect what the underlying [`Command`][::std::process::Command] is up to the
365 /// Inspect what the underlying [`Command`] is up to the
366366 /// current construction.
367367 pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
368368 where
src/tools/run-make-support/src/rustc.rs+1-1
......@@ -203,7 +203,7 @@ impl Rustc {
203203 self
204204 }
205205
206 /// Get the [`Output`][::std::process::Output] of the finished process.
206 /// Get the [`Output`] of the finished process.
207207 #[track_caller]
208208 pub fn command_output(&mut self) -> ::std::process::Output {
209209 // let's make sure we piped all the input and outputs
src/tools/run-make-support/src/rustdoc.rs+1-1
......@@ -94,7 +94,7 @@ impl Rustdoc {
9494 self
9595 }
9696
97 /// Get the [`Output`][::std::process::Output] of the finished process.
97 /// Get the [`Output`] of the finished process.
9898 #[track_caller]
9999 pub fn command_output(&mut self) -> ::std::process::Output {
100100 // let's make sure we piped all the input and outputs
src/tools/tidy/src/allowed_run_make_makefiles.txt-3
......@@ -144,7 +144,6 @@ run-make/lto-linkage-used-attr/Makefile
144144run-make/lto-no-link-whole-rlib/Makefile
145145run-make/lto-readonly-lib/Makefile
146146run-make/lto-smoke-c/Makefile
147run-make/lto-smoke/Makefile
148147run-make/macos-deployment-target/Makefile
149148run-make/macos-fat-archive/Makefile
150149run-make/manual-crate-name/Makefile
......@@ -156,7 +155,6 @@ run-make/min-global-align/Makefile
156155run-make/mingw-export-call-convention/Makefile
157156run-make/mismatching-target-triples/Makefile
158157run-make/missing-crate-dependency/Makefile
159run-make/mixing-deps/Makefile
160158run-make/mixing-formats/Makefile
161159run-make/mixing-libs/Makefile
162160run-make/msvc-opt-minsize/Makefile
......@@ -238,7 +236,6 @@ run-make/short-ice/Makefile
238236run-make/silly-file-names/Makefile
239237run-make/simd-ffi/Makefile
240238run-make/simple-dylib/Makefile
241run-make/simple-rlib/Makefile
242239run-make/split-debuginfo/Makefile
243240run-make/stable-symbol-names/Makefile
244241run-make/static-dylib-by-default/Makefile
src/tools/tidy/src/issues.txt-1
......@@ -2122,7 +2122,6 @@ ui/issues/issue-33687.rs
21222122ui/issues/issue-33770.rs
21232123ui/issues/issue-3389.rs
21242124ui/issues/issue-33941.rs
2125ui/issues/issue-33992.rs
21262125ui/issues/issue-34047.rs
21272126ui/issues/issue-34074.rs
21282127ui/issues/issue-34209.rs
src/tools/tidy/src/ui_tests.rs+1-1
......@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
1515const ENTRY_LIMIT: u32 = 900;
1616// FIXME: The following limits should be reduced eventually.
1717
18const ISSUES_ENTRY_LIMIT: u32 = 1676;
18const ISSUES_ENTRY_LIMIT: u32 = 1674;
1919
2020const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
2121 "rs", // test source files
tests/assembly/stack-protector/stack-protector-heuristics-effect.rs+1-4
......@@ -1,6 +1,6 @@
11//@ revisions: all strong basic none missing
22//@ assembly-output: emit-asm
3//@ ignore-macos slightly different policy on stack protection of arrays
3//@ ignore-apple slightly different policy on stack protection of arrays
44//@ ignore-msvc stack check code uses different function names
55//@ ignore-nvptx64 stack protector is not supported
66//@ ignore-wasm32-bare
......@@ -17,12 +17,9 @@
1717// See comments on https://github.com/rust-lang/rust/issues/114903.
1818
1919#![crate_type = "lib"]
20
2120#![allow(incomplete_features)]
22
2321#![feature(unsized_locals, unsized_fn_params)]
2422
25
2623// CHECK-LABEL: emptyfn:
2724#[no_mangle]
2825pub fn emptyfn() {
tests/assembly/x86_64-array-pair-load-store-merge.rs+1-1
......@@ -2,7 +2,7 @@
22//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
33//@ only-x86_64
44//@ ignore-sgx
5//@ ignore-macos (manipulates rsp too)
5//@ ignore-apple (manipulates rsp too)
66
77// Depending on various codegen choices, this might end up copying
88// a `<2 x i8>`, an `i16`, or two `i8`s.
tests/assembly/x86_64-function-return.rs+1-1
......@@ -9,7 +9,7 @@
99//@ [keep-thunk-extern] compile-flags: -Zfunction-return=keep -Zfunction-return=thunk-extern
1010//@ [thunk-extern-keep] compile-flags: -Zfunction-return=thunk-extern -Zfunction-return=keep
1111//@ only-x86_64
12//@ ignore-x86_64-apple-darwin Symbol is called `___x86_return_thunk` (Darwin's extra underscore)
12//@ ignore-apple Symbol is called `___x86_return_thunk` (Darwin's extra underscore)
1313//@ ignore-sgx Tests incompatible with LVI mitigations
1414
1515#![crate_type = "lib"]
tests/codegen/gdb_debug_script_load.rs+1-1
......@@ -1,6 +1,6 @@
11//
22//@ ignore-windows
3//@ ignore-macos
3//@ ignore-apple
44//@ ignore-wasm
55//@ ignore-emscripten
66
tests/codegen/instrument-coverage/testprog.rs+2-2
......@@ -11,7 +11,7 @@
1111//@ [LINUX] filecheck-flags: -DINSTR_PROF_COVFUN=__llvm_covfun
1212//@ [LINUX] filecheck-flags: '-DCOMDAT_IF_SUPPORTED=, comdat'
1313
14//@ [DARWIN] only-macos
14//@ [DARWIN] only-apple
1515//@ [DARWIN] filecheck-flags: -DINSTR_PROF_DATA=__DATA,__llvm_prf_data,regular,live_support
1616//@ [DARWIN] filecheck-flags: -DINSTR_PROF_NAME=__DATA,__llvm_prf_names
1717//@ [DARWIN] filecheck-flags: -DINSTR_PROF_CNTS=__DATA,__llvm_prf_cnts
......@@ -49,7 +49,7 @@ where
4949
5050pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F)
5151where
52 F: FnOnce(&T)
52 F: FnOnce(&T),
5353{
5454 if should_wrap {
5555 wrapper(&inner)
tests/codegen/intrinsics/ptr_metadata.rs created+36
......@@ -0,0 +1,36 @@
1//@ compile-flags: -O -C no-prepopulate-passes -Z inline-mir
2//@ only-64bit (so I don't need to worry about usize)
3
4#![crate_type = "lib"]
5#![feature(core_intrinsics)]
6
7use std::intrinsics::ptr_metadata;
8
9// CHECK-LABEL: @thin_metadata(
10#[no_mangle]
11pub fn thin_metadata(p: *const ()) {
12 // CHECK: start
13 // CHECK-NEXT: ret void
14 ptr_metadata(p)
15}
16
17// CHECK-LABEL: @slice_metadata(
18#[no_mangle]
19pub fn slice_metadata(p: *const [u8]) -> usize {
20 // CHECK: start
21 // CHECK-NEXT: ret i64 %p.1
22 ptr_metadata(p)
23}
24
25// CHECK-LABEL: @dyn_byte_offset(
26#[no_mangle]
27pub unsafe fn dyn_byte_offset(
28 p: *const dyn std::fmt::Debug,
29 n: usize,
30) -> *const dyn std::fmt::Debug {
31 // CHECK: %[[Q:.+]] = getelementptr inbounds i8, ptr %p.0, i64 %n
32 // CHECK: %[[TEMP1:.+]] = insertvalue { ptr, ptr } poison, ptr %[[Q]], 0
33 // CHECK: %[[TEMP2:.+]] = insertvalue { ptr, ptr } %[[TEMP1]], ptr %p.1, 1
34 // CHECK: ret { ptr, ptr } %[[TEMP2]]
35 p.byte_add(n)
36}
tests/codegen/issues/issue-44056-macos-tls-align.rs+1-1
......@@ -1,5 +1,5 @@
11//
2//@ only-macos
2//@ only-apple
33//@ compile-flags: -O
44
55#![crate_type = "rlib"]
tests/codegen/mainsubprogram.rs+2-3
......@@ -2,7 +2,7 @@
22// before 4.0, formerly backported to the Rust LLVM fork.
33
44//@ ignore-windows
5//@ ignore-macos
5//@ ignore-apple
66//@ ignore-wasi
77
88//@ compile-flags: -g -C no-prepopulate-passes
......@@ -10,5 +10,4 @@
1010// CHECK-LABEL: @main
1111// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DI{{(SP)?}}FlagMainSubprogram{{.*}}
1212
13pub fn main() {
14}
13pub fn main() {}
tests/codegen/mainsubprogramstart.rs+1-1
......@@ -1,5 +1,5 @@
11//@ ignore-windows
2//@ ignore-macos
2//@ ignore-apple
33//@ ignore-wasi wasi codegens the main symbol differently
44
55//@ compile-flags: -g -C no-prepopulate-passes
tests/codegen/pgo-counter-bias.rs+1-1
......@@ -1,6 +1,6 @@
11// Test that __llvm_profile_counter_bias does not get internalized by lto.
22
3//@ ignore-macos -runtime-counter-relocation not honored on Mach-O
3//@ ignore-apple -runtime-counter-relocation not honored on Mach-O
44//@ compile-flags: -Cprofile-generate -Cllvm-args=-runtime-counter-relocation -Clto=fat
55//@ needs-profiler-support
66//@ no-prefer-dynamic
tests/mir-opt/building/custom/operators.g.runtime.after.mir created+13
......@@ -0,0 +1,13 @@
1// MIR for `g` after runtime
2
3fn g(_1: *const i32, _2: *const [i32]) -> () {
4 let mut _0: ();
5 let mut _3: ();
6 let mut _4: usize;
7
8 bb0: {
9 _3 = PtrMetadata(_1);
10 _4 = PtrMetadata(_2);
11 return;
12 }
13}
tests/mir-opt/building/custom/operators.rs+10
......@@ -30,3 +30,13 @@ pub fn f(a: i32, b: bool) -> i32 {
3030 Return()
3131 })
3232}
33
34// EMIT_MIR operators.g.runtime.after.mir
35#[custom_mir(dialect = "runtime")]
36pub fn g(p: *const i32, q: *const [i32]) {
37 mir!({
38 let a = PtrMetadata(p);
39 let b = PtrMetadata(q);
40 Return()
41 })
42}
tests/mir-opt/lower_intrinsics.get_metadata.LowerIntrinsics.panic-abort.diff created+63
......@@ -0,0 +1,63 @@
1- // MIR for `get_metadata` before LowerIntrinsics
2+ // MIR for `get_metadata` after LowerIntrinsics
3
4 fn get_metadata(_1: *const i32, _2: *const [u8], _3: *const dyn Debug) -> () {
5 debug a => _1;
6 debug b => _2;
7 debug c => _3;
8 let mut _0: ();
9 let _4: ();
10 let mut _5: *const i32;
11 let mut _7: *const [u8];
12 let mut _9: *const dyn std::fmt::Debug;
13 scope 1 {
14 debug _unit => _4;
15 let _6: usize;
16 scope 2 {
17 debug _usize => _6;
18 let _8: std::ptr::DynMetadata<dyn std::fmt::Debug>;
19 scope 3 {
20 debug _vtable => _8;
21 }
22 }
23 }
24
25 bb0: {
26 StorageLive(_4);
27 StorageLive(_5);
28 _5 = _1;
29- _4 = ptr_metadata::<i32, ()>(move _5) -> [return: bb1, unwind unreachable];
30+ _4 = PtrMetadata(move _5);
31+ goto -> bb1;
32 }
33
34 bb1: {
35 StorageDead(_5);
36 StorageLive(_6);
37 StorageLive(_7);
38 _7 = _2;
39- _6 = ptr_metadata::<[u8], usize>(move _7) -> [return: bb2, unwind unreachable];
40+ _6 = PtrMetadata(move _7);
41+ goto -> bb2;
42 }
43
44 bb2: {
45 StorageDead(_7);
46 StorageLive(_8);
47 StorageLive(_9);
48 _9 = _3;
49- _8 = ptr_metadata::<dyn Debug, DynMetadata<dyn Debug>>(move _9) -> [return: bb3, unwind unreachable];
50+ _8 = PtrMetadata(move _9);
51+ goto -> bb3;
52 }
53
54 bb3: {
55 StorageDead(_9);
56 _0 = const ();
57 StorageDead(_8);
58 StorageDead(_6);
59 StorageDead(_4);
60 return;
61 }
62 }
63
tests/mir-opt/lower_intrinsics.get_metadata.LowerIntrinsics.panic-unwind.diff created+63
......@@ -0,0 +1,63 @@
1- // MIR for `get_metadata` before LowerIntrinsics
2+ // MIR for `get_metadata` after LowerIntrinsics
3
4 fn get_metadata(_1: *const i32, _2: *const [u8], _3: *const dyn Debug) -> () {
5 debug a => _1;
6 debug b => _2;
7 debug c => _3;
8 let mut _0: ();
9 let _4: ();
10 let mut _5: *const i32;
11 let mut _7: *const [u8];
12 let mut _9: *const dyn std::fmt::Debug;
13 scope 1 {
14 debug _unit => _4;
15 let _6: usize;
16 scope 2 {
17 debug _usize => _6;
18 let _8: std::ptr::DynMetadata<dyn std::fmt::Debug>;
19 scope 3 {
20 debug _vtable => _8;
21 }
22 }
23 }
24
25 bb0: {
26 StorageLive(_4);
27 StorageLive(_5);
28 _5 = _1;
29- _4 = ptr_metadata::<i32, ()>(move _5) -> [return: bb1, unwind unreachable];
30+ _4 = PtrMetadata(move _5);
31+ goto -> bb1;
32 }
33
34 bb1: {
35 StorageDead(_5);
36 StorageLive(_6);
37 StorageLive(_7);
38 _7 = _2;
39- _6 = ptr_metadata::<[u8], usize>(move _7) -> [return: bb2, unwind unreachable];
40+ _6 = PtrMetadata(move _7);
41+ goto -> bb2;
42 }
43
44 bb2: {
45 StorageDead(_7);
46 StorageLive(_8);
47 StorageLive(_9);
48 _9 = _3;
49- _8 = ptr_metadata::<dyn Debug, DynMetadata<dyn Debug>>(move _9) -> [return: bb3, unwind unreachable];
50+ _8 = PtrMetadata(move _9);
51+ goto -> bb3;
52 }
53
54 bb3: {
55 StorageDead(_9);
56 _0 = const ();
57 StorageDead(_8);
58 StorageDead(_6);
59 StorageDead(_4);
60 return;
61 }
62 }
63
tests/mir-opt/lower_intrinsics.rs+9
......@@ -258,3 +258,12 @@ pub fn make_pointers(a: *const u8, b: *mut (), n: usize) {
258258 let _slice_const: *const [u16] = aggregate_raw_ptr(a, n);
259259 let _slice_mut: *mut [u64] = aggregate_raw_ptr(b, n);
260260}
261
262// EMIT_MIR lower_intrinsics.get_metadata.LowerIntrinsics.diff
263pub fn get_metadata(a: *const i32, b: *const [u8], c: *const dyn std::fmt::Debug) {
264 use std::intrinsics::ptr_metadata;
265
266 let _unit = ptr_metadata(a);
267 let _usize = ptr_metadata(b);
268 let _vtable = ptr_metadata(c);
269}
tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir+3-7
......@@ -13,9 +13,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
1313 }
1414 scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
1515 let mut _5: *const ();
16 let mut _7: usize;
16 let mut _6: usize;
1717 scope 5 (inlined std::ptr::metadata::<[u32]>) {
18 let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
1918 }
2019 scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
2120 }
......@@ -30,13 +29,10 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
3029 StorageDead(_3);
3130 StorageLive(_5);
3231 _5 = _4 as *const () (PtrToPtr);
33 StorageLive(_7);
3432 StorageLive(_6);
35 _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
36 _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
33 _6 = PtrMetadata(_1);
34 _0 = *const [u32] from (_5, _6);
3735 StorageDead(_6);
38 _0 = *const [u32] from (_5, _7);
39 StorageDead(_7);
4036 StorageDead(_5);
4137 StorageDead(_4);
4238 return;
tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir+3-7
......@@ -13,9 +13,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
1313 }
1414 scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
1515 let mut _5: *const ();
16 let mut _7: usize;
16 let mut _6: usize;
1717 scope 5 (inlined std::ptr::metadata::<[u32]>) {
18 let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
1918 }
2019 scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
2120 }
......@@ -30,13 +29,10 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
3029 StorageDead(_3);
3130 StorageLive(_5);
3231 _5 = _4 as *const () (PtrToPtr);
33 StorageLive(_7);
3432 StorageLive(_6);
35 _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
36 _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
33 _6 = PtrMetadata(_1);
34 _0 = *const [u32] from (_5, _6);
3735 StorageDead(_6);
38 _0 = *const [u32] from (_5, _7);
39 StorageDead(_7);
4036 StorageDead(_5);
4137 StorageDead(_4);
4238 return;
tests/run-make/c-dynamic-dylib/Makefile+1-1
......@@ -4,7 +4,7 @@
44# ignore-cross-compile
55include ../tools.mk
66
7# ignore-macos
7# ignore-apple
88#
99# This hits an assertion in the linker on older versions of osx apparently
1010
tests/run-make/c-dynamic-rlib/Makefile+1-1
......@@ -4,7 +4,7 @@
44# ignore-cross-compile
55include ../tools.mk
66
7# ignore-macos
7# ignore-apple
88#
99# This hits an assertion in the linker on older versions of osx apparently
1010
tests/run-make/emit-stack-sizes/Makefile+2-2
......@@ -1,10 +1,10 @@
11include ../tools.mk
22
33# ignore-windows
4# ignore-macos
4# ignore-apple
55#
66# This feature only works when the output object format is ELF so we ignore
7# macOS and Windows
7# Apple and Windows
88
99# check that the .stack_sizes section is generated
1010all:
tests/run-make/fpic/Makefile+1-1
......@@ -2,7 +2,7 @@
22include ../tools.mk
33
44# ignore-windows
5# ignore-macos
5# ignore-apple
66
77# Test for #39529.
88# `-z text` causes ld to error if there are any non-PIC sections
tests/run-make/link-framework/Makefile+1-1
......@@ -1,4 +1,4 @@
1# only-macos
1# only-apple
22#
33# Check that linking to a framework actually makes it to the linker.
44
tests/run-make/lto-smoke/Makefile deleted-31
......@@ -1,31 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4all: noparam bool_true bool_false thin fat
5
6noparam:
7 $(RUSTC) lib.rs
8 $(RUSTC) main.rs -C lto
9 $(call RUN,main)
10
11bool_true:
12 $(RUSTC) lib.rs
13 $(RUSTC) main.rs -C lto=yes
14 $(call RUN,main)
15
16
17bool_false:
18 $(RUSTC) lib.rs
19 $(RUSTC) main.rs -C lto=off
20 $(call RUN,main)
21
22thin:
23 $(RUSTC) lib.rs
24 $(RUSTC) main.rs -C lto=thin
25 $(call RUN,main)
26
27fat:
28 $(RUSTC) lib.rs
29 $(RUSTC) main.rs -C lto=fat
30 $(call RUN,main)
31
tests/run-make/lto-smoke/rmake.rs created+16
......@@ -0,0 +1,16 @@
1// A simple smoke test to check that link time optimization
2// (LTO) is accepted by the compiler, and that
3// passing its various flags still results in successful compilation.
4// See https://github.com/rust-lang/rust/issues/10741
5
6//@ ignore-cross-compile
7
8use run_make_support::rustc;
9
10fn main() {
11 let lto_flags = ["-Clto", "-Clto=yes", "-Clto=off", "-Clto=thin", "-Clto=fat"];
12 for flag in lto_flags {
13 rustc().input("lib.rs").run();
14 rustc().input("main.rs").arg(flag).run();
15 }
16}
tests/run-make/macos-fat-archive/Makefile+1-1
......@@ -1,4 +1,4 @@
1# only-macos
1# only-apple
22
33include ../tools.mk
44
tests/run-make/mixing-deps/Makefile deleted-8
......@@ -1,8 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4all:
5 $(RUSTC) both.rs -C prefer-dynamic
6 $(RUSTC) dylib.rs -C prefer-dynamic
7 $(RUSTC) prog.rs
8 $(call RUN,prog)
tests/run-make/mixing-deps/rmake.rs created+13
......@@ -0,0 +1,13 @@
1// This test invokes the main function in prog.rs, which has dependencies
2// in both an rlib and a dylib. This test checks that these different library
3// types can be successfully mixed.
4//@ ignore-cross-compile
5
6use run_make_support::{run, rustc};
7
8fn main() {
9 rustc().input("both.rs").arg("-Cprefer-dynamic").run();
10 rustc().input("dylib.rs").arg("-Cprefer-dynamic").run();
11 rustc().input("prog.rs").run();
12 run("prog");
13}
tests/run-make/native-link-modifier-verbatim-linker/Makefile+1-1
......@@ -1,5 +1,5 @@
11# ignore-cross-compile
2# ignore-macos
2# ignore-apple
33
44include ../tools.mk
55
tests/run-make/print-check-cfg/lib.rs created+1
......@@ -0,0 +1 @@
1// empty crate
tests/run-make/print-check-cfg/rmake.rs created+106
......@@ -0,0 +1,106 @@
1//! This checks the output of `--print=check-cfg`
2
3extern crate run_make_support;
4
5use std::collections::HashSet;
6use std::iter::FromIterator;
7use std::ops::Deref;
8
9use run_make_support::rustc;
10
11fn main() {
12 check(
13 /*args*/ &[],
14 /*has_any*/ false,
15 /*has_any_any*/ true,
16 /*contains*/ &[],
17 );
18 check(
19 /*args*/ &["--check-cfg=cfg()"],
20 /*has_any*/ false,
21 /*has_any_any*/ false,
22 /*contains*/ &["unix", "miri"],
23 );
24 check(
25 /*args*/ &["--check-cfg=cfg(any())"],
26 /*has_any*/ true,
27 /*has_any_any*/ false,
28 /*contains*/ &["windows", "test"],
29 );
30 check(
31 /*args*/ &["--check-cfg=cfg(feature)"],
32 /*has_any*/ false,
33 /*has_any_any*/ false,
34 /*contains*/ &["unix", "miri", "feature"],
35 );
36 check(
37 /*args*/ &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#],
38 /*has_any*/ false,
39 /*has_any_any*/ false,
40 /*contains*/ &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""],
41 );
42 check(
43 /*args*/ &[
44 r#"--check-cfg=cfg(feature, values(any()))"#,
45 r#"--check-cfg=cfg(feature, values("tmp"))"#
46 ],
47 /*has_any*/ false,
48 /*has_any_any*/ false,
49 /*contains*/ &["unix", "miri", "feature=any()"],
50 );
51 check(
52 /*args*/ &[
53 r#"--check-cfg=cfg(has_foo, has_bar)"#,
54 r#"--check-cfg=cfg(feature, values("tmp"))"#,
55 r#"--check-cfg=cfg(feature, values("tmp"))"#
56 ],
57 /*has_any*/ false,
58 /*has_any_any*/ false,
59 /*contains*/ &["has_foo", "has_bar", "feature=\"tmp\""],
60 );
61}
62
63fn check(args: &[&str], has_any: bool, has_any_any: bool, contains: &[&str]) {
64 let output = rustc()
65 .input("lib.rs")
66 .arg("-Zunstable-options")
67 .arg("--print=check-cfg")
68 .args(&*args)
69 .run();
70
71 let stdout = String::from_utf8(output.stdout).unwrap();
72
73 let mut found_any = false;
74 let mut found_any_any = false;
75 let mut found = HashSet::<String>::new();
76 let mut recorded = HashSet::<String>::new();
77
78 for l in stdout.lines() {
79 assert!(l == l.trim());
80 if l == "any()" {
81 found_any = true;
82 } else if l == "any()=any()" {
83 found_any_any = true;
84 } else if let Some((left, right)) = l.split_once('=') {
85 if right != "any()" && right != "" {
86 assert!(right.starts_with("\""));
87 assert!(right.ends_with("\""));
88 }
89 assert!(!left.contains("\""));
90 } else {
91 assert!(!l.contains("\""));
92 }
93 assert!(recorded.insert(l.to_string()), "{}", &l);
94 if contains.contains(&l) {
95 assert!(found.insert(l.to_string()), "{}", &l);
96 }
97 }
98
99 let should_found = HashSet::<String>::from_iter(contains.iter().map(|s| s.to_string()));
100 let diff: Vec<_> = should_found.difference(&found).collect();
101
102 assert_eq!(found_any, has_any);
103 assert_eq!(found_any_any, has_any_any);
104 assert_eq!(found_any_any, recorded.len() == 1);
105 assert!(diff.is_empty(), "{:?} != {:?} (~ {:?})", &should_found, &found, &diff);
106}
tests/run-make/simple-rlib/Makefile deleted-6
......@@ -1,6 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3all:
4 $(RUSTC) bar.rs --crate-type=rlib
5 $(RUSTC) foo.rs
6 $(call RUN,foo)
tests/run-make/simple-rlib/bar.rs deleted-1
......@@ -1 +0,0 @@
1pub fn bar() {}
tests/run-make/simple-rlib/foo.rs deleted-5
......@@ -1,5 +0,0 @@
1extern crate bar;
2
3fn main() {
4 bar::bar();
5}
tests/run-make/used-cdylib-macos/Makefile+2-2
......@@ -1,9 +1,9 @@
11include ../tools.mk
22
3# only-macos
3# only-apple
44#
55# This checks that `#[used]` passes through to the linker on
6# darwin. This is subject to change in the future, see
6# Apple targets. This is subject to change in the future, see
77# https://github.com/rust-lang/rust/pull/93718 for discussion
88
99all:
tests/run-pass-valgrind/exit-flushes.rs+2-3
......@@ -1,6 +1,6 @@
11//@ ignore-wasm32 no subprocess support
22//@ ignore-sgx no processes
3//@ ignore-macos this needs valgrind 3.11 or higher; see
3//@ ignore-apple this needs valgrind 3.11 or higher; see
44// https://github.com/rust-lang/rust/pull/30365#issuecomment-165763679
55
66use std::env;
......@@ -11,8 +11,7 @@ fn main() {
1111 print!("hello!");
1212 exit(0);
1313 } else {
14 let out = Command::new(env::args().next().unwrap()).arg("foo")
15 .output().unwrap();
14 let out = Command::new(env::args().next().unwrap()).arg("foo").output().unwrap();
1615 assert!(out.status.success());
1716 assert_eq!(String::from_utf8(out.stdout).unwrap(), "hello!");
1817 assert_eq!(String::from_utf8(out.stderr).unwrap(), "");
tests/ui/abi/stack-probes-lto.rs+4
......@@ -10,5 +10,9 @@
1010//@ compile-flags: -C lto
1111//@ no-prefer-dynamic
1212//@ ignore-nto Crash analysis impossible at SIGSEGV in QNX Neutrino
13//@ ignore-ios Stack probes are enabled, but the SIGSEGV handler isn't
14//@ ignore-tvos Stack probes are enabled, but the SIGSEGV handler isn't
15//@ ignore-watchos Stack probes are enabled, but the SIGSEGV handler isn't
16//@ ignore-visionos Stack probes are enabled, but the SIGSEGV handler isn't
1317
1418include!("stack-probes.rs");
tests/ui/abi/stack-probes.rs+4
......@@ -8,6 +8,10 @@
88//@ ignore-sgx no processes
99//@ ignore-fuchsia no exception handler registered for segfault
1010//@ ignore-nto Crash analysis impossible at SIGSEGV in QNX Neutrino
11//@ ignore-ios Stack probes are enabled, but the SIGSEGV handler isn't
12//@ ignore-tvos Stack probes are enabled, but the SIGSEGV handler isn't
13//@ ignore-watchos Stack probes are enabled, but the SIGSEGV handler isn't
14//@ ignore-visionos Stack probes are enabled, but the SIGSEGV handler isn't
1115
1216use std::env;
1317use std::mem::MaybeUninit;
tests/ui/backtrace/apple-no-dsymutil.rs+1-1
......@@ -2,7 +2,7 @@
22
33//@ compile-flags:-Cstrip=none
44//@ compile-flags:-g -Csplit-debuginfo=unpacked
5//@ only-macos
5//@ only-apple
66
77use std::process::Command;
88use std::str;
tests/ui/deployment-target/macos-target.rs+1-1
......@@ -1,4 +1,4 @@
1//@ only-macos
1//@ only-apple
22//@ compile-flags: --print deployment-target
33//@ normalize-stdout-test: "\d+\." -> "$$CURRENT_MAJOR_VERSION."
44//@ normalize-stdout-test: "\d+" -> "$$CURRENT_MINOR_VERSION"
tests/ui/feature-gates/feature-gate-print-check-cfg.rs created+3
......@@ -0,0 +1,3 @@
1//@ compile-flags: --print=check-cfg
2
3fn main() {}
tests/ui/feature-gates/feature-gate-print-check-cfg.stderr created+2
......@@ -0,0 +1,2 @@
1error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option
2
tests/ui/imports/auxiliary/simple-rlib.rs created+2
......@@ -0,0 +1,2 @@
1#![crate_type = "rlib"]
2pub fn bar() {}
tests/ui/imports/import-from-missing-star-2.rs created+12
......@@ -0,0 +1,12 @@
1mod foo {
2 use spam::*; //~ ERROR unresolved import `spam` [E0432]
3}
4
5fn main() {
6 // Expect this to pass because the compiler knows there's a failed `*` import in `foo` that
7 // might have caused it.
8 foo::bar();
9 // FIXME: these two should *fail* because they can't be fixed by fixing the glob import in `foo`
10 ham(); // should error but doesn't
11 eggs(); // should error but doesn't
12}
tests/ui/imports/import-from-missing-star-2.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0432]: unresolved import `spam`
2 --> $DIR/import-from-missing-star-2.rs:2:9
3 |
4LL | use spam::*;
5 | ^^^^ maybe a missing crate `spam`?
6 |
7 = help: consider adding `extern crate spam` to use the `spam` crate
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0432`.
tests/ui/imports/import-from-missing-star-3.rs created+43
......@@ -0,0 +1,43 @@
1mod foo {
2 use spam::*; //~ ERROR unresolved import `spam` [E0432]
3
4 fn x() {
5 // Expect these to pass because the compiler knows there's a failed `*` import that might
6 // fix it.
7 eggs();
8 foo::bar();
9 }
10}
11
12mod bar {
13 fn z() {}
14 fn x() {
15 // Expect these to pass because the compiler knows there's a failed `*` import that might
16 // fix it.
17 foo::bar();
18 z();
19 // FIXME: should error but doesn't because as soon as there's a single glob import error, we
20 // silence all resolve errors.
21 eggs();
22 }
23}
24
25mod baz {
26 fn x() {
27 use spam::*; //~ ERROR unresolved import `spam` [E0432]
28 fn qux() {}
29 qux();
30 // Expect this to pass because the compiler knows there's a local failed `*` import that
31 // might have caused it.
32 eggs();
33 // Expect this to pass because the compiler knows there's a failed `*` import in `foo` that
34 // might have caused it.
35 foo::bar();
36 }
37}
38
39fn main() {
40 // FIXME: should error but doesn't because as soon as there's a single glob import error, we
41 // silence all resolve errors.
42 ham();
43}
tests/ui/imports/import-from-missing-star-3.stderr created+19
......@@ -0,0 +1,19 @@
1error[E0432]: unresolved import `spam`
2 --> $DIR/import-from-missing-star-3.rs:2:9
3 |
4LL | use spam::*;
5 | ^^^^ maybe a missing crate `spam`?
6 |
7 = help: consider adding `extern crate spam` to use the `spam` crate
8
9error[E0432]: unresolved import `spam`
10 --> $DIR/import-from-missing-star-3.rs:27:13
11 |
12LL | use spam::*;
13 | ^^^^ maybe a missing crate `spam`?
14 |
15 = help: consider adding `extern crate spam` to use the `spam` crate
16
17error: aborting due to 2 previous errors
18
19For more information about this error, try `rustc --explain E0432`.
tests/ui/imports/import-from-missing-star.rs created+10
......@@ -0,0 +1,10 @@
1use spam::*; //~ ERROR unresolved import `spam` [E0432]
2
3fn main() {
4 // Expect these to pass because the compiler knows there's a failed `*` import that might have
5 // caused it.
6 ham();
7 eggs();
8 // Even this case, as we might have expected `spam::foo` to exist.
9 foo::bar();
10}
tests/ui/imports/import-from-missing-star.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0432]: unresolved import `spam`
2 --> $DIR/import-from-missing-star.rs:1:5
3 |
4LL | use spam::*;
5 | ^^^^ maybe a missing crate `spam`?
6 |
7 = help: consider adding `extern crate spam` to use the `spam` crate
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0432`.
tests/ui/imports/issue-31212.rs+1-1
......@@ -6,5 +6,5 @@ mod foo {
66}
77
88fn main() {
9 foo::f(); //~ ERROR cannot find function `f` in module `foo`
9 foo::f(); // cannot find function `f` in module `foo`, but silenced
1010}
tests/ui/imports/issue-31212.stderr+2-9
......@@ -4,13 +4,6 @@ error[E0432]: unresolved import `self::*`
44LL | pub use self::*;
55 | ^^^^^^^ cannot glob-import a module into itself
66
7error[E0425]: cannot find function `f` in module `foo`
8 --> $DIR/issue-31212.rs:9:10
9 |
10LL | foo::f();
11 | ^ not found in `foo`
12
13error: aborting due to 2 previous errors
7error: aborting due to 1 previous error
148
15Some errors have detailed explanations: E0425, E0432.
16For more information about an error, try `rustc --explain E0425`.
9For more information about this error, try `rustc --explain E0432`.
tests/ui/imports/simple-rlib-import.rs created+12
......@@ -0,0 +1,12 @@
1// A simple test, where foo.rs has a dependency
2// on the rlib (a static Rust-specific library format) bar.rs. If the test passes,
3// rlibs can be built and linked into another file successfully..
4
5//@ aux-crate:bar=simple-rlib.rs
6//@ run-pass
7
8extern crate bar;
9
10fn main() {
11 bar::bar();
12}
tests/ui/intrinsics/intrinsic-alignment.rs+15-14
......@@ -10,20 +10,21 @@ mod rusti {
1010 }
1111}
1212
13#[cfg(any(target_os = "android",
14 target_os = "dragonfly",
15 target_os = "emscripten",
16 target_os = "freebsd",
17 target_os = "fuchsia",
18 target_os = "hurd",
19 target_os = "illumos",
20 target_os = "linux",
21 target_os = "macos",
22 target_os = "netbsd",
23 target_os = "openbsd",
24 target_os = "solaris",
25 target_os = "vxworks",
26 target_os = "nto",
13#[cfg(any(
14 target_os = "android",
15 target_os = "dragonfly",
16 target_os = "emscripten",
17 target_os = "freebsd",
18 target_os = "fuchsia",
19 target_os = "hurd",
20 target_os = "illumos",
21 target_os = "linux",
22 target_os = "netbsd",
23 target_os = "openbsd",
24 target_os = "solaris",
25 target_os = "vxworks",
26 target_os = "nto",
27 target_vendor = "apple",
2728))]
2829mod m {
2930 #[cfg(target_arch = "x86")]
tests/ui/invalid-compile-flags/print.stderr+1-1
......@@ -1,4 +1,4 @@
11error: unknown print request: `yyyy`
22 |
3 = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
3 = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
44
tests/ui/issues/issue-18804/auxiliary/lib.rs deleted-10
......@@ -1,10 +0,0 @@
1#![crate_type = "rlib"]
2#![feature(linkage)]
3
4pub fn foo<T>() -> *const () {
5 extern "C" {
6 #[linkage = "extern_weak"]
7 static FOO: *const ();
8 }
9 unsafe { FOO }
10}
tests/ui/issues/issue-18804/main.rs deleted-18
......@@ -1,18 +0,0 @@
1//@ run-pass
2// Test for issue #18804, #[linkage] does not propagate through generic
3// functions. Failure results in a linker error.
4
5//@ ignore-emscripten no weak symbol support
6//@ ignore-windows no extern_weak linkage
7//@ ignore-macos no extern_weak linkage
8
9//@ aux-build:lib.rs
10
11// rust-lang/rust#56772: nikic says we need this to be proper test.
12//@ compile-flags: -C no-prepopulate-passes -C passes=name-anon-globals
13
14extern crate lib;
15
16fn main() {
17 lib::foo::<i32>();
18}
tests/ui/issues/issue-33992.rs deleted-29
......@@ -1,29 +0,0 @@
1//@ run-pass
2//@ ignore-windows
3//@ ignore-macos
4//@ ignore-wasm32 common linkage not implemented right now
5
6#![feature(linkage)]
7
8#[linkage = "external"]
9pub static TEST2: bool = true;
10
11#[linkage = "internal"]
12pub static TEST3: bool = true;
13
14#[linkage = "linkonce"]
15pub static TEST4: bool = true;
16
17#[linkage = "linkonce_odr"]
18pub static TEST5: bool = true;
19
20#[linkage = "private"]
21pub static TEST6: bool = true;
22
23#[linkage = "weak"]
24pub static TEST7: bool = true;
25
26#[linkage = "weak_odr"]
27pub static TEST8: bool = true;
28
29fn main() {}
tests/ui/issues/issue-45731.rs+9-4
......@@ -2,10 +2,10 @@
22#![allow(unused_variables)]
33//@ compile-flags:--test -g
44
5#[cfg(target_os = "macos")]
5#[cfg(target_vendor = "apple")]
66#[test]
77fn simple_test() {
8 use std::{env, panic, fs};
8 use std::{env, fs, panic};
99
1010 // Find our dSYM and replace the DWARF binary with an empty file
1111 let mut dsym_path = env::current_exe().unwrap();
......@@ -13,8 +13,13 @@ fn simple_test() {
1313 assert!(dsym_path.pop()); // Pop executable
1414 dsym_path.push(format!("{}.dSYM/Contents/Resources/DWARF/{0}", executable_name));
1515 {
16 let file = fs::OpenOptions::new().read(false).write(true).truncate(true).create(false)
17 .open(&dsym_path).unwrap();
16 let file = fs::OpenOptions::new()
17 .read(false)
18 .write(true)
19 .truncate(true)
20 .create(false)
21 .open(&dsym_path)
22 .unwrap();
1823 }
1924
2025 env::set_var("RUST_BACKTRACE", "1");
tests/ui/link-section.rs+12-12
......@@ -1,32 +1,32 @@
11//@ run-pass
22
33#![allow(non_upper_case_globals)]
4#[cfg(not(target_os = "macos"))]
5#[link_section=".moretext"]
4#[cfg(not(target_vendor = "apple"))]
5#[link_section = ".moretext"]
66fn i_live_in_more_text() -> &'static str {
77 "knock knock"
88}
99
10#[cfg(not(target_os = "macos"))]
11#[link_section=".imm"]
10#[cfg(not(target_vendor = "apple"))]
11#[link_section = ".imm"]
1212static magic: usize = 42;
1313
14#[cfg(not(target_os = "macos"))]
15#[link_section=".mut"]
14#[cfg(not(target_vendor = "apple"))]
15#[link_section = ".mut"]
1616static mut frobulator: usize = 0xdeadbeef;
1717
18#[cfg(target_os = "macos")]
19#[link_section="__TEXT,__moretext"]
18#[cfg(target_vendor = "apple")]
19#[link_section = "__TEXT,__moretext"]
2020fn i_live_in_more_text() -> &'static str {
2121 "knock knock"
2222}
2323
24#[cfg(target_os = "macos")]
25#[link_section="__RODATA,__imm"]
24#[cfg(target_vendor = "apple")]
25#[link_section = "__RODATA,__imm"]
2626static magic: usize = 42;
2727
28#[cfg(target_os = "macos")]
29#[link_section="__DATA,__mut"]
28#[cfg(target_vendor = "apple")]
29#[link_section = "__DATA,__mut"]
3030static mut frobulator: usize = 0xdeadbeef;
3131
3232pub fn main() {
tests/ui/linkage-attr/framework.rs+1-1
......@@ -1,5 +1,5 @@
11// Check that linking frameworks on Apple platforms works.
2//@ only-macos
2//@ only-apple
33//@ revisions: omit link weak both
44//@ [omit]build-fail
55//@ [link]run-pass
tests/ui/linkage-attr/kind-framework.rs created+7
......@@ -0,0 +1,7 @@
1//@ ignore-apple this is supposed to succeed on Apple platforms (though it won't necessarily link)
2
3#[link(name = "foo", kind = "framework")]
4extern "C" {}
5//~^^ ERROR: link kind `framework` is only supported on Apple targets
6
7fn main() {}
tests/ui/linkage-attr/kind-framework.stderr created+9
......@@ -0,0 +1,9 @@
1error[E0455]: link kind `framework` is only supported on Apple targets
2 --> $DIR/kind-framework.rs:3:29
3 |
4LL | #[link(name = "foo", kind = "framework")]
5 | ^^^^^^^^^^^
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0455`.
tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs created+29
......@@ -0,0 +1,29 @@
1//@ run-pass
2//@ ignore-windows
3//@ ignore-apple
4//@ ignore-wasm32 common linkage not implemented right now
5
6#![feature(linkage)]
7
8#[linkage = "external"]
9pub static TEST2: bool = true;
10
11#[linkage = "internal"]
12pub static TEST3: bool = true;
13
14#[linkage = "linkonce"]
15pub static TEST4: bool = true;
16
17#[linkage = "linkonce_odr"]
18pub static TEST5: bool = true;
19
20#[linkage = "private"]
21pub static TEST6: bool = true;
22
23#[linkage = "weak"]
24pub static TEST7: bool = true;
25
26#[linkage = "weak_odr"]
27pub static TEST8: bool = true;
28
29fn main() {}
tests/ui/linkage-attr/linkage1.rs+1-1
......@@ -1,6 +1,6 @@
11//@ run-pass
22//@ ignore-windows
3//@ ignore-macos
3//@ ignore-apple
44//@ ignore-emscripten doesn't support this linkage
55//@ ignore-sgx weak linkage not permitted
66//@ aux-build:linkage1.rs
tests/ui/linkage-attr/propagate-generic-issue-18804/auxiliary/lib.rs created+10
......@@ -0,0 +1,10 @@
1#![crate_type = "rlib"]
2#![feature(linkage)]
3
4pub fn foo<T>() -> *const () {
5 extern "C" {
6 #[linkage = "extern_weak"]
7 static FOO: *const ();
8 }
9 unsafe { FOO }
10}
tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs created+18
......@@ -0,0 +1,18 @@
1//@ run-pass
2// Test for issue #18804, #[linkage] does not propagate through generic
3// functions. Failure results in a linker error.
4
5//@ ignore-emscripten no weak symbol support
6//@ ignore-windows no extern_weak linkage
7//@ ignore-apple no extern_weak linkage
8
9//@ aux-build:lib.rs
10
11// rust-lang/rust#56772: nikic says we need this to be proper test.
12//@ compile-flags: -C no-prepopulate-passes -C passes=name-anon-globals
13
14extern crate lib;
15
16fn main() {
17 lib::foo::<i32>();
18}
tests/ui/manual/manual-link-framework.rs+2-4
......@@ -1,7 +1,5 @@
1//@ ignore-macos
2//@ ignore-ios
1//@ ignore-apple
32//@ compile-flags:-l framework=foo
43//@ error-pattern: library kind `framework` is only supported on Apple targets
54
6fn main() {
7}
5fn main() {}
tests/ui/osx-frameworks.rs deleted-7
......@@ -1,7 +0,0 @@
1//@ ignore-macos this is supposed to succeed on osx
2
3#[link(name = "foo", kind = "framework")]
4extern "C" {}
5//~^^ ERROR: link kind `framework` is only supported on Apple targets
6
7fn main() {}
tests/ui/osx-frameworks.stderr deleted-9
......@@ -1,9 +0,0 @@
1error[E0455]: link kind `framework` is only supported on Apple targets
2 --> $DIR/osx-frameworks.rs:3:29
3 |
4LL | #[link(name = "foo", kind = "framework")]
5 | ^^^^^^^^^^^
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0455`.
tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs+1-3
......@@ -5,12 +5,11 @@
55//@ no-prefer-dynamic
66//@ ignore-wasm32 no processes
77//@ ignore-sgx no processes
8//@ ignore-macos
98
109extern crate exit_success_if_unwind;
1110
12use std::process::Command;
1311use std::env;
12use std::process::Command;
1413
1514fn main() {
1615 let mut args = env::args_os();
......@@ -25,7 +24,6 @@ fn main() {
2524 let mut cmd = Command::new(env::args_os().next().unwrap());
2625 cmd.arg("foo");
2726
28
2927 // ARMv6 hanges while printing the backtrace, see #41004
3028 if cfg!(target_arch = "arm") && cfg!(target_env = "gnu") {
3129 cmd.env("RUST_BACKTRACE", "0");
tests/ui/panic-runtime/abort.rs+1-3
......@@ -4,10 +4,9 @@
44//@ no-prefer-dynamic
55//@ ignore-wasm32 no processes
66//@ ignore-sgx no processes
7//@ ignore-macos
87
9use std::process::Command;
108use std::env;
9use std::process::Command;
1110
1211struct Bomb;
1312
......@@ -23,7 +22,6 @@ fn main() {
2322
2423 if let Some(s) = args.next() {
2524 if &*s == "foo" {
26
2725 let _bomb = Bomb;
2826
2927 panic!("try to catch me");
tests/ui/panic-runtime/link-to-abort.rs-1
......@@ -2,7 +2,6 @@
22
33//@ compile-flags:-C panic=abort
44//@ no-prefer-dynamic
5//@ ignore-macos
65
76#![feature(panic_abort)]
87
tests/ui/runtime/out-of-stack.rs+4
......@@ -7,6 +7,10 @@
77//@ ignore-sgx no processes
88//@ ignore-fuchsia must translate zircon signal to SIGABRT, FIXME (#58590)
99//@ ignore-nto no stack overflow handler used (no alternate stack available)
10//@ ignore-ios stack overflow handlers aren't enabled
11//@ ignore-tvos stack overflow handlers aren't enabled
12//@ ignore-watchos stack overflow handlers aren't enabled
13//@ ignore-visionos stack overflow handlers aren't enabled
1014
1115#![feature(rustc_private)]
1216
tests/ui/structs-enums/enum-rec/issue-17431-6.rs+1-1
......@@ -1,4 +1,4 @@
1//@ ignore-macos: cycle error does not appear on apple
1//@ ignore-apple: cycle error does not appear on apple
22
33use std::sync::Mutex;
44
tests/ui/structs-enums/rec-align-u64.rs+15-15
......@@ -30,21 +30,21 @@ struct Outer {
3030 t: Inner
3131}
3232
33
34#[cfg(any(target_os = "android",
35 target_os = "dragonfly",
36 target_os = "emscripten",
37 target_os = "freebsd",
38 target_os = "fuchsia",
39 target_os = "hurd",
40 target_os = "illumos",
41 target_os = "linux",
42 target_os = "macos",
43 target_os = "netbsd",
44 target_os = "openbsd",
45 target_os = "solaris",
46 target_os = "vxworks",
47 target_os = "nto",
33#[cfg(any(
34 target_os = "android",
35 target_os = "dragonfly",
36 target_os = "emscripten",
37 target_os = "freebsd",
38 target_os = "fuchsia",
39 target_os = "hurd",
40 target_os = "illumos",
41 target_os = "linux",
42 target_os = "netbsd",
43 target_os = "openbsd",
44 target_os = "solaris",
45 target_os = "vxworks",
46 target_os = "nto",
47 target_vendor = "apple",
4848))]
4949mod m {
5050 #[cfg(target_arch = "x86")]