Merge from rustc
This commit is contained in:
commit
c0c6f28cd6
882 changed files with 19369 additions and 9862 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -19,6 +19,9 @@ Session.vim
|
|||
*.iml
|
||||
.vscode
|
||||
.project
|
||||
.vim/
|
||||
.helix/
|
||||
.zed/
|
||||
.favorites.json
|
||||
.settings/
|
||||
.vs/
|
||||
|
|
|
|||
32
Cargo.lock
32
Cargo.lock
|
|
@ -205,11 +205,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ar_archive_writer"
|
||||
version = "0.3.0"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8412a2d690663356cba5a2532f3ed55d1e8090743bc6695b88403b27df67733"
|
||||
checksum = "3f2bcb7cf51decfbbfc7ef476e28b0775b13e5eb1190f8b7df145cd53d4f4374"
|
||||
dependencies = [
|
||||
"object 0.35.0",
|
||||
"object 0.36.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -564,7 +564,7 @@ dependencies = [
|
|||
"termize",
|
||||
"tokio",
|
||||
"toml 0.7.8",
|
||||
"ui_test 0.24.0",
|
||||
"ui_test 0.25.0",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
|
|
@ -572,6 +572,7 @@ dependencies = [
|
|||
name = "clippy_config"
|
||||
version = "0.1.82"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"rustc-semver",
|
||||
"serde",
|
||||
"toml 0.7.8",
|
||||
|
|
@ -1406,8 +1407,11 @@ name = "generate-copyright"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_metadata 0.18.1",
|
||||
"rinja",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2454,15 +2458,6 @@ dependencies = [
|
|||
"ruzstd 0.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.2"
|
||||
|
|
@ -3103,7 +3098,10 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d3762e3740cdbf2fd2be465cc2c26d643ad17353cc2e0223d211c1b096118bd"
|
||||
dependencies = [
|
||||
"humansize",
|
||||
"itoa",
|
||||
"num-traits",
|
||||
"percent-encoding",
|
||||
"rinja_derive",
|
||||
]
|
||||
|
||||
|
|
@ -4939,9 +4937,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "spanned"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed14ba8b4b82241bd5daba2c49185d4a0581a0058355fe96537338f002b8605d"
|
||||
checksum = "86af297923fbcfd107c20a189a6e9c872160df71a7190ae4a7a6c5dce4b2feb6"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"color-eyre",
|
||||
|
|
@ -5565,9 +5563,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ui_test"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc1c6c78d55482388711c8d417b8e547263046a607512278fed274c54633bbe4"
|
||||
checksum = "f7e4f339f62edc873975c47115f9e71c5454ddaa37c1142b42fc0b2672c8dacb"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.11.4",
|
||||
"anyhow",
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ SPDX-License-Identifier = "MIT OR Apache-2.0"
|
|||
path = "src/llvm-project/**"
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = [
|
||||
"2003-2019 by the contributors listed in [CREDITS.TXT](https://github.com/rust-lang/llvm-project/blob/7738295178045041669876bf32b0543ec8319a5c/llvm/CREDITS.TXT)",
|
||||
"2003-2019 by the contributors listed in CREDITS.TXT (https://github.com/rust-lang/llvm-project/blob/7738295178045041669876bf32b0543ec8319a5c/llvm/CREDITS.TXT)",
|
||||
"2010 Apple Inc",
|
||||
"2003-2019 University of Illinois at Urbana-Champaign.",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// We need this feature as it changes `dylib` linking behavior and allows us to link to `rustc_driver`.
|
||||
#![feature(rustc_private)]
|
||||
|
||||
// A note about jemalloc: rustc uses jemalloc when built for CI and
|
||||
// distribution. The obvious way to do this is with the `#[global_allocator]`
|
||||
// mechanism. However, for complicated reasons (see
|
||||
|
|
|
|||
|
|
@ -585,7 +585,9 @@ impl Pat {
|
|||
}
|
||||
// A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
|
||||
// when `P` can be reparsed as a type `T`.
|
||||
PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?,
|
||||
PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
|
||||
pat.to_ty().map(TyKind::Slice)?
|
||||
}
|
||||
// A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
|
||||
// assuming `T0` to `Tn` are all syntactically valid as types.
|
||||
PatKind::Tuple(pats) => {
|
||||
|
|
@ -1187,8 +1189,8 @@ impl Expr {
|
|||
/// Does not ensure that the path resolves to a const param, the caller should check this.
|
||||
pub fn is_potential_trivial_const_arg(&self) -> bool {
|
||||
let this = if let ExprKind::Block(block, None) = &self.kind
|
||||
&& block.stmts.len() == 1
|
||||
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
|
||||
&& let [stmt] = block.stmts.as_slice()
|
||||
&& let StmtKind::Expr(expr) = &stmt.kind
|
||||
{
|
||||
expr
|
||||
} else {
|
||||
|
|
@ -1248,7 +1250,9 @@ impl Expr {
|
|||
expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
|
||||
}
|
||||
|
||||
ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?,
|
||||
ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
|
||||
expr.to_ty().map(TyKind::Slice)?
|
||||
}
|
||||
|
||||
ExprKind::Tup(exprs) => {
|
||||
let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
|
||||
|
|
|
|||
|
|
@ -275,8 +275,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// FIXME(fn_delegation): Alternatives for target expression lowering:
|
||||
// https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600.
|
||||
fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> {
|
||||
if block.stmts.len() == 1
|
||||
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
|
||||
if let [stmt] = block.stmts.as_slice()
|
||||
&& let StmtKind::Expr(expr) = &stmt.kind
|
||||
{
|
||||
return self.lower_expr_mut(expr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1668,7 +1668,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}),
|
||||
)),
|
||||
)),
|
||||
// FIXME(effects) we might not need a default.
|
||||
default: Some(default_ct),
|
||||
is_host_effect: true,
|
||||
synthetic: true,
|
||||
|
|
|
|||
|
|
@ -502,8 +502,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||
if !self.is_beginning_of_line() {
|
||||
self.word(" ");
|
||||
}
|
||||
if cmnt.lines.len() == 1 {
|
||||
self.word(cmnt.lines[0].clone());
|
||||
if let [line] = cmnt.lines.as_slice() {
|
||||
self.word(line.clone());
|
||||
self.hardbreak()
|
||||
} else {
|
||||
self.visual_align();
|
||||
|
|
|
|||
|
|
@ -783,8 +783,8 @@ impl<'a> State<'a> {
|
|||
}
|
||||
if items.is_empty() {
|
||||
self.word("{}");
|
||||
} else if items.len() == 1 {
|
||||
self.print_use_tree(&items[0].0);
|
||||
} else if let [(item, _)] = items.as_slice() {
|
||||
self.print_use_tree(item);
|
||||
} else {
|
||||
self.cbox(INDENT_UNIT);
|
||||
self.word("{");
|
||||
|
|
|
|||
|
|
@ -665,12 +665,12 @@ pub fn eval_condition(
|
|||
res & eval_condition(mi.meta_item().unwrap(), sess, features, eval)
|
||||
}),
|
||||
sym::not => {
|
||||
if mis.len() != 1 {
|
||||
let [mi] = mis.as_slice() else {
|
||||
dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span });
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
!eval_condition(mis[0].meta_item().unwrap(), sess, features, eval)
|
||||
!eval_condition(mi.meta_item().unwrap(), sess, features, eval)
|
||||
}
|
||||
sym::target => {
|
||||
if let Some(features) = features
|
||||
|
|
@ -1051,10 +1051,10 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
|||
MetaItemKind::List(nested_items) => {
|
||||
if meta_item.has_name(sym::align) {
|
||||
recognised = true;
|
||||
if nested_items.len() == 1 {
|
||||
if let [nested_item] = nested_items.as_slice() {
|
||||
sess.dcx().emit_err(
|
||||
session_diagnostics::IncorrectReprFormatExpectInteger {
|
||||
span: nested_items[0].span(),
|
||||
span: nested_item.span(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
|
|
@ -1066,10 +1066,10 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
|||
}
|
||||
} else if meta_item.has_name(sym::packed) {
|
||||
recognised = true;
|
||||
if nested_items.len() == 1 {
|
||||
if let [nested_item] = nested_items.as_slice() {
|
||||
sess.dcx().emit_err(
|
||||
session_diagnostics::IncorrectReprFormatPackedExpectInteger {
|
||||
span: nested_items[0].span(),
|
||||
span: nested_item.span(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1124,8 +1124,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
|||
err.multipart_suggestion(
|
||||
"consider moving the expression out of the loop so it is only moved once",
|
||||
vec![
|
||||
(parent.span, "value".to_string()),
|
||||
(span.shrink_to_lo(), format!("let mut value = {value};{indent}")),
|
||||
(parent.span, "value".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -206,8 +206,8 @@ impl OutlivesSuggestionBuilder {
|
|||
|
||||
// If there is exactly one suggestable constraints, then just suggest it. Otherwise, emit a
|
||||
// list of diagnostics.
|
||||
let mut diag = if suggested.len() == 1 {
|
||||
mbcx.dcx().struct_help(match suggested.last().unwrap() {
|
||||
let mut diag = if let [constraint] = suggested.as_slice() {
|
||||
mbcx.dcx().struct_help(match constraint {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect();
|
||||
format!("add bound `{a}: {}`", bs.join(" + "))
|
||||
|
|
|
|||
|
|
@ -225,21 +225,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
// Find something that we can name
|
||||
let upper_bound = self.approx_universal_upper_bound(vid);
|
||||
let upper_bound = &self.definitions[upper_bound];
|
||||
match upper_bound.external_name {
|
||||
Some(reg) => reg,
|
||||
None => {
|
||||
// Nothing exact found, so we pick the first one that we find.
|
||||
let scc = self.constraint_sccs.scc(vid);
|
||||
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
|
||||
match self.definitions[vid].external_name {
|
||||
None => {}
|
||||
Some(region) if region.is_static() => {}
|
||||
Some(region) => return region,
|
||||
}
|
||||
}
|
||||
region
|
||||
}
|
||||
if let Some(universal_region) = self.definitions[upper_bound].external_name {
|
||||
return universal_region;
|
||||
}
|
||||
|
||||
// Nothing exact found, so we pick a named upper bound, if there's only one.
|
||||
// If there's >1 universal region, then we probably are dealing w/ an intersection
|
||||
// region which cannot be mapped back to a universal.
|
||||
// FIXME: We could probably compute the LUB if there is one.
|
||||
let scc = self.constraint_sccs.scc(vid);
|
||||
let upper_bounds: Vec<_> = self
|
||||
.rev_scc_graph
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.upper_bounds(scc)
|
||||
.filter_map(|vid| self.definitions[vid].external_name)
|
||||
.filter(|r| !r.is_static())
|
||||
.collect();
|
||||
match &upper_bounds[..] {
|
||||
[universal_region] => *universal_region,
|
||||
_ => region,
|
||||
}
|
||||
}
|
||||
_ => region,
|
||||
|
|
|
|||
|
|
@ -745,10 +745,9 @@ fn expand_preparsed_asm(
|
|||
unused_operands.push((args.operands[idx].1, msg));
|
||||
}
|
||||
}
|
||||
match unused_operands.len() {
|
||||
0 => {}
|
||||
1 => {
|
||||
let (sp, msg) = unused_operands.into_iter().next().unwrap();
|
||||
match unused_operands[..] {
|
||||
[] => {}
|
||||
[(sp, msg)] => {
|
||||
ecx.dcx()
|
||||
.struct_span_err(sp, msg)
|
||||
.with_span_label(sp, msg)
|
||||
|
|
|
|||
|
|
@ -378,8 +378,8 @@ impl BlockOrExpr {
|
|||
None => cx.expr_block(cx.block(span, ThinVec::new())),
|
||||
Some(expr) => expr,
|
||||
}
|
||||
} else if self.0.len() == 1
|
||||
&& let ast::StmtKind::Expr(expr) = &self.0[0].kind
|
||||
} else if let [stmt] = self.0.as_slice()
|
||||
&& let ast::StmtKind::Expr(expr) = &stmt.kind
|
||||
&& self.1.is_none()
|
||||
{
|
||||
// There's only a single statement expression. Pull it out.
|
||||
|
|
@ -1273,7 +1273,7 @@ impl<'a> MethodDef<'a> {
|
|||
}
|
||||
FieldlessVariantsStrategy::Default => (),
|
||||
}
|
||||
} else if variants.len() == 1 {
|
||||
} else if let [variant] = variants.as_slice() {
|
||||
// If there is a single variant, we don't need an operation on
|
||||
// the discriminant(s). Just use the most degenerate result.
|
||||
return self.call_substructure_method(
|
||||
|
|
@ -1281,7 +1281,7 @@ impl<'a> MethodDef<'a> {
|
|||
trait_,
|
||||
type_ident,
|
||||
nonselflike_args,
|
||||
&EnumMatching(0, &variants[0], Vec::new()),
|
||||
&EnumMatching(0, variant, Vec::new()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,8 +180,8 @@ fn make_format_args(
|
|||
Ok((mut err, suggested)) => {
|
||||
if !suggested {
|
||||
if let ExprKind::Block(block, None) = &efmt.kind
|
||||
&& block.stmts.len() == 1
|
||||
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
|
||||
&& let [stmt] = block.stmts.as_slice()
|
||||
&& let StmtKind::Expr(expr) = &stmt.kind
|
||||
&& let ExprKind::Path(None, path) = &expr.kind
|
||||
&& path.is_potential_trivial_const_arg()
|
||||
{
|
||||
|
|
@ -196,8 +196,8 @@ fn make_format_args(
|
|||
} else {
|
||||
let sugg_fmt = match args.explicit_args().len() {
|
||||
0 => "{}".to_string(),
|
||||
_ => {
|
||||
format!("{}{{}}", "{} ".repeat(args.explicit_args().len()))
|
||||
count => {
|
||||
format!("{}{{}}", "{} ".repeat(count))
|
||||
}
|
||||
};
|
||||
err.span_suggestion(
|
||||
|
|
@ -555,7 +555,7 @@ fn make_format_args(
|
|||
};
|
||||
let arg_name = args.explicit_args()[index].kind.ident().unwrap();
|
||||
ecx.buffered_early_lint.push(BufferedEarlyLint {
|
||||
span: arg_name.span.into(),
|
||||
span: Some(arg_name.span.into()),
|
||||
node_id: rustc_ast::CRATE_NODE_ID,
|
||||
lint_id: LintId::of(NAMED_ARGUMENTS_USED_POSITIONALLY),
|
||||
diagnostic: BuiltinLintDiag::NamedArgumentUsedPositionally {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ name: Abi-cafe
|
|||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
abi_cafe:
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
timeout-minutes: 30
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.env.TARGET_TRIPLE }}
|
||||
cancel-in-progress: true
|
||||
|
|
@ -27,12 +28,16 @@ jobs:
|
|||
- os: macos-latest
|
||||
env:
|
||||
TARGET_TRIPLE: x86_64-apple-darwin
|
||||
- os: macos-latest
|
||||
env:
|
||||
TARGET_TRIPLE: aarch64-apple-darwin
|
||||
- os: windows-latest
|
||||
env:
|
||||
TARGET_TRIPLE: x86_64-pc-windows-msvc
|
||||
- os: windows-latest
|
||||
env:
|
||||
TARGET_TRIPLE: x86_64-pc-windows-gnu
|
||||
# FIXME Currently hangs. Re-enable once this is fixed or abi-cafe adds a timeout.
|
||||
#- os: windows-latest
|
||||
# env:
|
||||
# TARGET_TRIPLE: x86_64-pc-windows-gnu
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
sed -i 's/components.*/components = []/' rust-toolchain
|
||||
echo 'profile = "minimal"' >> rust-toolchain
|
||||
- uses: rustsec/audit-check@v1.4.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ jobs:
|
|||
- name: Avoid installing rustc-dev
|
||||
run: |
|
||||
sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain
|
||||
echo 'profile = "minimal"' >> rust-toolchain
|
||||
rustfmt -v
|
||||
|
||||
- name: Rustfmt
|
||||
|
|
|
|||
68
compiler/rustc_codegen_cranelift/.zed/settings.json
Normal file
68
compiler/rustc_codegen_cranelift/.zed/settings.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"format_on_save": "on",
|
||||
"lsp": {
|
||||
"rust-analyzer": {
|
||||
"initialization_options": {
|
||||
"diagnostics": {
|
||||
// in case rustc.source is disabled for performance reasons; disable the errors about this
|
||||
"disabled": ["unresolved-extern-crate", "unresolved-macro-call"]
|
||||
},
|
||||
"rustc": {
|
||||
"source": "discover"
|
||||
},
|
||||
"imports": {
|
||||
"granularity": {
|
||||
"enforce": true,
|
||||
"group": "module"
|
||||
},
|
||||
"prefix": "crate"
|
||||
},
|
||||
"cargo": {
|
||||
"features": ["unstable-features"]
|
||||
},
|
||||
"linkedProjects": [
|
||||
"./Cargo.toml",
|
||||
"./build_system/Cargo.toml",
|
||||
{
|
||||
"crates": [
|
||||
{
|
||||
"root_module": "./example/mini_core.rs",
|
||||
"edition": "2018",
|
||||
"deps": [],
|
||||
"cfg": []
|
||||
},
|
||||
{
|
||||
"root_module": "./example/mini_core_hello_world.rs",
|
||||
"edition": "2018",
|
||||
"deps": [
|
||||
{
|
||||
"crate": 0,
|
||||
"name": "mini_core"
|
||||
}
|
||||
],
|
||||
"cfg": []
|
||||
},
|
||||
{
|
||||
"root_module": "./example/mod_bench.rs",
|
||||
"edition": "2018",
|
||||
"deps": [],
|
||||
"cfg": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sysroot_src": "./build/stdlib/library",
|
||||
"crates": [
|
||||
{
|
||||
"root_module": "./example/std_example.rs",
|
||||
"edition": "2015",
|
||||
"deps": [],
|
||||
"cfg": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,21 +46,28 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6b33d7e757a887989eb18b35712b2a67d96171ec3149d1bfb657b29b7b367c"
|
||||
checksum = "effa84ab2023f7138045ece6b326588c17447ca22e66db71ec15cb0a6c0c4ad2"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.109.0"
|
||||
name = "cranelift-bitset"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9acf15cb22be42d07c3b57d7856329cb228b7315d385346149df2566ad5e4aa"
|
||||
checksum = "38a1dfc50dca188a15d938867c4400589530bcb0138f7022aae6d059d1d8c309"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "821c20c639350158ecca928dc2a244d0d1c9cef2377a378fc62a445a286eb1ca"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"cranelift-bforest",
|
||||
"cranelift-bitset",
|
||||
"cranelift-codegen-meta",
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-control",
|
||||
|
|
@ -77,39 +84,42 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e934d301392b73b3f8b0540391fb82465a0f179a3cee7c726482ac4727efcc97"
|
||||
checksum = "064473f2fd59b44fa2c9aaa60de1f9c44db5e13521e28bc85d2b92ee535ef625"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb2a2566b3d54b854dfb288b3b187f6d3d17d6f762c92898207eba302931da"
|
||||
checksum = "d0f39b9ebfd2febdc2acfb9a0fca110665bcd5a6839502576307735ed07b2177"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-control"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0100f33b704cdacd01ad66ff41f8c5030d57cbff078e2a4e49ab1822591299fa"
|
||||
checksum = "94e125c189c3a1ca8dfe209fc6f46edba058a6d24e0b92aff69459a15f4711e7"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8cfdc315e5d18997093e040a8d234bea1ac1e118a716d3e30f40d449e78207b"
|
||||
checksum = "ea62eb109baec2247e1a6fa7b74c0f584b1e76e289cfd7017385b4b031fc8450"
|
||||
dependencies = [
|
||||
"cranelift-bitset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f74b84f16af2e982b0c0c72233503d9d55cbfe3865dbe807ca28dc6642a28b5"
|
||||
checksum = "722b089357aacb6c7528b2e59a5fe00917d61ce63448b25a3e477a5b7819fac8"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
|
|
@ -119,15 +129,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adf306d3dde705fb94bd48082f01d38c4ededc74293a4c007805f610bf08bc6e"
|
||||
checksum = "c4b5005a48288e7fc2a2991a377831c534e26929b063c379c018060727785a9b"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5c5cfb8bbd3339cd25cca30e7516ff8fe5cb1feeddde6980cc4d5ef34df97bb"
|
||||
checksum = "f843932baf8d1025c5f114b929eda172d74b7163d058e0de2597c308b567c7e9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
|
@ -145,9 +155,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9b0d4269b36fd858e6d8f20cd4938941186fb831488c361888cb2d6b33a9a6"
|
||||
checksum = "449819ef1c4af139cf1b9717916fcaea0e23248853d3e95135139773a842d3eb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
|
@ -156,9 +166,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ea0ebdef7aff4a79bcbc8b6495f31315f16b3bf311152f472eaa8d679352581"
|
||||
checksum = "3ae2d48f38081a9e679ad795bd36bb29bedeb5552fc1c195185bf9885fa1b16e"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
|
|
@ -167,9 +177,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.109.0"
|
||||
version = "0.110.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e33439ec20db058bc7cc3410f9748ab1ad90a35cef713d625c736f43e3820d"
|
||||
checksum = "3a39ee2cfd0ec485eca76f6b4dc17701a280fa406bc05137bb43f1635ed12c9f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
|
@ -279,9 +289,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.1"
|
||||
version = "0.36.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
|
||||
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"hashbrown 0.14.5",
|
||||
|
|
@ -411,9 +421,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-icache-coherence"
|
||||
version = "22.0.0"
|
||||
version = "23.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5afe2f0499542f9a4bcfa1b55bfdda803b6ade4e7c93c6b99e0f39dba44b0a91"
|
||||
checksum = "7fddf3e2980fb1d123d1fcac55189e417fdd3dba4f62139b5a0a1f9efe5669d5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { version = "0.109.0", default-features = false, features = ["std", "unwind", "all-arch"] }
|
||||
cranelift-frontend = { version = "0.109.0" }
|
||||
cranelift-module = { version = "0.109.0" }
|
||||
cranelift-native = { version = "0.109.0" }
|
||||
cranelift-jit = { version = "0.109.0", optional = true }
|
||||
cranelift-object = { version = "0.109.0" }
|
||||
cranelift-codegen = { version = "0.110.1", default-features = false, features = ["std", "unwind", "all-arch"] }
|
||||
cranelift-frontend = { version = "0.110.1" }
|
||||
cranelift-module = { version = "0.110.1" }
|
||||
cranelift-native = { version = "0.110.1" }
|
||||
cranelift-jit = { version = "0.110.1", optional = true }
|
||||
cranelift-object = { version = "0.110.1" }
|
||||
target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.28", default-features = false, features = ["write"]}
|
||||
object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ $ rustup component add rustc-codegen-cranelift-preview --toolchain nightly
|
|||
|
||||
Once it is installed, you can enable it with one of the following approaches:
|
||||
- `CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly build -Zcodegen-backend`
|
||||
- `RUSTFLAGS="-Zcodegen-backend=cranelift" cargo +nightly build`
|
||||
- Add the following to `.cargo/config.toml`:
|
||||
```toml
|
||||
[unstable]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::path::Dirs;
|
||||
use crate::path::{Dirs, RelPath};
|
||||
use crate::prepare::GitRepo;
|
||||
use crate::utils::{spawn_and_wait, CargoProject, Compiler};
|
||||
use crate::{build_sysroot, CodegenBackend, SysrootKind};
|
||||
|
|
@ -6,8 +6,8 @@ use crate::{build_sysroot, CodegenBackend, SysrootKind};
|
|||
static ABI_CAFE_REPO: GitRepo = GitRepo::github(
|
||||
"Gankra",
|
||||
"abi-cafe",
|
||||
"4c6dc8c9c687e2b3a760ff2176ce236872b37212",
|
||||
"588df6d66abbe105",
|
||||
"f1220cfd13b57f5c0082c26529163865ee25e115",
|
||||
"fe93a9acd461425d",
|
||||
"abi-cafe",
|
||||
);
|
||||
|
||||
|
|
@ -21,6 +21,7 @@ pub(crate) fn run(
|
|||
rustup_toolchain_name: Option<&str>,
|
||||
bootstrap_host_compiler: &Compiler,
|
||||
) {
|
||||
RelPath::DOWNLOAD.ensure_exists(dirs);
|
||||
ABI_CAFE_REPO.fetch(dirs);
|
||||
ABI_CAFE_REPO.patch(dirs);
|
||||
|
||||
|
|
@ -38,17 +39,23 @@ pub(crate) fn run(
|
|||
eprintln!("Running abi-cafe");
|
||||
|
||||
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
|
||||
|
||||
let mut cmd = ABI_CAFE.run(bootstrap_host_compiler, dirs);
|
||||
cmd.arg("--");
|
||||
cmd.arg("--pairs");
|
||||
cmd.args(
|
||||
let pairs =
|
||||
if cfg!(not(any(target_os = "macos", all(target_os = "windows", target_env = "msvc")))) {
|
||||
&pairs[..]
|
||||
} else {
|
||||
&pairs[..2]
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
let mut cmd = ABI_CAFE.run(bootstrap_host_compiler, dirs);
|
||||
cmd.arg("--");
|
||||
|
||||
// stdcall, vectorcall and such don't work yet
|
||||
cmd.arg("--conventions").arg("c").arg("--conventions").arg("rust");
|
||||
|
||||
for pair in pairs {
|
||||
cmd.arg("--pairs").arg(pair);
|
||||
}
|
||||
|
||||
cmd.arg("--add-rustc-codegen-backend");
|
||||
match cg_clif_dylib {
|
||||
CodegenBackend::Local(path) => {
|
||||
|
|
@ -58,6 +65,7 @@ pub(crate) fn run(
|
|||
cmd.arg(format!("cgclif:{name}"));
|
||||
}
|
||||
}
|
||||
|
||||
cmd.current_dir(ABI_CAFE.source_dir(dirs));
|
||||
|
||||
spawn_and_wait(cmd);
|
||||
|
|
|
|||
|
|
@ -312,7 +312,6 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option<SysrootTarget> {
|
|||
let obj = RTSTARTUP_SYSROOT.to_path(dirs).join(format!("{file}.o"));
|
||||
let mut build_rtstartup_cmd = Command::new(&compiler.rustc);
|
||||
build_rtstartup_cmd
|
||||
.arg("-Ainternal_features") // Missing #[allow(internal_features)]
|
||||
.arg("--target")
|
||||
.arg(&compiler.triple)
|
||||
.arg("--emit=obj")
|
||||
|
|
|
|||
|
|
@ -22,36 +22,6 @@ pub(crate) fn prepare_stdlib(dirs: &Dirs, rustc: &Path) {
|
|||
assert!(sysroot_src_orig.exists());
|
||||
|
||||
apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs));
|
||||
|
||||
std::fs::write(
|
||||
STDLIB_SRC.to_path(dirs).join("Cargo.toml"),
|
||||
r#"
|
||||
[workspace]
|
||||
resolver = "1"
|
||||
members = ["./library/sysroot"]
|
||||
|
||||
[patch.crates-io]
|
||||
rustc-std-workspace-core = { path = "./library/rustc-std-workspace-core" }
|
||||
rustc-std-workspace-alloc = { path = "./library/rustc-std-workspace-alloc" }
|
||||
rustc-std-workspace-std = { path = "./library/rustc-std-workspace-std" }
|
||||
|
||||
# Mandatory for correctly compiling compiler-builtins
|
||||
[profile.dev.package.compiler_builtins]
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
codegen-units = 10000
|
||||
|
||||
[profile.release.package.compiler_builtins]
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
codegen-units = 10000
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let source_lockfile = RelPath::PATCHES.to_path(dirs).join("stdlib-lock.toml");
|
||||
let target_lockfile = STDLIB_SRC.to_path(dirs).join("Cargo.lock");
|
||||
fs::copy(source_lockfile, target_lockfile).unwrap();
|
||||
}
|
||||
|
||||
pub(crate) struct GitRepo {
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
|||
]);
|
||||
runner.run_out_command("gen_block_iterate", &[]);
|
||||
}),
|
||||
TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]),
|
||||
];
|
||||
|
||||
pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
|
||||
|
|
@ -437,7 +438,7 @@ impl<'a> TestRunner<'a> {
|
|||
cmd.arg("-L");
|
||||
cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
|
||||
cmd.arg("--out-dir");
|
||||
cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
|
||||
cmd.arg(BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs));
|
||||
cmd.arg("-Cdebuginfo=2");
|
||||
cmd.arg("--target");
|
||||
cmd.arg(&self.target_compiler.triple);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ aot.issue-59326
|
|||
aot.polymorphize_coroutine
|
||||
aot.neon
|
||||
aot.gen_block_iterate
|
||||
aot.raw-dylib
|
||||
|
||||
testsuite.extended_sysroot
|
||||
test.rust-random/rand
|
||||
|
|
|
|||
|
|
@ -585,6 +585,7 @@ pub enum E2<X> {
|
|||
V4,
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
fn check_niche_behavior() {
|
||||
if let E1::V2 { .. } = (E1::V1 { f: true }) {
|
||||
intrinsics::abort();
|
||||
|
|
|
|||
31
compiler/rustc_codegen_cranelift/example/raw-dylib.rs
Normal file
31
compiler/rustc_codegen_cranelift/example/raw-dylib.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Tests the raw-dylib feature for Windows.
|
||||
// https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute
|
||||
|
||||
fn main() {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
#[link(name = "kernel32", kind = "raw-dylib")]
|
||||
extern "C" {
|
||||
fn GetModuleFileNameA(
|
||||
module: *mut std::ffi::c_void,
|
||||
filename: *mut u8,
|
||||
size: u32,
|
||||
) -> u32;
|
||||
}
|
||||
|
||||
// Get the filename of the current executable....
|
||||
let mut buffer = [0u8; 1024];
|
||||
let size = unsafe {
|
||||
GetModuleFileNameA(core::ptr::null_mut(), buffer.as_mut_ptr(), buffer.len() as u32)
|
||||
};
|
||||
if size == 0 {
|
||||
eprintln!("failed to get module file name: {}", std::io::Error::last_os_error());
|
||||
return;
|
||||
} else {
|
||||
// ...and make sure that it matches the test name.
|
||||
let filename =
|
||||
std::ffi::CStr::from_bytes_with_nul(&buffer[..size as usize + 1]).unwrap();
|
||||
assert!(filename.to_str().unwrap().ends_with("raw-dylib.exe"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 2b15fee2bb5fd14e34c7e17e44d99cb34f4c555d Mon Sep 17 00:00:00 2001
|
||||
From: Afonso Bordado <afonsobordado@az8.co>
|
||||
Date: Tue, 27 Sep 2022 07:55:17 +0100
|
||||
Subject: [PATCH] Disable some test on x86_64-pc-windows-gnu
|
||||
|
||||
---
|
||||
src/report.rs | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/report.rs b/src/report.rs
|
||||
index eeec614..f582867 100644
|
||||
--- a/src/report.rs
|
||||
+++ b/src/report.rs
|
||||
@@ -48,6 +48,15 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn AbiImpl, callee: &dyn AbiImpl
|
||||
//
|
||||
// THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES
|
||||
|
||||
+ // x86_64-pc-windows-gnu has some broken i128 tests that aren't disabled by default
|
||||
+ if cfg!(all(target_os = "windows", target_env = "gnu")) && test.test_name == "ui128" {
|
||||
+ result.run = Link;
|
||||
+ result.check = Pass(Link);
|
||||
+ } else if test.test_name == "ui128" {
|
||||
+ result.run == Check;
|
||||
+ result.check = Pass(Check);
|
||||
+ }
|
||||
+
|
||||
// END OF VENDOR RESERVED AREA
|
||||
//
|
||||
//
|
||||
--
|
||||
2.30.1.windows.1
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
From 236df390f3bc4ed69c26f4d51d584bea246da886 Mon Sep 17 00:00:00 2001
|
||||
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
|
||||
Date: Tue, 9 Jul 2024 11:25:14 +0000
|
||||
Subject: [PATCH] Disable broken tests
|
||||
|
||||
---
|
||||
src/report.rs | 36 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
|
||||
diff --git a/src/report.rs b/src/report.rs
|
||||
index 958ab43..dcf1044 100644
|
||||
--- a/src/report.rs
|
||||
+++ b/src/report.rs
|
||||
@@ -48,6 +48,58 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn Toolchain, callee: &dyn Toolc
|
||||
//
|
||||
// THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES
|
||||
|
||||
+ if cfg!(all(target_arch = "aarch64", target_os = "linux")) {
|
||||
+ if test.test == "F32Array" && test.options.convention == CallingConvention::C {
|
||||
+ result.check = Busted(Check);
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::C {
|
||||
+ result.check = Busted(Check);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if cfg!(all(target_arch = "aarch64", target_os = "macos")) {
|
||||
+ if test.test == "SingleVariantUnion" && test.options.convention == CallingConvention::C && test.options.repr == LangRepr::C {
|
||||
+ result.check = Busted(Check);
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "OptionU128" && test.caller == "rustc" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::C {
|
||||
+ result.check = Busted(Run);
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "OptionU128" && test.caller == "cgclif" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::C {
|
||||
+ result.check = Busted(Check);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if cfg!(all(target_arch = "x86_64", unix)) {
|
||||
+ if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust && test.options.repr == LangRepr::Rust {
|
||||
+ result.check = Busted(Run);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if cfg!(all(target_arch = "x86_64", windows)) {
|
||||
+ if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust {
|
||||
+ result.check = Busted(Check);
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "OptionU128" && test.options.convention == CallingConvention::Rust && (test.caller == "rustc" || test.options.repr == LangRepr::Rust) {
|
||||
+ result.check = Busted(Run);
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "simple" && test.options.convention == CallingConvention::Rust {
|
||||
+ result.check = Busted(Check);
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "simple" && test.options.convention == CallingConvention::Rust && test.caller == "rustc" {
|
||||
+ result.check = Busted(Run);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if test.test == "f16" || test.test == "f128" {
|
||||
+ result.run = Skip;
|
||||
+ }
|
||||
+
|
||||
// END OF VENDOR RESERVED AREA
|
||||
//
|
||||
//
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
|
@ -37,8 +37,8 @@ index 42a26ae..5ac1042 100644
|
|||
+++ b/lib.rs
|
||||
@@ -1,3 +1,4 @@
|
||||
+#![cfg(test)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(array_chunks)]
|
||||
#![feature(array_ptr_get)]
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(offset_of_nested))]
|
||||
#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
|
||||
--
|
||||
2.21.0 (Apple Git-122)
|
||||
|
|
|
|||
|
|
@ -11,17 +11,17 @@ Cranelift doesn't support them yet
|
|||
4 files changed, 4 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/lib.rs b/lib.rs
|
||||
index 897a5e9..331f66f 100644
|
||||
index 1e336bf..35e6f54 100644
|
||||
--- a/lib.rs
|
||||
+++ b/lib.rs
|
||||
@@ -93,7 +93,6 @@
|
||||
#![feature(const_option)]
|
||||
#![feature(const_option_ext)]
|
||||
#![feature(const_result)]
|
||||
@@ -1,7 +1,6 @@
|
||||
#![cfg(test)]
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(offset_of_nested))]
|
||||
-#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
|
||||
#![cfg_attr(test, feature(cfg_match))]
|
||||
#![feature(int_roundings)]
|
||||
#![feature(split_array)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(array_chunks)]
|
||||
diff --git a/atomic.rs b/atomic.rs
|
||||
index b735957..ea728b6 100644
|
||||
--- a/atomic.rs
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
From 175d52c5e1779764b66777db1e6f172c2dc365ff Mon Sep 17 00:00:00 2001
|
||||
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
|
||||
Date: Fri, 9 Aug 2024 15:44:51 +0000
|
||||
Subject: [PATCH] Disable f16 and f128 in compiler-builtins
|
||||
|
||||
---
|
||||
library/sysroot/Cargo.toml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
|
||||
index 7165c3e48af..968552ad435 100644
|
||||
--- a/library/sysroot/Cargo.toml
|
||||
+++ b/library/sysroot/Cargo.toml
|
||||
@@ -11,7 +11,7 @@ test = { path = "../test" }
|
||||
|
||||
# Forward features to the `std` crate as necessary
|
||||
[features]
|
||||
-default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"]
|
||||
+default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind", "compiler-builtins-no-f16-f128"]
|
||||
backtrace = ["std/backtrace"]
|
||||
compiler-builtins-c = ["std/compiler-builtins-c"]
|
||||
compiler-builtins-mem = ["std/compiler-builtins-mem"]
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
From 9f65e742ba3e41474e6126c6c4469c48eaa6ca7e Mon Sep 17 00:00:00 2001
|
||||
From: Chris Denton <chris@chrisdenton.dev>
|
||||
Date: Tue, 20 Feb 2024 16:01:40 -0300
|
||||
Subject: [PATCH] Don't use raw-dylib in std
|
||||
|
||||
---
|
||||
library/std/src/sys/pal/windows/c.rs | 2 +-
|
||||
library/std/src/sys/pal/windows/rand.rs | 3 +--
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
|
||||
index ad8e01bfa9b..9ca8e4c16ce 100644
|
||||
--- a/library/std/src/sys/pal/windows/c.rs
|
||||
+++ b/library/std/src/sys/pal/windows/c.rs
|
||||
@@ -312,7 +312,7 @@ pub unsafe fn NtWriteFile(
|
||||
|
||||
// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
|
||||
cfg_if::cfg_if! {
|
||||
-if #[cfg(not(target_vendor = "win7"))] {
|
||||
+if #[cfg(any())] {
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
|
||||
extern "system" {
|
||||
diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs
|
||||
index e427546222a..f2fe42a4d51 100644
|
||||
--- a/library/std/src/sys/pal/windows/rand.rs
|
||||
+++ b/library/std/src/sys/pal/windows/rand.rs
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::sys::c;
|
||||
|
||||
-#[cfg(not(target_vendor = "win7"))]
|
||||
+#[cfg(any())]
|
||||
#[inline]
|
||||
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
let mut v = (0, 0);
|
||||
@@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
v
|
||||
}
|
||||
|
||||
-#[cfg(target_vendor = "win7")]
|
||||
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
use crate::ffi::c_void;
|
||||
use crate::io;
|
||||
--
|
||||
2.42.0.windows.2
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 0d741cf82c3c908616abd39dc84ebf7d8702e0c3 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Denton <chris@chrisdenton.dev>
|
||||
Date: Tue, 16 Apr 2024 15:51:34 +0000
|
||||
Subject: [PATCH] Revert use raw-dylib for Windows futex APIs
|
||||
|
||||
---
|
||||
library/std/src/sys/pal/windows/c.rs | 14 +-------------
|
||||
1 file changed, 1 insertion(+), 13 deletions(-)
|
||||
|
||||
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
|
||||
index 9d58ce05f01..1c828bac4b6 100644
|
||||
--- a/library/std/src/sys/pal/windows/c.rs
|
||||
+++ b/library/std/src/sys/pal/windows/c.rs
|
||||
@@ -357,19 +357,7 @@ pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(target_vendor = "win7"))]
|
||||
-// Use raw-dylib to import synchronization functions to workaround issues with the older mingw import library.
|
||||
-#[cfg_attr(
|
||||
- target_arch = "x86",
|
||||
- link(
|
||||
- name = "api-ms-win-core-synch-l1-2-0",
|
||||
- kind = "raw-dylib",
|
||||
- import_name_type = "undecorated"
|
||||
- )
|
||||
-)]
|
||||
-#[cfg_attr(
|
||||
- not(target_arch = "x86"),
|
||||
- link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
|
||||
-)]
|
||||
+#[link(name = "synchronization")]
|
||||
extern "system" {
|
||||
pub fn WaitOnAddress(
|
||||
address: *const c_void,
|
||||
--
|
||||
2.42.0.windows.2
|
||||
|
||||
|
|
@ -1,455 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli 0.29.0",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4ab134a739bafec76aa91ccb15d519a54e569350644a1fea6528d5a0d407e22"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cupid"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bad352a84b567cc38a5854e3aa8ee903cb8519a25d0b799b739bafffd1f91a1"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlmalloc"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
"rustc-std-workspace-std",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"memchr",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic_abort"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic_unwind"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
"unwind",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc_macro"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiler_builtins"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e244f96e03a3067f9e521d3167bd42657594cb8588c8d3a2db01545dc1af2e0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi-alloc"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"r-efi",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-alloc"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-core"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-std"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "std"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"dlmalloc",
|
||||
"fortanix-sgx-abi",
|
||||
"hashbrown",
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
"r-efi",
|
||||
"r-efi-alloc",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"rustc-demangle",
|
||||
"std_detect",
|
||||
"unwind",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "std_detect"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"cupid",
|
||||
"libc",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysroot"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc_macro",
|
||||
"std",
|
||||
"test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"getopts",
|
||||
"libc",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
"rustc-std-workspace-std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unwind"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
"unwinding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unwinding"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37a19a21a537f635c16c7576f22d0f2f7d63353c1337ad4ce0d8001c7952a25b"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli 0.28.1",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2024-07-13"
|
||||
channel = "nightly-2024-08-09"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools"]
|
||||
profile = "minimal"
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.r
|
|||
# exotic linkages
|
||||
rm tests/incremental/hashes/function_interfaces.rs
|
||||
rm tests/incremental/hashes/statics.rs
|
||||
rm -r tests/run-make/naked-symbol-visibility
|
||||
|
||||
# variadic arguments
|
||||
rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
|
||||
|
|
@ -118,6 +119,7 @@ rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
|
|||
rm tests/ui/mir/mir_raw_fat_ptr.rs # same
|
||||
rm tests/ui/consts/issue-33537.rs # same
|
||||
rm tests/ui/consts/const-mut-refs-crate.rs # same
|
||||
rm tests/ui/abi/large-byval-align.rs # exceeds implementation limit of Cranelift
|
||||
|
||||
# doesn't work due to the way the rustc test suite is invoked.
|
||||
# should work when using ./x.py test the way it is intended
|
||||
|
|
@ -134,6 +136,8 @@ rm tests/ui/deprecation/deprecated_inline_threshold.rs # missing deprecation war
|
|||
# bugs in the test suite
|
||||
# ======================
|
||||
rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
|
||||
rm tests/ui/backtrace/synchronized-panic-handler.rs # missing needs-unwind annotation
|
||||
rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables
|
||||
|
||||
rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
|
||||
|
||||
|
|
@ -157,8 +161,8 @@ index ea06b620c4c..b969d0009c6 100644
|
|||
RUSTDOC := \$(RUSTDOC) -Clinker='\$(RUSTC_LINKER)'
|
||||
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
|
||||
index 9607ff02f96..b7d97caf9a2 100644
|
||||
--- a/src/tools/run-make-support/src/rustdoc.rs
|
||||
+++ b/src/tools/run-make-support/src/rustdoc.rs
|
||||
--- a/src/tools/run-make-support/src/external_deps/rustdoc.rs
|
||||
+++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs
|
||||
@@ -34,8 +34,6 @@ pub fn bare() -> Self {
|
||||
#[track_caller]
|
||||
pub fn new() -> Self {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::borrow::Borrow;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use ar_archive_writer::{COFFShortExport, MachineTypes};
|
||||
use rustc_codegen_ssa::back::archive::{
|
||||
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
|
||||
create_mingw_dll_import_lib, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
|
||||
DEFAULT_OBJECT_READER,
|
||||
};
|
||||
use rustc_codegen_ssa::common::is_mingw_gnu_toolchain;
|
||||
use rustc_session::Session;
|
||||
|
||||
pub(crate) struct ArArchiveBuilderBuilder;
|
||||
|
|
@ -15,11 +20,74 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
|
|||
fn create_dll_import_lib(
|
||||
&self,
|
||||
sess: &Session,
|
||||
_lib_name: &str,
|
||||
_dll_imports: &[rustc_session::cstore::DllImport],
|
||||
_tmpdir: &Path,
|
||||
_is_direct_dependency: bool,
|
||||
) -> PathBuf {
|
||||
sess.dcx().fatal("raw-dylib is not yet supported by rustc_codegen_cranelift");
|
||||
lib_name: &str,
|
||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
||||
output_path: &Path,
|
||||
) {
|
||||
if is_mingw_gnu_toolchain(&sess.target) {
|
||||
// The binutils linker used on -windows-gnu targets cannot read the import
|
||||
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
||||
// that loaded but crashed with an AV upon calling one of the imported
|
||||
// functions. Therefore, use binutils to create the import library instead,
|
||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
||||
create_mingw_dll_import_lib(
|
||||
sess,
|
||||
lib_name,
|
||||
import_name_and_ordinal_vector,
|
||||
output_path,
|
||||
);
|
||||
} else {
|
||||
let mut file =
|
||||
match fs::OpenOptions::new().write(true).create_new(true).open(&output_path) {
|
||||
Ok(file) => file,
|
||||
Err(error) => {
|
||||
sess.dcx().fatal(format!(
|
||||
"failed to create import library file `{path}`: {error}",
|
||||
path = output_path.display(),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let machine = match sess.target.arch.borrow() {
|
||||
"x86" => MachineTypes::I386,
|
||||
"x86_64" => MachineTypes::AMD64,
|
||||
"arm" => MachineTypes::ARMNT,
|
||||
"aarch64" => MachineTypes::ARM64,
|
||||
_ => {
|
||||
sess.dcx().fatal(format!(
|
||||
"unsupported target architecture `{arch}`",
|
||||
arch = sess.target.arch,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let exports = import_name_and_ordinal_vector
|
||||
.iter()
|
||||
.map(|(name, ordinal)| COFFShortExport {
|
||||
name: name.to_string(),
|
||||
ext_name: None,
|
||||
symbol_name: None,
|
||||
alias_target: None,
|
||||
ordinal: ordinal.unwrap_or(0),
|
||||
noname: ordinal.is_some(),
|
||||
data: false,
|
||||
private: false,
|
||||
constant: false,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Err(error) = ar_archive_writer::write_import_library(
|
||||
&mut file,
|
||||
lib_name,
|
||||
&exports,
|
||||
machine,
|
||||
!sess.target.is_like_msvc,
|
||||
) {
|
||||
sess.dcx().fatal(format!(
|
||||
"failed to create import library `{path}`: `{error}`",
|
||||
path = output_path.display(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,19 +23,7 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||
match bin_op {
|
||||
BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => None,
|
||||
BinOp::Add | BinOp::AddUnchecked | BinOp::Sub | BinOp::SubUnchecked => None,
|
||||
BinOp::Mul | BinOp::MulUnchecked => {
|
||||
let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
|
||||
let ret_val = fx.lib_call(
|
||||
"__multi3",
|
||||
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
|
||||
vec![AbiParam::new(types::I128)],
|
||||
&args,
|
||||
)[0];
|
||||
Some(CValue::by_val(
|
||||
ret_val,
|
||||
fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }),
|
||||
))
|
||||
}
|
||||
BinOp::Mul | BinOp::MulUnchecked => None,
|
||||
BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"),
|
||||
BinOp::Div | BinOp::Rem => {
|
||||
let name = match (bin_op, is_signed) {
|
||||
|
|
@ -92,6 +80,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
|
|||
|
||||
match bin_op {
|
||||
BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => unreachable!(),
|
||||
BinOp::Add | BinOp::Sub => None,
|
||||
BinOp::Mul if is_signed => {
|
||||
let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]);
|
||||
let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
|
||||
|
|
@ -112,7 +101,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
|
|||
let oflow = fx.bcx.ins().ireduce(types::I8, oflow);
|
||||
Some(CValue::by_val_pair(res, oflow, fx.layout_of(out_ty)))
|
||||
}
|
||||
BinOp::Add | BinOp::Sub | BinOp::Mul => {
|
||||
BinOp::Mul => {
|
||||
let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]);
|
||||
let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
|
||||
let param_types = vec![
|
||||
|
|
@ -121,15 +110,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
|
|||
AbiParam::new(types::I128),
|
||||
];
|
||||
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
|
||||
let name = match (bin_op, is_signed) {
|
||||
(BinOp::Add, false) => "__rust_u128_addo",
|
||||
(BinOp::Add, true) => "__rust_i128_addo",
|
||||
(BinOp::Sub, false) => "__rust_u128_subo",
|
||||
(BinOp::Sub, true) => "__rust_i128_subo",
|
||||
(BinOp::Mul, false) => "__rust_u128_mulo",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
fx.lib_call(name, param_types, vec![], &args);
|
||||
fx.lib_call("__rust_u128_mulo", param_types, vec![], &args);
|
||||
Some(out_place.to_cvalue(fx))
|
||||
}
|
||||
BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(),
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
let tail = tcx.struct_tail_erasing_lifetimes(ty, ParamEnv::reveal_all());
|
||||
let tail = tcx.struct_tail_for_codegen(ty, ParamEnv::reveal_all());
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
|
|
|
|||
|
|
@ -38,18 +38,12 @@ builtin_functions! {
|
|||
register_functions_for_jit;
|
||||
|
||||
// integers
|
||||
fn __multi3(a: i128, b: i128) -> i128;
|
||||
fn __muloti4(n: i128, d: i128, oflow: &mut i32) -> i128;
|
||||
fn __udivti3(n: u128, d: u128) -> u128;
|
||||
fn __divti3(n: i128, d: i128) -> i128;
|
||||
fn __umodti3(n: u128, d: u128) -> u128;
|
||||
fn __modti3(n: i128, d: i128) -> i128;
|
||||
fn __rust_u128_addo(a: u128, b: u128) -> (u128, bool);
|
||||
fn __rust_i128_addo(a: i128, b: i128) -> (i128, bool);
|
||||
fn __rust_u128_subo(a: u128, b: u128) -> (u128, bool);
|
||||
fn __rust_i128_subo(a: i128, b: i128) -> (i128, bool);
|
||||
fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool);
|
||||
fn __rust_i128_mulo(a: i128, b: i128) -> (i128, bool);
|
||||
|
||||
// floats
|
||||
fn __floattisf(i: i128) -> f32;
|
||||
|
|
|
|||
|
|
@ -169,39 +169,6 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
"llvm.x86.sse.add.ss" => {
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_ss&ig_expand=171
|
||||
intrinsic_args!(fx, args => (a, b); intrinsic);
|
||||
|
||||
assert_eq!(a.layout(), b.layout());
|
||||
assert_eq!(a.layout(), ret.layout());
|
||||
let layout = a.layout();
|
||||
|
||||
let (_, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||
assert!(lane_ty.is_floating_point());
|
||||
let ret_lane_layout = fx.layout_of(lane_ty);
|
||||
|
||||
ret.write_cvalue(fx, a);
|
||||
|
||||
let a_lane = a.value_lane(fx, 0).load_scalar(fx);
|
||||
let b_lane = b.value_lane(fx, 0).load_scalar(fx);
|
||||
|
||||
let res = fx.bcx.ins().fadd(a_lane, b_lane);
|
||||
|
||||
let res_lane = CValue::by_val(res, ret_lane_layout);
|
||||
ret.place_lane(fx, 0).write_cvalue(fx, res_lane);
|
||||
}
|
||||
|
||||
"llvm.x86.sse.sqrt.ps" => {
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_ps&ig_expand=6245
|
||||
intrinsic_args!(fx, args => (a); intrinsic);
|
||||
|
||||
// FIXME use vector instructions when possible
|
||||
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
||||
fx.bcx.ins().sqrt(lane)
|
||||
});
|
||||
}
|
||||
|
||||
"llvm.x86.sse.max.ps" => {
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_ps&ig_expand=4357
|
||||
intrinsic_args!(fx, args => (a, b); intrinsic);
|
||||
|
|
@ -744,117 +711,6 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
pack_instruction(fx, a, b, ret, PackSize::S16, PackWidth::Avx);
|
||||
}
|
||||
|
||||
"llvm.x86.fma.vfmaddsub.ps"
|
||||
| "llvm.x86.fma.vfmaddsub.pd"
|
||||
| "llvm.x86.fma.vfmaddsub.ps.256"
|
||||
| "llvm.x86.fma.vfmaddsub.pd.256" => {
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_fmaddsub_ps&ig_expand=3205
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_fmaddsub_pd&ig_expand=3181
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_fmaddsub_ps&ig_expand=3209
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_fmaddsub_pd&ig_expand=3185
|
||||
intrinsic_args!(fx, args => (a, b, c); intrinsic);
|
||||
|
||||
assert_eq!(a.layout(), b.layout());
|
||||
assert_eq!(a.layout(), c.layout());
|
||||
let layout = a.layout();
|
||||
|
||||
let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||
let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
|
||||
assert!(lane_ty.is_floating_point());
|
||||
assert!(ret_lane_ty.is_floating_point());
|
||||
assert_eq!(lane_count, ret_lane_count);
|
||||
let ret_lane_layout = fx.layout_of(ret_lane_ty);
|
||||
|
||||
for idx in 0..lane_count {
|
||||
let a_lane = a.value_lane(fx, idx).load_scalar(fx);
|
||||
let b_lane = b.value_lane(fx, idx).load_scalar(fx);
|
||||
let c_lane = c.value_lane(fx, idx).load_scalar(fx);
|
||||
|
||||
let mul = fx.bcx.ins().fmul(a_lane, b_lane);
|
||||
let res = if idx & 1 == 0 {
|
||||
fx.bcx.ins().fsub(mul, c_lane)
|
||||
} else {
|
||||
fx.bcx.ins().fadd(mul, c_lane)
|
||||
};
|
||||
|
||||
let res_lane = CValue::by_val(res, ret_lane_layout);
|
||||
ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
|
||||
}
|
||||
}
|
||||
|
||||
"llvm.x86.fma.vfmsubadd.ps"
|
||||
| "llvm.x86.fma.vfmsubadd.pd"
|
||||
| "llvm.x86.fma.vfmsubadd.ps.256"
|
||||
| "llvm.x86.fma.vfmsubadd.pd.256" => {
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_fmsubadd_ps&ig_expand=3325
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_fmsubadd_pd&ig_expand=3301
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_fmsubadd_ps&ig_expand=3329
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_fmsubadd_pd&ig_expand=3305
|
||||
intrinsic_args!(fx, args => (a, b, c); intrinsic);
|
||||
|
||||
assert_eq!(a.layout(), b.layout());
|
||||
assert_eq!(a.layout(), c.layout());
|
||||
let layout = a.layout();
|
||||
|
||||
let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||
let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
|
||||
assert!(lane_ty.is_floating_point());
|
||||
assert!(ret_lane_ty.is_floating_point());
|
||||
assert_eq!(lane_count, ret_lane_count);
|
||||
let ret_lane_layout = fx.layout_of(ret_lane_ty);
|
||||
|
||||
for idx in 0..lane_count {
|
||||
let a_lane = a.value_lane(fx, idx).load_scalar(fx);
|
||||
let b_lane = b.value_lane(fx, idx).load_scalar(fx);
|
||||
let c_lane = c.value_lane(fx, idx).load_scalar(fx);
|
||||
|
||||
let mul = fx.bcx.ins().fmul(a_lane, b_lane);
|
||||
let res = if idx & 1 == 0 {
|
||||
fx.bcx.ins().fadd(mul, c_lane)
|
||||
} else {
|
||||
fx.bcx.ins().fsub(mul, c_lane)
|
||||
};
|
||||
|
||||
let res_lane = CValue::by_val(res, ret_lane_layout);
|
||||
ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
|
||||
}
|
||||
}
|
||||
|
||||
"llvm.x86.fma.vfnmadd.ps"
|
||||
| "llvm.x86.fma.vfnmadd.pd"
|
||||
| "llvm.x86.fma.vfnmadd.ps.256"
|
||||
| "llvm.x86.fma.vfnmadd.pd.256" => {
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_fnmadd_ps&ig_expand=3391
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_fnmadd_pd&ig_expand=3367
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_fnmadd_ps&ig_expand=3395
|
||||
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_fnmadd_pd&ig_expand=3371
|
||||
intrinsic_args!(fx, args => (a, b, c); intrinsic);
|
||||
|
||||
assert_eq!(a.layout(), b.layout());
|
||||
assert_eq!(a.layout(), c.layout());
|
||||
let layout = a.layout();
|
||||
|
||||
let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||
let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
|
||||
assert!(lane_ty.is_floating_point());
|
||||
assert!(ret_lane_ty.is_floating_point());
|
||||
assert_eq!(lane_count, ret_lane_count);
|
||||
let ret_lane_layout = fx.layout_of(ret_lane_ty);
|
||||
|
||||
for idx in 0..lane_count {
|
||||
let a_lane = a.value_lane(fx, idx).load_scalar(fx);
|
||||
let b_lane = b.value_lane(fx, idx).load_scalar(fx);
|
||||
let c_lane = c.value_lane(fx, idx).load_scalar(fx);
|
||||
|
||||
let mul = fx.bcx.ins().fmul(a_lane, b_lane);
|
||||
let neg_mul = fx.bcx.ins().fneg(mul);
|
||||
let res = fx.bcx.ins().fadd(neg_mul, c_lane);
|
||||
|
||||
let res_lane = CValue::by_val(res, ret_lane_layout);
|
||||
ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
|
||||
}
|
||||
}
|
||||
|
||||
"llvm.x86.sse42.crc32.32.8"
|
||||
| "llvm.x86.sse42.crc32.32.16"
|
||||
| "llvm.x86.sse42.crc32.32.32"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#![warn(unused_lifetimes)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
extern crate ar_archive_writer;
|
||||
extern crate jobserver;
|
||||
#[macro_use]
|
||||
extern crate rustc_middle;
|
||||
|
|
@ -190,9 +191,20 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
if sess.target.arch == "x86_64" && sess.target.os != "none" {
|
||||
// x86_64 mandates SSE2 support
|
||||
vec![Symbol::intern("fxsr"), sym::sse, Symbol::intern("sse2")]
|
||||
} else if sess.target.arch == "aarch64" && sess.target.os != "none" {
|
||||
// AArch64 mandates Neon support
|
||||
vec![sym::neon]
|
||||
} else if sess.target.arch == "aarch64" {
|
||||
match &*sess.target.os {
|
||||
"none" => vec![],
|
||||
// On macOS the aes, sha2 and sha3 features are enabled by default and ring
|
||||
// fails to compile on macOS when they are not present.
|
||||
"macos" => vec![
|
||||
sym::neon,
|
||||
Symbol::intern("aes"),
|
||||
Symbol::intern("sha2"),
|
||||
Symbol::intern("sha3"),
|
||||
],
|
||||
// AArch64 mandates Neon support
|
||||
_ => vec![sym::neon],
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub(crate) fn unsized_info<'tcx>(
|
|||
old_info: Option<Value>,
|
||||
) -> Value {
|
||||
let (source, target) =
|
||||
fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
|
||||
fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all());
|
||||
match (&source.kind(), &target.kind()) {
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => fx
|
||||
.bcx
|
||||
|
|
|
|||
|
|
@ -677,8 +677,10 @@ impl<'tcx> CPlace<'tcx> {
|
|||
let to_addr = to_ptr.get_addr(fx);
|
||||
let src_layout = from.1;
|
||||
let size = dst_layout.size.bytes();
|
||||
let src_align = src_layout.align.abi.bytes() as u8;
|
||||
let dst_align = dst_layout.align.abi.bytes() as u8;
|
||||
// `emit_small_memory_copy` uses `u8` for alignments, just use the maximum
|
||||
// alignment that fits in a `u8` if the actual alignment is larger.
|
||||
let src_align = src_layout.align.abi.bytes().try_into().unwrap_or(128);
|
||||
let dst_align = dst_layout.align.abi.bytes().try_into().unwrap_or(128);
|
||||
fx.bcx.emit_small_memory_copy(
|
||||
fx.target_config,
|
||||
to_addr,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.109"
|
||||
version = "0.1.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f11973008a8cf741fe6d22f339eba21fd0ca81e2760a769ba8243ed6c21edd7e"
|
||||
dependencies = [
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ resolver = "2"
|
|||
|
||||
[dependencies]
|
||||
core = { path = "./sysroot_src/library/core" }
|
||||
# TODO: after the sync, revert to using version 0.1.
|
||||
# compiler_builtins = "0.1"
|
||||
compiler_builtins = "=0.1.109"
|
||||
compiler_builtins = "0.1"
|
||||
alloc = { path = "./sysroot_src/library/alloc" }
|
||||
std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
|
||||
test = { path = "./sysroot_src/library/test" }
|
||||
|
|
|
|||
|
|
@ -430,6 +430,7 @@ pub enum E2<X> {
|
|||
V4,
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
fn check_niche_behavior () {
|
||||
if let E1::V2 { .. } = (E1::V1 { f: true }) {
|
||||
intrinsics::abort();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
|
||||
use rustc_codegen_ssa::back::archive::{
|
||||
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
|
||||
};
|
||||
use rustc_session::cstore::DllImport;
|
||||
use rustc_session::Session;
|
||||
|
||||
pub(crate) struct ArArchiveBuilderBuilder;
|
||||
|
|
@ -17,10 +16,9 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
|
|||
&self,
|
||||
_sess: &Session,
|
||||
_lib_name: &str,
|
||||
_dll_imports: &[DllImport],
|
||||
_tmpdir: &Path,
|
||||
_is_direct_dependency: bool,
|
||||
) -> PathBuf {
|
||||
_import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
||||
_output_path: &Path,
|
||||
) {
|
||||
unimplemented!("creating dll imports is not yet supported");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
|
|||
let function_features = codegen_fn_attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.map(|features| features.as_str())
|
||||
.map(|features| features.name.as_str())
|
||||
.collect::<Vec<&str>>();
|
||||
|
||||
if let Some(features) = check_tied_features(
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
|
|||
|
||||
let feature = backend_feature_name(s)?;
|
||||
// Warn against use of GCC specific feature names on the CLI.
|
||||
if diagnostics && !supported_features.iter().any(|&(v, _)| v == feature) {
|
||||
let rust_feature = supported_features.iter().find_map(|&(rust_feature, _)| {
|
||||
if diagnostics && !supported_features.iter().any(|&(v, _, _)| v == feature) {
|
||||
let rust_feature = supported_features.iter().find_map(|&(rust_feature, _, _)| {
|
||||
let gcc_features = to_gcc_features(sess, rust_feature);
|
||||
if gcc_features.contains(&feature) && !gcc_features.contains(&rust_feature) {
|
||||
Some(rust_feature)
|
||||
|
|
|
|||
|
|
@ -486,7 +486,7 @@ pub fn target_features(
|
|||
sess.target
|
||||
.supported_target_features()
|
||||
.iter()
|
||||
.filter_map(|&(feature, gate)| {
|
||||
.filter_map(|&(feature, gate, _)| {
|
||||
if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
|
||||
Some(feature)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,13 @@
|
|||
codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err}
|
||||
|
||||
codegen_llvm_dlltool_fail_import_library =
|
||||
Dlltool could not create import library with {$dlltool_path} {$dlltool_args}:
|
||||
{$stdout}
|
||||
{$stderr}
|
||||
|
||||
codegen_llvm_dynamic_linking_with_lto =
|
||||
cannot prefer dynamic linking when performing LTO
|
||||
.note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO
|
||||
|
||||
codegen_llvm_error_calling_dlltool =
|
||||
Error calling dlltool '{$dlltool_path}': {$error}
|
||||
|
||||
codegen_llvm_error_creating_import_library =
|
||||
Error creating import library for {$lib_name}: {$error}
|
||||
|
||||
codegen_llvm_error_writing_def_file =
|
||||
Error writing .DEF file: {$error}
|
||||
|
||||
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
|
||||
|
||||
codegen_llvm_from_llvm_diag = {$message}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
|||
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_session::config;
|
||||
pub use rustc_target::abi::call::*;
|
||||
use rustc_target::abi::{self, HasDataLayout, Int, Size};
|
||||
|
|
@ -16,6 +16,7 @@ pub use rustc_target::spec::abi::Abi;
|
|||
use rustc_target::spec::SanitizerSet;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::attributes::llfn_attrs_from_instance;
|
||||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
use crate::llvm::{self, Attribute, AttributePlace};
|
||||
|
|
@ -310,7 +311,16 @@ pub trait FnAbiLlvmExt<'ll, 'tcx> {
|
|||
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||
fn llvm_cconv(&self) -> llvm::CallConv;
|
||||
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value);
|
||||
|
||||
/// Apply attributes to a function declaration/definition.
|
||||
fn apply_attrs_llfn(
|
||||
&self,
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
llfn: &'ll Value,
|
||||
instance: Option<ty::Instance<'tcx>>,
|
||||
);
|
||||
|
||||
/// Apply attributes to a function call.
|
||||
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value);
|
||||
}
|
||||
|
||||
|
|
@ -396,7 +406,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||
self.conv.into()
|
||||
}
|
||||
|
||||
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
|
||||
fn apply_attrs_llfn(
|
||||
&self,
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
llfn: &'ll Value,
|
||||
instance: Option<ty::Instance<'tcx>>,
|
||||
) {
|
||||
let mut func_attrs = SmallVec::<[_; 3]>::new();
|
||||
if self.ret.layout.abi.is_uninhabited() {
|
||||
func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx));
|
||||
|
|
@ -477,6 +492,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the declaration has an associated instance, compute extra attributes based on that.
|
||||
if let Some(instance) = instance {
|
||||
llfn_attrs_from_instance(cx, llfn, instance);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value) {
|
||||
|
|
|
|||
|
|
@ -324,9 +324,10 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
|
|||
llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc")
|
||||
}
|
||||
|
||||
/// Helper for `FnAbi::apply_attrs_llfn`:
|
||||
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
|
||||
/// attributes.
|
||||
pub fn from_fn_attrs<'ll, 'tcx>(
|
||||
pub fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
llfn: &'ll Value,
|
||||
instance: ty::Instance<'tcx>,
|
||||
|
|
@ -496,7 +497,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
|||
to_add.extend(tune_cpu_attr(cx));
|
||||
|
||||
let function_features =
|
||||
codegen_fn_attrs.target_features.iter().map(|f| f.as_str()).collect::<Vec<&str>>();
|
||||
codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::<Vec<&str>>();
|
||||
|
||||
if let Some(f) = llvm_util::check_tied_features(
|
||||
cx.tcx.sess,
|
||||
|
|
|
|||
|
|
@ -1,21 +1,19 @@
|
|||
//! A helper class for dealing with static archives
|
||||
|
||||
use std::ffi::{c_char, c_void, CStr, CString, OsString};
|
||||
use std::ffi::{c_char, c_void, CStr, CString};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, io, mem, ptr, str};
|
||||
use std::{io, mem, ptr, str};
|
||||
|
||||
use rustc_codegen_ssa::back::archive::{
|
||||
try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
|
||||
ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
|
||||
create_mingw_dll_import_lib, try_extract_macho_fat_archive, ArArchiveBuilder,
|
||||
ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind,
|
||||
DEFAULT_OBJECT_READER,
|
||||
};
|
||||
use rustc_session::cstore::DllImport;
|
||||
use rustc_codegen_ssa::common;
|
||||
use rustc_session::Session;
|
||||
use tracing::trace;
|
||||
|
||||
use crate::common;
|
||||
use crate::errors::{
|
||||
DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile,
|
||||
};
|
||||
use crate::errors::ErrorCreatingImportLibrary;
|
||||
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
||||
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
|
||||
|
||||
|
|
@ -121,116 +119,21 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
|||
&self,
|
||||
sess: &Session,
|
||||
lib_name: &str,
|
||||
dll_imports: &[DllImport],
|
||||
tmpdir: &Path,
|
||||
is_direct_dependency: bool,
|
||||
) -> PathBuf {
|
||||
let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
|
||||
let output_path = tmpdir.join(format!("{lib_name}{name_suffix}.lib"));
|
||||
|
||||
let target = &sess.target;
|
||||
let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(target);
|
||||
|
||||
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
|
||||
.iter()
|
||||
.map(|import: &DllImport| {
|
||||
if sess.target.arch == "x86" {
|
||||
(
|
||||
common::i686_decorated_name(import, mingw_gnu_toolchain, false),
|
||||
import.ordinal(),
|
||||
)
|
||||
} else {
|
||||
(import.name.to_string(), import.ordinal())
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if mingw_gnu_toolchain {
|
||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
||||
output_path: &Path,
|
||||
) {
|
||||
if common::is_mingw_gnu_toolchain(&sess.target) {
|
||||
// The binutils linker used on -windows-gnu targets cannot read the import
|
||||
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
||||
// that loaded but crashed with an AV upon calling one of the imported
|
||||
// functions. Therefore, use binutils to create the import library instead,
|
||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
||||
let def_file_path = tmpdir.join(format!("{lib_name}{name_suffix}.def"));
|
||||
|
||||
let def_file_content = format!(
|
||||
"EXPORTS\n{}",
|
||||
import_name_and_ordinal_vector
|
||||
.into_iter()
|
||||
.map(|(name, ordinal)| {
|
||||
match ordinal {
|
||||
Some(n) => format!("{name} @{n} NONAME"),
|
||||
None => name,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
create_mingw_dll_import_lib(
|
||||
sess,
|
||||
lib_name,
|
||||
import_name_and_ordinal_vector,
|
||||
output_path,
|
||||
);
|
||||
|
||||
match std::fs::write(&def_file_path, def_file_content) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
sess.dcx().emit_fatal(ErrorWritingDEFFile { error: e });
|
||||
}
|
||||
};
|
||||
|
||||
// --no-leading-underscore: For the `import_name_type` feature to work, we need to be
|
||||
// able to control the *exact* spelling of each of the symbols that are being imported:
|
||||
// hence we don't want `dlltool` adding leading underscores automatically.
|
||||
let dlltool = find_binutils_dlltool(sess);
|
||||
let temp_prefix = {
|
||||
let mut path = PathBuf::from(&output_path);
|
||||
path.pop();
|
||||
path.push(lib_name);
|
||||
path
|
||||
};
|
||||
// dlltool target architecture args from:
|
||||
// https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69
|
||||
let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch.as_ref() {
|
||||
"x86_64" => ("i386:x86-64", "--64"),
|
||||
"x86" => ("i386", "--32"),
|
||||
"aarch64" => ("arm64", "--64"),
|
||||
"arm" => ("arm", "--32"),
|
||||
_ => panic!("unsupported arch {}", sess.target.arch),
|
||||
};
|
||||
let mut dlltool_cmd = std::process::Command::new(&dlltool);
|
||||
dlltool_cmd
|
||||
.arg("-d")
|
||||
.arg(def_file_path)
|
||||
.arg("-D")
|
||||
.arg(lib_name)
|
||||
.arg("-l")
|
||||
.arg(&output_path)
|
||||
.arg("-m")
|
||||
.arg(dlltool_target_arch)
|
||||
.arg("-f")
|
||||
.arg(dlltool_target_bitness)
|
||||
.arg("--no-leading-underscore")
|
||||
.arg("--temp-prefix")
|
||||
.arg(temp_prefix);
|
||||
|
||||
match dlltool_cmd.output() {
|
||||
Err(e) => {
|
||||
sess.dcx().emit_fatal(ErrorCallingDllTool {
|
||||
dlltool_path: dlltool.to_string_lossy(),
|
||||
error: e,
|
||||
});
|
||||
}
|
||||
// dlltool returns '0' on failure, so check for error output instead.
|
||||
Ok(output) if !output.stderr.is_empty() => {
|
||||
sess.dcx().emit_fatal(DlltoolFailImportLibrary {
|
||||
dlltool_path: dlltool.to_string_lossy(),
|
||||
dlltool_args: dlltool_cmd
|
||||
.get_args()
|
||||
.map(|arg| arg.to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "),
|
||||
stdout: String::from_utf8_lossy(&output.stdout),
|
||||
stderr: String::from_utf8_lossy(&output.stderr),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
// we've checked for \0 characters in the library name already
|
||||
let dll_name_z = CString::new(lib_name).unwrap();
|
||||
|
|
@ -242,9 +145,9 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
|||
trace!(" output_path {}", output_path.display());
|
||||
trace!(
|
||||
" import names: {}",
|
||||
dll_imports
|
||||
import_name_and_ordinal_vector
|
||||
.iter()
|
||||
.map(|import| import.name.to_string())
|
||||
.map(|(name, _ordinal)| name.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
);
|
||||
|
|
@ -281,9 +184,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
|||
error: llvm::last_error().unwrap_or("unknown LLVM error".to_string()),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
output_path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,39 +358,3 @@ impl<'a> LlvmArchiveBuilder<'a> {
|
|||
fn string_to_io_error(s: String) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, format!("bad archive: {s}"))
|
||||
}
|
||||
|
||||
fn find_binutils_dlltool(sess: &Session) -> OsString {
|
||||
assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc);
|
||||
if let Some(dlltool_path) = &sess.opts.cg.dlltool {
|
||||
return dlltool_path.clone().into_os_string();
|
||||
}
|
||||
|
||||
let tool_name: OsString = if sess.host.options.is_like_windows {
|
||||
// If we're compiling on Windows, always use "dlltool.exe".
|
||||
"dlltool.exe"
|
||||
} else {
|
||||
// On other platforms, use the architecture-specific name.
|
||||
match sess.target.arch.as_ref() {
|
||||
"x86_64" => "x86_64-w64-mingw32-dlltool",
|
||||
"x86" => "i686-w64-mingw32-dlltool",
|
||||
"aarch64" => "aarch64-w64-mingw32-dlltool",
|
||||
|
||||
// For non-standard architectures (e.g., aarch32) fallback to "dlltool".
|
||||
_ => "dlltool",
|
||||
}
|
||||
}
|
||||
.into();
|
||||
|
||||
// NOTE: it's not clear how useful it is to explicitly search PATH.
|
||||
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
|
||||
let full_path = dir.join(&tool_name);
|
||||
if full_path.is_file() {
|
||||
return full_path.into_os_string();
|
||||
}
|
||||
}
|
||||
|
||||
// The user didn't specify the location of the dlltool binary, and we weren't able
|
||||
// to find the appropriate one on the PATH. Just return the name of the tool
|
||||
// and let the invocation fail with a hopefully useful error message.
|
||||
tool_name
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,11 +95,14 @@ pub fn write_output_file<'ll>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_informational_target_machine(sess: &Session) -> OwnedTargetMachine {
|
||||
pub fn create_informational_target_machine(
|
||||
sess: &Session,
|
||||
only_base_features: bool,
|
||||
) -> OwnedTargetMachine {
|
||||
let config = TargetMachineFactoryConfig { split_dwarf_file: None, output_obj_file: None };
|
||||
// Can't use query system here quite yet because this function is invoked before the query
|
||||
// system/tcx is set up.
|
||||
let features = llvm_util::global_llvm_features(sess, false);
|
||||
let features = llvm_util::global_llvm_features(sess, false, only_base_features);
|
||||
target_machine_factory(sess, config::OptLevel::No, &features)(config)
|
||||
.unwrap_or_else(|err| llvm_err(sess.dcx(), err).raise())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ use rustc_data_structures::small_c_str::SmallCStr;
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
||||
TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_sanitizers::{cfi, kcfi};
|
||||
|
|
@ -531,7 +532,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
#[instrument(level = "trace", skip(self))]
|
||||
fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> {
|
||||
if place.layout.is_unsized() {
|
||||
let tail = self.tcx.struct_tail_with_normalize(place.layout.ty, |ty| ty, || {});
|
||||
let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.param_env());
|
||||
if matches!(tail.kind(), ty::Foreign(..)) {
|
||||
// Unsized locals and, at least conceptually, even unsized arguments must be copied
|
||||
// around, which requires dynamically determining their size. Therefore, we cannot
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@
|
|||
//! and methods are represented as just a fn ptr and not a full
|
||||
//! closure.
|
||||
|
||||
use rustc_codegen_ssa::common;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::context::CodegenCx;
|
||||
use crate::llvm;
|
||||
use crate::value::Value;
|
||||
use crate::{attributes, common, llvm};
|
||||
|
||||
/// Codegens a reference to a fn/method item, monomorphizing and
|
||||
/// inlining as it goes.
|
||||
|
|
@ -46,7 +47,7 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
|||
} else {
|
||||
let instance_def_id = instance.def_id();
|
||||
let llfn = if tcx.sess.target.arch == "x86"
|
||||
&& let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym)
|
||||
&& let Some(dllimport) = crate::common::get_dllimport(tcx, instance_def_id, sym)
|
||||
{
|
||||
// Fix for https://github.com/rust-lang/rust/issues/104453
|
||||
// On x86 Windows, LLVM uses 'L' as the prefix for any private
|
||||
|
|
@ -77,8 +78,6 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
|||
};
|
||||
debug!("get_fn: not casting pointer!");
|
||||
|
||||
attributes::from_fn_attrs(cx, llfn, instance);
|
||||
|
||||
// Apply an appropriate linkage/visibility value to our item that we
|
||||
// just declared.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
//! Code that is useful in various codegen modules.
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
use libc::{c_char, c_uint};
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
|
|
@ -10,9 +8,8 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType};
|
||||
use rustc_session::cstore::DllImport;
|
||||
use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer};
|
||||
use rustc_target::spec::Target;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::consts::const_alloc_to_llvm;
|
||||
|
|
@ -379,64 +376,3 @@ pub(crate) fn get_dllimport<'tcx>(
|
|||
tcx.native_library(id)
|
||||
.and_then(|lib| lib.dll_imports.iter().find(|di| di.name.as_str() == name))
|
||||
}
|
||||
|
||||
pub(crate) fn is_mingw_gnu_toolchain(target: &Target) -> bool {
|
||||
target.vendor == "pc" && target.os == "windows" && target.env == "gnu" && target.abi.is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn i686_decorated_name(
|
||||
dll_import: &DllImport,
|
||||
mingw: bool,
|
||||
disable_name_mangling: bool,
|
||||
) -> String {
|
||||
let name = dll_import.name.as_str();
|
||||
|
||||
let (add_prefix, add_suffix) = match dll_import.import_name_type {
|
||||
Some(PeImportNameType::NoPrefix) => (false, true),
|
||||
Some(PeImportNameType::Undecorated) => (false, false),
|
||||
_ => (true, true),
|
||||
};
|
||||
|
||||
// Worst case: +1 for disable name mangling, +1 for prefix, +4 for suffix (@@__).
|
||||
let mut decorated_name = String::with_capacity(name.len() + 6);
|
||||
|
||||
if disable_name_mangling {
|
||||
// LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled.
|
||||
decorated_name.push('\x01');
|
||||
}
|
||||
|
||||
let prefix = if add_prefix && dll_import.is_fn {
|
||||
match dll_import.calling_convention {
|
||||
DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
|
||||
DllCallingConvention::Stdcall(_) => (!mingw
|
||||
|| dll_import.import_name_type == Some(PeImportNameType::Decorated))
|
||||
.then_some('_'),
|
||||
DllCallingConvention::Fastcall(_) => Some('@'),
|
||||
}
|
||||
} else if !dll_import.is_fn && !mingw {
|
||||
// For static variables, prefix with '_' on MSVC.
|
||||
Some('_')
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(prefix) = prefix {
|
||||
decorated_name.push(prefix);
|
||||
}
|
||||
|
||||
decorated_name.push_str(name);
|
||||
|
||||
if add_suffix && dll_import.is_fn {
|
||||
match dll_import.calling_convention {
|
||||
DllCallingConvention::C => {}
|
||||
DllCallingConvention::Stdcall(arg_list_size)
|
||||
| DllCallingConvention::Fastcall(arg_list_size) => {
|
||||
write!(&mut decorated_name, "@{arg_list_size}").unwrap();
|
||||
}
|
||||
DllCallingConvention::Vectorcall(arg_list_size) => {
|
||||
write!(&mut decorated_name, "@@{arg_list_size}").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decorated_name
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use rustc_codegen_ssa::common;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
|
@ -18,7 +19,7 @@ use rustc_target::abi::{
|
|||
};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::common::{self, CodegenCx};
|
||||
use crate::common::CodegenCx;
|
||||
use crate::errors::{
|
||||
InvalidMinimumAlignmentNotPowerOfTwo, InvalidMinimumAlignmentTooLarge, SymbolAlreadyDefined,
|
||||
};
|
||||
|
|
@ -195,7 +196,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
|
|||
g2
|
||||
}
|
||||
} else if cx.tcx.sess.target.arch == "x86"
|
||||
&& let Some(dllimport) = common::get_dllimport(cx.tcx, def_id, sym)
|
||||
&& let Some(dllimport) = crate::common::get_dllimport(cx.tcx, def_id, sym)
|
||||
{
|
||||
cx.declare_global(
|
||||
&common::i686_decorated_name(
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ pub unsafe fn create_module<'ll>(
|
|||
|
||||
// Ensure the data-layout values hardcoded remain the defaults.
|
||||
{
|
||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess);
|
||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
|
||||
unsafe {
|
||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
|
||||
}
|
||||
|
|
@ -775,10 +775,10 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
ifn!("llvm.debugtrap", fn() -> void);
|
||||
ifn!("llvm.frameaddress", fn(t_i32) -> ptr);
|
||||
|
||||
ifn!("llvm.powi.f16", fn(t_f16, t_i32) -> t_f16);
|
||||
ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
|
||||
ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
|
||||
ifn!("llvm.powi.f128", fn(t_f128, t_i32) -> t_f128);
|
||||
ifn!("llvm.powi.f16.i32", fn(t_f16, t_i32) -> t_f16);
|
||||
ifn!("llvm.powi.f32.i32", fn(t_f32, t_i32) -> t_f32);
|
||||
ifn!("llvm.powi.f64.i32", fn(t_f64, t_i32) -> t_f64);
|
||||
ifn!("llvm.powi.f128.i32", fn(t_f128, t_i32) -> t_f128);
|
||||
|
||||
ifn!("llvm.pow.f16", fn(t_f16, t_f16) -> t_f16);
|
||||
ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
pointee_ty: Ty<'tcx>,
|
||||
) -> Option<FatPtrKind> {
|
||||
let pointee_tail_ty = cx.tcx.struct_tail_erasing_lifetimes(pointee_ty, cx.param_env());
|
||||
let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.param_env());
|
||||
let layout = cx.layout_of(pointee_tail_ty);
|
||||
trace!(
|
||||
"fat_pointer_kind: {:?} has layout {:?} (is_unsized? {})",
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
llvm::Visibility::Default,
|
||||
fn_abi.llvm_type(self),
|
||||
);
|
||||
fn_abi.apply_attrs_llfn(self, llfn);
|
||||
fn_abi.apply_attrs_llfn(self, llfn, instance);
|
||||
|
||||
if self.tcx.sess.is_sanitizer_cfi_enabled() {
|
||||
if let Some(instance) = instance {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use std::borrow::Cow;
|
||||
use std::ffi::CString;
|
||||
use std::path::Path;
|
||||
|
||||
|
|
@ -71,28 +70,6 @@ pub(crate) struct InvalidMinimumAlignmentTooLarge {
|
|||
#[diag(codegen_llvm_sanitizer_memtag_requires_mte)]
|
||||
pub(crate) struct SanitizerMemtagRequiresMte;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_error_writing_def_file)]
|
||||
pub(crate) struct ErrorWritingDEFFile {
|
||||
pub error: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_error_calling_dlltool)]
|
||||
pub(crate) struct ErrorCallingDllTool<'a> {
|
||||
pub dlltool_path: Cow<'a, str>,
|
||||
pub error: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_dlltool_fail_import_library)]
|
||||
pub(crate) struct DlltoolFailImportLibrary<'a> {
|
||||
pub dlltool_path: Cow<'a, str>,
|
||||
pub dlltool_args: String,
|
||||
pub stdout: Cow<'a, str>,
|
||||
pub stderr: Cow<'a, str>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_dynamic_linking_with_lto)]
|
||||
#[note]
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ fn get_simple_intrinsic<'ll>(
|
|||
sym::sqrtf64 => "llvm.sqrt.f64",
|
||||
sym::sqrtf128 => "llvm.sqrt.f128",
|
||||
|
||||
sym::powif16 => "llvm.powi.f16",
|
||||
sym::powif32 => "llvm.powi.f32",
|
||||
sym::powif64 => "llvm.powi.f64",
|
||||
sym::powif128 => "llvm.powi.f128",
|
||||
sym::powif16 => "llvm.powi.f16.i32",
|
||||
sym::powif32 => "llvm.powi.f32.i32",
|
||||
sym::powif64 => "llvm.powi.f64.i32",
|
||||
sym::powif128 => "llvm.powi.f128.i32",
|
||||
|
||||
sym::sinf16 => "llvm.sin.f16",
|
||||
sym::sinf32 => "llvm.sin.f32",
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
|
||||
fn provide(&self, providers: &mut Providers) {
|
||||
providers.global_backend_features =
|
||||
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
|
||||
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true, false)
|
||||
}
|
||||
|
||||
fn print(&self, req: &PrintRequest, out: &mut String, sess: &Session) {
|
||||
|
|
@ -434,7 +434,7 @@ impl ModuleLlvm {
|
|||
ModuleLlvm {
|
||||
llmod_raw,
|
||||
llcx,
|
||||
tm: ManuallyDrop::new(create_informational_target_machine(tcx.sess)),
|
||||
tm: ManuallyDrop::new(create_informational_target_machine(tcx.sess, false)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use libc::c_int;
|
|||
use rustc_codegen_ssa::base::wants_wasm_eh;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_fs_util::path_to_c_string;
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::config::{PrintKind, PrintRequest};
|
||||
|
|
@ -239,40 +240,8 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
|
|||
}
|
||||
// In LLVM neon implicitly enables fp, but we manually enable
|
||||
// neon when a feature only implicitly enables fp
|
||||
("aarch64", "f32mm") => {
|
||||
LLVMFeature::with_dependency("f32mm", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "f64mm") => {
|
||||
LLVMFeature::with_dependency("f64mm", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "fhm") => {
|
||||
LLVMFeature::with_dependency("fp16fml", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "fp16") => {
|
||||
LLVMFeature::with_dependency("fullfp16", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "jsconv") => {
|
||||
LLVMFeature::with_dependency("jsconv", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "sve") => {
|
||||
LLVMFeature::with_dependency("sve", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "sve2") => {
|
||||
LLVMFeature::with_dependency("sve2", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "sve2-aes") => {
|
||||
LLVMFeature::with_dependency("sve2-aes", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "sve2-sm4") => {
|
||||
LLVMFeature::with_dependency("sve2-sm4", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "sve2-sha3") => {
|
||||
LLVMFeature::with_dependency("sve2-sha3", TargetFeatureFoldStrength::EnableOnly("neon"))
|
||||
}
|
||||
("aarch64", "sve2-bitperm") => LLVMFeature::with_dependency(
|
||||
"sve2-bitperm",
|
||||
TargetFeatureFoldStrength::EnableOnly("neon"),
|
||||
),
|
||||
("aarch64", "fhm") => LLVMFeature::new("fp16fml"),
|
||||
("aarch64", "fp16") => LLVMFeature::new("fullfp16"),
|
||||
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
|
||||
// `fast-unaligned-access`. In LLVM 19, it was split back out.
|
||||
("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
|
||||
|
|
@ -308,11 +277,53 @@ pub fn check_tied_features(
|
|||
/// Used to generate cfg variables and apply features
|
||||
/// Must express features in the way Rust understands them
|
||||
pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
|
||||
let target_machine = create_informational_target_machine(sess);
|
||||
let mut features = vec![];
|
||||
|
||||
// Add base features for the target
|
||||
let target_machine = create_informational_target_machine(sess, true);
|
||||
features.extend(
|
||||
sess.target
|
||||
.supported_target_features()
|
||||
.iter()
|
||||
.filter(|(feature, _, _)| {
|
||||
// skip checking special features, as LLVM may not understands them
|
||||
if RUSTC_SPECIAL_FEATURES.contains(feature) {
|
||||
return true;
|
||||
}
|
||||
// check that all features in a given smallvec are enabled
|
||||
for llvm_feature in to_llvm_features(sess, feature) {
|
||||
let cstr = SmallCStr::new(llvm_feature);
|
||||
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
})
|
||||
.map(|(feature, _, _)| Symbol::intern(feature)),
|
||||
);
|
||||
|
||||
// Add enabled features
|
||||
for (enabled, feature) in
|
||||
sess.opts.cg.target_feature.split(',').filter_map(|s| match s.chars().next() {
|
||||
Some('+') => Some((true, Symbol::intern(&s[1..]))),
|
||||
Some('-') => Some((false, Symbol::intern(&s[1..]))),
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
if enabled {
|
||||
features.extend(sess.target.implied_target_features(std::iter::once(feature)));
|
||||
} else {
|
||||
features.retain(|f| {
|
||||
!sess.target.implied_target_features(std::iter::once(*f)).contains(&feature)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Filter enabled features based on feature gates
|
||||
sess.target
|
||||
.supported_target_features()
|
||||
.iter()
|
||||
.filter_map(|&(feature, gate)| {
|
||||
.filter_map(|&(feature, gate, _)| {
|
||||
if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
|
||||
Some(feature)
|
||||
} else {
|
||||
|
|
@ -320,18 +331,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
|
|||
}
|
||||
})
|
||||
.filter(|feature| {
|
||||
// skip checking special features, as LLVM may not understands them
|
||||
if RUSTC_SPECIAL_FEATURES.contains(feature) {
|
||||
return true;
|
||||
}
|
||||
// check that all features in a given smallvec are enabled
|
||||
for llvm_feature in to_llvm_features(sess, feature) {
|
||||
let cstr = SmallCStr::new(llvm_feature);
|
||||
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
RUSTC_SPECIAL_FEATURES.contains(feature) || features.contains(&Symbol::intern(feature))
|
||||
})
|
||||
.map(|feature| Symbol::intern(feature))
|
||||
.collect()
|
||||
|
|
@ -386,7 +386,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
|
|||
.target
|
||||
.supported_target_features()
|
||||
.iter()
|
||||
.map(|(feature, _gate)| {
|
||||
.map(|(feature, _gate, _implied)| {
|
||||
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
|
||||
let llvm_feature = to_llvm_features(sess, *feature).llvm_feature_name;
|
||||
let desc =
|
||||
|
|
@ -440,7 +440,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
|
|||
|
||||
pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
|
||||
require_inited();
|
||||
let tm = create_informational_target_machine(sess);
|
||||
let tm = create_informational_target_machine(sess, false);
|
||||
match req.kind {
|
||||
PrintKind::TargetCPUs => {
|
||||
// SAFETY generate a C compatible string from a byte slice to pass
|
||||
|
|
@ -488,7 +488,11 @@ pub fn target_cpu(sess: &Session) -> &str {
|
|||
|
||||
/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
|
||||
/// `--target` and similar).
|
||||
pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<String> {
|
||||
pub(crate) fn global_llvm_features(
|
||||
sess: &Session,
|
||||
diagnostics: bool,
|
||||
only_base_features: bool,
|
||||
) -> Vec<String> {
|
||||
// Features that come earlier are overridden by conflicting features later in the string.
|
||||
// Typically we'll want more explicit settings to override the implicit ones, so:
|
||||
//
|
||||
|
|
@ -548,94 +552,124 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
|
|||
}
|
||||
|
||||
// -Ctarget-features
|
||||
let supported_features = sess.target.supported_target_features();
|
||||
let (llvm_major, _, _) = get_version();
|
||||
let mut featsmap = FxHashMap::default();
|
||||
let feats = sess
|
||||
.opts
|
||||
.cg
|
||||
.target_feature
|
||||
.split(',')
|
||||
.filter_map(|s| {
|
||||
let enable_disable = match s.chars().next() {
|
||||
None => return None,
|
||||
Some(c @ ('+' | '-')) => c,
|
||||
Some(_) => {
|
||||
if diagnostics {
|
||||
sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature: s });
|
||||
if !only_base_features {
|
||||
let supported_features = sess.target.supported_target_features();
|
||||
let (llvm_major, _, _) = get_version();
|
||||
let mut featsmap = FxHashMap::default();
|
||||
|
||||
// insert implied features
|
||||
let mut all_rust_features = vec![];
|
||||
for feature in sess.opts.cg.target_feature.split(',') {
|
||||
match feature.strip_prefix('+') {
|
||||
Some(feature) => all_rust_features.extend(
|
||||
UnordSet::from(
|
||||
sess.target
|
||||
.implied_target_features(std::iter::once(Symbol::intern(feature))),
|
||||
)
|
||||
.to_sorted_stable_ord()
|
||||
.iter()
|
||||
.map(|s| format!("+{}", s.as_str())),
|
||||
),
|
||||
_ => all_rust_features.push(feature.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
let feats = all_rust_features
|
||||
.iter()
|
||||
.filter_map(|s| {
|
||||
let enable_disable = match s.chars().next() {
|
||||
None => return None,
|
||||
Some(c @ ('+' | '-')) => c,
|
||||
Some(_) => {
|
||||
if diagnostics {
|
||||
sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature: s });
|
||||
}
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let feature = backend_feature_name(sess, s)?;
|
||||
// Warn against use of LLVM specific feature names and unstable features on the CLI.
|
||||
if diagnostics {
|
||||
let feature_state = supported_features.iter().find(|&&(v, _, _)| v == feature);
|
||||
if feature_state.is_none() {
|
||||
let rust_feature =
|
||||
supported_features.iter().find_map(|&(rust_feature, _, _)| {
|
||||
let llvm_features = to_llvm_features(sess, rust_feature);
|
||||
if llvm_features.contains(feature)
|
||||
&& !llvm_features.contains(rust_feature)
|
||||
{
|
||||
Some(rust_feature)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let unknown_feature = if let Some(rust_feature) = rust_feature {
|
||||
UnknownCTargetFeature {
|
||||
feature,
|
||||
rust_feature: PossibleFeature::Some { rust_feature },
|
||||
}
|
||||
} else {
|
||||
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
|
||||
};
|
||||
sess.dcx().emit_warn(unknown_feature);
|
||||
} else if feature_state
|
||||
.is_some_and(|(_name, feature_gate, _implied)| !feature_gate.is_stable())
|
||||
{
|
||||
// An unstable feature. Warn about using it.
|
||||
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
|
||||
}
|
||||
}
|
||||
|
||||
if diagnostics {
|
||||
// FIXME(nagisa): figure out how to not allocate a full hashset here.
|
||||
featsmap.insert(feature, enable_disable == '+');
|
||||
}
|
||||
|
||||
// rustc-specific features do not get passed down to LLVM…
|
||||
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let feature = backend_feature_name(sess, s)?;
|
||||
// Warn against use of LLVM specific feature names and unstable features on the CLI.
|
||||
if diagnostics {
|
||||
let feature_state = supported_features.iter().find(|&&(v, _)| v == feature);
|
||||
if feature_state.is_none() {
|
||||
let rust_feature = supported_features.iter().find_map(|&(rust_feature, _)| {
|
||||
let llvm_features = to_llvm_features(sess, rust_feature);
|
||||
if llvm_features.contains(feature) && !llvm_features.contains(rust_feature)
|
||||
{
|
||||
Some(rust_feature)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let unknown_feature = if let Some(rust_feature) = rust_feature {
|
||||
UnknownCTargetFeature {
|
||||
feature,
|
||||
rust_feature: PossibleFeature::Some { rust_feature },
|
||||
}
|
||||
} else {
|
||||
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
|
||||
};
|
||||
sess.dcx().emit_warn(unknown_feature);
|
||||
} else if feature_state
|
||||
.is_some_and(|(_name, feature_gate)| !feature_gate.is_stable())
|
||||
{
|
||||
// An unstable feature. Warn about using it.
|
||||
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
|
||||
// if the target-feature is "backchain" and LLVM version is greater than 18
|
||||
// then we also need to add "+backchain" to the target-features attribute.
|
||||
// otherwise, we will only add the naked `backchain` attribute to the attribute-group.
|
||||
if feature == "backchain" && llvm_major < 18 {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
// ... otherwise though we run through `to_llvm_features` when
|
||||
// passing requests down to LLVM. This means that all in-language
|
||||
// features also work on the command line instead of having two
|
||||
// different names when the LLVM name and the Rust name differ.
|
||||
let llvm_feature = to_llvm_features(sess, feature);
|
||||
|
||||
if diagnostics {
|
||||
// FIXME(nagisa): figure out how to not allocate a full hashset here.
|
||||
featsmap.insert(feature, enable_disable == '+');
|
||||
}
|
||||
|
||||
// rustc-specific features do not get passed down to LLVM…
|
||||
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// if the target-feature is "backchain" and LLVM version is greater than 18
|
||||
// then we also need to add "+backchain" to the target-features attribute.
|
||||
// otherwise, we will only add the naked `backchain` attribute to the attribute-group.
|
||||
if feature == "backchain" && llvm_major < 18 {
|
||||
return None;
|
||||
}
|
||||
// ... otherwise though we run through `to_llvm_features` when
|
||||
// passing requests down to LLVM. This means that all in-language
|
||||
// features also work on the command line instead of having two
|
||||
// different names when the LLVM name and the Rust name differ.
|
||||
let llvm_feature = to_llvm_features(sess, feature);
|
||||
|
||||
Some(
|
||||
std::iter::once(format!("{}{}", enable_disable, llvm_feature.llvm_feature_name))
|
||||
.chain(llvm_feature.dependency.into_iter().filter_map(move |feat| {
|
||||
match (enable_disable, feat) {
|
||||
Some(
|
||||
std::iter::once(format!(
|
||||
"{}{}",
|
||||
enable_disable, llvm_feature.llvm_feature_name
|
||||
))
|
||||
.chain(llvm_feature.dependency.into_iter().filter_map(
|
||||
move |feat| match (enable_disable, feat) {
|
||||
('-' | '+', TargetFeatureFoldStrength::Both(f))
|
||||
| ('+', TargetFeatureFoldStrength::EnableOnly(f)) => {
|
||||
Some(format!("{enable_disable}{f}"))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})),
|
||||
)
|
||||
})
|
||||
.flatten();
|
||||
features.extend(feats);
|
||||
},
|
||||
)),
|
||||
)
|
||||
})
|
||||
.flatten();
|
||||
features.extend(feats);
|
||||
|
||||
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
|
||||
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
|
||||
features: f,
|
||||
span: None,
|
||||
missing_features: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// -Zfixed-x18
|
||||
if sess.opts.unstable_opts.fixed_x18 {
|
||||
|
|
@ -646,14 +680,6 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
|
|||
}
|
||||
}
|
||||
|
||||
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
|
||||
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
|
||||
features: f,
|
||||
span: None,
|
||||
missing_features: None,
|
||||
});
|
||||
}
|
||||
|
||||
features
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use tracing::debug;
|
|||
use crate::context::CodegenCx;
|
||||
use crate::errors::SymbolAlreadyDefined;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::{attributes, base, llvm};
|
||||
use crate::{base, llvm};
|
||||
|
||||
impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
||||
fn predefine_static(
|
||||
|
|
@ -87,8 +87,6 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
|||
|
||||
debug!("predefine_fn: instance = {:?}", instance);
|
||||
|
||||
attributes::from_fn_attrs(self, lldecl, instance);
|
||||
|
||||
unsafe {
|
||||
if self.should_assume_dso_local(lldecl, false) {
|
||||
llvm::LLVMRustSetDSOLocal(lldecl, true);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
ar_archive_writer = "0.3.0"
|
||||
ar_archive_writer = "0.3.3"
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
bitflags = "2.4.1"
|
||||
cc = "1.0.90"
|
||||
|
|
|
|||
|
|
@ -24,8 +24,19 @@ codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$e
|
|||
|
||||
codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
|
||||
|
||||
codegen_ssa_dlltool_fail_import_library =
|
||||
Dlltool could not create import library with {$dlltool_path} {$dlltool_args}:
|
||||
{$stdout}
|
||||
{$stderr}
|
||||
|
||||
codegen_ssa_error_calling_dlltool =
|
||||
Error calling dlltool '{$dlltool_path}': {$error}
|
||||
|
||||
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
|
||||
|
||||
codegen_ssa_error_writing_def_file =
|
||||
Error writing .DEF file: {$error}
|
||||
|
||||
codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
|
||||
|
||||
codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
@ -9,7 +11,6 @@ use object::read::archive::ArchiveFile;
|
|||
use object::read::macho::FatArch;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_session::cstore::DllImport;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use tempfile::Builder as TempFileBuilder;
|
||||
|
|
@ -17,6 +18,7 @@ use tempfile::Builder as TempFileBuilder;
|
|||
use super::metadata::search_for_section;
|
||||
// Re-exporting for rustc_codegen_llvm::back::archive
|
||||
pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind};
|
||||
use crate::errors::{DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorWritingDEFFile};
|
||||
|
||||
pub trait ArchiveBuilderBuilder {
|
||||
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a>;
|
||||
|
|
@ -30,10 +32,9 @@ pub trait ArchiveBuilderBuilder {
|
|||
&self,
|
||||
sess: &Session,
|
||||
lib_name: &str,
|
||||
dll_imports: &[DllImport],
|
||||
tmpdir: &Path,
|
||||
is_direct_dependency: bool,
|
||||
) -> PathBuf;
|
||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
||||
output_path: &Path,
|
||||
);
|
||||
|
||||
fn extract_bundled_libs<'a>(
|
||||
&'a self,
|
||||
|
|
@ -72,6 +73,130 @@ pub trait ArchiveBuilderBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_mingw_dll_import_lib(
|
||||
sess: &Session,
|
||||
lib_name: &str,
|
||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
||||
output_path: &Path,
|
||||
) {
|
||||
let def_file_path = output_path.with_extension("def");
|
||||
|
||||
let def_file_content = format!(
|
||||
"EXPORTS\n{}",
|
||||
import_name_and_ordinal_vector
|
||||
.into_iter()
|
||||
.map(|(name, ordinal)| {
|
||||
match ordinal {
|
||||
Some(n) => format!("{name} @{n} NONAME"),
|
||||
None => name,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
);
|
||||
|
||||
match std::fs::write(&def_file_path, def_file_content) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
sess.dcx().emit_fatal(ErrorWritingDEFFile { error: e });
|
||||
}
|
||||
};
|
||||
|
||||
// --no-leading-underscore: For the `import_name_type` feature to work, we need to be
|
||||
// able to control the *exact* spelling of each of the symbols that are being imported:
|
||||
// hence we don't want `dlltool` adding leading underscores automatically.
|
||||
let dlltool = find_binutils_dlltool(sess);
|
||||
let temp_prefix = {
|
||||
let mut path = PathBuf::from(&output_path);
|
||||
path.pop();
|
||||
path.push(lib_name);
|
||||
path
|
||||
};
|
||||
// dlltool target architecture args from:
|
||||
// https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69
|
||||
let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch.as_ref() {
|
||||
"x86_64" => ("i386:x86-64", "--64"),
|
||||
"x86" => ("i386", "--32"),
|
||||
"aarch64" => ("arm64", "--64"),
|
||||
"arm" => ("arm", "--32"),
|
||||
_ => panic!("unsupported arch {}", sess.target.arch),
|
||||
};
|
||||
let mut dlltool_cmd = std::process::Command::new(&dlltool);
|
||||
dlltool_cmd
|
||||
.arg("-d")
|
||||
.arg(def_file_path)
|
||||
.arg("-D")
|
||||
.arg(lib_name)
|
||||
.arg("-l")
|
||||
.arg(&output_path)
|
||||
.arg("-m")
|
||||
.arg(dlltool_target_arch)
|
||||
.arg("-f")
|
||||
.arg(dlltool_target_bitness)
|
||||
.arg("--no-leading-underscore")
|
||||
.arg("--temp-prefix")
|
||||
.arg(temp_prefix);
|
||||
|
||||
match dlltool_cmd.output() {
|
||||
Err(e) => {
|
||||
sess.dcx().emit_fatal(ErrorCallingDllTool {
|
||||
dlltool_path: dlltool.to_string_lossy(),
|
||||
error: e,
|
||||
});
|
||||
}
|
||||
// dlltool returns '0' on failure, so check for error output instead.
|
||||
Ok(output) if !output.stderr.is_empty() => {
|
||||
sess.dcx().emit_fatal(DlltoolFailImportLibrary {
|
||||
dlltool_path: dlltool.to_string_lossy(),
|
||||
dlltool_args: dlltool_cmd
|
||||
.get_args()
|
||||
.map(|arg| arg.to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "),
|
||||
stdout: String::from_utf8_lossy(&output.stdout),
|
||||
stderr: String::from_utf8_lossy(&output.stderr),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_binutils_dlltool(sess: &Session) -> OsString {
|
||||
assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc);
|
||||
if let Some(dlltool_path) = &sess.opts.cg.dlltool {
|
||||
return dlltool_path.clone().into_os_string();
|
||||
}
|
||||
|
||||
let tool_name: OsString = if sess.host.options.is_like_windows {
|
||||
// If we're compiling on Windows, always use "dlltool.exe".
|
||||
"dlltool.exe"
|
||||
} else {
|
||||
// On other platforms, use the architecture-specific name.
|
||||
match sess.target.arch.as_ref() {
|
||||
"x86_64" => "x86_64-w64-mingw32-dlltool",
|
||||
"x86" => "i686-w64-mingw32-dlltool",
|
||||
"aarch64" => "aarch64-w64-mingw32-dlltool",
|
||||
|
||||
// For non-standard architectures (e.g., aarch32) fallback to "dlltool".
|
||||
_ => "dlltool",
|
||||
}
|
||||
}
|
||||
.into();
|
||||
|
||||
// NOTE: it's not clear how useful it is to explicitly search PATH.
|
||||
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
|
||||
let full_path = dir.join(&tool_name);
|
||||
if full_path.is_file() {
|
||||
return full_path.into_os_string();
|
||||
}
|
||||
}
|
||||
|
||||
// The user didn't specify the location of the dlltool binary, and we weren't able
|
||||
// to find the appropriate one on the PATH. Just return the name of the tool
|
||||
// and let the invocation fail with a hopefully useful error message.
|
||||
tool_name
|
||||
}
|
||||
|
||||
pub trait ArchiveBuilder {
|
||||
fn add_file(&mut self, path: &Path);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ use super::linker::{self, Linker};
|
|||
use super::metadata::{create_wrapper_file, MetadataPosition};
|
||||
use super::rpath::{self, RPathConfig};
|
||||
use crate::{
|
||||
errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib,
|
||||
common, errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo,
|
||||
NativeLib,
|
||||
};
|
||||
|
||||
pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
|
||||
|
|
@ -390,17 +391,13 @@ fn link_rlib<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
for (raw_dylib_name, raw_dylib_imports) in
|
||||
collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
|
||||
{
|
||||
let output_path = archive_builder_builder.create_dll_import_lib(
|
||||
sess,
|
||||
&raw_dylib_name,
|
||||
&raw_dylib_imports,
|
||||
tmpdir.as_ref(),
|
||||
true,
|
||||
);
|
||||
|
||||
for output_path in create_dll_import_libs(
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results.crate_info.used_libraries.iter(),
|
||||
tmpdir.as_ref(),
|
||||
true,
|
||||
)? {
|
||||
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
|
||||
sess.dcx().emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
|
||||
});
|
||||
|
|
@ -488,6 +485,47 @@ fn collate_raw_dylibs<'a>(
|
|||
.collect())
|
||||
}
|
||||
|
||||
fn create_dll_import_libs<'a>(
|
||||
sess: &Session,
|
||||
archive_builder_builder: &dyn ArchiveBuilderBuilder,
|
||||
used_libraries: impl IntoIterator<Item = &'a NativeLib>,
|
||||
tmpdir: &Path,
|
||||
is_direct_dependency: bool,
|
||||
) -> Result<Vec<PathBuf>, ErrorGuaranteed> {
|
||||
Ok(collate_raw_dylibs(sess, used_libraries)?
|
||||
.into_iter()
|
||||
.map(|(raw_dylib_name, raw_dylib_imports)| {
|
||||
let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
|
||||
let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib"));
|
||||
|
||||
let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target);
|
||||
|
||||
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = raw_dylib_imports
|
||||
.iter()
|
||||
.map(|import: &DllImport| {
|
||||
if sess.target.arch == "x86" {
|
||||
(
|
||||
common::i686_decorated_name(import, mingw_gnu_toolchain, false),
|
||||
import.ordinal(),
|
||||
)
|
||||
} else {
|
||||
(import.name.to_string(), import.ordinal())
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
archive_builder_builder.create_dll_import_lib(
|
||||
sess,
|
||||
&raw_dylib_name,
|
||||
import_name_and_ordinal_vector,
|
||||
&output_path,
|
||||
);
|
||||
|
||||
output_path
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Create a static archive.
|
||||
///
|
||||
/// This is essentially the same thing as an rlib, but it also involves adding all of the upstream
|
||||
|
|
@ -2305,16 +2343,14 @@ fn linker_with_args(
|
|||
);
|
||||
|
||||
// Link with the import library generated for any raw-dylib functions.
|
||||
for (raw_dylib_name, raw_dylib_imports) in
|
||||
collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
|
||||
{
|
||||
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
|
||||
sess,
|
||||
&raw_dylib_name,
|
||||
&raw_dylib_imports,
|
||||
tmpdir,
|
||||
true,
|
||||
));
|
||||
for output_path in create_dll_import_libs(
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results.crate_info.used_libraries.iter(),
|
||||
tmpdir,
|
||||
true,
|
||||
)? {
|
||||
cmd.add_object(&output_path);
|
||||
}
|
||||
// As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
|
||||
// they are used within inlined functions or instantiated generic functions. We do this *after*
|
||||
|
|
@ -2339,16 +2375,14 @@ fn linker_with_args(
|
|||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
native_libraries_from_nonstatics.sort_unstable_by(|a, b| a.name.as_str().cmp(b.name.as_str()));
|
||||
for (raw_dylib_name, raw_dylib_imports) in
|
||||
collate_raw_dylibs(sess, native_libraries_from_nonstatics)?
|
||||
{
|
||||
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
|
||||
sess,
|
||||
&raw_dylib_name,
|
||||
&raw_dylib_imports,
|
||||
tmpdir,
|
||||
false,
|
||||
));
|
||||
for output_path in create_dll_import_libs(
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
native_libraries_from_nonstatics,
|
||||
tmpdir,
|
||||
false,
|
||||
)? {
|
||||
cmd.add_object(&output_path);
|
||||
}
|
||||
|
||||
// Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
|
||||
|
|
@ -2612,16 +2646,7 @@ fn add_native_libs_from_crate(
|
|||
NativeLibKind::Static { bundle, whole_archive } => {
|
||||
if link_static {
|
||||
let bundle = bundle.unwrap_or(true);
|
||||
let whole_archive = whole_archive == Some(true)
|
||||
// Backward compatibility case: this can be a rlib (so `+whole-archive`
|
||||
// cannot be added explicitly if necessary, see the error in `fn link_rlib`)
|
||||
// compiled as an executable due to `--test`. Use whole-archive implicitly,
|
||||
// like before the introduction of native lib modifiers.
|
||||
|| (whole_archive == None
|
||||
&& bundle
|
||||
&& cnum == LOCAL_CRATE
|
||||
&& sess.is_test_crate());
|
||||
|
||||
let whole_archive = whole_archive == Some(true);
|
||||
if bundle && cnum != LOCAL_CRATE {
|
||||
if let Some(filename) = lib.filename {
|
||||
// If rlib contains native libs as archives, they are unpacked to tmpdir.
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
|
|||
"powerpc64" => (Architecture::PowerPc64, None),
|
||||
"riscv32" => (Architecture::Riscv32, None),
|
||||
"riscv64" => (Architecture::Riscv64, None),
|
||||
"sparc" => (Architecture::Sparc32Plus, None),
|
||||
"sparc64" => (Architecture::Sparc64, None),
|
||||
"avr" => (Architecture::Avr, None),
|
||||
"msp430" => (Architecture::Msp430, None),
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
) -> Bx::Value {
|
||||
let cx = bx.cx();
|
||||
let (source, target) =
|
||||
cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, bx.param_env());
|
||||
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env());
|
||||
match (source.kind(), target.kind()) {
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => {
|
||||
cx.const_usize(len.eval_target_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ use rustc_hir::LangItem;
|
|||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::{self, Instance, TyCtxt};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::Target;
|
||||
|
||||
use crate::traits::*;
|
||||
|
||||
|
|
@ -176,3 +178,66 @@ pub fn asm_const_to_str<'tcx>(
|
|||
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_mingw_gnu_toolchain(target: &Target) -> bool {
|
||||
target.vendor == "pc" && target.os == "windows" && target.env == "gnu" && target.abi.is_empty()
|
||||
}
|
||||
|
||||
pub fn i686_decorated_name(
|
||||
dll_import: &DllImport,
|
||||
mingw: bool,
|
||||
disable_name_mangling: bool,
|
||||
) -> String {
|
||||
let name = dll_import.name.as_str();
|
||||
|
||||
let (add_prefix, add_suffix) = match dll_import.import_name_type {
|
||||
Some(PeImportNameType::NoPrefix) => (false, true),
|
||||
Some(PeImportNameType::Undecorated) => (false, false),
|
||||
_ => (true, true),
|
||||
};
|
||||
|
||||
// Worst case: +1 for disable name mangling, +1 for prefix, +4 for suffix (@@__).
|
||||
let mut decorated_name = String::with_capacity(name.len() + 6);
|
||||
|
||||
if disable_name_mangling {
|
||||
// LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled.
|
||||
decorated_name.push('\x01');
|
||||
}
|
||||
|
||||
let prefix = if add_prefix && dll_import.is_fn {
|
||||
match dll_import.calling_convention {
|
||||
DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
|
||||
DllCallingConvention::Stdcall(_) => (!mingw
|
||||
|| dll_import.import_name_type == Some(PeImportNameType::Decorated))
|
||||
.then_some('_'),
|
||||
DllCallingConvention::Fastcall(_) => Some('@'),
|
||||
}
|
||||
} else if !dll_import.is_fn && !mingw {
|
||||
// For static variables, prefix with '_' on MSVC.
|
||||
Some('_')
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(prefix) = prefix {
|
||||
decorated_name.push(prefix);
|
||||
}
|
||||
|
||||
decorated_name.push_str(name);
|
||||
|
||||
if add_suffix && dll_import.is_fn {
|
||||
use std::fmt::Write;
|
||||
|
||||
match dll_import.calling_convention {
|
||||
DllCallingConvention::C => {}
|
||||
DllCallingConvention::Stdcall(arg_list_size)
|
||||
| DllCallingConvention::Fastcall(arg_list_size) => {
|
||||
write!(&mut decorated_name, "@{arg_list_size}").unwrap();
|
||||
}
|
||||
DllCallingConvention::Vectorcall(arg_list_size) => {
|
||||
write!(&mut decorated_name, "@@{arg_list_size}").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decorated_name
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1026,6 +1026,28 @@ pub struct FailedToGetLayout<'tcx> {
|
|||
pub err: LayoutError<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_dlltool_fail_import_library)]
|
||||
pub(crate) struct DlltoolFailImportLibrary<'a> {
|
||||
pub dlltool_path: Cow<'a, str>,
|
||||
pub dlltool_args: String,
|
||||
pub stdout: Cow<'a, str>,
|
||||
pub stderr: Cow<'a, str>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_error_writing_def_file)]
|
||||
pub(crate) struct ErrorWritingDEFFile {
|
||||
pub error: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_error_calling_dlltool)]
|
||||
pub(crate) struct ErrorCallingDllTool<'a> {
|
||||
pub dlltool_path: Cow<'a, str>,
|
||||
pub error: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_error_creating_remark_dir)]
|
||||
pub struct ErrorCreatingRemarkDir {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use rustc_ast::ast;
|
||||
use rustc_attr::InstructionSetAttr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::parse::feature_err;
|
||||
|
|
@ -18,7 +19,7 @@ pub fn from_target_feature(
|
|||
tcx: TyCtxt<'_>,
|
||||
attr: &ast::Attribute,
|
||||
supported_target_features: &UnordMap<String, Option<Symbol>>,
|
||||
target_features: &mut Vec<Symbol>,
|
||||
target_features: &mut Vec<TargetFeature>,
|
||||
) {
|
||||
let Some(list) = attr.meta_item_list() else { return };
|
||||
let bad_item = |span| {
|
||||
|
|
@ -99,14 +100,26 @@ pub fn from_target_feature(
|
|||
}));
|
||||
}
|
||||
|
||||
// Add both explicit and implied target features, using a set to deduplicate
|
||||
let mut target_features_set = UnordSet::new();
|
||||
// Add explicit features
|
||||
target_features.extend(
|
||||
added_target_features.iter().copied().map(|name| TargetFeature { name, implied: false }),
|
||||
);
|
||||
|
||||
// Add implied features
|
||||
let mut implied_target_features = UnordSet::new();
|
||||
for feature in added_target_features.iter() {
|
||||
target_features_set
|
||||
.extend_unord(tcx.implied_target_features(*feature).clone().into_items());
|
||||
implied_target_features.extend(tcx.implied_target_features(*feature).clone());
|
||||
}
|
||||
target_features_set.extend(added_target_features);
|
||||
target_features.extend(target_features_set.into_sorted_stable_ord())
|
||||
for feature in added_target_features.iter() {
|
||||
implied_target_features.remove(feature);
|
||||
}
|
||||
target_features.extend(
|
||||
implied_target_features
|
||||
.into_sorted_stable_ord()
|
||||
.iter()
|
||||
.copied()
|
||||
.map(|name| TargetFeature { name, implied: true }),
|
||||
)
|
||||
}
|
||||
|
||||
/// Computes the set of target features used in a function for the purposes of
|
||||
|
|
@ -115,7 +128,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
|
|||
let mut target_features = tcx.sess.unstable_target_features.clone();
|
||||
if tcx.def_kind(did).has_codegen_attrs() {
|
||||
let attrs = tcx.codegen_fn_attrs(did);
|
||||
target_features.extend(&attrs.target_features);
|
||||
target_features.extend(attrs.target_features.iter().map(|feature| feature.name));
|
||||
match attrs.instruction_set {
|
||||
None => {}
|
||||
Some(InstructionSetAttr::ArmA32) => {
|
||||
|
|
@ -160,31 +173,13 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
.target
|
||||
.supported_target_features()
|
||||
.iter()
|
||||
.map(|&(a, b)| (a.to_string(), b.as_feature_name()))
|
||||
.map(|&(a, b, _)| (a.to_string(), b.as_feature_name()))
|
||||
.collect()
|
||||
}
|
||||
},
|
||||
implied_target_features: |tcx, feature| {
|
||||
let implied_features = tcx
|
||||
.sess
|
||||
.target
|
||||
.implied_target_features()
|
||||
.iter()
|
||||
.map(|(f, i)| (Symbol::intern(f), i))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
// implied target features have their own implied target features, so we traverse the
|
||||
// map until there are no more features to add
|
||||
let mut features = UnordSet::new();
|
||||
let mut new_features = vec![feature];
|
||||
while let Some(new_feature) = new_features.pop() {
|
||||
if features.insert(new_feature) {
|
||||
if let Some(implied_features) = implied_features.get(&new_feature) {
|
||||
new_features.extend(implied_features.iter().copied().map(Symbol::intern))
|
||||
}
|
||||
}
|
||||
}
|
||||
features
|
||||
UnordSet::from(tcx.sess.target.implied_target_features(std::iter::once(feature)))
|
||||
.into_sorted_stable_ord()
|
||||
},
|
||||
asm_target_features,
|
||||
..*providers
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
|
|||
return false;
|
||||
}
|
||||
|
||||
let tail = self.tcx().struct_tail_erasing_lifetimes(ty, param_env);
|
||||
let tail = self.tcx().struct_tail_for_codegen(ty, param_env);
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
|
|
|
|||
|
|
@ -317,19 +317,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
&& attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.any(|feature| !self.tcx.sess.target_features.contains(feature))
|
||||
.any(|feature| !self.tcx.sess.target_features.contains(&feature.name))
|
||||
{
|
||||
throw_ub_custom!(
|
||||
fluent::const_eval_unavailable_target_features_for_fn,
|
||||
unavailable_feats = attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.filter(|&feature| !self.tcx.sess.target_features.contains(feature))
|
||||
.filter(|&feature| !feature.implied
|
||||
&& !self.tcx.sess.target_features.contains(&feature.name))
|
||||
.fold(String::new(), |mut s, feature| {
|
||||
if !s.is_empty() {
|
||||
s.push_str(", ");
|
||||
}
|
||||
s.push_str(feature.as_str());
|
||||
s.push_str(feature.name.as_str());
|
||||
s
|
||||
}),
|
||||
);
|
||||
|
|
@ -677,9 +678,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
} else {
|
||||
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
|
||||
// (For that reason we also cannot use `unpack_dyn_trait`.)
|
||||
let receiver_tail = self
|
||||
.tcx
|
||||
.struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env);
|
||||
let receiver_tail =
|
||||
self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.param_env);
|
||||
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
|
||||
span_bug!(
|
||||
self.cur_span(),
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
) -> InterpResult<'tcx> {
|
||||
// A<Struct> -> A<Trait> conversion
|
||||
let (src_pointee_ty, dest_pointee_ty) =
|
||||
self.tcx.struct_lockstep_tails_erasing_lifetimes(source_ty, cast_ty, self.param_env);
|
||||
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env);
|
||||
|
||||
match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
|
||||
(&ty::Array(_, length), &ty::Slice(_)) => {
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
|||
meta: MemPlaceMeta<M::Provenance>,
|
||||
pointee: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
|
||||
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.param_env);
|
||||
match tail.kind() {
|
||||
ty::Dynamic(data, _, ty::Dyn) => {
|
||||
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ where
|
|||
};
|
||||
|
||||
let ty = place.ty(local_decls, tcx).ty;
|
||||
let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {});
|
||||
let unsized_tail = || tcx.struct_tail_for_codegen(ty, param_env);
|
||||
match tcx.layout_of(param_env.and(ty)) {
|
||||
Ok(layout)
|
||||
if layout.align.abi <= pack
|
||||
|
|
|
|||
|
|
@ -51,6 +51,15 @@ impl<T> Steal<T> {
|
|||
let value = value_ref.take();
|
||||
value.expect("attempt to steal from stolen value")
|
||||
}
|
||||
|
||||
/// Writers of rustc drivers often encounter stealing issues. This function makes it possible to
|
||||
/// handle these errors gracefully.
|
||||
///
|
||||
/// This should not be used within rustc as it leaks information not tracked
|
||||
/// by the query system, breaking incremental compilation.
|
||||
pub fn is_stolen(&self) -> bool {
|
||||
self.value.borrow().is_none()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX, T: HashStable<CTX>> HashStable<CTX> for Steal<T> {
|
||||
|
|
|
|||
|
|
@ -203,9 +203,9 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
|
|||
/// exists). See `postdom_upper_bound` for details.
|
||||
pub fn mutual_immediate_postdominator(&self, mut mubs: Vec<T>) -> Option<T> {
|
||||
loop {
|
||||
match mubs.len() {
|
||||
0 => return None,
|
||||
1 => return Some(mubs[0]),
|
||||
match mubs[..] {
|
||||
[] => return None,
|
||||
[mub] => return Some(mub),
|
||||
_ => {
|
||||
let m = mubs.pop().unwrap();
|
||||
let n = mubs.pop().unwrap();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ use rustc_metadata::creader::MetadataLoader;
|
|||
use rustc_metadata::locator;
|
||||
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
||||
use rustc_session::config::{
|
||||
nightly_options, ErrorOutputType, Input, OutFileName, OutputType, CG_OPTIONS, Z_OPTIONS,
|
||||
nightly_options, ErrorOutputType, Input, OutFileName, OutputType, UnstableOptions, CG_OPTIONS,
|
||||
Z_OPTIONS,
|
||||
};
|
||||
use rustc_session::getopts::{self, Matches};
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
|
|
@ -301,6 +302,8 @@ fn run_compiler(
|
|||
let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };
|
||||
|
||||
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
|
||||
// fully initialize ice path static once unstable options are available as context
|
||||
let ice_file = ice_path_with_config(Some(&sopts.unstable_opts)).clone();
|
||||
|
||||
if let Some(ref code) = matches.opt_str("explain") {
|
||||
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
||||
|
|
@ -315,7 +318,7 @@ fn run_compiler(
|
|||
input: Input::File(PathBuf::new()),
|
||||
output_file: ofile,
|
||||
output_dir: odir,
|
||||
ice_file: ice_path().clone(),
|
||||
ice_file,
|
||||
file_loader,
|
||||
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
||||
lint_caps: Default::default(),
|
||||
|
|
@ -335,12 +338,11 @@ fn run_compiler(
|
|||
config.input = input;
|
||||
true // has input: normal compilation
|
||||
}
|
||||
Ok(None) => match matches.free.len() {
|
||||
0 => false, // no input: we will exit early
|
||||
1 => panic!("make_input should have provided valid inputs"),
|
||||
_ => default_early_dcx.early_fatal(format!(
|
||||
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
||||
matches.free[0], matches.free[1],
|
||||
Ok(None) => match matches.free.as_slice() {
|
||||
[] => false, // no input: we will exit early
|
||||
[_] => panic!("make_input should have provided valid inputs"),
|
||||
[fst, snd, ..] => default_early_dcx.early_fatal(format!(
|
||||
"multiple input filenames provided (first two filenames are `{fst}` and `{snd}`)"
|
||||
)),
|
||||
},
|
||||
};
|
||||
|
|
@ -488,34 +490,30 @@ fn make_input(
|
|||
early_dcx: &EarlyDiagCtxt,
|
||||
free_matches: &[String],
|
||||
) -> Result<Option<Input>, ErrorGuaranteed> {
|
||||
if free_matches.len() == 1 {
|
||||
let ifile = &free_matches[0];
|
||||
if ifile == "-" {
|
||||
let mut src = String::new();
|
||||
if io::stdin().read_to_string(&mut src).is_err() {
|
||||
// Immediately stop compilation if there was an issue reading
|
||||
// the input (for example if the input stream is not UTF-8).
|
||||
let reported = early_dcx
|
||||
.early_err("couldn't read from stdin, as it did not contain valid UTF-8");
|
||||
return Err(reported);
|
||||
}
|
||||
if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
|
||||
let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
|
||||
"when UNSTABLE_RUSTDOC_TEST_PATH is set \
|
||||
let [ifile] = free_matches else { return Ok(None) };
|
||||
if ifile == "-" {
|
||||
let mut src = String::new();
|
||||
if io::stdin().read_to_string(&mut src).is_err() {
|
||||
// Immediately stop compilation if there was an issue reading
|
||||
// the input (for example if the input stream is not UTF-8).
|
||||
let reported =
|
||||
early_dcx.early_err("couldn't read from stdin, as it did not contain valid UTF-8");
|
||||
return Err(reported);
|
||||
}
|
||||
if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
|
||||
let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
|
||||
"when UNSTABLE_RUSTDOC_TEST_PATH is set \
|
||||
UNSTABLE_RUSTDOC_TEST_LINE also needs to be set",
|
||||
);
|
||||
let line = isize::from_str_radix(&line, 10)
|
||||
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
|
||||
let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
|
||||
Ok(Some(Input::Str { name: file_name, input: src }))
|
||||
} else {
|
||||
Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src }))
|
||||
}
|
||||
);
|
||||
let line = isize::from_str_radix(&line, 10)
|
||||
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
|
||||
let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
|
||||
Ok(Some(Input::Str { name: file_name, input: src }))
|
||||
} else {
|
||||
Ok(Some(Input::File(PathBuf::from(ifile))))
|
||||
Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src }))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
Ok(Some(Input::File(PathBuf::from(ifile))))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1306,25 +1304,43 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
|
|||
|
||||
static ICE_PATH: OnceLock<Option<PathBuf>> = OnceLock::new();
|
||||
|
||||
// This function should only be called from the ICE hook.
|
||||
//
|
||||
// The intended behavior is that `run_compiler` will invoke `ice_path_with_config` early in the
|
||||
// initialization process to properly initialize the ICE_PATH static based on parsed CLI flags.
|
||||
//
|
||||
// Subsequent calls to either function will then return the proper ICE path as configured by
|
||||
// the environment and cli flags
|
||||
fn ice_path() -> &'static Option<PathBuf> {
|
||||
ice_path_with_config(None)
|
||||
}
|
||||
|
||||
fn ice_path_with_config(config: Option<&UnstableOptions>) -> &'static Option<PathBuf> {
|
||||
if ICE_PATH.get().is_some() && config.is_some() && cfg!(debug_assertions) {
|
||||
tracing::warn!(
|
||||
"ICE_PATH has already been initialized -- files may be emitted at unintended paths"
|
||||
)
|
||||
}
|
||||
|
||||
ICE_PATH.get_or_init(|| {
|
||||
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
|
||||
return None;
|
||||
}
|
||||
if let Some(s) = std::env::var_os("RUST_BACKTRACE")
|
||||
&& s == "0"
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let mut path = match std::env::var_os("RUSTC_ICE") {
|
||||
Some(s) => {
|
||||
if s == "0" {
|
||||
// Explicitly opting out of writing ICEs to disk.
|
||||
return None;
|
||||
}
|
||||
if let Some(unstable_opts) = config && unstable_opts.metrics_dir.is_some() {
|
||||
tracing::warn!("ignoring -Zerror-metrics in favor of RUSTC_ICE for destination of ICE report files");
|
||||
}
|
||||
PathBuf::from(s)
|
||||
}
|
||||
None => std::env::current_dir().unwrap_or_default(),
|
||||
None => config
|
||||
.and_then(|unstable_opts| unstable_opts.metrics_dir.to_owned())
|
||||
.or_else(|| std::env::current_dir().ok())
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
let now: OffsetDateTime = SystemTime::now().into();
|
||||
let file_now = now
|
||||
|
|
|
|||
|
|
@ -25,14 +25,17 @@ impl Foo {
|
|||
These attributes do not work on typedefs, since typedefs are just aliases.
|
||||
|
||||
Representations like `#[repr(u8)]`, `#[repr(i64)]` are for selecting the
|
||||
discriminant size for enums with no data fields on any of the variants, e.g.
|
||||
`enum Color {Red, Blue, Green}`, effectively setting the size of the enum to
|
||||
the size of the provided type. Such an enum can be cast to a value of the same
|
||||
type as well. In short, `#[repr(u8)]` makes the enum behave like an integer
|
||||
with a constrained set of allowed values.
|
||||
discriminant size for enums. For enums with no data fields on any of the
|
||||
variants, e.g. `enum Color {Red, Blue, Green}`, this effectively sets the size
|
||||
of the enum to the size of the provided type. Such an enum can be cast to a
|
||||
value of the same type as well. In short, `#[repr(u8)]` makes a field-less enum
|
||||
behave like an integer with a constrained set of allowed values.
|
||||
|
||||
Only field-less enums can be cast to numerical primitives, so this attribute
|
||||
will not apply to structs.
|
||||
For a description of how `#[repr(C)]` and representations like `#[repr(u8)]`
|
||||
affect the layout of enums with data fields, see [RFC 2195][rfc2195].
|
||||
|
||||
Only field-less enums can be cast to numerical primitives. Representations like
|
||||
`#[repr(u8)]` will not apply to structs.
|
||||
|
||||
`#[repr(packed)]` reduces padding to make the struct size smaller. The
|
||||
representation of enums isn't strictly defined in Rust, and this attribute
|
||||
|
|
@ -42,3 +45,5 @@ won't work on enums.
|
|||
types (i.e., `u8`, `i32`, etc) a representation that permits vectorization via
|
||||
SIMD. This doesn't make much sense for enums since they don't consist of a
|
||||
single list of data.
|
||||
|
||||
[rfc2195]: https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md
|
||||
|
|
|
|||
|
|
@ -920,8 +920,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
|||
applicability: Applicability,
|
||||
style: SuggestionStyle,
|
||||
) -> &mut Self {
|
||||
suggestion.sort_unstable();
|
||||
suggestion.dedup_by(|(s1, m1), (s2, m2)| s1.source_equal(*s2) && m1 == m2);
|
||||
let mut seen = crate::FxHashSet::default();
|
||||
suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone())));
|
||||
|
||||
let parts = suggestion
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ macro_rules! into_diag_arg_for_number {
|
|||
impl IntoDiagArg for $ty {
|
||||
fn into_diag_arg(self) -> DiagArgValue {
|
||||
// Convert to a string if it won't fit into `Number`.
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Ok(n) = TryInto::<i32>::try_into(self) {
|
||||
DiagArgValue::Number(n)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -43,19 +43,14 @@ const DEFAULT_COLUMN_WIDTH: usize = 140;
|
|||
/// Describes the way the content of the `rendered` field of the json output is generated
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum HumanReadableErrorType {
|
||||
Default(ColorConfig),
|
||||
AnnotateSnippet(ColorConfig),
|
||||
Short(ColorConfig),
|
||||
Default,
|
||||
AnnotateSnippet,
|
||||
Short,
|
||||
}
|
||||
|
||||
impl HumanReadableErrorType {
|
||||
/// Returns a (`short`, `color`) tuple
|
||||
pub fn unzip(self) -> (bool, ColorConfig) {
|
||||
match self {
|
||||
HumanReadableErrorType::Default(cc) => (false, cc),
|
||||
HumanReadableErrorType::Short(cc) => (true, cc),
|
||||
HumanReadableErrorType::AnnotateSnippet(cc) => (false, cc),
|
||||
}
|
||||
pub fn short(&self) -> bool {
|
||||
*self == HumanReadableErrorType::Short
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,17 +226,17 @@ pub trait Emitter: Translate {
|
|||
) {
|
||||
if let Some((sugg, rest)) = suggestions.split_first() {
|
||||
let msg = self.translate_message(&sugg.msg, fluent_args).map_err(Report::new).unwrap();
|
||||
if rest.is_empty() &&
|
||||
if rest.is_empty()
|
||||
// ^ if there is only one suggestion
|
||||
// don't display multi-suggestions as labels
|
||||
sugg.substitutions.len() == 1 &&
|
||||
&& let [substitution] = sugg.substitutions.as_slice()
|
||||
// don't display multipart suggestions as labels
|
||||
sugg.substitutions[0].parts.len() == 1 &&
|
||||
&& let [part] = substitution.parts.as_slice()
|
||||
// don't display long messages as labels
|
||||
msg.split_whitespace().count() < 10 &&
|
||||
&& msg.split_whitespace().count() < 10
|
||||
// don't display multiline suggestions as labels
|
||||
!sugg.substitutions[0].parts[0].snippet.contains('\n') &&
|
||||
![
|
||||
&& !part.snippet.contains('\n')
|
||||
&& ![
|
||||
// when this style is set we want the suggestion to be a message, not inline
|
||||
SuggestionStyle::HideCodeAlways,
|
||||
// trivial suggestion for tooling's sake, never shown
|
||||
|
|
@ -250,8 +245,8 @@ pub trait Emitter: Translate {
|
|||
SuggestionStyle::ShowAlways,
|
||||
].contains(&sugg.style)
|
||||
{
|
||||
let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
|
||||
let msg = if substitution.is_empty() || sugg.style.hide_inline() {
|
||||
let snippet = part.snippet.trim();
|
||||
let msg = if snippet.is_empty() || sugg.style.hide_inline() {
|
||||
// This substitution is only removal OR we explicitly don't want to show the
|
||||
// code inline (`hide_inline`). Therefore, we don't show the substitution.
|
||||
format!("help: {msg}")
|
||||
|
|
@ -260,19 +255,18 @@ pub trait Emitter: Translate {
|
|||
format!(
|
||||
"help: {}{}: `{}`",
|
||||
msg,
|
||||
if self.source_map().is_some_and(|sm| is_case_difference(
|
||||
sm,
|
||||
substitution,
|
||||
sugg.substitutions[0].parts[0].span,
|
||||
)) {
|
||||
if self
|
||||
.source_map()
|
||||
.is_some_and(|sm| is_case_difference(sm, snippet, part.span,))
|
||||
{
|
||||
" (notice the capitalization)"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
substitution,
|
||||
snippet,
|
||||
)
|
||||
};
|
||||
primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
|
||||
primary_span.push_span_label(part.span, msg);
|
||||
|
||||
// We return only the modified primary_span
|
||||
suggestions.clear();
|
||||
|
|
@ -2595,9 +2589,7 @@ fn num_decimal_digits(num: usize) -> usize {
|
|||
|
||||
// We replace some characters so the CLI output is always consistent and underlines aligned.
|
||||
// Keep the following list in sync with `rustc_span::char_width`.
|
||||
// ATTENTION: keep lexicografically sorted so that the binary search will work
|
||||
const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
|
||||
// tidy-alphabetical-start
|
||||
// In terminals without Unicode support the following will be garbled, but in *all* terminals
|
||||
// the underlying codepoint will be as well. We could gate this replacement behind a "unicode
|
||||
// support" gate.
|
||||
|
|
@ -2610,7 +2602,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
|
|||
('\u{0006}', "␆"),
|
||||
('\u{0007}', "␇"),
|
||||
('\u{0008}', "␈"),
|
||||
('\u{0009}', " "), // We do our own tab replacement
|
||||
('\t', " "), // We do our own tab replacement
|
||||
('\u{000b}', "␋"),
|
||||
('\u{000c}', "␌"),
|
||||
('\u{000d}', "␍"),
|
||||
|
|
@ -2643,13 +2635,23 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
|
|||
('\u{2067}', "<EFBFBD>"),
|
||||
('\u{2068}', "<EFBFBD>"),
|
||||
('\u{2069}', "<EFBFBD>"),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
fn normalize_whitespace(s: &str) -> String {
|
||||
// Scan the input string for a character in the ordered table above. If it's present, replace
|
||||
// it with it's alternative string (it can be more than 1 char!). Otherwise, retain the input
|
||||
// char. At the end, allocate all chars into a string in one operation.
|
||||
const {
|
||||
let mut i = 1;
|
||||
while i < OUTPUT_REPLACEMENTS.len() {
|
||||
assert!(
|
||||
OUTPUT_REPLACEMENTS[i - 1].0 < OUTPUT_REPLACEMENTS[i].0,
|
||||
"The OUTPUT_REPLACEMENTS array must be sorted (for binary search to work) \
|
||||
and must contain no duplicate entries"
|
||||
);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
// Scan the input string for a character in the ordered table above.
|
||||
// If it's present, replace it with its alternative string (it can be more than 1 char!).
|
||||
// Otherwise, retain the input char.
|
||||
s.chars().fold(String::with_capacity(s.len()), |mut s, c| {
|
||||
match OUTPUT_REPLACEMENTS.binary_search_by_key(&c, |(k, _)| *k) {
|
||||
Ok(i) => s.push_str(OUTPUT_REPLACEMENTS[i].1),
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ pub struct JsonEmitter {
|
|||
ignored_directories_in_source_blocks: Vec<String>,
|
||||
#[setters(skip)]
|
||||
json_rendered: HumanReadableErrorType,
|
||||
color_config: ColorConfig,
|
||||
diagnostic_width: Option<usize>,
|
||||
macro_backtrace: bool,
|
||||
track_diagnostics: bool,
|
||||
|
|
@ -68,6 +69,7 @@ impl JsonEmitter {
|
|||
fallback_bundle: LazyFallbackBundle,
|
||||
pretty: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
color_config: ColorConfig,
|
||||
) -> JsonEmitter {
|
||||
JsonEmitter {
|
||||
dst: IntoDynSyncSend(dst),
|
||||
|
|
@ -79,6 +81,7 @@ impl JsonEmitter {
|
|||
ui_testing: false,
|
||||
ignored_directories_in_source_blocks: Vec::new(),
|
||||
json_rendered,
|
||||
color_config,
|
||||
diagnostic_width: None,
|
||||
macro_backtrace: false,
|
||||
track_diagnostics: false,
|
||||
|
|
@ -173,7 +176,7 @@ impl Emitter for JsonEmitter {
|
|||
}
|
||||
|
||||
fn should_show_explain(&self) -> bool {
|
||||
!matches!(self.json_rendered, HumanReadableErrorType::Short(_))
|
||||
!self.json_rendered.short()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -353,8 +356,8 @@ impl Diagnostic {
|
|||
|
||||
let buf = BufWriter::default();
|
||||
let mut dst: Destination = Box::new(buf.clone());
|
||||
let (short, color_config) = je.json_rendered.unzip();
|
||||
match color_config {
|
||||
let short = je.json_rendered.short();
|
||||
match je.color_config {
|
||||
ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
|
||||
ColorConfig::Never => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
|
|||
sm,
|
||||
fallback_bundle,
|
||||
true, // pretty
|
||||
HumanReadableErrorType::Short(ColorConfig::Never),
|
||||
HumanReadableErrorType::Short,
|
||||
ColorConfig::Never,
|
||||
);
|
||||
|
||||
let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1));
|
||||
|
|
|
|||
|
|
@ -2024,11 +2024,11 @@ pub fn a_or_an(s: &str) -> &'static str {
|
|||
///
|
||||
/// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c"
|
||||
pub fn display_list_with_comma_and<T: std::fmt::Display>(v: &[T]) -> String {
|
||||
match v.len() {
|
||||
0 => "".to_string(),
|
||||
1 => v[0].to_string(),
|
||||
2 => format!("{} and {}", v[0], v[1]),
|
||||
_ => format!("{}, {}", v[0], display_list_with_comma_and(&v[1..])),
|
||||
match v {
|
||||
[] => "".to_string(),
|
||||
[a] => a.to_string(),
|
||||
[a, b] => format!("{a} and {b}"),
|
||||
[a, v @ ..] => format!("{a}, {}", display_list_with_comma_and(v)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1306,12 +1306,12 @@ pub fn parse_macro_name_and_helper_attrs(
|
|||
// that it's of the form `#[proc_macro_derive(Foo)]` or
|
||||
// `#[proc_macro_derive(Foo, attributes(A, ..))]`
|
||||
let list = attr.meta_item_list()?;
|
||||
if list.len() != 1 && list.len() != 2 {
|
||||
let ([trait_attr] | [trait_attr, _]) = list.as_slice() else {
|
||||
dcx.emit_err(errors::AttrNoArguments { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
let Some(trait_attr) = list[0].meta_item() else {
|
||||
dcx.emit_err(errors::NotAMetaItem { span: list[0].span() });
|
||||
};
|
||||
let Some(trait_attr) = trait_attr.meta_item() else {
|
||||
dcx.emit_err(errors::NotAMetaItem { span: trait_attr.span() });
|
||||
return None;
|
||||
};
|
||||
let trait_ident = match trait_attr.ident() {
|
||||
|
|
|
|||
|
|
@ -3,34 +3,32 @@ use std::borrow::Cow;
|
|||
use rustc_ast::token::{self, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Applicability, Diag, DiagMessage};
|
||||
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
|
||||
use rustc_macros::Subdiagnostic;
|
||||
use rustc_parse::parser::{Parser, Recovery};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use tracing::debug;
|
||||
|
||||
use super::macro_rules::{parser_from_cx, NoopTracker};
|
||||
use crate::base::{DummyResult, ExtCtxt, MacResult};
|
||||
use crate::expand::{parse_ast_fragment, AstFragmentKind};
|
||||
use crate::mbe::macro_parser::ParseResult::*;
|
||||
use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser};
|
||||
use crate::mbe::macro_rules::{try_match_macro, Tracker};
|
||||
|
||||
pub(super) fn failed_to_match_macro<'cx>(
|
||||
cx: &'cx mut ExtCtxt<'_>,
|
||||
pub(super) fn failed_to_match_macro(
|
||||
psess: &ParseSess,
|
||||
sp: Span,
|
||||
def_span: Span,
|
||||
name: Ident,
|
||||
arg: TokenStream,
|
||||
lhses: &[Vec<MatcherLoc>],
|
||||
) -> Box<dyn MacResult + 'cx> {
|
||||
let psess = &cx.sess.psess;
|
||||
|
||||
) -> (Span, ErrorGuaranteed) {
|
||||
// An error occurred, try the expansion again, tracking the expansion closely for better
|
||||
// diagnostics.
|
||||
let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
|
||||
let mut tracker = CollectTrackerAndEmitter::new(psess.dcx(), sp);
|
||||
|
||||
let try_success_result = try_match_macro(psess, name, &arg, lhses, &mut tracker);
|
||||
|
||||
|
|
@ -38,7 +36,7 @@ pub(super) fn failed_to_match_macro<'cx>(
|
|||
// Nonterminal parser recovery might turn failed matches into successful ones,
|
||||
// but for that it must have emitted an error already
|
||||
assert!(
|
||||
tracker.cx.dcx().has_errors().is_some(),
|
||||
tracker.dcx.has_errors().is_some(),
|
||||
"Macro matching returned a success on the second try"
|
||||
);
|
||||
}
|
||||
|
|
@ -50,15 +48,15 @@ pub(super) fn failed_to_match_macro<'cx>(
|
|||
|
||||
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
|
||||
else {
|
||||
return DummyResult::any(sp, cx.dcx().span_delayed_bug(sp, "failed to match a macro"));
|
||||
return (sp, psess.dcx().span_delayed_bug(sp, "failed to match a macro"));
|
||||
};
|
||||
|
||||
let span = token.span.substitute_dummy(sp);
|
||||
|
||||
let mut err = cx.dcx().struct_span_err(span, parse_failure_msg(&token, None));
|
||||
let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None));
|
||||
err.span_label(span, label);
|
||||
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
|
||||
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
|
||||
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
|
||||
err.span_label(psess.source_map().guess_head_span(def_span), "when calling this macro");
|
||||
}
|
||||
|
||||
annotate_doc_comment(&mut err, psess.source_map(), span);
|
||||
|
|
@ -76,7 +74,7 @@ pub(super) fn failed_to_match_macro<'cx>(
|
|||
err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens");
|
||||
err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");
|
||||
|
||||
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
|
||||
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
|
||||
err.help("try using `:tt` instead in the macro definition");
|
||||
}
|
||||
}
|
||||
|
|
@ -104,18 +102,17 @@ pub(super) fn failed_to_match_macro<'cx>(
|
|||
}
|
||||
}
|
||||
let guar = err.emit();
|
||||
cx.trace_macros_diag();
|
||||
DummyResult::any(sp, guar)
|
||||
(sp, guar)
|
||||
}
|
||||
|
||||
/// The tracker used for the slow error path that collects useful info for diagnostics.
|
||||
struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
|
||||
cx: &'a mut ExtCtxt<'cx>,
|
||||
struct CollectTrackerAndEmitter<'dcx, 'matcher> {
|
||||
dcx: DiagCtxtHandle<'dcx>,
|
||||
remaining_matcher: Option<&'matcher MatcherLoc>,
|
||||
/// Which arm's failure should we report? (the one furthest along)
|
||||
best_failure: Option<BestFailure>,
|
||||
root_span: Span,
|
||||
result: Option<Box<dyn MacResult + 'cx>>,
|
||||
result: Option<(Span, ErrorGuaranteed)>,
|
||||
}
|
||||
|
||||
struct BestFailure {
|
||||
|
|
@ -131,7 +128,7 @@ impl BestFailure {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
|
||||
impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'matcher> {
|
||||
type Failure = (Token, u32, &'static str);
|
||||
|
||||
fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure {
|
||||
|
|
@ -151,7 +148,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
|
|||
Success(_) => {
|
||||
// Nonterminal parser recovery might turn failed matches into successful ones,
|
||||
// but for that it must have emitted an error already
|
||||
self.cx.dcx().span_delayed_bug(
|
||||
self.dcx.span_delayed_bug(
|
||||
self.root_span,
|
||||
"should not collect detailed info for successful macro match",
|
||||
);
|
||||
|
|
@ -177,10 +174,10 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
|
|||
}
|
||||
Error(err_sp, msg) => {
|
||||
let span = err_sp.substitute_dummy(self.root_span);
|
||||
let guar = self.cx.dcx().span_err(span, msg.clone());
|
||||
self.result = Some(DummyResult::any(span, guar));
|
||||
let guar = self.dcx.span_err(span, msg.clone());
|
||||
self.result = Some((span, guar));
|
||||
}
|
||||
ErrorReported(guar) => self.result = Some(DummyResult::any(self.root_span, *guar)),
|
||||
ErrorReported(guar) => self.result = Some((self.root_span, *guar)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -193,9 +190,9 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> {
|
||||
fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
|
||||
Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None }
|
||||
impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {
|
||||
fn new(dcx: DiagCtxtHandle<'dcx>, root_span: Span) -> Self {
|
||||
Self { dcx, remaining_matcher: None, best_failure: None, root_span, result: None }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,7 +268,10 @@ fn expand_macro<'cx>(
|
|||
}
|
||||
Err(CanRetry::Yes) => {
|
||||
// Retry and emit a better error.
|
||||
diagnostics::failed_to_match_macro(cx, sp, def_span, name, arg, lhses)
|
||||
let (span, guar) =
|
||||
diagnostics::failed_to_match_macro(cx.psess(), sp, def_span, name, arg, lhses);
|
||||
cx.trace_macros_diag();
|
||||
DummyResult::any(span, guar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ declare_features! (
|
|||
(accepted, min_const_generics, "1.51.0", Some(74878)),
|
||||
/// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
|
||||
(accepted, min_const_unsafe_fn, "1.33.0", Some(55607)),
|
||||
/// Allows exhaustive pattern matching on uninhabited types when matched by value.
|
||||
(accepted, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(119612)),
|
||||
/// Allows using `Self` and associated types in struct expressions and patterns.
|
||||
(accepted, more_struct_aliases, "1.16.0", Some(37544)),
|
||||
/// Allows using the MOVBE target feature.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue