authorbors <bors@rust-lang.org> 2025-06-16 18:20:05 UTC
committerbors <bors@rust-lang.org> 2025-06-16 18:20:05 UTC
log45acf54eea118ed27927282b5e0bfdcd80b7987c
treee876174d258caa3d3ab3233f3e6a0697b9601157
parent3bc767e1a215c4bf8f099b32e84edb85780591b1
parentb1ba2cdf41da538fa2195ff439cc6b82723b9474

Auto merge of #142589 - Kobzol:rollup-j90fk2j, r=Kobzol

Rollup of 8 pull requests Successful merges: - rust-lang/rust#139340 (Fix RISC-V C function ABI when passing/returning structs containing floats) - rust-lang/rust#142341 (Don't suggest converting `///` to `//` when expecting `,`) - rust-lang/rust#142414 (ignore `run-make` tests that need `std` on targets without `std`) - rust-lang/rust#142498 (Port `#[rustc_as_ptr]` to the new attribute system) - rust-lang/rust#142554 (Fix `PathSource` lifetimes.) - rust-lang/rust#142562 (Update the `backtrace` submodule) - rust-lang/rust#142565 (Test naked asm for wasm32-unknown-unknown) - rust-lang/rust#142573 (`fn candidate_is_applicable` to method) r? `@ghost` `@rustbot` modify labels: rollup

135 files changed, 913 insertions(+), 239 deletions(-)

compiler/rustc_attr_data_structures/src/attributes.rs+3
...@@ -188,6 +188,9 @@ pub enum AttributeKind {...@@ -188,6 +188,9 @@ pub enum AttributeKind {
188 /// Represents `#[allow_internal_unstable]`.188 /// Represents `#[allow_internal_unstable]`.
189 AllowInternalUnstable(ThinVec<(Symbol, Span)>),189 AllowInternalUnstable(ThinVec<(Symbol, Span)>),
190190
191 /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
192 AsPtr(Span),
193
191 /// Represents `#[rustc_default_body_unstable]`.194 /// Represents `#[rustc_default_body_unstable]`.
192 BodyStability {195 BodyStability {
193 stability: DefaultBodyStability,196 stability: DefaultBodyStability,
compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs created+21
...@@ -0,0 +1,21 @@
1use rustc_attr_data_structures::AttributeKind;
2use rustc_span::{Symbol, sym};
3
4use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
5use crate::context::{AcceptContext, Stage};
6use crate::parser::ArgParser;
7
8pub(crate) struct AsPtrParser;
9
10impl<S: Stage> SingleAttributeParser<S> for AsPtrParser {
11 const PATH: &[Symbol] = &[sym::rustc_as_ptr];
12
13 const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
14
15 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
16
17 fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
18 // FIXME: check that there's no args (this is currently checked elsewhere)
19 Some(AttributeKind::AsPtr(cx.attr_span))
20 }
21}
compiler/rustc_attr_parsing/src/attributes/mod.rs+1
...@@ -29,6 +29,7 @@ pub(crate) mod allow_unstable;...@@ -29,6 +29,7 @@ pub(crate) mod allow_unstable;
29pub(crate) mod cfg;29pub(crate) mod cfg;
30pub(crate) mod confusables;30pub(crate) mod confusables;
31pub(crate) mod deprecation;31pub(crate) mod deprecation;
32pub(crate) mod lint_helpers;
32pub(crate) mod repr;33pub(crate) mod repr;
33pub(crate) mod stability;34pub(crate) mod stability;
34pub(crate) mod transparency;35pub(crate) mod transparency;
compiler/rustc_attr_parsing/src/context.rs+2
...@@ -18,6 +18,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};...@@ -18,6 +18,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
18use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};18use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
19use crate::attributes::confusables::ConfusablesParser;19use crate::attributes::confusables::ConfusablesParser;
20use crate::attributes::deprecation::DeprecationParser;20use crate::attributes::deprecation::DeprecationParser;
21use crate::attributes::lint_helpers::AsPtrParser;
21use crate::attributes::repr::ReprParser;22use crate::attributes::repr::ReprParser;
22use crate::attributes::stability::{23use crate::attributes::stability::{
23 BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,24 BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
...@@ -102,6 +103,7 @@ attribute_parsers!(...@@ -102,6 +103,7 @@ attribute_parsers!(
102 // tidy-alphabetical-end103 // tidy-alphabetical-end
103104
104 // tidy-alphabetical-start105 // tidy-alphabetical-start
106 Single<AsPtrParser>,
105 Single<ConstStabilityIndirectParser>,107 Single<ConstStabilityIndirectParser>,
106 Single<DeprecationParser>,108 Single<DeprecationParser>,
107 Single<TransparencyParser>,109 Single<TransparencyParser>,
compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs+42-24
...@@ -40,7 +40,18 @@ fn apply_attrs_to_abi_param(param: AbiParam, arg_attrs: ArgAttributes) -> AbiPar...@@ -40,7 +40,18 @@ fn apply_attrs_to_abi_param(param: AbiParam, arg_attrs: ArgAttributes) -> AbiPar
40 }40 }
41}41}
4242
43fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[AbiParam; 2]> {43fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[(Size, AbiParam); 2]> {
44 if let Some(offset_from_start) = cast.rest_offset {
45 assert!(cast.prefix[1..].iter().all(|p| p.is_none()));
46 assert_eq!(cast.rest.unit.size, cast.rest.total);
47 let first = cast.prefix[0].unwrap();
48 let second = cast.rest.unit;
49 return smallvec![
50 (Size::ZERO, reg_to_abi_param(first)),
51 (offset_from_start, reg_to_abi_param(second))
52 ];
53 }
54
44 let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 {55 let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 {
45 (0, 0)56 (0, 0)
46 } else {57 } else {
...@@ -55,25 +66,32 @@ fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[AbiParam; 2]> {...@@ -55,25 +66,32 @@ fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[AbiParam; 2]> {
55 // different types in Cranelift IR. Instead a single array of primitive types is used.66 // different types in Cranelift IR. Instead a single array of primitive types is used.
5667
57 // Create list of fields in the main structure68 // Create list of fields in the main structure
58 let mut args = cast69 let args = cast
59 .prefix70 .prefix
60 .iter()71 .iter()
61 .flatten()72 .flatten()
62 .map(|&reg| reg_to_abi_param(reg))73 .map(|&reg| reg_to_abi_param(reg))
63 .chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))74 .chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)));
64 .collect::<SmallVec<_>>();75
76 let mut res = SmallVec::new();
77 let mut offset = Size::ZERO;
78
79 for arg in args {
80 res.push((offset, arg));
81 offset += Size::from_bytes(arg.value_type.bytes());
82 }
6583
66 // Append final integer84 // Append final integer
67 if rem_bytes != 0 {85 if rem_bytes != 0 {
68 // Only integers can be really split further.86 // Only integers can be really split further.
69 assert_eq!(cast.rest.unit.kind, RegKind::Integer);87 assert_eq!(cast.rest.unit.kind, RegKind::Integer);
70 args.push(reg_to_abi_param(Reg {88 res.push((
71 kind: RegKind::Integer,89 offset,
72 size: Size::from_bytes(rem_bytes),90 reg_to_abi_param(Reg { kind: RegKind::Integer, size: Size::from_bytes(rem_bytes) }),
73 }));91 ));
74 }92 }
7593
76 args94 res
77}95}
7896
79impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {97impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
...@@ -104,7 +122,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {...@@ -104,7 +122,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
104 },122 },
105 PassMode::Cast { ref cast, pad_i32 } => {123 PassMode::Cast { ref cast, pad_i32 } => {
106 assert!(!pad_i32, "padding support not yet implemented");124 assert!(!pad_i32, "padding support not yet implemented");
107 cast_target_to_abi_params(cast)125 cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect()
108 }126 }
109 PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {127 PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {
110 if on_stack {128 if on_stack {
...@@ -160,9 +178,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {...@@ -160,9 +178,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
160 }178 }
161 _ => unreachable!("{:?}", self.layout.backend_repr),179 _ => unreachable!("{:?}", self.layout.backend_repr),
162 },180 },
163 PassMode::Cast { ref cast, .. } => {181 PassMode::Cast { ref cast, .. } => (
164 (None, cast_target_to_abi_params(cast).into_iter().collect())182 None,
165 }183 cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect(),
184 ),
166 PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {185 PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {
167 assert!(!on_stack);186 assert!(!on_stack);
168 (187 (
...@@ -187,12 +206,14 @@ pub(super) fn to_casted_value<'tcx>(...@@ -187,12 +206,14 @@ pub(super) fn to_casted_value<'tcx>(
187) -> SmallVec<[Value; 2]> {206) -> SmallVec<[Value; 2]> {
188 let (ptr, meta) = arg.force_stack(fx);207 let (ptr, meta) = arg.force_stack(fx);
189 assert!(meta.is_none());208 assert!(meta.is_none());
190 let mut offset = 0;
191 cast_target_to_abi_params(cast)209 cast_target_to_abi_params(cast)
192 .into_iter()210 .into_iter()
193 .map(|param| {211 .map(|(offset, param)| {
194 let val = ptr.offset_i64(fx, offset).load(fx, param.value_type, MemFlags::new());212 let val = ptr.offset_i64(fx, offset.bytes() as i64).load(
195 offset += i64::from(param.value_type.bytes());213 fx,
214 param.value_type,
215 MemFlags::new(),
216 );
196 val217 val
197 })218 })
198 .collect()219 .collect()
...@@ -205,7 +226,7 @@ pub(super) fn from_casted_value<'tcx>(...@@ -205,7 +226,7 @@ pub(super) fn from_casted_value<'tcx>(
205 cast: &CastTarget,226 cast: &CastTarget,
206) -> CValue<'tcx> {227) -> CValue<'tcx> {
207 let abi_params = cast_target_to_abi_params(cast);228 let abi_params = cast_target_to_abi_params(cast);
208 let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();229 let abi_param_size: u32 = abi_params.iter().map(|(_, param)| param.value_type.bytes()).sum();
209 let layout_size = u32::try_from(layout.size.bytes()).unwrap();230 let layout_size = u32::try_from(layout.size.bytes()).unwrap();
210 let ptr = fx.create_stack_slot(231 let ptr = fx.create_stack_slot(
211 // Stack slot size may be bigger for example `[u8; 3]` which is packed into an `i32`.232 // Stack slot size may be bigger for example `[u8; 3]` which is packed into an `i32`.
...@@ -214,16 +235,13 @@ pub(super) fn from_casted_value<'tcx>(...@@ -214,16 +235,13 @@ pub(super) fn from_casted_value<'tcx>(
214 std::cmp::max(abi_param_size, layout_size),235 std::cmp::max(abi_param_size, layout_size),
215 u32::try_from(layout.align.abi.bytes()).unwrap(),236 u32::try_from(layout.align.abi.bytes()).unwrap(),
216 );237 );
217 let mut offset = 0;
218 let mut block_params_iter = block_params.iter().copied();238 let mut block_params_iter = block_params.iter().copied();
219 for param in abi_params {239 for (offset, _) in abi_params {
220 let val = ptr.offset_i64(fx, offset).store(240 ptr.offset_i64(fx, offset.bytes() as i64).store(
221 fx,241 fx,
222 block_params_iter.next().unwrap(),242 block_params_iter.next().unwrap(),
223 MemFlags::new(),243 MemFlags::new(),
224 );244 )
225 offset += i64::from(param.value_type.bytes());
226 val
227 }245 }
228 assert_eq!(block_params_iter.next(), None, "Leftover block param");246 assert_eq!(block_params_iter.next(), None, "Leftover block param");
229 CValue::by_ref(ptr, layout)247 CValue::by_ref(ptr, layout)
compiler/rustc_codegen_gcc/src/intrinsic/mod.rs+1-1
...@@ -626,7 +626,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {...@@ -626,7 +626,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
626 bx.lifetime_start(llscratch, scratch_size);626 bx.lifetime_start(llscratch, scratch_size);
627627
628 // ... where we first store the value...628 // ... where we first store the value...
629 bx.store(val, llscratch, scratch_align);629 rustc_codegen_ssa::mir::store_cast(bx, cast, val, llscratch, scratch_align);
630630
631 // ... and then memcpy it to the intended destination.631 // ... and then memcpy it to the intended destination.
632 bx.memcpy(632 bx.memcpy(
compiler/rustc_codegen_llvm/src/abi.rs+1-1
...@@ -229,7 +229,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {...@@ -229,7 +229,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
229 let llscratch = bx.alloca(scratch_size, scratch_align);229 let llscratch = bx.alloca(scratch_size, scratch_align);
230 bx.lifetime_start(llscratch, scratch_size);230 bx.lifetime_start(llscratch, scratch_size);
231 // ...store the value...231 // ...store the value...
232 bx.store(val, llscratch, scratch_align);232 rustc_codegen_ssa::mir::store_cast(bx, cast, val, llscratch, scratch_align);
233 // ... and then memcpy it to the intended destination.233 // ... and then memcpy it to the intended destination.
234 bx.memcpy(234 bx.memcpy(
235 dst.val.llval,235 dst.val.llval,
compiler/rustc_codegen_ssa/src/mir/block.rs+48-6
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1use std::cmp;1use std::cmp;
22
3use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, Size, WrappingRange};3use rustc_abi::{Align, BackendRepr, ExternAbi, HasDataLayout, Reg, Size, WrappingRange};
4use rustc_ast as ast;4use rustc_ast as ast;
5use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};5use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
6use rustc_data_structures::packed::Pu128;6use rustc_data_structures::packed::Pu128;
...@@ -13,7 +13,7 @@ use rustc_middle::{bug, span_bug};...@@ -13,7 +13,7 @@ use rustc_middle::{bug, span_bug};
13use rustc_session::config::OptLevel;13use rustc_session::config::OptLevel;
14use rustc_span::Span;14use rustc_span::Span;
15use rustc_span::source_map::Spanned;15use rustc_span::source_map::Spanned;
16use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};16use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, PassMode};
17use tracing::{debug, info};17use tracing::{debug, info};
1818
19use super::operand::OperandRef;19use super::operand::OperandRef;
...@@ -558,8 +558,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {...@@ -558,8 +558,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
558 }558 }
559 ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"),559 ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"),
560 };560 };
561 let ty = bx.cast_backend_type(cast_ty);561 load_cast(bx, cast_ty, llslot, self.fn_abi.ret.layout.align.abi)
562 bx.load(ty, llslot, self.fn_abi.ret.layout.align.abi)
563 }562 }
564 };563 };
565 bx.ret(llval);564 bx.ret(llval);
...@@ -1618,8 +1617,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {...@@ -1618,8 +1617,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1618 MemFlags::empty(),1617 MemFlags::empty(),
1619 );1618 );
1620 // ...and then load it with the ABI type.1619 // ...and then load it with the ABI type.
1621 let cast_ty = bx.cast_backend_type(cast);1620 llval = load_cast(bx, cast, llscratch, scratch_align);
1622 llval = bx.load(cast_ty, llscratch, scratch_align);
1623 bx.lifetime_end(llscratch, scratch_size);1621 bx.lifetime_end(llscratch, scratch_size);
1624 } else {1622 } else {
1625 // We can't use `PlaceRef::load` here because the argument1623 // We can't use `PlaceRef::load` here because the argument
...@@ -1969,3 +1967,47 @@ enum ReturnDest<'tcx, V> {...@@ -1969,3 +1967,47 @@ enum ReturnDest<'tcx, V> {
1969 /// Store a direct return value to an operand local place.1967 /// Store a direct return value to an operand local place.
1970 DirectOperand(mir::Local),1968 DirectOperand(mir::Local),
1971}1969}
1970
1971fn load_cast<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
1972 bx: &mut Bx,
1973 cast: &CastTarget,
1974 ptr: Bx::Value,
1975 align: Align,
1976) -> Bx::Value {
1977 let cast_ty = bx.cast_backend_type(cast);
1978 if let Some(offset_from_start) = cast.rest_offset {
1979 assert!(cast.prefix[1..].iter().all(|p| p.is_none()));
1980 assert_eq!(cast.rest.unit.size, cast.rest.total);
1981 let first_ty = bx.reg_backend_type(&cast.prefix[0].unwrap());
1982 let second_ty = bx.reg_backend_type(&cast.rest.unit);
1983 let first = bx.load(first_ty, ptr, align);
1984 let second_ptr = bx.inbounds_ptradd(ptr, bx.const_usize(offset_from_start.bytes()));
1985 let second = bx.load(second_ty, second_ptr, align.restrict_for_offset(offset_from_start));
1986 let res = bx.cx().const_poison(cast_ty);
1987 let res = bx.insert_value(res, first, 0);
1988 bx.insert_value(res, second, 1)
1989 } else {
1990 bx.load(cast_ty, ptr, align)
1991 }
1992}
1993
1994pub fn store_cast<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
1995 bx: &mut Bx,
1996 cast: &CastTarget,
1997 value: Bx::Value,
1998 ptr: Bx::Value,
1999 align: Align,
2000) {
2001 if let Some(offset_from_start) = cast.rest_offset {
2002 assert!(cast.prefix[1..].iter().all(|p| p.is_none()));
2003 assert_eq!(cast.rest.unit.size, cast.rest.total);
2004 assert!(cast.prefix[0].is_some());
2005 let first = bx.extract_value(value, 0);
2006 let second = bx.extract_value(value, 1);
2007 bx.store(first, ptr, align);
2008 let second_ptr = bx.inbounds_ptradd(ptr, bx.const_usize(offset_from_start.bytes()));
2009 bx.store(second, second_ptr, align.restrict_for_offset(offset_from_start));
2010 } else {
2011 bx.store(value, ptr, align);
2012 };
2013}
compiler/rustc_codegen_ssa/src/mir/mod.rs+2-1
...@@ -26,6 +26,7 @@ pub mod place;...@@ -26,6 +26,7 @@ pub mod place;
26mod rvalue;26mod rvalue;
27mod statement;27mod statement;
2828
29pub use self::block::store_cast;
29use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo};30use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo};
30use self::operand::{OperandRef, OperandValue};31use self::operand::{OperandRef, OperandValue};
31use self::place::PlaceRef;32use self::place::PlaceRef;
...@@ -259,7 +260,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(...@@ -259,7 +260,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
259 }260 }
260 PassMode::Cast { ref cast, .. } => {261 PassMode::Cast { ref cast, .. } => {
261 debug!("alloc: {:?} (return place) -> place", local);262 debug!("alloc: {:?} (return place) -> place", local);
262 let size = cast.size(&start_bx);263 let size = cast.size(&start_bx).max(layout.size);
263 return LocalRef::Place(PlaceRef::alloca_size(&mut start_bx, size, layout));264 return LocalRef::Place(PlaceRef::alloca_size(&mut start_bx, size, layout));
264 }265 }
265 _ => {}266 _ => {}
compiler/rustc_lint/src/dangling.rs+2-1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1use rustc_ast::visit::{visit_opt, walk_list};1use rustc_ast::visit::{visit_opt, walk_list};
2use rustc_attr_data_structures::{AttributeKind, find_attr};
2use rustc_hir::def_id::LocalDefId;3use rustc_hir::def_id::LocalDefId;
3use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};4use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
4use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem};5use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem};
...@@ -133,7 +134,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {...@@ -133,7 +134,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
133 && let ty = cx.typeck_results().expr_ty(receiver)134 && let ty = cx.typeck_results().expr_ty(receiver)
134 && owns_allocation(cx.tcx, ty)135 && owns_allocation(cx.tcx, ty)
135 && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)136 && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
136 && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr)137 && find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr(_))
137 {138 {
138 // FIXME: use `emit_node_lint` when `#[primary_span]` is added.139 // FIXME: use `emit_node_lint` when `#[primary_span]` is added.
139 cx.tcx.emit_node_span_lint(140 cx.tcx.emit_node_span_lint(
compiler/rustc_parse/src/parser/diagnostics.rs+28-17
...@@ -686,23 +686,34 @@ impl<'a> Parser<'a> {...@@ -686,23 +686,34 @@ impl<'a> Parser<'a> {
686 }686 }
687687
688 if let token::DocComment(kind, style, _) = self.token.kind {688 if let token::DocComment(kind, style, _) = self.token.kind {
689 // We have something like `expr //!val` where the user likely meant `expr // !val`689 // This is to avoid suggesting converting a doc comment to a regular comment
690 let pos = self.token.span.lo() + BytePos(2);690 // when missing a comma before the doc comment in lists (#142311):
691 let span = self.token.span.with_lo(pos).with_hi(pos);691 //
692 err.span_suggestion_verbose(692 // ```
693 span,693 // enum Foo{
694 format!(694 // A /// xxxxxxx
695 "add a space before {} to write a regular comment",695 // B,
696 match (kind, style) {696 // }
697 (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`",697 // ```
698 (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`",698 if !expected.contains(&TokenType::Comma) {
699 (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`",699 // We have something like `expr //!val` where the user likely meant `expr // !val`
700 (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`",700 let pos = self.token.span.lo() + BytePos(2);
701 },701 let span = self.token.span.with_lo(pos).with_hi(pos);
702 ),702 err.span_suggestion_verbose(
703 " ".to_string(),703 span,
704 Applicability::MachineApplicable,704 format!(
705 );705 "add a space before {} to write a regular comment",
706 match (kind, style) {
707 (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`",
708 (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`",
709 (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`",
710 (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`",
711 },
712 ),
713 " ".to_string(),
714 Applicability::MaybeIncorrect,
715 );
716 }
706 }717 }
707718
708 let sp = if self.token == token::Eof {719 let sp = if self.token == token::Eof {
compiler/rustc_passes/src/check_attr.rs+12-12
...@@ -147,6 +147,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {...@@ -147,6 +147,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
147 | AttributeKind::ConstStabilityIndirect147 | AttributeKind::ConstStabilityIndirect
148 | AttributeKind::MacroTransparency(_),148 | AttributeKind::MacroTransparency(_),
149 ) => { /* do nothing */ }149 ) => { /* do nothing */ }
150 Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
151 self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
152 }
150 Attribute::Unparsed(_) => {153 Attribute::Unparsed(_) => {
151 match attr.path().as_slice() {154 match attr.path().as_slice() {
152 [sym::diagnostic, sym::do_not_recommend, ..] => {155 [sym::diagnostic, sym::do_not_recommend, ..] => {
...@@ -188,26 +191,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {...@@ -188,26 +191,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
188 self.check_rustc_std_internal_symbol(attr, span, target)191 self.check_rustc_std_internal_symbol(attr, span, target)
189 }192 }
190 [sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs),193 [sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs),
191 [sym::rustc_as_ptr, ..] => {
192 self.check_applied_to_fn_or_method(hir_id, attr, span, target)
193 }
194 [sym::rustc_no_implicit_autorefs, ..] => {194 [sym::rustc_no_implicit_autorefs, ..] => {
195 self.check_applied_to_fn_or_method(hir_id, attr, span, target)195 self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
196 }196 }
197 [sym::rustc_never_returns_null_ptr, ..] => {197 [sym::rustc_never_returns_null_ptr, ..] => {
198 self.check_applied_to_fn_or_method(hir_id, attr, span, target)198 self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
199 }199 }
200 [sym::rustc_legacy_const_generics, ..] => {200 [sym::rustc_legacy_const_generics, ..] => {
201 self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)201 self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)
202 }202 }
203 [sym::rustc_lint_query_instability, ..] => {203 [sym::rustc_lint_query_instability, ..] => {
204 self.check_applied_to_fn_or_method(hir_id, attr, span, target)204 self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
205 }205 }
206 [sym::rustc_lint_untracked_query_information, ..] => {206 [sym::rustc_lint_untracked_query_information, ..] => {
207 self.check_applied_to_fn_or_method(hir_id, attr, span, target)207 self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
208 }208 }
209 [sym::rustc_lint_diagnostics, ..] => {209 [sym::rustc_lint_diagnostics, ..] => {
210 self.check_applied_to_fn_or_method(hir_id, attr, span, target)210 self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
211 }211 }
212 [sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target),212 [sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target),
213 [sym::rustc_lint_opt_deny_field_access, ..] => {213 [sym::rustc_lint_opt_deny_field_access, ..] => {
...@@ -1825,15 +1825,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {...@@ -1825,15 +1825,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
1825 fn check_applied_to_fn_or_method(1825 fn check_applied_to_fn_or_method(
1826 &self,1826 &self,
1827 hir_id: HirId,1827 hir_id: HirId,
1828 attr: &Attribute,1828 attr_span: Span,
1829 span: Span,1829 defn_span: Span,
1830 target: Target,1830 target: Target,
1831 ) {1831 ) {
1832 let is_function = matches!(target, Target::Fn | Target::Method(..));1832 let is_function = matches!(target, Target::Fn | Target::Method(..));
1833 if !is_function {1833 if !is_function {
1834 self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {1834 self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
1835 attr_span: attr.span(),1835 attr_span,
1836 defn_span: span,1836 defn_span,
1837 on_crate: hir_id == CRATE_HIR_ID,1837 on_crate: hir_id == CRATE_HIR_ID,
1838 });1838 });
1839 }1839 }
compiler/rustc_resolve/src/late.rs+12-12
...@@ -415,24 +415,24 @@ pub(crate) enum AliasPossibility {...@@ -415,24 +415,24 @@ pub(crate) enum AliasPossibility {
415}415}
416416
417#[derive(Copy, Clone, Debug)]417#[derive(Copy, Clone, Debug)]
418pub(crate) enum PathSource<'a, 'c> {418pub(crate) enum PathSource<'a, 'ast, 'ra> {
419 /// Type paths `Path`.419 /// Type paths `Path`.
420 Type,420 Type,
421 /// Trait paths in bounds or impls.421 /// Trait paths in bounds or impls.
422 Trait(AliasPossibility),422 Trait(AliasPossibility),
423 /// Expression paths `path`, with optional parent context.423 /// Expression paths `path`, with optional parent context.
424 Expr(Option<&'a Expr>),424 Expr(Option<&'ast Expr>),
425 /// Paths in path patterns `Path`.425 /// Paths in path patterns `Path`.
426 Pat,426 Pat,
427 /// Paths in struct expressions and patterns `Path { .. }`.427 /// Paths in struct expressions and patterns `Path { .. }`.
428 Struct,428 Struct,
429 /// Paths in tuple struct patterns `Path(..)`.429 /// Paths in tuple struct patterns `Path(..)`.
430 TupleStruct(Span, &'a [Span]),430 TupleStruct(Span, &'ra [Span]),
431 /// `m::A::B` in `<T as m::A>::B::C`.431 /// `m::A::B` in `<T as m::A>::B::C`.
432 ///432 ///
433 /// Second field holds the "cause" of this one, i.e. the context within433 /// Second field holds the "cause" of this one, i.e. the context within
434 /// which the trait item is resolved. Used for diagnostics.434 /// which the trait item is resolved. Used for diagnostics.
435 TraitItem(Namespace, &'c PathSource<'a, 'c>),435 TraitItem(Namespace, &'a PathSource<'a, 'ast, 'ra>),
436 /// Paths in delegation item436 /// Paths in delegation item
437 Delegation,437 Delegation,
438 /// An arg in a `use<'a, N>` precise-capturing bound.438 /// An arg in a `use<'a, N>` precise-capturing bound.
...@@ -443,7 +443,7 @@ pub(crate) enum PathSource<'a, 'c> {...@@ -443,7 +443,7 @@ pub(crate) enum PathSource<'a, 'c> {
443 DefineOpaques,443 DefineOpaques,
444}444}
445445
446impl<'a> PathSource<'a, '_> {446impl PathSource<'_, '_, '_> {
447 fn namespace(self) -> Namespace {447 fn namespace(self) -> Namespace {
448 match self {448 match self {
449 PathSource::Type449 PathSource::Type
...@@ -773,7 +773,7 @@ struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -773,7 +773,7 @@ struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
773}773}
774774
775/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.775/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
776impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {776impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
777 fn visit_attribute(&mut self, _: &'ast Attribute) {777 fn visit_attribute(&mut self, _: &'ast Attribute) {
778 // We do not want to resolve expressions that appear in attributes,778 // We do not want to resolve expressions that appear in attributes,
779 // as they do not correspond to actual code.779 // as they do not correspond to actual code.
...@@ -1462,7 +1462,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r...@@ -1462,7 +1462,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
1462 }1462 }
1463}1463}
14641464
1465impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {1465impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
1466 fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {1466 fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
1467 // During late resolution we only track the module component of the parent scope,1467 // During late resolution we only track the module component of the parent scope,
1468 // although it may be useful to track other components as well for diagnostics.1468 // although it may be useful to track other components as well for diagnostics.
...@@ -2010,7 +2010,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -2010,7 +2010,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
2010 &mut self,2010 &mut self,
2011 partial_res: PartialRes,2011 partial_res: PartialRes,
2012 path: &[Segment],2012 path: &[Segment],
2013 source: PathSource<'_, '_>,2013 source: PathSource<'_, '_, '_>,
2014 path_span: Span,2014 path_span: Span,
2015 ) {2015 ) {
2016 let proj_start = path.len() - partial_res.unresolved_segments();2016 let proj_start = path.len() - partial_res.unresolved_segments();
...@@ -4161,7 +4161,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -4161,7 +4161,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
4161 id: NodeId,4161 id: NodeId,
4162 qself: &Option<P<QSelf>>,4162 qself: &Option<P<QSelf>>,
4163 path: &Path,4163 path: &Path,
4164 source: PathSource<'ast, '_>,4164 source: PathSource<'_, 'ast, '_>,
4165 ) {4165 ) {
4166 self.smart_resolve_path_fragment(4166 self.smart_resolve_path_fragment(
4167 qself,4167 qself,
...@@ -4178,7 +4178,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -4178,7 +4178,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
4178 &mut self,4178 &mut self,
4179 qself: &Option<P<QSelf>>,4179 qself: &Option<P<QSelf>>,
4180 path: &[Segment],4180 path: &[Segment],
4181 source: PathSource<'ast, '_>,4181 source: PathSource<'_, 'ast, '_>,
4182 finalize: Finalize,4182 finalize: Finalize,
4183 record_partial_res: RecordPartialRes,4183 record_partial_res: RecordPartialRes,
4184 parent_qself: Option<&QSelf>,4184 parent_qself: Option<&QSelf>,
...@@ -4482,7 +4482,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -4482,7 +4482,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
4482 span: Span,4482 span: Span,
4483 defer_to_typeck: bool,4483 defer_to_typeck: bool,
4484 finalize: Finalize,4484 finalize: Finalize,
4485 source: PathSource<'ast, '_>,4485 source: PathSource<'_, 'ast, '_>,
4486 ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {4486 ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
4487 let mut fin_res = None;4487 let mut fin_res = None;
44884488
...@@ -4525,7 +4525,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -4525,7 +4525,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
4525 path: &[Segment],4525 path: &[Segment],
4526 ns: Namespace,4526 ns: Namespace,
4527 finalize: Finalize,4527 finalize: Finalize,
4528 source: PathSource<'ast, '_>,4528 source: PathSource<'_, 'ast, '_>,
4529 ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {4529 ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
4530 debug!(4530 debug!(
4531 "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",4531 "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
compiler/rustc_resolve/src/late/diagnostics.rs+21-21
...@@ -170,12 +170,12 @@ impl TypoCandidate {...@@ -170,12 +170,12 @@ impl TypoCandidate {
170 }170 }
171}171}
172172
173impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {173impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
174 fn make_base_error(174 fn make_base_error(
175 &mut self,175 &mut self,
176 path: &[Segment],176 path: &[Segment],
177 span: Span,177 span: Span,
178 source: PathSource<'_, '_>,178 source: PathSource<'_, '_, '_>,
179 res: Option<Res>,179 res: Option<Res>,
180 ) -> BaseError {180 ) -> BaseError {
181 // Make the base error.181 // Make the base error.
...@@ -421,7 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -421,7 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
421 path: &[Segment],421 path: &[Segment],
422 following_seg: Option<&Segment>,422 following_seg: Option<&Segment>,
423 span: Span,423 span: Span,
424 source: PathSource<'_, '_>,424 source: PathSource<'_, '_, '_>,
425 res: Option<Res>,425 res: Option<Res>,
426 qself: Option<&QSelf>,426 qself: Option<&QSelf>,
427 ) -> (Diag<'tcx>, Vec<ImportSuggestion>) {427 ) -> (Diag<'tcx>, Vec<ImportSuggestion>) {
...@@ -539,7 +539,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -539,7 +539,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
539 path: &[Segment],539 path: &[Segment],
540 following_seg: Option<&Segment>,540 following_seg: Option<&Segment>,
541 span: Span,541 span: Span,
542 source: PathSource<'_, '_>,542 source: PathSource<'_, '_, '_>,
543 res: Option<Res>,543 res: Option<Res>,
544 qself: Option<&QSelf>,544 qself: Option<&QSelf>,
545 ) {545 ) {
...@@ -650,7 +650,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -650,7 +650,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
650 fn try_lookup_name_relaxed(650 fn try_lookup_name_relaxed(
651 &mut self,651 &mut self,
652 err: &mut Diag<'_>,652 err: &mut Diag<'_>,
653 source: PathSource<'_, '_>,653 source: PathSource<'_, '_, '_>,
654 path: &[Segment],654 path: &[Segment],
655 following_seg: Option<&Segment>,655 following_seg: Option<&Segment>,
656 span: Span,656 span: Span,
...@@ -940,7 +940,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -940,7 +940,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
940 fn suggest_trait_and_bounds(940 fn suggest_trait_and_bounds(
941 &mut self,941 &mut self,
942 err: &mut Diag<'_>,942 err: &mut Diag<'_>,
943 source: PathSource<'_, '_>,943 source: PathSource<'_, '_, '_>,
944 res: Option<Res>,944 res: Option<Res>,
945 span: Span,945 span: Span,
946 base_error: &BaseError,946 base_error: &BaseError,
...@@ -1017,7 +1017,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1017,7 +1017,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1017 fn suggest_typo(1017 fn suggest_typo(
1018 &mut self,1018 &mut self,
1019 err: &mut Diag<'_>,1019 err: &mut Diag<'_>,
1020 source: PathSource<'_, '_>,1020 source: PathSource<'_, '_, '_>,
1021 path: &[Segment],1021 path: &[Segment],
1022 following_seg: Option<&Segment>,1022 following_seg: Option<&Segment>,
1023 span: Span,1023 span: Span,
...@@ -1063,7 +1063,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1063,7 +1063,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1063 fn suggest_shadowed(1063 fn suggest_shadowed(
1064 &mut self,1064 &mut self,
1065 err: &mut Diag<'_>,1065 err: &mut Diag<'_>,
1066 source: PathSource<'_, '_>,1066 source: PathSource<'_, '_, '_>,
1067 path: &[Segment],1067 path: &[Segment],
1068 following_seg: Option<&Segment>,1068 following_seg: Option<&Segment>,
1069 span: Span,1069 span: Span,
...@@ -1096,7 +1096,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1096,7 +1096,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1096 fn err_code_special_cases(1096 fn err_code_special_cases(
1097 &mut self,1097 &mut self,
1098 err: &mut Diag<'_>,1098 err: &mut Diag<'_>,
1099 source: PathSource<'_, '_>,1099 source: PathSource<'_, '_, '_>,
1100 path: &[Segment],1100 path: &[Segment],
1101 span: Span,1101 span: Span,
1102 ) {1102 ) {
...@@ -1141,7 +1141,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1141,7 +1141,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1141 fn suggest_self_ty(1141 fn suggest_self_ty(
1142 &mut self,1142 &mut self,
1143 err: &mut Diag<'_>,1143 err: &mut Diag<'_>,
1144 source: PathSource<'_, '_>,1144 source: PathSource<'_, '_, '_>,
1145 path: &[Segment],1145 path: &[Segment],
1146 span: Span,1146 span: Span,
1147 ) -> bool {1147 ) -> bool {
...@@ -1164,7 +1164,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1164,7 +1164,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1164 fn suggest_self_value(1164 fn suggest_self_value(
1165 &mut self,1165 &mut self,
1166 err: &mut Diag<'_>,1166 err: &mut Diag<'_>,
1167 source: PathSource<'_, '_>,1167 source: PathSource<'_, '_, '_>,
1168 path: &[Segment],1168 path: &[Segment],
1169 span: Span,1169 span: Span,
1170 ) -> bool {1170 ) -> bool {
...@@ -1332,7 +1332,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1332,7 +1332,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1332 fn suggest_swapping_misplaced_self_ty_and_trait(1332 fn suggest_swapping_misplaced_self_ty_and_trait(
1333 &mut self,1333 &mut self,
1334 err: &mut Diag<'_>,1334 err: &mut Diag<'_>,
1335 source: PathSource<'_, '_>,1335 source: PathSource<'_, '_, '_>,
1336 res: Option<Res>,1336 res: Option<Res>,
1337 span: Span,1337 span: Span,
1338 ) {1338 ) {
...@@ -1361,7 +1361,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1361,7 +1361,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1361 &mut self,1361 &mut self,
1362 err: &mut Diag<'_>,1362 err: &mut Diag<'_>,
1363 res: Option<Res>,1363 res: Option<Res>,
1364 source: PathSource<'_, '_>,1364 source: PathSource<'_, '_, '_>,
1365 ) {1365 ) {
1366 let PathSource::TupleStruct(_, _) = source else { return };1366 let PathSource::TupleStruct(_, _) = source else { return };
1367 let Some(Res::Def(DefKind::Fn, _)) = res else { return };1367 let Some(Res::Def(DefKind::Fn, _)) = res else { return };
...@@ -1373,7 +1373,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1373,7 +1373,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1373 &mut self,1373 &mut self,
1374 err: &mut Diag<'_>,1374 err: &mut Diag<'_>,
1375 res: Option<Res>,1375 res: Option<Res>,
1376 source: PathSource<'_, '_>,1376 source: PathSource<'_, '_, '_>,
1377 span: Span,1377 span: Span,
1378 ) {1378 ) {
1379 let PathSource::Trait(_) = source else { return };1379 let PathSource::Trait(_) = source else { return };
...@@ -1422,7 +1422,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1422,7 +1422,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1422 fn suggest_pattern_match_with_let(1422 fn suggest_pattern_match_with_let(
1423 &mut self,1423 &mut self,
1424 err: &mut Diag<'_>,1424 err: &mut Diag<'_>,
1425 source: PathSource<'_, '_>,1425 source: PathSource<'_, '_, '_>,
1426 span: Span,1426 span: Span,
1427 ) -> bool {1427 ) -> bool {
1428 if let PathSource::Expr(_) = source1428 if let PathSource::Expr(_) = source
...@@ -1448,7 +1448,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1448,7 +1448,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1448 fn get_single_associated_item(1448 fn get_single_associated_item(
1449 &mut self,1449 &mut self,
1450 path: &[Segment],1450 path: &[Segment],
1451 source: &PathSource<'_, '_>,1451 source: &PathSource<'_, '_, '_>,
1452 filter_fn: &impl Fn(Res) -> bool,1452 filter_fn: &impl Fn(Res) -> bool,
1453 ) -> Option<TypoSuggestion> {1453 ) -> Option<TypoSuggestion> {
1454 if let crate::PathSource::TraitItem(_, _) = source {1454 if let crate::PathSource::TraitItem(_, _) = source {
...@@ -1556,7 +1556,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1556,7 +1556,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
15561556
1557 /// Check if the source is call expression and the first argument is `self`. If true,1557 /// Check if the source is call expression and the first argument is `self`. If true,
1558 /// return the span of whole call and the span for all arguments expect the first one (`self`).1558 /// return the span of whole call and the span for all arguments expect the first one (`self`).
1559 fn call_has_self_arg(&self, source: PathSource<'_, '_>) -> Option<(Span, Option<Span>)> {1559 fn call_has_self_arg(&self, source: PathSource<'_, '_, '_>) -> Option<(Span, Option<Span>)> {
1560 let mut has_self_arg = None;1560 let mut has_self_arg = None;
1561 if let PathSource::Expr(Some(parent)) = source1561 if let PathSource::Expr(Some(parent)) = source
1562 && let ExprKind::Call(_, args) = &parent.kind1562 && let ExprKind::Call(_, args) = &parent.kind
...@@ -1614,7 +1614,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1614,7 +1614,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1614 &mut self,1614 &mut self,
1615 err: &mut Diag<'_>,1615 err: &mut Diag<'_>,
1616 span: Span,1616 span: Span,
1617 source: PathSource<'_, '_>,1617 source: PathSource<'_, '_, '_>,
1618 path: &[Segment],1618 path: &[Segment],
1619 res: Res,1619 res: Res,
1620 path_str: &str,1620 path_str: &str,
...@@ -1666,7 +1666,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -1666,7 +1666,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1666 }1666 }
1667 };1667 };
16681668
1669 let find_span = |source: &PathSource<'_, '_>, err: &mut Diag<'_>| {1669 let find_span = |source: &PathSource<'_, '_, '_>, err: &mut Diag<'_>| {
1670 match source {1670 match source {
1671 PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. }))1671 PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. }))
1672 | PathSource::TupleStruct(span, _) => {1672 | PathSource::TupleStruct(span, _) => {
...@@ -2699,7 +2699,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -2699,7 +2699,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
2699 fn suggest_using_enum_variant(2699 fn suggest_using_enum_variant(
2700 &mut self,2700 &mut self,
2701 err: &mut Diag<'_>,2701 err: &mut Diag<'_>,
2702 source: PathSource<'_, '_>,2702 source: PathSource<'_, '_, '_>,
2703 def_id: DefId,2703 def_id: DefId,
2704 span: Span,2704 span: Span,
2705 ) {2705 ) {
...@@ -2877,7 +2877,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {...@@ -2877,7 +2877,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
2877 pub(crate) fn suggest_adding_generic_parameter(2877 pub(crate) fn suggest_adding_generic_parameter(
2878 &self,2878 &self,
2879 path: &[Segment],2879 path: &[Segment],
2880 source: PathSource<'_, '_>,2880 source: PathSource<'_, '_, '_>,
2881 ) -> Option<(Span, &'static str, String, Applicability)> {2881 ) -> Option<(Span, &'static str, String, Applicability)> {
2882 let (ident, span) = match path {2882 let (ident, span) = match path {
2883 [segment]2883 [segment]
compiler/rustc_target/src/callconv/mips64.rs+2-13
...@@ -2,9 +2,7 @@ use rustc_abi::{...@@ -2,9 +2,7 @@ use rustc_abi::{
2 BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Size, TyAbiInterface,2 BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Size, TyAbiInterface,
3};3};
44
5use crate::callconv::{5use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
6 ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode, Uniform,
7};
86
9fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {7fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
10 // Always sign extend u32 values on 64-bit mips8 // Always sign extend u32 values on 64-bit mips
...@@ -140,16 +138,7 @@ where...@@ -140,16 +138,7 @@ where
140138
141 // Extract first 8 chunks as the prefix139 // Extract first 8 chunks as the prefix
142 let rest_size = size - Size::from_bytes(8) * prefix_index as u64;140 let rest_size = size - Size::from_bytes(8) * prefix_index as u64;
143 arg.cast_to(CastTarget {141 arg.cast_to(CastTarget::prefixed(prefix, Uniform::new(Reg::i64(), rest_size)));
144 prefix,
145 rest: Uniform::new(Reg::i64(), rest_size),
146 attrs: ArgAttributes {
147 regular: ArgAttribute::default(),
148 arg_ext: ArgExtension::None,
149 pointee_size: Size::ZERO,
150 pointee_align: None,
151 },
152 });
153}142}
154143
155pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)144pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
compiler/rustc_target/src/callconv/mod.rs+57-27
...@@ -197,6 +197,17 @@ impl ArgAttributes {...@@ -197,6 +197,17 @@ impl ArgAttributes {
197 }197 }
198}198}
199199
200impl From<ArgAttribute> for ArgAttributes {
201 fn from(value: ArgAttribute) -> Self {
202 Self {
203 regular: value,
204 arg_ext: ArgExtension::None,
205 pointee_size: Size::ZERO,
206 pointee_align: None,
207 }
208 }
209}
210
200/// An argument passed entirely registers with the211/// An argument passed entirely registers with the
201/// same kind (e.g., HFA / HVA on PPC64 and AArch64).212/// same kind (e.g., HFA / HVA on PPC64 and AArch64).
202#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]213#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
...@@ -251,6 +262,9 @@ impl Uniform {...@@ -251,6 +262,9 @@ impl Uniform {
251#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]262#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
252pub struct CastTarget {263pub struct CastTarget {
253 pub prefix: [Option<Reg>; 8],264 pub prefix: [Option<Reg>; 8],
265 /// The offset of `rest` from the start of the value. Currently only implemented for a `Reg`
266 /// pair created by the `offset_pair` method.
267 pub rest_offset: Option<Size>,
254 pub rest: Uniform,268 pub rest: Uniform,
255 pub attrs: ArgAttributes,269 pub attrs: ArgAttributes,
256}270}
...@@ -263,42 +277,45 @@ impl From<Reg> for CastTarget {...@@ -263,42 +277,45 @@ impl From<Reg> for CastTarget {
263277
264impl From<Uniform> for CastTarget {278impl From<Uniform> for CastTarget {
265 fn from(uniform: Uniform) -> CastTarget {279 fn from(uniform: Uniform) -> CastTarget {
266 CastTarget {280 Self::prefixed([None; 8], uniform)
267 prefix: [None; 8],
268 rest: uniform,
269 attrs: ArgAttributes {
270 regular: ArgAttribute::default(),
271 arg_ext: ArgExtension::None,
272 pointee_size: Size::ZERO,
273 pointee_align: None,
274 },
275 }
276 }281 }
277}282}
278283
279impl CastTarget {284impl CastTarget {
280 pub fn pair(a: Reg, b: Reg) -> CastTarget {285 pub fn prefixed(prefix: [Option<Reg>; 8], rest: Uniform) -> Self {
281 CastTarget {286 Self { prefix, rest_offset: None, rest, attrs: ArgAttributes::new() }
287 }
288
289 pub fn offset_pair(a: Reg, offset_from_start: Size, b: Reg) -> Self {
290 Self {
282 prefix: [Some(a), None, None, None, None, None, None, None],291 prefix: [Some(a), None, None, None, None, None, None, None],
283 rest: Uniform::from(b),292 rest_offset: Some(offset_from_start),
284 attrs: ArgAttributes {293 rest: b.into(),
285 regular: ArgAttribute::default(),294 attrs: ArgAttributes::new(),
286 arg_ext: ArgExtension::None,
287 pointee_size: Size::ZERO,
288 pointee_align: None,
289 },
290 }295 }
291 }296 }
292297
298 pub fn with_attrs(mut self, attrs: ArgAttributes) -> Self {
299 self.attrs = attrs;
300 self
301 }
302
303 pub fn pair(a: Reg, b: Reg) -> CastTarget {
304 Self::prefixed([Some(a), None, None, None, None, None, None, None], Uniform::from(b))
305 }
306
293 /// When you only access the range containing valid data, you can use this unaligned size;307 /// When you only access the range containing valid data, you can use this unaligned size;
294 /// otherwise, use the safer `size` method.308 /// otherwise, use the safer `size` method.
295 pub fn unaligned_size<C: HasDataLayout>(&self, _cx: &C) -> Size {309 pub fn unaligned_size<C: HasDataLayout>(&self, _cx: &C) -> Size {
296 // Prefix arguments are passed in specific designated registers310 // Prefix arguments are passed in specific designated registers
297 let prefix_size = self311 let prefix_size = if let Some(offset_from_start) = self.rest_offset {
298 .prefix312 offset_from_start
299 .iter()313 } else {
300 .filter_map(|x| x.map(|reg| reg.size))314 self.prefix
301 .fold(Size::ZERO, |acc, size| acc + size);315 .iter()
316 .filter_map(|x| x.map(|reg| reg.size))
317 .fold(Size::ZERO, |acc, size| acc + size)
318 };
302 // Remaining arguments are passed in chunks of the unit size319 // Remaining arguments are passed in chunks of the unit size
303 let rest_size =320 let rest_size =
304 self.rest.unit.size * self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes());321 self.rest.unit.size * self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes());
...@@ -322,9 +339,22 @@ impl CastTarget {...@@ -322,9 +339,22 @@ impl CastTarget {
322 /// Checks if these two `CastTarget` are equal enough to be considered "the same for all339 /// Checks if these two `CastTarget` are equal enough to be considered "the same for all
323 /// function call ABIs".340 /// function call ABIs".
324 pub fn eq_abi(&self, other: &Self) -> bool {341 pub fn eq_abi(&self, other: &Self) -> bool {
325 let CastTarget { prefix: prefix_l, rest: rest_l, attrs: attrs_l } = self;342 let CastTarget {
326 let CastTarget { prefix: prefix_r, rest: rest_r, attrs: attrs_r } = other;343 prefix: prefix_l,
327 prefix_l == prefix_r && rest_l == rest_r && attrs_l.eq_abi(attrs_r)344 rest_offset: rest_offset_l,
345 rest: rest_l,
346 attrs: attrs_l,
347 } = self;
348 let CastTarget {
349 prefix: prefix_r,
350 rest_offset: rest_offset_r,
351 rest: rest_r,
352 attrs: attrs_r,
353 } = other;
354 prefix_l == prefix_r
355 && rest_offset_l == rest_offset_r
356 && rest_l == rest_r
357 && attrs_l.eq_abi(attrs_r)
328 }358 }
329}359}
330360
compiler/rustc_target/src/callconv/nvptx64.rs+9-16
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1use rustc_abi::{HasDataLayout, Reg, Size, TyAbiInterface};1use rustc_abi::{HasDataLayout, Reg, Size, TyAbiInterface};
22
3use super::{ArgAttribute, ArgAttributes, ArgExtension, CastTarget};3use super::CastTarget;
4use crate::callconv::{ArgAbi, FnAbi, Uniform};4use crate::callconv::{ArgAbi, FnAbi, Uniform};
55
6fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {6fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
...@@ -34,16 +34,10 @@ fn classify_aggregate<Ty>(arg: &mut ArgAbi<'_, Ty>) {...@@ -34,16 +34,10 @@ fn classify_aggregate<Ty>(arg: &mut ArgAbi<'_, Ty>) {
34 };34 };
3535
36 if align_bytes == size.bytes() {36 if align_bytes == size.bytes() {
37 arg.cast_to(CastTarget {37 arg.cast_to(CastTarget::prefixed(
38 prefix: [Some(reg), None, None, None, None, None, None, None],38 [Some(reg), None, None, None, None, None, None, None],
39 rest: Uniform::new(Reg::i8(), Size::from_bytes(0)),39 Uniform::new(Reg::i8(), Size::ZERO),
40 attrs: ArgAttributes {40 ));
41 regular: ArgAttribute::default(),
42 arg_ext: ArgExtension::None,
43 pointee_size: Size::ZERO,
44 pointee_align: None,
45 },
46 });
47 } else {41 } else {
48 arg.cast_to(Uniform::new(reg, size));42 arg.cast_to(Uniform::new(reg, size));
49 }43 }
...@@ -78,11 +72,10 @@ where...@@ -78,11 +72,10 @@ where
78 };72 };
79 if arg.layout.size.bytes() / align_bytes == 1 {73 if arg.layout.size.bytes() / align_bytes == 1 {
80 // Make sure we pass the struct as array at the LLVM IR level and not as a single integer.74 // Make sure we pass the struct as array at the LLVM IR level and not as a single integer.
81 arg.cast_to(CastTarget {75 arg.cast_to(CastTarget::prefixed(
82 prefix: [Some(unit), None, None, None, None, None, None, None],76 [Some(unit), None, None, None, None, None, None, None],
83 rest: Uniform::new(unit, Size::ZERO),77 Uniform::new(unit, Size::ZERO),
84 attrs: ArgAttributes::new(),78 ));
85 });
86 } else {79 } else {
87 arg.cast_to(Uniform::new(unit, arg.layout.size));80 arg.cast_to(Uniform::new(unit, arg.layout.size));
88 }81 }
compiler/rustc_target/src/callconv/riscv.rs+105-32
...@@ -14,16 +14,16 @@ use crate::spec::HasTargetSpec;...@@ -14,16 +14,16 @@ use crate::spec::HasTargetSpec;
1414
15#[derive(Copy, Clone)]15#[derive(Copy, Clone)]
16enum RegPassKind {16enum RegPassKind {
17 Float(Reg),17 Float { offset_from_start: Size, ty: Reg },
18 Integer(Reg),18 Integer { offset_from_start: Size, ty: Reg },
19 Unknown,19 Unknown,
20}20}
2121
22#[derive(Copy, Clone)]22#[derive(Copy, Clone)]
23enum FloatConv {23enum FloatConv {
24 FloatPair(Reg, Reg),24 FloatPair { first_ty: Reg, second_ty_offset_from_start: Size, second_ty: Reg },
25 Float(Reg),25 Float(Reg),
26 MixedPair(Reg, Reg),26 MixedPair { first_ty: Reg, second_ty_offset_from_start: Size, second_ty: Reg },
27}27}
2828
29#[derive(Copy, Clone)]29#[derive(Copy, Clone)]
...@@ -43,6 +43,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(...@@ -43,6 +43,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
43 flen: u64,43 flen: u64,
44 field1_kind: &mut RegPassKind,44 field1_kind: &mut RegPassKind,
45 field2_kind: &mut RegPassKind,45 field2_kind: &mut RegPassKind,
46 offset_from_start: Size,
46) -> Result<(), CannotUseFpConv>47) -> Result<(), CannotUseFpConv>
47where48where
48 Ty: TyAbiInterface<'a, C> + Copy,49 Ty: TyAbiInterface<'a, C> + Copy,
...@@ -55,16 +56,16 @@ where...@@ -55,16 +56,16 @@ where
55 }56 }
56 match (*field1_kind, *field2_kind) {57 match (*field1_kind, *field2_kind) {
57 (RegPassKind::Unknown, _) => {58 (RegPassKind::Unknown, _) => {
58 *field1_kind = RegPassKind::Integer(Reg {59 *field1_kind = RegPassKind::Integer {
59 kind: RegKind::Integer,60 offset_from_start,
60 size: arg_layout.size,61 ty: Reg { kind: RegKind::Integer, size: arg_layout.size },
61 });62 };
62 }63 }
63 (RegPassKind::Float(_), RegPassKind::Unknown) => {64 (RegPassKind::Float { .. }, RegPassKind::Unknown) => {
64 *field2_kind = RegPassKind::Integer(Reg {65 *field2_kind = RegPassKind::Integer {
65 kind: RegKind::Integer,66 offset_from_start,
66 size: arg_layout.size,67 ty: Reg { kind: RegKind::Integer, size: arg_layout.size },
67 });68 };
68 }69 }
69 _ => return Err(CannotUseFpConv),70 _ => return Err(CannotUseFpConv),
70 }71 }
...@@ -75,12 +76,16 @@ where...@@ -75,12 +76,16 @@ where
75 }76 }
76 match (*field1_kind, *field2_kind) {77 match (*field1_kind, *field2_kind) {
77 (RegPassKind::Unknown, _) => {78 (RegPassKind::Unknown, _) => {
78 *field1_kind =79 *field1_kind = RegPassKind::Float {
79 RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size });80 offset_from_start,
81 ty: Reg { kind: RegKind::Float, size: arg_layout.size },
82 };
80 }83 }
81 (_, RegPassKind::Unknown) => {84 (_, RegPassKind::Unknown) => {
82 *field2_kind =85 *field2_kind = RegPassKind::Float {
83 RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size });86 offset_from_start,
87 ty: Reg { kind: RegKind::Float, size: arg_layout.size },
88 };
84 }89 }
85 _ => return Err(CannotUseFpConv),90 _ => return Err(CannotUseFpConv),
86 }91 }
...@@ -102,13 +107,14 @@ where...@@ -102,13 +107,14 @@ where
102 flen,107 flen,
103 field1_kind,108 field1_kind,
104 field2_kind,109 field2_kind,
110 offset_from_start,
105 );111 );
106 }112 }
107 return Err(CannotUseFpConv);113 return Err(CannotUseFpConv);
108 }114 }
109 }115 }
110 FieldsShape::Array { count, .. } => {116 FieldsShape::Array { count, .. } => {
111 for _ in 0..count {117 for i in 0..count {
112 let elem_layout = arg_layout.field(cx, 0);118 let elem_layout = arg_layout.field(cx, 0);
113 should_use_fp_conv_helper(119 should_use_fp_conv_helper(
114 cx,120 cx,
...@@ -117,6 +123,7 @@ where...@@ -117,6 +123,7 @@ where
117 flen,123 flen,
118 field1_kind,124 field1_kind,
119 field2_kind,125 field2_kind,
126 offset_from_start + elem_layout.size * i,
120 )?;127 )?;
121 }128 }
122 }129 }
...@@ -127,7 +134,15 @@ where...@@ -127,7 +134,15 @@ where
127 }134 }
128 for i in arg_layout.fields.index_by_increasing_offset() {135 for i in arg_layout.fields.index_by_increasing_offset() {
129 let field = arg_layout.field(cx, i);136 let field = arg_layout.field(cx, i);
130 should_use_fp_conv_helper(cx, &field, xlen, flen, field1_kind, field2_kind)?;137 should_use_fp_conv_helper(
138 cx,
139 &field,
140 xlen,
141 flen,
142 field1_kind,
143 field2_kind,
144 offset_from_start + arg_layout.fields.offset(i),
145 )?;
131 }146 }
132 }147 }
133 },148 },
...@@ -146,14 +161,52 @@ where...@@ -146,14 +161,52 @@ where
146{161{
147 let mut field1_kind = RegPassKind::Unknown;162 let mut field1_kind = RegPassKind::Unknown;
148 let mut field2_kind = RegPassKind::Unknown;163 let mut field2_kind = RegPassKind::Unknown;
149 if should_use_fp_conv_helper(cx, arg, xlen, flen, &mut field1_kind, &mut field2_kind).is_err() {164 if should_use_fp_conv_helper(
165 cx,
166 arg,
167 xlen,
168 flen,
169 &mut field1_kind,
170 &mut field2_kind,
171 Size::ZERO,
172 )
173 .is_err()
174 {
150 return None;175 return None;
151 }176 }
152 match (field1_kind, field2_kind) {177 match (field1_kind, field2_kind) {
153 (RegPassKind::Integer(l), RegPassKind::Float(r)) => Some(FloatConv::MixedPair(l, r)),178 (
154 (RegPassKind::Float(l), RegPassKind::Integer(r)) => Some(FloatConv::MixedPair(l, r)),179 RegPassKind::Integer { offset_from_start, .. }
155 (RegPassKind::Float(l), RegPassKind::Float(r)) => Some(FloatConv::FloatPair(l, r)),180 | RegPassKind::Float { offset_from_start, .. },
156 (RegPassKind::Float(f), RegPassKind::Unknown) => Some(FloatConv::Float(f)),181 _,
182 ) if offset_from_start != Size::ZERO => {
183 panic!("type {:?} has a first field with non-zero offset {offset_from_start:?}", arg.ty)
184 }
185 (
186 RegPassKind::Integer { ty: first_ty, .. },
187 RegPassKind::Float { offset_from_start, ty: second_ty },
188 ) => Some(FloatConv::MixedPair {
189 first_ty,
190 second_ty_offset_from_start: offset_from_start,
191 second_ty,
192 }),
193 (
194 RegPassKind::Float { ty: first_ty, .. },
195 RegPassKind::Integer { offset_from_start, ty: second_ty },
196 ) => Some(FloatConv::MixedPair {
197 first_ty,
198 second_ty_offset_from_start: offset_from_start,
199 second_ty,
200 }),
201 (
202 RegPassKind::Float { ty: first_ty, .. },
203 RegPassKind::Float { offset_from_start, ty: second_ty },
204 ) => Some(FloatConv::FloatPair {
205 first_ty,
206 second_ty_offset_from_start: offset_from_start,
207 second_ty,
208 }),
209 (RegPassKind::Float { ty, .. }, RegPassKind::Unknown) => Some(FloatConv::Float(ty)),
157 _ => None,210 _ => None,
158 }211 }
159}212}
...@@ -171,11 +224,19 @@ where...@@ -171,11 +224,19 @@ where
171 FloatConv::Float(f) => {224 FloatConv::Float(f) => {
172 arg.cast_to(f);225 arg.cast_to(f);
173 }226 }
174 FloatConv::FloatPair(l, r) => {227 FloatConv::FloatPair { first_ty, second_ty_offset_from_start, second_ty } => {
175 arg.cast_to(CastTarget::pair(l, r));228 arg.cast_to(CastTarget::offset_pair(
229 first_ty,
230 second_ty_offset_from_start,
231 second_ty,
232 ));
176 }233 }
177 FloatConv::MixedPair(l, r) => {234 FloatConv::MixedPair { first_ty, second_ty_offset_from_start, second_ty } => {
178 arg.cast_to(CastTarget::pair(l, r));235 arg.cast_to(CastTarget::offset_pair(
236 first_ty,
237 second_ty_offset_from_start,
238 second_ty,
239 ));
179 }240 }
180 }241 }
181 return false;242 return false;
...@@ -239,15 +300,27 @@ fn classify_arg<'a, Ty, C>(...@@ -239,15 +300,27 @@ fn classify_arg<'a, Ty, C>(
239 arg.cast_to(f);300 arg.cast_to(f);
240 return;301 return;
241 }302 }
242 Some(FloatConv::FloatPair(l, r)) if *avail_fprs >= 2 => {303 Some(FloatConv::FloatPair { first_ty, second_ty_offset_from_start, second_ty })
304 if *avail_fprs >= 2 =>
305 {
243 *avail_fprs -= 2;306 *avail_fprs -= 2;
244 arg.cast_to(CastTarget::pair(l, r));307 arg.cast_to(CastTarget::offset_pair(
308 first_ty,
309 second_ty_offset_from_start,
310 second_ty,
311 ));
245 return;312 return;
246 }313 }
247 Some(FloatConv::MixedPair(l, r)) if *avail_fprs >= 1 && *avail_gprs >= 1 => {314 Some(FloatConv::MixedPair { first_ty, second_ty_offset_from_start, second_ty })
315 if *avail_fprs >= 1 && *avail_gprs >= 1 =>
316 {
248 *avail_gprs -= 1;317 *avail_gprs -= 1;
249 *avail_fprs -= 1;318 *avail_fprs -= 1;
250 arg.cast_to(CastTarget::pair(l, r));319 arg.cast_to(CastTarget::offset_pair(
320 first_ty,
321 second_ty_offset_from_start,
322 second_ty,
323 ));
251 return;324 return;
252 }325 }
253 _ => (),326 _ => (),
compiler/rustc_target/src/callconv/sparc64.rs+5-13
...@@ -5,9 +5,7 @@ use rustc_abi::{...@@ -5,9 +5,7 @@ use rustc_abi::{
5 TyAndLayout,5 TyAndLayout,
6};6};
77
8use crate::callconv::{8use crate::callconv::{ArgAbi, ArgAttribute, CastTarget, FnAbi, Uniform};
9 ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, Uniform,
10};
11use crate::spec::HasTargetSpec;9use crate::spec::HasTargetSpec;
1210
13#[derive(Clone, Debug)]11#[derive(Clone, Debug)]
...@@ -197,16 +195,10 @@ where...@@ -197,16 +195,10 @@ where
197 rest_size = rest_size - Reg::i32().size;195 rest_size = rest_size - Reg::i32().size;
198 }196 }
199197
200 arg.cast_to(CastTarget {198 arg.cast_to(
201 prefix: data.prefix,199 CastTarget::prefixed(data.prefix, Uniform::new(Reg::i64(), rest_size))
202 rest: Uniform::new(Reg::i64(), rest_size),200 .with_attrs(data.arg_attribute.into()),
203 attrs: ArgAttributes {201 );
204 regular: data.arg_attribute,
205 arg_ext: ArgExtension::None,
206 pointee_size: Size::ZERO,
207 pointee_align: None,
208 },
209 });
210 return;202 return;
211 }203 }
212 }204 }
compiler/rustc_type_ir/src/search_graph/mod.rs+6-17
...@@ -842,9 +842,8 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {...@@ -842,9 +842,8 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
842 /// evaluating this entry would not have ended up depending on either a goal842 /// evaluating this entry would not have ended up depending on either a goal
843 /// already on the stack or a provisional cache entry.843 /// already on the stack or a provisional cache entry.
844 fn candidate_is_applicable(844 fn candidate_is_applicable(
845 stack: &Stack<X>,845 &self,
846 step_kind_from_parent: PathKind,846 step_kind_from_parent: PathKind,
847 provisional_cache: &HashMap<X::Input, Vec<ProvisionalCacheEntry<X>>>,
848 nested_goals: &NestedGoals<X>,847 nested_goals: &NestedGoals<X>,
849 ) -> bool {848 ) -> bool {
850 // If the global cache entry didn't depend on any nested goals, it always849 // If the global cache entry didn't depend on any nested goals, it always
...@@ -855,7 +854,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {...@@ -855,7 +854,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
855854
856 // If a nested goal of the global cache entry is on the stack, we would855 // If a nested goal of the global cache entry is on the stack, we would
857 // definitely encounter a cycle.856 // definitely encounter a cycle.
858 if stack.iter().any(|e| nested_goals.contains(e.input)) {857 if self.stack.iter().any(|e| nested_goals.contains(e.input)) {
859 debug!("cache entry not applicable due to stack");858 debug!("cache entry not applicable due to stack");
860 return false;859 return false;
861 }860 }
...@@ -864,7 +863,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {...@@ -864,7 +863,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
864 // would apply for any of its nested goals.863 // would apply for any of its nested goals.
865 #[allow(rustc::potential_query_instability)]864 #[allow(rustc::potential_query_instability)]
866 for (input, path_from_global_entry) in nested_goals.iter() {865 for (input, path_from_global_entry) in nested_goals.iter() {
867 let Some(entries) = provisional_cache.get(&input) else {866 let Some(entries) = self.provisional_cache.get(&input) else {
868 continue;867 continue;
869 };868 };
870869
...@@ -890,7 +889,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {...@@ -890,7 +889,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
890 // We check if any of the paths taken while computing the global goal889 // We check if any of the paths taken while computing the global goal
891 // would end up with an applicable provisional cache entry.890 // would end up with an applicable provisional cache entry.
892 let head = heads.highest_cycle_head();891 let head = heads.highest_cycle_head();
893 let head_to_curr = Self::cycle_path_kind(stack, step_kind_from_parent, head);892 let head_to_curr = Self::cycle_path_kind(&self.stack, step_kind_from_parent, head);
894 let full_paths = path_from_global_entry.extend_with(head_to_curr);893 let full_paths = path_from_global_entry.extend_with(head_to_curr);
895 if full_paths.contains(head_to_provisional.into()) {894 if full_paths.contains(head_to_provisional.into()) {
896 debug!(895 debug!(
...@@ -918,12 +917,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {...@@ -918,12 +917,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
918 cx.with_global_cache(|cache| {917 cx.with_global_cache(|cache| {
919 cache918 cache
920 .get(cx, input, available_depth, |nested_goals| {919 .get(cx, input, available_depth, |nested_goals| {
921 Self::candidate_is_applicable(920 self.candidate_is_applicable(step_kind_from_parent, nested_goals)
922 &self.stack,
923 step_kind_from_parent,
924 &self.provisional_cache,
925 nested_goals,
926 )
927 })921 })
928 .map(|c| c.result)922 .map(|c| c.result)
929 })923 })
...@@ -942,12 +936,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {...@@ -942,12 +936,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
942 cx.with_global_cache(|cache| {936 cx.with_global_cache(|cache| {
943 let CacheData { result, required_depth, encountered_overflow, nested_goals } = cache937 let CacheData { result, required_depth, encountered_overflow, nested_goals } = cache
944 .get(cx, input, available_depth, |nested_goals| {938 .get(cx, input, available_depth, |nested_goals| {
945 Self::candidate_is_applicable(939 self.candidate_is_applicable(step_kind_from_parent, nested_goals)
946 &self.stack,
947 step_kind_from_parent,
948 &self.provisional_cache,
949 nested_goals,
950 )
951 })?;940 })?;
952941
953 // We don't move cycle participants to the global cache, so the942 // We don't move cycle participants to the global cache, so the
library/backtrace+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1Subproject commit 6c882eb11984d737f62e85f36703effaf34c24531Subproject commit b65ab935fb2e0d59dba8966ffca09c9cc5a5f57c
tests/assembly/naked-functions/wasm32.rs+6-3
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1// FIXME: add wasm32-unknown when the wasm32-unknown-unknown ABI is fixed1//@ revisions: wasm32-unknown wasm64-unknown wasm32-wasip1
2// see https://github.com/rust-lang/rust/issues/115666
3//@ revisions: wasm64-unknown wasm32-wasip1
4//@ add-core-stubs2//@ add-core-stubs
5//@ assembly-output: emit-asm3//@ assembly-output: emit-asm
4//@ [wasm32-unknown] compile-flags: --target wasm32-unknown-unknown
6//@ [wasm64-unknown] compile-flags: --target wasm64-unknown-unknown5//@ [wasm64-unknown] compile-flags: --target wasm64-unknown-unknown
7//@ [wasm32-wasip1] compile-flags: --target wasm32-wasip16//@ [wasm32-wasip1] compile-flags: --target wasm32-wasip1
7//@ [wasm32-unknown] needs-llvm-components: webassembly
8//@ [wasm64-unknown] needs-llvm-components: webassembly8//@ [wasm64-unknown] needs-llvm-components: webassembly
9//@ [wasm32-wasip1] needs-llvm-components: webassembly9//@ [wasm32-wasip1] needs-llvm-components: webassembly
1010
...@@ -97,6 +97,7 @@ extern "C" fn fn_i64_i64(num: i64) -> i64 {...@@ -97,6 +97,7 @@ extern "C" fn fn_i64_i64(num: i64) -> i64 {
97}97}
9898
99// CHECK-LABEL: fn_i128_i128:99// CHECK-LABEL: fn_i128_i128:
100// wasm32-unknown: .functype fn_i128_i128 (i32, i64, i64) -> ()
100// wasm32-wasip1: .functype fn_i128_i128 (i32, i64, i64) -> ()101// wasm32-wasip1: .functype fn_i128_i128 (i32, i64, i64) -> ()
101// wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()102// wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()
102#[allow(improper_ctypes_definitions)]103#[allow(improper_ctypes_definitions)]
...@@ -114,6 +115,7 @@ extern "C" fn fn_i128_i128(num: i128) -> i128 {...@@ -114,6 +115,7 @@ extern "C" fn fn_i128_i128(num: i128) -> i128 {
114}115}
115116
116// CHECK-LABEL: fn_f128_f128:117// CHECK-LABEL: fn_f128_f128:
118// wasm32-unknown: .functype fn_f128_f128 (i32, i64, i64) -> ()
117// wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()119// wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()
118// wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()120// wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()
119#[no_mangle]121#[no_mangle]
...@@ -136,6 +138,7 @@ struct Compound {...@@ -136,6 +138,7 @@ struct Compound {
136}138}
137139
138// CHECK-LABEL: fn_compound_compound:140// CHECK-LABEL: fn_compound_compound:
141// wasm32-unknown: .functype fn_compound_compound (i32, i32) -> ()
139// wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()142// wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()
140// wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()143// wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()
141#[no_mangle]144#[no_mangle]
tests/assembly/riscv-float-struct-abi.rs created+177
...@@ -0,0 +1,177 @@
1//@ add-core-stubs
2//@ assembly-output: emit-asm
3//@ compile-flags: -Copt-level=3 --target riscv64gc-unknown-linux-gnu
4//@ needs-llvm-components: riscv
5
6#![feature(no_core, lang_items)]
7#![no_std]
8#![no_core]
9#![crate_type = "lib"]
10
11extern crate minicore;
12use minicore::*;
13
14#[repr(C, align(64))]
15struct Aligned(f64);
16
17#[repr(C)]
18struct Padded(u8, Aligned);
19
20#[repr(C, packed)]
21struct Packed(u8, f32);
22
23impl Copy for Aligned {}
24impl Copy for Padded {}
25impl Copy for Packed {}
26
27extern "C" {
28 fn take_padded(x: Padded);
29 fn get_padded() -> Padded;
30 fn take_packed(x: Packed);
31 fn get_packed() -> Packed;
32}
33
34// CHECK-LABEL: pass_padded
35#[unsafe(no_mangle)]
36extern "C" fn pass_padded(out: &mut Padded, x: Padded) {
37 // CHECK: sb a1, 0(a0)
38 // CHECK-NEXT: fsd fa0, 64(a0)
39 // CHECK-NEXT: ret
40 *out = x;
41}
42
43// CHECK-LABEL: ret_padded
44#[unsafe(no_mangle)]
45extern "C" fn ret_padded(x: &Padded) -> Padded {
46 // CHECK: fld fa0, 64(a0)
47 // CHECK-NEXT: lbu a0, 0(a0)
48 // CHECK-NEXT: ret
49 *x
50}
51
52#[unsafe(no_mangle)]
53extern "C" fn call_padded(x: &Padded) {
54 // CHECK: fld fa0, 64(a0)
55 // CHECK-NEXT: lbu a0, 0(a0)
56 // CHECK-NEXT: tail take_padded
57 unsafe {
58 take_padded(*x);
59 }
60}
61
62#[unsafe(no_mangle)]
63extern "C" fn receive_padded(out: &mut Padded) {
64 // CHECK: addi sp, sp, -16
65 // CHECK-NEXT: .cfi_def_cfa_offset 16
66 // CHECK-NEXT: sd ra, [[#%d,RA_SPILL:]](sp)
67 // CHECK-NEXT: sd [[TEMP:.*]], [[#%d,TEMP_SPILL:]](sp)
68 // CHECK-NEXT: .cfi_offset ra, [[#%d,RA_SPILL - 16]]
69 // CHECK-NEXT: .cfi_offset [[TEMP]], [[#%d,TEMP_SPILL - 16]]
70 // CHECK-NEXT: mv [[TEMP]], a0
71 // CHECK-NEXT: call get_padded
72 // CHECK-NEXT: sb a0, 0([[TEMP]])
73 // CHECK-NEXT: fsd fa0, 64([[TEMP]])
74 // CHECK-NEXT: ld ra, [[#%d,RA_SPILL]](sp)
75 // CHECK-NEXT: ld [[TEMP]], [[#%d,TEMP_SPILL]](sp)
76 // CHECK: addi sp, sp, 16
77 // CHECK: ret
78 unsafe {
79 *out = get_padded();
80 }
81}
82
83// CHECK-LABEL: pass_packed
84#[unsafe(no_mangle)]
85extern "C" fn pass_packed(out: &mut Packed, x: Packed) {
86 // CHECK: addi sp, sp, -16
87 // CHECK-NEXT: .cfi_def_cfa_offset 16
88 // CHECK-NEXT: sb a1, 0(a0)
89 // CHECK-NEXT: fsw fa0, 8(sp)
90 // CHECK-NEXT: lw [[VALUE:.*]], 8(sp)
91 // CHECK-DAG: srli [[BYTE4:.*]], [[VALUE]], 24
92 // CHECK-DAG: srli [[BYTE3:.*]], [[VALUE]], 16
93 // CHECK-DAG: srli [[BYTE2:.*]], [[VALUE]], 8
94 // CHECK-DAG: sb [[VALUE]], 1(a0)
95 // CHECK-DAG: sb [[BYTE2]], 2(a0)
96 // CHECK-DAG: sb [[BYTE3]], 3(a0)
97 // CHECK-DAG: sb [[BYTE4]], 4(a0)
98 // CHECK-NEXT: addi sp, sp, 16
99 // CHECK: ret
100 *out = x;
101}
102
103// CHECK-LABEL: ret_packed
104#[unsafe(no_mangle)]
105extern "C" fn ret_packed(x: &Packed) -> Packed {
106 // CHECK: addi sp, sp, -16
107 // CHECK-NEXT: .cfi_def_cfa_offset 16
108 // CHECK-NEXT: lbu [[BYTE2:.*]], 2(a0)
109 // CHECK-NEXT: lbu [[BYTE1:.*]], 1(a0)
110 // CHECK-NEXT: lbu [[BYTE3:.*]], 3(a0)
111 // CHECK-NEXT: lbu [[BYTE4:.*]], 4(a0)
112 // CHECK-NEXT: slli [[SHIFTED2:.*]], [[BYTE2]], 8
113 // CHECK-NEXT: or [[BYTE12:.*]], [[SHIFTED2]], [[BYTE1]]
114 // CHECK-NEXT: slli [[SHIFTED3:.*]], [[BYTE3]], 16
115 // CHECK-NEXT: slli [[SHIFTED4:.*]], [[BYTE4]], 24
116 // CHECK-NEXT: or [[BYTE34:.*]], [[SHIFTED3]], [[SHIFTED4]]
117 // CHECK-NEXT: or [[VALUE:.*]], [[BYTE12]], [[BYTE34]]
118 // CHECK-NEXT: sw [[VALUE]], 8(sp)
119 // CHECK-NEXT: flw fa0, 8(sp)
120 // CHECK-NEXT: lbu a0, 0(a0)
121 // CHECK-NEXT: addi sp, sp, 16
122 // CHECK: ret
123 *x
124}
125
126#[unsafe(no_mangle)]
127extern "C" fn call_packed(x: &Packed) {
128 // CHECK: addi sp, sp, -16
129 // CHECK-NEXT: .cfi_def_cfa_offset 16
130 // CHECK-NEXT: lbu [[BYTE2:.*]], 2(a0)
131 // CHECK-NEXT: lbu [[BYTE1:.*]], 1(a0)
132 // CHECK-NEXT: lbu [[BYTE3:.*]], 3(a0)
133 // CHECK-NEXT: lbu [[BYTE4:.*]], 4(a0)
134 // CHECK-NEXT: slli [[SHIFTED2:.*]], [[BYTE2]], 8
135 // CHECK-NEXT: or [[BYTE12:.*]], [[SHIFTED2]], [[BYTE1]]
136 // CHECK-NEXT: slli [[SHIFTED3:.*]], [[BYTE3]], 16
137 // CHECK-NEXT: slli [[SHIFTED4:.*]], [[BYTE4]], 24
138 // CHECK-NEXT: or [[BYTE34:.*]], [[SHIFTED3]], [[SHIFTED4]]
139 // CHECK-NEXT: or [[VALUE:.*]], [[BYTE12]], [[BYTE34]]
140 // CHECK-NEXT: sw [[VALUE]], 8(sp)
141 // CHECK-NEXT: flw fa0, 8(sp)
142 // CHECK-NEXT: lbu a0, 0(a0)
143 // CHECK-NEXT: addi sp, sp, 16
144 // CHECK: tail take_packed
145 unsafe {
146 take_packed(*x);
147 }
148}
149
150#[unsafe(no_mangle)]
151extern "C" fn receive_packed(out: &mut Packed) {
152 // CHECK: addi sp, sp, -32
153 // CHECK-NEXT: .cfi_def_cfa_offset 32
154 // CHECK-NEXT: sd ra, [[#%d,RA_SPILL:]](sp)
155 // CHECK-NEXT: sd [[TEMP:.*]], [[#%d,TEMP_SPILL:]](sp)
156 // CHECK-NEXT: .cfi_offset ra, [[#%d,RA_SPILL - 32]]
157 // CHECK-NEXT: .cfi_offset [[TEMP]], [[#%d,TEMP_SPILL - 32]]
158 // CHECK-NEXT: mv [[TEMP]], a0
159 // CHECK-NEXT: call get_packed
160 // CHECK-NEXT: sb a0, 0([[TEMP]])
161 // CHECK-NEXT: fsw fa0, [[FLOAT_SPILL:.*]](sp)
162 // CHECK-NEXT: lw [[VALUE:.*]], [[FLOAT_SPILL]](sp)
163 // CHECK-DAG: srli [[BYTE4:.*]], [[VALUE]], 24
164 // CHECK-DAG: srli [[BYTE3:.*]], [[VALUE]], 16
165 // CHECK-DAG: srli [[BYTE2:.*]], [[VALUE]], 8
166 // CHECK-DAG: sb [[VALUE]], 1([[TEMP]])
167 // CHECK-DAG: sb [[BYTE2]], 2([[TEMP]])
168 // CHECK-DAG: sb [[BYTE3]], 3([[TEMP]])
169 // CHECK-DAG: sb [[BYTE4]], 4([[TEMP]])
170 // CHECK-NEXT: ld ra, [[#%d,RA_SPILL]](sp)
171 // CHECK-NEXT: ld [[TEMP]], [[#%d,TEMP_SPILL]](sp)
172 // CHECK: addi sp, sp, 32
173 // CHECK: ret
174 unsafe {
175 *out = get_packed();
176 }
177}
tests/codegen/riscv-abi/cast-local-large-enough.rs created+44
...@@ -0,0 +1,44 @@
1//@ add-core-stubs
2//@ compile-flags: -Copt-level=0 -Cdebuginfo=0 --target riscv64gc-unknown-linux-gnu
3//@ needs-llvm-components: riscv
4
5#![feature(no_core, lang_items)]
6#![no_std]
7#![no_core]
8#![crate_type = "lib"]
9
10extern crate minicore;
11use minicore::*;
12
13#[repr(C, align(64))]
14struct Aligned(f64);
15
16#[repr(C, align(64))]
17struct AlignedPair(f32, f64);
18
19impl Copy for Aligned {}
20impl Copy for AlignedPair {}
21
22// CHECK-LABEL: define double @read_aligned
23#[unsafe(no_mangle)]
24pub extern "C" fn read_aligned(x: &Aligned) -> Aligned {
25 // CHECK: %[[TEMP:.*]] = alloca [64 x i8], align 64
26 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 64 %[[TEMP]], ptr align 64 %[[PTR:.*]], i64 64, i1 false)
27 // CHECK-NEXT: %[[RES:.*]] = load double, ptr %[[TEMP]], align 64
28 // CHECK-NEXT: ret double %[[RES]]
29 *x
30}
31
32// CHECK-LABEL: define { float, double } @read_aligned_pair
33#[unsafe(no_mangle)]
34pub extern "C" fn read_aligned_pair(x: &AlignedPair) -> AlignedPair {
35 // CHECK: %[[TEMP:.*]] = alloca [64 x i8], align 64
36 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 64 %[[TEMP]], ptr align 64 %[[PTR:.*]], i64 64, i1 false)
37 // CHECK-NEXT: %[[FIRST:.*]] = load float, ptr %[[TEMP]], align 64
38 // CHECK-NEXT: %[[SECOND_PTR:.*]] = getelementptr inbounds i8, ptr %[[TEMP]], i64 8
39 // CHECK-NEXT: %[[SECOND:.*]] = load double, ptr %[[SECOND_PTR]], align 8
40 // CHECK-NEXT: %[[RES1:.*]] = insertvalue { float, double } poison, float %[[FIRST]], 0
41 // CHECK-NEXT: %[[RES2:.*]] = insertvalue { float, double } %[[RES1]], double %[[SECOND]], 1
42 // CHECK-NEXT: ret { float, double } %[[RES2]]
43 *x
44}
tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1// ignore-tidy-linelength2// ignore-tidy-linelength
23
3// Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current4// Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current
tests/run-make/allow-warnings-cmdline-stability/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1// Test that `-Awarnings` suppresses warnings for unstable APIs.2// Test that `-Awarnings` suppresses warnings for unstable APIs.
23
3use run_make_support::rustc;4use run_make_support::rustc;
tests/run-make/artifact-incr-cache-no-obj/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// emitting an object file is not necessary if user didn't ask for one3// emitting an object file is not necessary if user didn't ask for one
2//4//
3// This test is similar to run-make/artifact-incr-cache but it doesn't5// This test is similar to run-make/artifact-incr-cache but it doesn't
tests/run-make/artifact-incr-cache/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// rustc should be able to emit required files (asm, llvm-*, etc) during incremental3// rustc should be able to emit required files (asm, llvm-*, etc) during incremental
2// compilation on the first pass by running the code gen as well as on subsequent runs -4// compilation on the first pass by running the code gen as well as on subsequent runs -
3// extracting them from the cache5// extracting them from the cache
tests/run-make/bin-emit-no-symbols/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When setting the crate type as a "bin" (in app.rs),3// When setting the crate type as a "bin" (in app.rs),
2// this could cause a bug where some symbols would not be4// this could cause a bug where some symbols would not be
3// emitted in the object files. This has been fixed, and5// emitted in the object files. This has been fixed, and
tests/run-make/box-struct-no-segfault/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// The crate "foo" tied to this test executes a very specific function,3// The crate "foo" tied to this test executes a very specific function,
2// which involves boxing an instance of the struct Foo. However,4// which involves boxing an instance of the struct Foo. However,
3// this once caused a segmentation fault in cargo release builds due to an LLVM5// this once caused a segmentation fault in cargo release builds due to an LLVM
tests/run-make/checksum-freshness/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{rfs, rustc};2use run_make_support::{rfs, rustc};
23
3fn main() {4fn main() {
tests/run-make/compiler-lookup-paths-2/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test checks that extern crate declarations in Cargo without a corresponding declaration3// This test checks that extern crate declarations in Cargo without a corresponding declaration
2// in the manifest of a dependency are NOT allowed. The last rustc call does it anyways, which4// in the manifest of a dependency are NOT allowed. The last rustc call does it anyways, which
3// should result in a compilation failure.5// should result in a compilation failure.
tests/run-make/compiler-lookup-paths/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Since #19941, rustc can accept specifications on its library search paths.3// Since #19941, rustc can accept specifications on its library search paths.
2// This test runs Rust programs with varied library dependencies, expecting them4// This test runs Rust programs with varied library dependencies, expecting them
3// to succeed or fail depending on the situation.5// to succeed or fail depending on the situation.
tests/run-make/const-trait-stable-toolchain/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Test output of const super trait errors in both stable and nightly.3// Test output of const super trait errors in both stable and nightly.
2// We don't want to provide suggestions on stable that only make sense in nightly.4// We don't want to provide suggestions on stable that only make sense in nightly.
35
tests/run-make/crate-circular-deps-link/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Test that previously triggered a linker failure with root cause3// Test that previously triggered a linker failure with root cause
2// similar to one found in the issue #69368.4// similar to one found in the issue #69368.
3//5//
tests/run-make/cross-lang-lto-upstream-rlibs/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When using the flag -C linker-plugin-lto, static libraries could lose their upstream object3// When using the flag -C linker-plugin-lto, static libraries could lose their upstream object
2// files during compilation. This bug was fixed in #53031, and this test compiles a staticlib4// files during compilation. This bug was fixed in #53031, and this test compiles a staticlib
3// dependent on upstream, checking that the upstream object file still exists after no LTO and5// dependent on upstream, checking that the upstream object file still exists after no LTO and
tests/run-make/cross-lang-lto/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test checks that the object files we generate are actually3// This test checks that the object files we generate are actually
2// LLVM bitcode files (as used by linker LTO plugins) when compiling with4// LLVM bitcode files (as used by linker LTO plugins) when compiling with
3// -Clinker-plugin-lto.5// -Clinker-plugin-lto.
tests/run-make/debugger-visualizer-dep-info/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test checks that files referenced via #[debugger_visualizer] are3// This test checks that files referenced via #[debugger_visualizer] are
2// included in `--emit dep-info` output.4// included in `--emit dep-info` output.
3// See https://github.com/rust-lang/rust/pull/1116415// See https://github.com/rust-lang/rust/pull/111641
tests/run-make/dep-info/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This is a simple smoke test for rustc's `--emit dep-info` feature. It prints out3// This is a simple smoke test for rustc's `--emit dep-info` feature. It prints out
2// information about dependencies in a Makefile-compatible format, as a `.d` file.4// information about dependencies in a Makefile-compatible format, as a `.d` file.
3// Note that this test does not check that the `.d` file is Makefile-compatible.5// Note that this test does not check that the `.d` file is Makefile-compatible.
tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Non-regression test for issue #132920 where multiple versions of the same crate are present in3// Non-regression test for issue #132920 where multiple versions of the same crate are present in
2// the dependency graph, and an unexpected error in a dependent crate caused an ICE in the4// the dependency graph, and an unexpected error in a dependent crate caused an ICE in the
3// unsatisfied bounds diagnostics for traits present in multiple crate versions.5// unsatisfied bounds diagnostics for traits present in multiple crate versions.
tests/run-make/doctests-merge/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use std::path::Path;2use std::path::Path;
23
3use run_make_support::{cwd, diff, rustc, rustdoc};4use run_make_support::{cwd, diff, rustc, rustdoc};
tests/run-make/doctests-runtool/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Tests behavior of rustdoc `--test-runtool`.3// Tests behavior of rustdoc `--test-runtool`.
24
3use std::path::PathBuf;5use std::path::PathBuf;
tests/run-make/dump-mono-stats/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// A flag named dump-mono-stats was added to the compiler in 2022, which3// A flag named dump-mono-stats was added to the compiler in 2022, which
2// collects stats on instantiation of items and their associated costs.4// collects stats on instantiation of items and their associated costs.
3// This test checks that the output stat file exists, and that it contains5// This test checks that the output stat file exists, and that it contains
tests/run-make/duplicate-output-flavors/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::rustc;2use run_make_support::rustc;
23
3fn main() {4fn main() {
tests/run-make/embed-metadata/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Tests the -Zembed-metadata compiler flag.3// Tests the -Zembed-metadata compiler flag.
2// Tracking issue: https://github.com/rust-lang/rust/issues/1391654// Tracking issue: https://github.com/rust-lang/rust/issues/139165
35
tests/run-make/embed-source-dwarf/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1//@ ignore-windows2//@ ignore-windows
2//@ ignore-apple3//@ ignore-apple
34
tests/run-make/emit-named-files/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use std::path::Path;2use std::path::Path;
23
3use run_make_support::{rfs, rustc};4use run_make_support::{rfs, rustc};
tests/run-make/emit-path-unhashed/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Specifying how rustc outputs a file can be done in different ways, such as3// Specifying how rustc outputs a file can be done in different ways, such as
2// the output flag or the KIND=NAME syntax. However, some of these methods used4// the output flag or the KIND=NAME syntax. However, some of these methods used
3// to result in different hashes on output files even though they yielded the5// to result in different hashes on output files even though they yielded the
tests/run-make/emit-stack-sizes/rmake.rs+1
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
6// this diagnostics information should be located.6// this diagnostics information should be located.
7// See https://github.com/rust-lang/rust/pull/519467// See https://github.com/rust-lang/rust/pull/51946
88
9//@ needs-target-std
9//@ ignore-windows10//@ ignore-windows
10//@ ignore-apple11//@ ignore-apple
11// Reason: this feature only works when the output object format is ELF.12// Reason: this feature only works when the output object format is ELF.
tests/run-make/emit-to-stdout/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1//! If `-o -` or `--emit KIND=-` is provided, output should be written to stdout2//! If `-o -` or `--emit KIND=-` is provided, output should be written to stdout
2//! instead. Binary output (`obj`, `llvm-bc`, `link` and `metadata`)3//! instead. Binary output (`obj`, `llvm-bc`, `link` and `metadata`)
3//! being written this way will result in an error if stdout is a tty.4//! being written this way will result in an error if stdout is a tty.
tests/run-make/env-dep-info/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Inside dep-info emit files, #71858 made it so all accessed environment3// Inside dep-info emit files, #71858 made it so all accessed environment
2// variables are usefully printed. This test checks that this feature works4// variables are usefully printed. This test checks that this feature works
3// as intended by checking if the environment variables used in compilation5// as intended by checking if the environment variables used in compilation
tests/run-make/error-found-staticlib-instead-crate/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When rustc is looking for a crate but is given a staticlib instead,3// When rustc is looking for a crate but is given a staticlib instead,
2// the error message should be helpful and indicate precisely the cause4// the error message should be helpful and indicate precisely the cause
3// of the compilation failure.5// of the compilation failure.
tests/run-make/exit-code/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Test that we exit with the correct exit code for successful / unsuccessful / ICE compilations3// Test that we exit with the correct exit code for successful / unsuccessful / ICE compilations
24
3use run_make_support::{rustc, rustdoc};5use run_make_support::{rustc, rustdoc};
tests/run-make/export/disambiguator/rmake.rs+3-8
...@@ -1,12 +1,7 @@...@@ -1,12 +1,7 @@
1//@ needs-target-std
1use run_make_support::rustc;2use run_make_support::rustc;
23
3fn main() {4fn main() {
4 rustc()5 rustc().env("RUSTC_FORCE_RUSTC_VERSION", "1").input("libr.rs").run();
5 .env("RUSTC_FORCE_RUSTC_VERSION", "1")6 rustc().env("RUSTC_FORCE_RUSTC_VERSION", "2").input("app.rs").run();
6 .input("libr.rs")
7 .run();
8 rustc()
9 .env("RUSTC_FORCE_RUSTC_VERSION", "2")
10 .input("app.rs")
11 .run();
12}7}
tests/run-make/export/extern-opt/rmake.rs+3-5
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1use run_make_support::{rustc, dynamic_lib_name};1//@ needs-target-std
2use run_make_support::{dynamic_lib_name, rustc};
23
3fn main() {4fn main() {
4 rustc()5 rustc().env("RUSTC_FORCE_RUSTC_VERSION", "1").input("libr.rs").run();
5 .env("RUSTC_FORCE_RUSTC_VERSION", "1")
6 .input("libr.rs")
7 .run();
86
9 rustc()7 rustc()
10 .env("RUSTC_FORCE_RUSTC_VERSION", "2")8 .env("RUSTC_FORCE_RUSTC_VERSION", "2")
tests/run-make/export/simple/rmake.rs+3-8
...@@ -1,12 +1,7 @@...@@ -1,12 +1,7 @@
1//@ needs-target-std
1use run_make_support::rustc;2use run_make_support::rustc;
23
3fn main() {4fn main() {
4 rustc()5 rustc().env("RUSTC_FORCE_RUSTC_VERSION", "1").input("libr.rs").run();
5 .env("RUSTC_FORCE_RUSTC_VERSION", "1")6 rustc().env("RUSTC_FORCE_RUSTC_VERSION", "2").input("app.rs").run();
6 .input("libr.rs")
7 .run();
8 rustc()
9 .env("RUSTC_FORCE_RUSTC_VERSION", "2")
10 .input("app.rs")
11 .run();
12}7}
tests/run-make/extern-diff-internal-name/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In the following scenario:3// In the following scenario:
2// 1. The crate foo, is referenced multiple times4// 1. The crate foo, is referenced multiple times
3// 2. --extern foo=./path/to/libbar.rlib is specified to rustc5// 2. --extern foo=./path/to/libbar.rlib is specified to rustc
tests/run-make/extern-flag-fun/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// The --extern flag can override the default crate search of3// The --extern flag can override the default crate search of
2// the compiler and directly fetch a given path. There are a few rules4// the compiler and directly fetch a given path. There are a few rules
3// to follow: for example, there can't be more than one rlib, the crates must5// to follow: for example, there can't be more than one rlib, the crates must
tests/run-make/extern-flag-rename-transitive/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In this test, baz.rs is looking for an extern crate "a" which3// In this test, baz.rs is looking for an extern crate "a" which
2// does not exist, and can only run through the --extern rustc flag4// does not exist, and can only run through the --extern rustc flag
3// defining that the "a" crate is in fact just "foo". This test5// defining that the "a" crate is in fact just "foo". This test
tests/run-make/extern-multiple-copies/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In this test, the rust library foo1 exists in two different locations, but only one3// In this test, the rust library foo1 exists in two different locations, but only one
2// is required by the --extern flag. This test checks that the copy is ignored (as --extern4// is required by the --extern flag. This test checks that the copy is ignored (as --extern
3// demands fetching only the original instance of foo1) and that no error is emitted, resulting5// demands fetching only the original instance of foo1) and that no error is emitted, resulting
tests/run-make/extern-multiple-copies2/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Almost identical to `extern-multiple-copies`, but with a variation in the --extern calls3// Almost identical to `extern-multiple-copies`, but with a variation in the --extern calls
2// and the addition of #[macro_use] in the rust code files, which used to break --extern4// and the addition of #[macro_use] in the rust code files, which used to break --extern
3// until #33625.5// until #33625.
tests/run-make/ice-static-mir/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Trying to access mid-level internal representation (MIR) in statics3// Trying to access mid-level internal representation (MIR) in statics
2// used to cause an internal compiler error (ICE), now handled as a proper4// used to cause an internal compiler error (ICE), now handled as a proper
3// error since #100211. This test checks that the correct error is printed5// error since #100211. This test checks that the correct error is printed
tests/run-make/include-all-symbols-linking/rmake.rs+1
...@@ -7,6 +7,7 @@...@@ -7,6 +7,7 @@
7// See https://github.com/rust-lang/rust/pull/956047// See https://github.com/rust-lang/rust/pull/95604
8// See https://github.com/rust-lang/rust/issues/473848// See https://github.com/rust-lang/rust/issues/47384
99
10//@ needs-target-std
10//@ ignore-wasm differences in object file formats causes errors in the llvm_objdump step.11//@ ignore-wasm differences in object file formats causes errors in the llvm_objdump step.
11//@ ignore-windows differences in object file formats causes errors in the llvm_objdump step.12//@ ignore-windows differences in object file formats causes errors in the llvm_objdump step.
1213
tests/run-make/include-bytes-deps/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// include_bytes! and include_str! in `main.rs`3// include_bytes! and include_str! in `main.rs`
2// should register the included file as of #24423,4// should register the included file as of #24423,
3// and this test checks that this is still the case.5// and this test checks that this is still the case.
tests/run-make/incremental-debugger-visualizer/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test ensures that changes to files referenced via #[debugger_visualizer]3// This test ensures that changes to files referenced via #[debugger_visualizer]
2// (in this case, foo.py and foo.natvis) are picked up when compiling incrementally.4// (in this case, foo.py and foo.natvis) are picked up when compiling incrementally.
3// See https://github.com/rust-lang/rust/pull/1116415// See https://github.com/rust-lang/rust/pull/111641
tests/run-make/inline-always-many-cgu/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use std::ffi::OsStr;2use std::ffi::OsStr;
23
3use run_make_support::regex::Regex;4use run_make_support::regex::Regex;
tests/run-make/invalid-so/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When a fake library was given to the compiler, it would3// When a fake library was given to the compiler, it would
2// result in an obscure and unhelpful error message. This test4// result in an obscure and unhelpful error message. This test
3// creates a false "foo" dylib, and checks that the standard error5// creates a false "foo" dylib, and checks that the standard error
tests/run-make/invalid-staticlib/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// If the static library provided is not valid (in this test,3// If the static library provided is not valid (in this test,
2// created as an empty file),4// created as an empty file),
3// rustc should print a normal error message and not throw5// rustc should print a normal error message and not throw
tests/run-make/invalid-symlink-search-path/rmake.rs+1
...@@ -5,6 +5,7 @@...@@ -5,6 +5,7 @@
5//5//
6// See https://github.com/rust-lang/rust/issues/260066// See https://github.com/rust-lang/rust/issues/26006
77
8//@ needs-target-std
8//@ needs-symlink9//@ needs-symlink
9//Reason: symlink requires elevated permission in Windows10//Reason: symlink requires elevated permission in Windows
1011
tests/run-make/invalid-tmpdir-env-var/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When the TMP (on Windows) or TMPDIR (on Unix) variable is set to an invalid3// When the TMP (on Windows) or TMPDIR (on Unix) variable is set to an invalid
2// or non-existing directory, this used to cause an internal compiler error (ICE). After the4// or non-existing directory, this used to cause an internal compiler error (ICE). After the
3// addition of proper error handling in #28430, this test checks that the expected message is5// addition of proper error handling in #28430, this test checks that the expected message is
tests/run-make/issue-107495-archive-permissions/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1#[cfg(unix)]2#[cfg(unix)]
2use std::os::unix::fs::PermissionsExt;3use std::os::unix::fs::PermissionsExt;
3use std::path::Path;4use std::path::Path;
tests/run-make/issue-125484-used-dependencies/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Non-regression test for issues #125474, #125484, #125646, with the repro taken from #125484. Some3// Non-regression test for issues #125474, #125484, #125646, with the repro taken from #125484. Some
2// queries use "used dependencies" while others use "speculatively loaded dependencies", and an4// queries use "used dependencies" while others use "speculatively loaded dependencies", and an
3// indexing ICE appeared in some cases when these were unexpectedly used in the same context.5// indexing ICE appeared in some cases when these were unexpectedly used in the same context.
tests/run-make/json-error-no-offset/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// The byte positions in json format error logging used to have a small, difficult3// The byte positions in json format error logging used to have a small, difficult
2// to predict offset. This was changed to be the top of the file every time in #42973,4// to predict offset. This was changed to be the top of the file every time in #42973,
3// and this test checks that the measurements appearing in the standard error are correct.5// and this test checks that the measurements appearing in the standard error are correct.
tests/run-make/lib-trait-for-trait-no-ice/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Inside a library, implementing a trait for another trait3// Inside a library, implementing a trait for another trait
2// with a lifetime used to cause an internal compiler error (ICE).4// with a lifetime used to cause an internal compiler error (ICE).
3// This test checks that this bug does not make a resurgence -5// This test checks that this bug does not make a resurgence -
tests/run-make/link-arg/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In 2016, the rustc flag "-C link-arg" was introduced - it can be repeatedly used3// In 2016, the rustc flag "-C link-arg" was introduced - it can be repeatedly used
2// to add single arguments to the linker. This test passes 2 arguments to the linker using it,4// to add single arguments to the linker. This test passes 2 arguments to the linker using it,
3// then checks that the compiler's output contains the arguments passed to it.5// then checks that the compiler's output contains the arguments passed to it.
tests/run-make/link-args-order/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Passing linker arguments to the compiler used to be lost or reordered in a messy way3// Passing linker arguments to the compiler used to be lost or reordered in a messy way
2// as they were passed further to the linker. This was fixed in #70665, and this test4// as they were passed further to the linker. This was fixed in #70665, and this test
3// checks that linker arguments remain intact and in the order they were originally passed in.5// checks that linker arguments remain intact and in the order they were originally passed in.
tests/run-make/link-dedup/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When native libraries are passed to the linker, there used to be an annoyance3// When native libraries are passed to the linker, there used to be an annoyance
2// where multiple instances of the same library in a row would cause duplication in4// where multiple instances of the same library in a row would cause duplication in
3// outputs. This has been fixed, and this test checks that it stays fixed.5// outputs. This has been fixed, and this test checks that it stays fixed.
tests/run-make/linker-warning/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{Rustc, diff, regex, rustc};2use run_make_support::{Rustc, diff, regex, rustc};
23
3fn run_rustc() -> Rustc {4fn run_rustc() -> Rustc {
tests/run-make/llvm-outputs/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1// test that directories get created when emitting llvm bitcode and IR2// test that directories get created when emitting llvm bitcode and IR
23
3use std::path::PathBuf;4use std::path::PathBuf;
tests/run-make/lto-avoid-object-duplication/rmake.rs+1
...@@ -8,6 +8,7 @@...@@ -8,6 +8,7 @@
8// This test makes sure that functions defined in the upstream crates do not8// This test makes sure that functions defined in the upstream crates do not
9// appear twice in the final staticlib when listing all the symbols from it.9// appear twice in the final staticlib when listing all the symbols from it.
1010
11//@ needs-target-std
11//@ ignore-windows12//@ ignore-windows
12// Reason: `llvm-objdump`'s output looks different on windows than on other platforms.13// Reason: `llvm-objdump`'s output looks different on windows than on other platforms.
13// Only checking on Unix platforms should suffice.14// Only checking on Unix platforms should suffice.
tests/run-make/manual-crate-name/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{path, rustc};2use run_make_support::{path, rustc};
23
3fn main() {4fn main() {
tests/run-make/many-crates-but-no-match/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// An extended version of the ui/changing-crates.rs test, this test puts3// An extended version of the ui/changing-crates.rs test, this test puts
2// multiple mismatching crates into the search path of crateC (A2 and A3)4// multiple mismatching crates into the search path of crateC (A2 and A3)
3// and checks that the standard error contains helpful messages to indicate5// and checks that the standard error contains helpful messages to indicate
tests/run-make/metadata-dep-info/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Emitting dep-info alongside metadata would present subtle discrepancies3// Emitting dep-info alongside metadata would present subtle discrepancies
2// in the output file, such as the filename transforming underscores_ into hyphens-.4// in the output file, such as the filename transforming underscores_ into hyphens-.
3// After the fix in #114750, this test checks that the emitted files are identical5// After the fix in #114750, this test checks that the emitted files are identical
tests/run-make/metadata-only-crate-no-ice/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In a dependency hierarchy, metadata-only crates could cause an Internal3// In a dependency hierarchy, metadata-only crates could cause an Internal
2// Compiler Error (ICE) due to a compiler bug - not correctly fetching sources for4// Compiler Error (ICE) due to a compiler bug - not correctly fetching sources for
3// metadata-only crates. This test is a minimal reproduction of a program that triggered5// metadata-only crates. This test is a minimal reproduction of a program that triggered
tests/run-make/missing-crate-dependency/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// A simple smoke test to check that rustc fails compilation3// A simple smoke test to check that rustc fails compilation
2// and outputs a helpful message when a dependency is missing4// and outputs a helpful message when a dependency is missing
3// in a dependency chain.5// in a dependency chain.
tests/run-make/multiple-emits/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{path, rustc};2use run_make_support::{path, rustc};
23
3fn main() {4fn main() {
tests/run-make/native-lib-alt-naming/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// On MSVC the alternative naming format for static libraries (`libfoo.a`) is accepted in addition3// On MSVC the alternative naming format for static libraries (`libfoo.a`) is accepted in addition
2// to the default format (`foo.lib`).4// to the default format (`foo.lib`).
35
tests/run-make/native-link-modifier-verbatim-linker/rmake.rs+1
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
3// This test is the same as native-link-modifier-rustc, but without rlibs.3// This test is the same as native-link-modifier-rustc, but without rlibs.
4// See https://github.com/rust-lang/rust/issues/994254// See https://github.com/rust-lang/rust/issues/99425
55
6//@ needs-target-std
6//@ ignore-apple7//@ ignore-apple
7// Reason: linking fails due to the unusual ".ext" staticlib name.8// Reason: linking fails due to the unusual ".ext" staticlib name.
89
tests/run-make/native-link-modifier-verbatim-rustc/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// `verbatim` is a native link modifier that forces rustc to only accept libraries with3// `verbatim` is a native link modifier that forces rustc to only accept libraries with
2// a specified name. This test checks that this modifier works as intended.4// a specified name. This test checks that this modifier works as intended.
3// This test is the same as native-link-modifier-linker, but with rlibs.5// This test is the same as native-link-modifier-linker, but with rlibs.
tests/run-make/no-builtins-attribute/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// `no_builtins` is an attribute related to LLVM's optimizations. In order to ensure that it has an3// `no_builtins` is an attribute related to LLVM's optimizations. In order to ensure that it has an
2// effect on link-time optimizations (LTO), it should be added to function declarations in a crate.4// effect on link-time optimizations (LTO), it should be added to function declarations in a crate.
3// This test uses the `llvm-filecheck` tool to determine that this attribute is successfully5// This test uses the `llvm-filecheck` tool to determine that this attribute is successfully
tests/run-make/no-builtins-lto/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// The rlib produced by a no_builtins crate should be explicitly linked3// The rlib produced by a no_builtins crate should be explicitly linked
2// during compilation, and as a result be present in the linker arguments.4// during compilation, and as a result be present in the linker arguments.
3// See the comments inside this file for more details.5// See the comments inside this file for more details.
tests/run-make/non-unicode-env/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{rfs, rustc};2use run_make_support::{rfs, rustc};
23
3fn main() {4fn main() {
tests/run-make/non-unicode-in-incremental-dir/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{rfs, rustc};2use run_make_support::{rfs, rustc};
23
3fn main() {4fn main() {
tests/run-make/notify-all-emit-artifacts/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// rust should produce artifact notifications about files it was asked to --emit.3// rust should produce artifact notifications about files it was asked to --emit.
2//4//
3// It should work in incremental mode both on the first pass where files are generated as well5// It should work in incremental mode both on the first pass where files are generated as well
tests/run-make/optimization-remarks-dir/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In this test, the function `bar` has #[inline(never)] and the function `foo`3// In this test, the function `bar` has #[inline(never)] and the function `foo`
2// does not. This test outputs LLVM optimization remarks twice - first for all4// does not. This test outputs LLVM optimization remarks twice - first for all
3// functions (including `bar`, and the `inline` mention), and then for only `foo`5// functions (including `bar`, and the `inline` mention), and then for only `foo`
tests/run-make/overwrite-input/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// An attempt to set the output `-o` into a directory or a file we cannot write into should indeed3// An attempt to set the output `-o` into a directory or a file we cannot write into should indeed
2// be an error; but not an ICE (Internal Compiler Error). This test attempts both and checks4// be an error; but not an ICE (Internal Compiler Error). This test attempts both and checks
3// that the standard error matches what is expected.5// that the standard error matches what is expected.
tests/run-make/parallel-rustc-no-overwrite/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When two instances of rustc are invoked in parallel, they3// When two instances of rustc are invoked in parallel, they
2// can conflict on their temporary files and overwrite each others',4// can conflict on their temporary files and overwrite each others',
3// leading to unsuccessful compilation. The -Z temps-dir flag adds5// leading to unsuccessful compilation. The -Z temps-dir flag adds
tests/run-make/pass-linker-flags-from-dep/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// A similar test to pass-linker-flags, testing that the `-l link-arg` flag3// A similar test to pass-linker-flags, testing that the `-l link-arg` flag
2// respects the order relative to other `-l` flags, but this time, the flags4// respects the order relative to other `-l` flags, but this time, the flags
3// are passed on the compilation of a dependency. This test checks that the5// are passed on the compilation of a dependency. This test checks that the
tests/run-make/pass-linker-flags/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test checks the proper function of `-l link-arg=NAME`, which, unlike3// This test checks the proper function of `-l link-arg=NAME`, which, unlike
2// -C link-arg, is supposed to guarantee that the order relative to other -l4// -C link-arg, is supposed to guarantee that the order relative to other -l
3// options will be respected. In this test, compilation fails (because none of the5// options will be respected. In this test, compilation fails (because none of the
tests/run-make/pgo-gen-no-imp-symbols/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// LLVM's profiling instrumentation adds a few symbols that are used by the profiler runtime.3// LLVM's profiling instrumentation adds a few symbols that are used by the profiler runtime.
2// Since these show up as globals in the LLVM IR, the compiler generates dllimport-related4// Since these show up as globals in the LLVM IR, the compiler generates dllimport-related
3// __imp_ stubs for them. This can lead to linker errors because the instrumentation5// __imp_ stubs for them. This can lead to linker errors because the instrumentation
tests/run-make/pretty-print-with-dep-file/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Passing --emit=dep-info to the Rust compiler should create a .d file...3// Passing --emit=dep-info to the Rust compiler should create a .d file...
2// but it failed to do so in Rust 1.69.0 when combined with -Z unpretty=expanded4// but it failed to do so in Rust 1.69.0 when combined with -Z unpretty=expanded
3// due to a bug. This test checks that -Z unpretty=expanded does not prevent the5// due to a bug. This test checks that -Z unpretty=expanded does not prevent the
tests/run-make/proc-macro-three-crates/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// A compiler bug caused the following issue:3// A compiler bug caused the following issue:
2// If a crate A depends on crate B, and crate B4// If a crate A depends on crate B, and crate B
3// depends on crate C, and crate C contains a procedural5// depends on crate C, and crate C contains a procedural
tests/run-make/remap-path-prefix-dwarf/rmake.rs+1
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
4// It tests several cases, each of them has a detailed description attached to it.4// It tests several cases, each of them has a detailed description attached to it.
5// See https://github.com/rust-lang/rust/pull/968675// See https://github.com/rust-lang/rust/pull/96867
66
7//@ needs-target-std
7//@ ignore-windows8//@ ignore-windows
8// Reason: the remap path prefix is not printed in the dwarf dump.9// Reason: the remap path prefix is not printed in the dwarf dump.
910
tests/run-make/remap-path-prefix/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Generating metadata alongside remap-path-prefix would fail to actually remap the path3// Generating metadata alongside remap-path-prefix would fail to actually remap the path
2// in the metadata. After this was fixed in #85344, this test checks that "auxiliary" is being4// in the metadata. After this was fixed in #85344, this test checks that "auxiliary" is being
3// successfully remapped to "/the/aux" in the rmeta files.5// successfully remapped to "/the/aux" in the rmeta files.
tests/run-make/repr128-dwarf/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1//@ ignore-windows2//@ ignore-windows
2// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums.3// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums.
34
tests/run-make/reproducible-build-2/rmake.rs+1
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
6// Outputs should be identical.6// Outputs should be identical.
7// See https://github.com/rust-lang/rust/issues/349027// See https://github.com/rust-lang/rust/issues/34902
88
9//@ needs-target-std
9//@ ignore-windows10//@ ignore-windows
10// Reasons:11// Reasons:
11// 1. The object files are reproducible, but their paths are not, which causes12// 1. The object files are reproducible, but their paths are not, which causes
tests/run-make/resolve-rename/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// If a library is compiled with -C extra-filename, the rust compiler3// If a library is compiled with -C extra-filename, the rust compiler
2// will take this into account when searching for libraries. However,4// will take this into account when searching for libraries. However,
3// if that library is then renamed, the rust compiler should fall back5// if that library is then renamed, the rust compiler should fall back
tests/run-make/rlib-format-packed-bundled-libs-2/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// `-Z packed_bundled_libs` is an unstable rustc flag that makes the compiler3// `-Z packed_bundled_libs` is an unstable rustc flag that makes the compiler
2// only require a native library and no supplementary object files to compile.4// only require a native library and no supplementary object files to compile.
3// This test simply checks that this flag can be passed alongside verbatim syntax5// This test simply checks that this flag can be passed alongside verbatim syntax
tests/run-make/rustc-macro-dep-files/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// --emit dep-info used to print all macro-generated code it could3// --emit dep-info used to print all macro-generated code it could
2// find as if it was part of a nonexistent file named "proc-macro source",4// find as if it was part of a nonexistent file named "proc-macro source",
3// which is not a valid path. After this was fixed in #36776, this test checks5// which is not a valid path. After this was fixed in #36776, this test checks
tests/run-make/rustdoc-scrape-examples-invalid-expr/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]2#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]
2mod scrape;3mod scrape;
34
tests/run-make/rustdoc-scrape-examples-multiple/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]2#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]
2mod scrape;3mod scrape;
34
tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]2#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]
2mod scrape;3mod scrape;
34
tests/run-make/rustdoc-scrape-examples-remap/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1mod scrape;2mod scrape;
23
3fn main() {4fn main() {
tests/run-make/rustdoc-scrape-examples-test/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]2#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]
2mod scrape;3mod scrape;
34
tests/run-make/rustdoc-scrape-examples-whitespace/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]2#[path = "../rustdoc-scrape-examples-remap/scrape.rs"]
2mod scrape;3mod scrape;
34
tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1use run_make_support::{htmldocck, rustdoc};2use run_make_support::{htmldocck, rustdoc};
23
3fn main() {4fn main() {
tests/run-make/share-generics-dylib/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test makes sure all generic instances get re-exported from Rust dylibs for use by3// This test makes sure all generic instances get re-exported from Rust dylibs for use by
2// `-Zshare-generics`. There are two rlibs (`instance_provider_a` and `instance_provider_b`)4// `-Zshare-generics`. There are two rlibs (`instance_provider_a` and `instance_provider_b`)
3// which both provide an instance of `Cell<i32>::set`. There is `instance_user_dylib` which is5// which both provide an instance of `Cell<i32>::set`. There is `instance_user_dylib` which is
tests/run-make/short-ice/rmake.rs+1
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
4// was shortened down to an appropriate length.4// was shortened down to an appropriate length.
5// See https://github.com/rust-lang/rust/issues/1079105// See https://github.com/rust-lang/rust/issues/107910
66
7//@ needs-target-std
7//@ ignore-windows8//@ ignore-windows
8// Reason: the assert_eq! on line 32 fails, as error output on Windows is different.9// Reason: the assert_eq! on line 32 fails, as error output on Windows is different.
910
tests/run-make/stable-symbol-names/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// A typo in rustc caused generic symbol names to be non-deterministic -3// A typo in rustc caused generic symbol names to be non-deterministic -
2// that is, it was possible to compile the same file twice with no changes4// that is, it was possible to compile the same file twice with no changes
3// and get outputs with different symbol names.5// and get outputs with different symbol names.
tests/run-make/staticlib-blank-lib/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// In this test, the static library foo is made blank, which used to cause3// In this test, the static library foo is made blank, which used to cause
2// a compilation error. As the compiler now returns Ok upon encountering a blank4// a compilation error. As the compiler now returns Ok upon encountering a blank
3// staticlib as of #12379, this test checks that compilation is successful despite5// staticlib as of #12379, this test checks that compilation is successful despite
tests/run-make/staticlib-broken-bitcode/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Regression test for https://github.com/rust-lang/rust/issues/128955#issuecomment-26578111963// Regression test for https://github.com/rust-lang/rust/issues/128955#issuecomment-2657811196
2// which checks that rustc can read an archive containing LLVM bitcode with a4// which checks that rustc can read an archive containing LLVM bitcode with a
3// newer version from the one rustc links against.5// newer version from the one rustc links against.
tests/run-make/staticlib-thin-archive/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Regression test for https://github.com/rust-lang/rust/issues/107407 which3// Regression test for https://github.com/rust-lang/rust/issues/107407 which
2// checks that rustc can read thin archive. Before the object crate added thin4// checks that rustc can read thin archive. Before the object crate added thin
3// archive support rustc would add emit object files to the staticlib and after5// archive support rustc would add emit object files to the staticlib and after
tests/run-make/stdin-rustc/rmake.rs+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1//@ needs-target-std
1//! This test checks rustc `-` (stdin) support2//! This test checks rustc `-` (stdin) support
23
3use std::path::PathBuf;4use std::path::PathBuf;
tests/run-make/symbol-visibility/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Dynamic libraries on Rust used to export a very high amount of symbols,3// Dynamic libraries on Rust used to export a very high amount of symbols,
2// going as far as filling the output with mangled names and generic function4// going as far as filling the output with mangled names and generic function
3// names. After the rework of #38117, this test checks that no mangled Rust symbols5// names. After the rework of #38117, this test checks that no mangled Rust symbols
tests/run-make/symbols-include-type-name/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Method names used to be obfuscated when exported into symbols,3// Method names used to be obfuscated when exported into symbols,
2// leaving only an obscure `<impl>`. After the fix in #30328,4// leaving only an obscure `<impl>`. After the fix in #30328,
3// this test checks that method names are successfully saved in the symbol list.5// this test checks that method names are successfully saved in the symbol list.
tests/run-make/track-path-dep-info/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test checks the functionality of `tracked_path::path`, a procedural macro3// This test checks the functionality of `tracked_path::path`, a procedural macro
2// feature that adds a dependency to another file inside the procmacro. In this case,4// feature that adds a dependency to another file inside the procmacro. In this case,
3// the text file is added through this method, and the test checks that the compilation5// the text file is added through this method, and the test checks that the compilation
tests/run-make/type-mismatch-same-crate-name/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// When a compilation failure deals with seemingly identical types, some helpful3// When a compilation failure deals with seemingly identical types, some helpful
2// errors should be printed.4// errors should be printed.
3// The main use case of this error is when there are two crates5// The main use case of this error is when there are two crates
tests/run-make/unknown-mod-stdin/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// Rustc displays a compilation error when it finds a `mod` (module)3// Rustc displays a compilation error when it finds a `mod` (module)
2// statement referencing a file that does not exist. However, a bug from 20194// statement referencing a file that does not exist. However, a bug from 2019
3// caused invalid `mod` statements to silently insert empty inline modules5// caused invalid `mod` statements to silently insert empty inline modules
tests/run-make/unstable-feature-usage-metrics-incremental/rmake.rs+1
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10//! - forked from dump-ice-to-disk test, which has flakeyness issues on i686-mingw, I'm assuming10//! - forked from dump-ice-to-disk test, which has flakeyness issues on i686-mingw, I'm assuming
11//! those will be present in this test as well on the same platform11//! those will be present in this test as well on the same platform
1212
13//@ needs-target-std
13//@ ignore-windows14//@ ignore-windows
14//FIXME(#128911): still flakey on i686-mingw.15//FIXME(#128911): still flakey on i686-mingw.
1516
tests/run-make/unstable-feature-usage-metrics/rmake.rs+1
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10//! - forked from dump-ice-to-disk test, which has flakeyness issues on i686-mingw, I'm assuming10//! - forked from dump-ice-to-disk test, which has flakeyness issues on i686-mingw, I'm assuming
11//! those will be present in this test as well on the same platform11//! those will be present in this test as well on the same platform
1212
13//@ needs-target-std
13//@ ignore-windows14//@ ignore-windows
14//FIXME(#128911): still flakey on i686-mingw.15//FIXME(#128911): still flakey on i686-mingw.
1516
tests/run-make/use-suggestions-rust-2018/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// The compilation error caused by calling on an unimported crate3// The compilation error caused by calling on an unimported crate
2// should have a suggestion to write, say, crate::bar::Foo instead4// should have a suggestion to write, say, crate::bar::Foo instead
3// of just bar::Foo. However, this suggestion used to only appear for5// of just bar::Foo. However, this suggestion used to only appear for
tests/run-make/used/rmake.rs+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1//@ needs-target-std
2//
1// This test ensures that the compiler is keeping static variables, even if not referenced3// This test ensures that the compiler is keeping static variables, even if not referenced
2// by another part of the program, in the output object file.4// by another part of the program, in the output object file.
3//5//
tests/ui/abi/numbers-arithmetic/float-struct.rs created+44
...@@ -0,0 +1,44 @@
1//@ run-pass
2
3use std::fmt::Debug;
4use std::hint::black_box;
5
6#[repr(C)]
7#[derive(Copy, Clone, PartialEq, Debug, Default)]
8struct Regular(f32, f64);
9
10#[repr(C, packed)]
11#[derive(Copy, Clone, PartialEq, Debug, Default)]
12struct Packed(f32, f64);
13
14#[repr(C, align(64))]
15#[derive(Copy, Clone, PartialEq, Debug, Default)]
16struct AlignedF32(f32);
17
18#[repr(C)]
19#[derive(Copy, Clone, PartialEq, Debug, Default)]
20struct Aligned(f64, AlignedF32);
21
22#[inline(never)]
23extern "C" fn read<T: Copy>(x: &T) -> T {
24 *black_box(x)
25}
26
27#[inline(never)]
28extern "C" fn write<T: Copy>(x: T, dest: &mut T) {
29 *dest = black_box(x)
30}
31
32#[track_caller]
33fn check<T: Copy + PartialEq + Debug + Default>(x: T) {
34 assert_eq!(read(&x), x);
35 let mut out = T::default();
36 write(x, &mut out);
37 assert_eq!(out, x);
38}
39
40fn main() {
41 check(Regular(1.0, 2.0));
42 check(Packed(3.0, 4.0));
43 check(Aligned(5.0, AlignedF32(6.0)));
44}
tests/ui/parser/doc-comment-after-missing-comma-issue-142311.rs created+34
...@@ -0,0 +1,34 @@
1//! Check that if the parser suggests converting `///` to a regular comment
2//! when it appears after a missing comma in an list (e.g. `enum` variants).
3//!
4//! Related issue
5//! - https://github.com/rust-lang/rust/issues/142311
6
7enum Foo {
8 /// Like the noise a sheep makes
9 Bar
10 /// Like where people drink
11 //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `/// Like where people drink`
12 Baa///xxxxxx
13 //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx`
14 Baz///xxxxxx
15 //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx`
16}
17
18fn foo() {
19 let a = [
20 1///xxxxxx
21 //~^ ERROR expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found doc comment `///xxxxxx`
22 2
23 ];
24}
25
26fn bar() {
27 let a = [
28 1,
29 2///xxxxxx
30 //~^ ERROR expected one of `,`, `.`, `?`, `]`, or an operator, found doc comment `///xxxxxx`
31 ];
32}
33
34fn main() {}
tests/ui/parser/doc-comment-after-missing-comma-issue-142311.stderr created+43
...@@ -0,0 +1,43 @@
1error: expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `/// Like where people drink`
2 --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:10:5
3 |
4LL | Bar
5 | -
6 | |
7 | expected one of `(`, `,`, `=`, `{`, or `}`
8 | help: missing `,`
9LL | /// Like where people drink
10 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ unexpected token
11
12error: expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx`
13 --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:12:8
14 |
15LL | Baa///xxxxxx
16 | -^^^^^^^^
17 | |
18 | expected one of `(`, `,`, `=`, `{`, or `}`
19 | help: missing `,`
20
21error: expected one of `(`, `,`, `=`, `{`, or `}`, found doc comment `///xxxxxx`
22 --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:14:8
23 |
24LL | Baz///xxxxxx
25 | ^^^^^^^^^ expected one of `(`, `,`, `=`, `{`, or `}`
26 |
27 = help: doc comments must come before what they document, if a comment was intended use `//`
28 = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
29
30error: expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found doc comment `///xxxxxx`
31 --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:20:10
32 |
33LL | 1///xxxxxx
34 | ^^^^^^^^^ expected one of `,`, `.`, `;`, `?`, `]`, or an operator
35
36error: expected one of `,`, `.`, `?`, `]`, or an operator, found doc comment `///xxxxxx`
37 --> $DIR/doc-comment-after-missing-comma-issue-142311.rs:29:10
38 |
39LL | 2///xxxxxx
40 | ^^^^^^^^^ expected one of `,`, `.`, `?`, `]`, or an operator
41
42error: aborting due to 5 previous errors
43