Skip to content

Commit 2b85785

Browse files
committed
Fix merge conflict
1 parent 228ae82 commit 2b85785

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+6508
-7
lines changed

compiler/rustc_lint/src/unused.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,10 +1069,13 @@ pub(crate) struct UnusedParens {
10691069
/// `1 as (i32) < 2` parses to ExprKind::Lt
10701070
/// `1 as i32 < 2` parses to i32::<2[missing angle bracket]
10711071
parens_in_cast_in_lt: Vec<ast::NodeId>,
1072-
<<<<<<< HEAD
10731072
/// Ty nodes in this map are in TypeNoBounds position. Any bounds they
10741073
/// contain may be ambiguous w/r/t trailing `+` operators.
10751074
in_no_bounds_pos: FxHashMap<ast::NodeId, NoBoundsException>,
1075+
// Used for tracking parent expressions that would immediately followed
1076+
// by block. Storing false here indicates that expression itself is Block
1077+
// expression. This is meant for to prevent report false positive cases.
1078+
followed_by_block: Vec<bool>,
10761079
}
10771080

10781081
/// Whether parentheses may be omitted from a type without resulting in ambiguity.
@@ -1095,12 +1098,6 @@ enum NoBoundsException {
10951098
/// The type is the last bound of the containing type expression. If it has exactly one bound,
10961099
/// parentheses around the type are unnecessary.
10971100
OneBound,
1098-
=======
1099-
// Used for tracking parent expressions that would immediately followed
1100-
// by block. Storing false here indicates that expression itself is Block
1101-
// expression. This is meant for to prevent report false positive cases.
1102-
followed_by_block: Vec<bool>,
1103-
>>>>>>> 5c02bc9efda (Improve changes)
11041101
}
11051102

11061103
impl_lint_pass!(UnusedParens => [UNUSED_PARENS]);

library/stdarch/.cirrus.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
task:
2+
name: x86_64-unknown-freebsd
3+
freebsd_instance:
4+
image_family: freebsd-13-4
5+
env:
6+
# FIXME(freebsd): FreeBSD has a segfault when `RUST_BACKTRACE` is set
7+
# https://github.com/rust-lang/rust/issues/132185
8+
RUST_BACKTRACE: "0"
9+
setup_script:
10+
- curl https://sh.rustup.rs -sSf --output rustup.sh
11+
- sh rustup.sh --default-toolchain nightly -y
12+
- . $HOME/.cargo/env
13+
- rustup default nightly
14+
test_script:
15+
- . $HOME/.cargo/env
16+
- cargo build --all
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
3+
# Build std_detect on non-Linux & non-x86 targets.
4+
#
5+
# In std_detect, non-x86 targets have OS-specific implementations,
6+
# but we can test only Linux in CI. This script builds targets supported
7+
# by std_detect but cannot be tested in CI.
8+
9+
set -ex
10+
cd "$(dirname "$0")"/..
11+
12+
targets=(
13+
# Linux
14+
aarch64-unknown-linux-musl
15+
armv5te-unknown-linux-musleabi
16+
aarch64-unknown-linux-ohos
17+
armv7-unknown-linux-ohos
18+
19+
# Android
20+
aarch64-linux-android
21+
arm-linux-androideabi
22+
23+
# FreeBSD
24+
aarch64-unknown-freebsd
25+
armv6-unknown-freebsd
26+
powerpc-unknown-freebsd
27+
powerpc64-unknown-freebsd
28+
29+
# OpenBSD
30+
aarch64-unknown-openbsd
31+
32+
# Windows
33+
aarch64-pc-windows-msvc
34+
)
35+
36+
rustup component add rust-src # for -Z build-std
37+
38+
cd crates/std_detect
39+
for target in "${targets[@]}"; do
40+
if rustup target add "${target}" &>/dev/null; then
41+
cargo build --target "${target}"
42+
else
43+
# tier 3 targets requires -Z build-std.
44+
cargo build -Z build-std="core,alloc" --target "${target}"
45+
fi
46+
done
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
use std::ops::Range;
2+
3+
use crate::Language;
4+
use crate::format::Indentation;
5+
use crate::json_parser::ArgPrep;
6+
use crate::types::{IntrinsicType, TypeKind};
7+
8+
/// An argument for the intrinsic.
9+
#[derive(Debug, PartialEq, Clone)]
10+
pub struct Argument {
11+
/// The argument's index in the intrinsic function call.
12+
pub pos: usize,
13+
/// The argument name.
14+
pub name: String,
15+
/// The type of the argument.
16+
pub ty: IntrinsicType,
17+
/// Any constraints that are on this argument
18+
pub constraints: Vec<Constraint>,
19+
}
20+
21+
#[derive(Debug, PartialEq, Clone)]
22+
pub enum Constraint {
23+
Equal(i64),
24+
Range(Range<i64>),
25+
}
26+
27+
impl TryFrom<ArgPrep> for Constraint {
28+
type Error = ();
29+
30+
fn try_from(prep: ArgPrep) -> Result<Self, Self::Error> {
31+
let parsed_ints = match prep {
32+
ArgPrep::Immediate { min, max } => Ok((min, max)),
33+
_ => Err(()),
34+
};
35+
if let Ok((min, max)) = parsed_ints {
36+
if min == max {
37+
Ok(Constraint::Equal(min))
38+
} else {
39+
Ok(Constraint::Range(min..max + 1))
40+
}
41+
} else {
42+
Err(())
43+
}
44+
}
45+
}
46+
47+
impl Constraint {
48+
pub fn to_range(&self) -> Range<i64> {
49+
match self {
50+
Constraint::Equal(eq) => *eq..*eq + 1,
51+
Constraint::Range(range) => range.clone(),
52+
}
53+
}
54+
}
55+
56+
impl Argument {
57+
fn to_c_type(&self) -> String {
58+
self.ty.c_type()
59+
}
60+
61+
fn is_simd(&self) -> bool {
62+
self.ty.is_simd()
63+
}
64+
65+
pub fn is_ptr(&self) -> bool {
66+
self.ty.is_ptr()
67+
}
68+
69+
pub fn has_constraint(&self) -> bool {
70+
!self.constraints.is_empty()
71+
}
72+
73+
pub fn type_and_name_from_c(arg: &str) -> (&str, &str) {
74+
let split_index = arg
75+
.rfind([' ', '*'])
76+
.expect("Couldn't split type and argname");
77+
78+
(arg[..split_index + 1].trim_end(), &arg[split_index + 1..])
79+
}
80+
81+
pub fn from_c(pos: usize, arg: &str, arg_prep: Option<ArgPrep>) -> Argument {
82+
let (ty, var_name) = Self::type_and_name_from_c(arg);
83+
84+
let ty = IntrinsicType::from_c(ty)
85+
.unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'"));
86+
87+
let constraint = arg_prep.and_then(|a| a.try_into().ok());
88+
89+
Argument {
90+
pos,
91+
name: String::from(var_name),
92+
ty,
93+
constraints: constraint.map_or(vec![], |r| vec![r]),
94+
}
95+
}
96+
97+
fn is_rust_vals_array_const(&self) -> bool {
98+
use TypeKind::*;
99+
match self.ty {
100+
// Floats have to be loaded at runtime for stable NaN conversion.
101+
IntrinsicType::Type { kind: Float, .. } => false,
102+
IntrinsicType::Type {
103+
kind: Int | UInt | Poly,
104+
..
105+
} => true,
106+
_ => unimplemented!(),
107+
}
108+
}
109+
110+
/// The binding keyword (e.g. "const" or "let") for the array of possible test inputs.
111+
pub fn rust_vals_array_binding(&self) -> impl std::fmt::Display {
112+
if self.is_rust_vals_array_const() {
113+
"const"
114+
} else {
115+
"let"
116+
}
117+
}
118+
119+
/// The name (e.g. "A_VALS" or "a_vals") for the array of possible test inputs.
120+
pub fn rust_vals_array_name(&self) -> impl std::fmt::Display {
121+
if self.is_rust_vals_array_const() {
122+
format!("{}_VALS", self.name.to_uppercase())
123+
} else {
124+
format!("{}_vals", self.name.to_lowercase())
125+
}
126+
}
127+
}
128+
129+
#[derive(Debug, PartialEq, Clone)]
130+
pub struct ArgumentList {
131+
pub args: Vec<Argument>,
132+
}
133+
134+
impl ArgumentList {
135+
/// Converts the argument list into the call parameters for a C function call.
136+
/// e.g. this would generate something like `a, &b, c`
137+
pub fn as_call_param_c(&self) -> String {
138+
self.args
139+
.iter()
140+
.map(|arg| match arg.ty {
141+
IntrinsicType::Ptr { .. } => {
142+
format!("&{}", arg.name)
143+
}
144+
IntrinsicType::Type { .. } => arg.name.clone(),
145+
})
146+
.collect::<Vec<String>>()
147+
.join(", ")
148+
}
149+
150+
/// Converts the argument list into the call parameters for a Rust function.
151+
/// e.g. this would generate something like `a, b, c`
152+
pub fn as_call_param_rust(&self) -> String {
153+
self.args
154+
.iter()
155+
.filter(|a| !a.has_constraint())
156+
.map(|arg| arg.name.clone())
157+
.collect::<Vec<String>>()
158+
.join(", ")
159+
}
160+
161+
pub fn as_constraint_parameters_rust(&self) -> String {
162+
self.args
163+
.iter()
164+
.filter(|a| a.has_constraint())
165+
.map(|arg| arg.name.clone())
166+
.collect::<Vec<String>>()
167+
.join(", ")
168+
}
169+
170+
/// Creates a line for each argument that initializes an array for C from which `loads` argument
171+
/// values can be loaded as a sliding window.
172+
/// e.g `const int32x2_t a_vals = {0x3effffff, 0x3effffff, 0x3f7fffff}`, if loads=2.
173+
pub fn gen_arglists_c(&self, indentation: Indentation, loads: u32) -> String {
174+
self.iter()
175+
.filter_map(|arg| {
176+
(!arg.has_constraint()).then(|| {
177+
format!(
178+
"{indentation}const {ty} {name}_vals[] = {values};",
179+
ty = arg.ty.c_scalar_type(),
180+
name = arg.name,
181+
values = arg.ty.populate_random(indentation, loads, &Language::C)
182+
)
183+
})
184+
})
185+
.collect::<Vec<_>>()
186+
.join("\n")
187+
}
188+
189+
/// Creates a line for each argument that initializes an array for Rust from which `loads` argument
190+
/// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20] = [...];`
191+
pub fn gen_arglists_rust(&self, indentation: Indentation, loads: u32) -> String {
192+
self.iter()
193+
.filter_map(|arg| {
194+
(!arg.has_constraint()).then(|| {
195+
format!(
196+
"{indentation}{bind} {name}: [{ty}; {load_size}] = {values};",
197+
bind = arg.rust_vals_array_binding(),
198+
name = arg.rust_vals_array_name(),
199+
ty = arg.ty.rust_scalar_type(),
200+
load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1,
201+
values = arg.ty.populate_random(indentation, loads, &Language::Rust)
202+
)
203+
})
204+
})
205+
.collect::<Vec<_>>()
206+
.join("\n")
207+
}
208+
209+
/// Creates a line for each argument that initializes the argument from an array `[arg]_vals` at
210+
/// an offset `i` using a load intrinsic, in C.
211+
/// e.g `uint8x8_t a = vld1_u8(&a_vals[i]);`
212+
pub fn load_values_c(&self, indentation: Indentation, target: &str) -> String {
213+
self.iter()
214+
.filter_map(|arg| {
215+
// The ACLE doesn't support 64-bit polynomial loads on Armv7
216+
// This and the cast are a workaround for this
217+
let armv7_p64 = if let TypeKind::Poly = arg.ty.kind() {
218+
target.contains("v7")
219+
} else {
220+
false
221+
};
222+
223+
(!arg.has_constraint()).then(|| {
224+
format!(
225+
"{indentation}{ty} {name} = {open_cast}{load}(&{name}_vals[i]){close_cast};\n",
226+
ty = arg.to_c_type(),
227+
name = arg.name,
228+
load = if arg.is_simd() {
229+
arg.ty.get_load_function(armv7_p64)
230+
} else {
231+
"*".to_string()
232+
},
233+
open_cast = if armv7_p64 {
234+
format!("cast<{}>(", arg.to_c_type())
235+
} else {
236+
"".to_string()
237+
},
238+
close_cast = if armv7_p64 {
239+
")".to_string()
240+
} else {
241+
"".to_string()
242+
}
243+
)
244+
})
245+
})
246+
.collect()
247+
}
248+
249+
/// Creates a line for each argument that initializes the argument from array `[ARG]_VALS` at
250+
/// an offset `i` using a load intrinsic, in Rust.
251+
/// e.g `let a = vld1_u8(A_VALS.as_ptr().offset(i));`
252+
pub fn load_values_rust(&self, indentation: Indentation) -> String {
253+
self.iter()
254+
.filter_map(|arg| {
255+
(!arg.has_constraint()).then(|| {
256+
format!(
257+
"{indentation}let {name} = {load}({vals_name}.as_ptr().offset(i));\n",
258+
name = arg.name,
259+
vals_name = arg.rust_vals_array_name(),
260+
load = if arg.is_simd() {
261+
arg.ty.get_load_function(false)
262+
} else {
263+
"*".to_string()
264+
},
265+
)
266+
})
267+
})
268+
.collect()
269+
}
270+
271+
pub fn iter(&self) -> std::slice::Iter<'_, Argument> {
272+
self.args.iter()
273+
}
274+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//! Basic code formatting tools.
2+
//!
3+
//! We don't need perfect formatting for the generated tests, but simple indentation can make
4+
//! debugging a lot easier.
5+
6+
#[derive(Copy, Clone, Debug, Default)]
7+
pub struct Indentation(u32);
8+
9+
impl Indentation {
10+
pub fn nested(self) -> Self {
11+
Self(self.0 + 1)
12+
}
13+
}
14+
15+
impl std::fmt::Display for Indentation {
16+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
17+
for _ in 0..self.0 {
18+
write!(f, " ")?;
19+
}
20+
Ok(())
21+
}
22+
}

0 commit comments

Comments
 (0)