Merge pull request #4758 from rust-lang/rustup-2025-12-11
Automatic Rustup
This commit is contained in:
commit
a4777e418e
1051 changed files with 17601 additions and 10784 deletions
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
custom: ["rust-lang.org/funding"]
|
||||
2
.github/workflows/ghcr.yml
vendored
2
.github/workflows/ghcr.yml
vendored
|
|
@ -55,6 +55,8 @@ jobs:
|
|||
images=(
|
||||
# Mirrored because used by the tidy job, which doesn't cache Docker images
|
||||
"ubuntu:22.04"
|
||||
# Mirrored because used by x86-64-gnu-miri
|
||||
"ubuntu:24.04"
|
||||
# Mirrored because used by all linux CI jobs, including tidy
|
||||
"moby/buildkit:buildx-stable-1"
|
||||
# Mirrored because used when CI is running inside a Docker container
|
||||
|
|
|
|||
1
.mailmap
1
.mailmap
|
|
@ -83,6 +83,7 @@ Ben Sago <ogham@users.noreply.github.com> <ogham@bsago.me>
|
|||
Ben Striegel <ben.striegel@gmail.com>
|
||||
Benjamin Jackman <ben@jackman.biz>
|
||||
Benoît Cortier <benoit.cortier@fried-world.eu>
|
||||
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61+github@gmail.com> <dogedoge61@gmail.com>
|
||||
Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
|
||||
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3@users.noreply.github.com>
|
||||
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3_gh@protonmail.com>
|
||||
|
|
|
|||
14
Cargo.lock
14
Cargo.lock
|
|
@ -621,7 +621,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
|||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.1.93"
|
||||
version = "0.1.94"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"askama",
|
||||
|
|
@ -648,7 +648,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clippy_config"
|
||||
version = "0.1.93"
|
||||
version = "0.1.94"
|
||||
dependencies = [
|
||||
"clippy_utils",
|
||||
"itertools",
|
||||
|
|
@ -671,7 +671,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.93"
|
||||
version = "0.1.94"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"cargo_metadata 0.18.1",
|
||||
|
|
@ -703,7 +703,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.93"
|
||||
version = "0.1.94"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"itertools",
|
||||
|
|
@ -1107,7 +1107,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "declare_clippy_lint"
|
||||
version = "0.1.93"
|
||||
version = "0.1.94"
|
||||
|
||||
[[package]]
|
||||
name = "derive-where"
|
||||
|
|
@ -3945,6 +3945,7 @@ dependencies = [
|
|||
"rustc_hashes",
|
||||
"rustc_hir_id",
|
||||
"rustc_index",
|
||||
"rustc_lint_defs",
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
"rustc_span",
|
||||
|
|
@ -3962,7 +3963,6 @@ dependencies = [
|
|||
"rustc_abi",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_attr_parsing",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
|
|
@ -3970,6 +3970,7 @@ dependencies = [
|
|||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_infer",
|
||||
"rustc_lint",
|
||||
"rustc_lint_defs",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
|
|
@ -5615,6 +5616,7 @@ dependencies = [
|
|||
"semver",
|
||||
"serde",
|
||||
"similar",
|
||||
"tempfile",
|
||||
"termcolor",
|
||||
"toml 0.7.8",
|
||||
"walkdir",
|
||||
|
|
|
|||
85
RELEASES.md
85
RELEASES.md
|
|
@ -1,3 +1,88 @@
|
|||
Version 1.92.0 (2025-12-11)
|
||||
==========================
|
||||
|
||||
<a id="1.92.0-Language"></a>
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Document `MaybeUninit` representation and validity](https://github.com/rust-lang/rust/pull/140463)
|
||||
- [Allow `&raw [mut | const]` for union field in safe code](https://github.com/rust-lang/rust/pull/141469)
|
||||
- [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](https://github.com/rust-lang/rust/pull/144064)
|
||||
- [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](https://github.com/rust-lang/rust/pull/145277)
|
||||
- [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](https://github.com/rust-lang/rust/pull/145724)
|
||||
- [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](https://github.com/rust-lang/rust/pull/146167)
|
||||
- [Allow specifying multiple bounds for same associated item, except in trait objects](https://github.com/rust-lang/rust/pull/146593)
|
||||
- [Slightly strengthen higher-ranked region handling in coherence](https://github.com/rust-lang/rust/pull/146725)
|
||||
- [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow<Uninhabited, ()>`](https://github.com/rust-lang/rust/pull/147382). This avoids having to check for an error that can never happen.
|
||||
|
||||
<a id="1.92.0-Compiler"></a>
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Make `mips64el-unknown-linux-muslabi64` link dynamically](https://github.com/rust-lang/rust/pull/146858)
|
||||
- [Remove current code for embedding command-line args in PDB](https://github.com/rust-lang/rust/pull/147022)
|
||||
Command-line information is typically not needed by debugging tools, and the removed code
|
||||
was causing problems for incremental builds even on targets that don't use PDB debuginfo.
|
||||
|
||||
<a id="1.92.0-Libraries"></a>
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](https://github.com/rust-lang/rust/pull/137122)
|
||||
- [Simplify `Extend` for tuples](https://github.com/rust-lang/rust/pull/138799)
|
||||
- [Added details to `Debug` for `EncodeWide`](https://github.com/rust-lang/rust/pull/140153).
|
||||
- [`iter::Repeat::last`](https://github.com/rust-lang/rust/pull/147258) and [`count`](https://github.com/rust-lang/rust/pull/146410) will now panic, rather than looping infinitely.
|
||||
|
||||
<a id="1.92.0-Stabilized-APIs"></a>
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`NonZero<u{N}>::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil)
|
||||
- [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str)
|
||||
- [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade)
|
||||
- [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed)
|
||||
- [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice)
|
||||
- [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed)
|
||||
- [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice)
|
||||
- [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed)
|
||||
- [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice)
|
||||
- [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry)
|
||||
- [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry)
|
||||
- [`impl Extend<proc_macro::Group> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream)
|
||||
- [`impl Extend<proc_macro::Literal> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream)
|
||||
- [`impl Extend<proc_macro::Punct> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream)
|
||||
- [`impl Extend<proc_macro::Ident> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream)
|
||||
|
||||
These previously stable APIs are now stable in const contexts:
|
||||
|
||||
- [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left)
|
||||
- [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right)
|
||||
|
||||
<a id="1.92.0-Cargo"></a>
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [Added a new chapter](https://github.com/rust-lang/cargo/issues/16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html).
|
||||
|
||||
<a id="1.92.0-Rustdoc"></a>
|
||||
|
||||
Rustdoc
|
||||
-----
|
||||
- [If a trait item appears in rustdoc search, hide the corresponding impl items](https://github.com/rust-lang/rust/pull/145898). Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`. Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`.
|
||||
- [Relax rules for identifiers in search](https://github.com/rust-lang/rust/pull/147860). Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier. For example, you can now perform a search that starts with a digit.
|
||||
|
||||
<a id="1.92.0-Compatibility-Notes"></a>
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
* [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](https://github.com/rust-lang/rust/pull/143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables.
|
||||
- As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](https://github.com/rust-lang/rust/pull/143857)
|
||||
- [Update the minimum external LLVM to 20](https://github.com/rust-lang/rust/pull/145071)
|
||||
- [Prevent downstream `impl DerefMut for Pin<LocalType>`](https://github.com/rust-lang/rust/pull/145608)
|
||||
- [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](https://github.com/rust-lang/rust/pull/145838)
|
||||
|
||||
|
||||
Version 1.91.1 (2025-11-10)
|
||||
===========================
|
||||
|
||||
|
|
|
|||
|
|
@ -1259,6 +1259,19 @@ pub enum StmtKind {
|
|||
MacCall(Box<MacCallStmt>),
|
||||
}
|
||||
|
||||
impl StmtKind {
|
||||
pub fn descr(&self) -> &'static str {
|
||||
match self {
|
||||
StmtKind::Let(_) => "local",
|
||||
StmtKind::Item(_) => "item",
|
||||
StmtKind::Expr(_) => "expression",
|
||||
StmtKind::Semi(_) => "statement",
|
||||
StmtKind::Empty => "semicolon",
|
||||
StmtKind::MacCall(_) => "macro call",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub struct MacCallStmt {
|
||||
pub mac: Box<MacCall>,
|
||||
|
|
@ -1806,8 +1819,14 @@ pub enum ExprKind {
|
|||
/// A use expression (`x.use`). Span is of use keyword.
|
||||
Use(Box<Expr>, Span),
|
||||
|
||||
/// A try block (`try { ... }`).
|
||||
TryBlock(Box<Block>),
|
||||
/// A try block (`try { ... }`), if the type is `None`, or
|
||||
/// A try block (`try bikeshed Ty { ... }`) if the type is `Some`.
|
||||
///
|
||||
/// Note that `try bikeshed` is a *deliberately ridiculous* placeholder
|
||||
/// syntax to avoid deciding what keyword or symbol should go there.
|
||||
/// It's that way for experimentation only; an RFC to decide the final
|
||||
/// semantics and syntax would be needed to put it on stabilization-track.
|
||||
TryBlock(Box<Block>, Option<Box<Ty>>),
|
||||
|
||||
/// An assignment (`a = foo()`).
|
||||
/// The `Span` argument is the span of the `=` token.
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
//! This API is completely unstable and subject to change.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(array_windows))]
|
||||
#![doc(test(attr(deny(warnings), allow(internal_features))))]
|
||||
#![feature(array_windows)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(if_let_guard)]
|
||||
|
|
|
|||
|
|
@ -1048,8 +1048,8 @@ macro_rules! common_visitor_and_walkers {
|
|||
visit_visitable!($($mut)? vis, kind),
|
||||
ExprKind::Try(subexpression) =>
|
||||
visit_visitable!($($mut)? vis, subexpression),
|
||||
ExprKind::TryBlock(body) =>
|
||||
visit_visitable!($($mut)? vis, body),
|
||||
ExprKind::TryBlock(body, optional_type) =>
|
||||
visit_visitable!($($mut)? vis, body, optional_type),
|
||||
ExprKind::Lit(token) =>
|
||||
visit_visitable!($($mut)? vis, token),
|
||||
ExprKind::IncludedBytes(bytes) =>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// The order in which things are lowered is important! I.e to
|
||||
// refer to variables in contract_decls from postcond/precond,
|
||||
// we must lower it first!
|
||||
let contract_decls = self.lower_stmts(&contract.declarations).0;
|
||||
let contract_decls = self.lower_decls(contract);
|
||||
|
||||
match (&contract.requires, &contract.ensures) {
|
||||
(Some(req), Some(ens)) => {
|
||||
|
|
@ -124,6 +124,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_decls(&mut self, contract: &rustc_ast::FnContract) -> &'hir [rustc_hir::Stmt<'hir>] {
|
||||
let (decls, decls_tail) = self.lower_stmts(&contract.declarations);
|
||||
|
||||
if let Some(e) = decls_tail {
|
||||
// include the tail expression in the declaration statements
|
||||
let tail = self.stmt_expr(e.span, *e);
|
||||
self.arena.alloc_from_iter(decls.into_iter().map(|d| *d).chain([tail].into_iter()))
|
||||
} else {
|
||||
decls
|
||||
}
|
||||
}
|
||||
|
||||
/// Lower the precondition check intrinsic.
|
||||
fn lower_precond(&mut self, req: &Box<rustc_ast::Expr>) -> rustc_hir::Stmt<'hir> {
|
||||
let lowered_req = self.lower_expr_mut(&req);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ use hir::{BodyId, HirId};
|
|||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::*;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::attrs::{AttributeKind, InlineAttr};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
|
||||
|
|
@ -87,6 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
|
||||
match sig_id {
|
||||
Ok(sig_id) => {
|
||||
self.add_inline_attribute_if_needed(span);
|
||||
|
||||
let is_method = self.is_method(sig_id, span);
|
||||
let (param_count, c_variadic) = self.param_count(sig_id);
|
||||
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
|
||||
|
|
@ -100,6 +103,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_inline_attribute_if_needed(&mut self, span: Span) {
|
||||
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
|
||||
let create_inline_attr_slice =
|
||||
|| [hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span))];
|
||||
|
||||
let new_attributes = match self.attrs.get(&PARENT_ID) {
|
||||
Some(attrs) => {
|
||||
// Check if reuse already specifies any inline attribute, if so, do nothing
|
||||
if attrs
|
||||
.iter()
|
||||
.any(|a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.arena.alloc_from_iter(
|
||||
attrs.into_iter().map(|a| a.clone()).chain(create_inline_attr_slice()),
|
||||
)
|
||||
}
|
||||
None => self.arena.alloc_from_iter(create_inline_attr_slice()),
|
||||
};
|
||||
|
||||
self.attrs.insert(PARENT_ID, new_attributes);
|
||||
}
|
||||
|
||||
fn get_delegation_sig_id(
|
||||
&self,
|
||||
item_id: NodeId,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::mem;
|
||||
use std::ops::ControlFlow;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
@ -27,7 +28,9 @@ use super::{
|
|||
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
|
||||
};
|
||||
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
|
||||
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated};
|
||||
use crate::{
|
||||
AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated,
|
||||
};
|
||||
|
||||
struct WillCreateDefIdsVisitor {}
|
||||
|
||||
|
|
@ -199,7 +202,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
)
|
||||
})
|
||||
}
|
||||
ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
|
||||
ExprKind::TryBlock(body, opt_ty) => {
|
||||
self.lower_expr_try_block(body, opt_ty.as_deref())
|
||||
}
|
||||
ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match(
|
||||
self.lower_expr(expr),
|
||||
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
|
||||
|
|
@ -562,9 +567,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
|
||||
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_output(()) }`
|
||||
/// and save the block id to use it as a break target for desugaring of the `?` operator.
|
||||
fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
|
||||
fn lower_expr_try_block(&mut self, body: &Block, opt_ty: Option<&Ty>) -> hir::ExprKind<'hir> {
|
||||
let body_hir_id = self.lower_node_id(body.id);
|
||||
self.with_catch_scope(body_hir_id, |this| {
|
||||
let new_scope = if opt_ty.is_some() {
|
||||
TryBlockScope::Heterogeneous(body_hir_id)
|
||||
} else {
|
||||
TryBlockScope::Homogeneous(body_hir_id)
|
||||
};
|
||||
let whole_block = self.with_try_block_scope(new_scope, |this| {
|
||||
let mut block = this.lower_block_noalloc(body_hir_id, body, true);
|
||||
|
||||
// Final expression of the block (if present) or `()` with span at the end of block
|
||||
|
|
@ -598,8 +608,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ok_wrapped_span,
|
||||
));
|
||||
|
||||
hir::ExprKind::Block(this.arena.alloc(block), None)
|
||||
})
|
||||
this.arena.alloc(block)
|
||||
});
|
||||
|
||||
if let Some(ty) = opt_ty {
|
||||
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path));
|
||||
let block_expr = self.arena.alloc(self.expr_block(whole_block));
|
||||
hir::ExprKind::Type(block_expr, ty)
|
||||
} else {
|
||||
hir::ExprKind::Block(whole_block, None)
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_in_try_constructor(
|
||||
|
|
@ -1617,10 +1635,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn with_catch_scope<T>(&mut self, catch_id: hir::HirId, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
let old_scope = self.catch_scope.replace(catch_id);
|
||||
fn with_try_block_scope<T>(
|
||||
&mut self,
|
||||
scope: TryBlockScope,
|
||||
f: impl FnOnce(&mut Self) -> T,
|
||||
) -> T {
|
||||
let old_scope = mem::replace(&mut self.try_block_scope, scope);
|
||||
let result = f(self);
|
||||
self.catch_scope = old_scope;
|
||||
self.try_block_scope = old_scope;
|
||||
result
|
||||
}
|
||||
|
||||
|
|
@ -1978,18 +2000,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let residual_ident = Ident::with_dummy_span(sym::residual);
|
||||
let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident);
|
||||
let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid);
|
||||
|
||||
let (constructor_item, target_id) = match self.try_block_scope {
|
||||
TryBlockScope::Function => {
|
||||
(hir::LangItem::TryTraitFromResidual, Err(hir::LoopIdError::OutsideLoopScope))
|
||||
}
|
||||
TryBlockScope::Homogeneous(block_id) => {
|
||||
(hir::LangItem::ResidualIntoTryType, Ok(block_id))
|
||||
}
|
||||
TryBlockScope::Heterogeneous(block_id) => {
|
||||
(hir::LangItem::TryTraitFromResidual, Ok(block_id))
|
||||
}
|
||||
};
|
||||
let from_residual_expr = self.wrap_in_try_constructor(
|
||||
if self.catch_scope.is_some() {
|
||||
hir::LangItem::ResidualIntoTryType
|
||||
} else {
|
||||
hir::LangItem::TryTraitFromResidual
|
||||
},
|
||||
constructor_item,
|
||||
try_span,
|
||||
self.arena.alloc(residual_expr),
|
||||
unstable_span,
|
||||
);
|
||||
let ret_expr = if let Some(catch_id) = self.catch_scope {
|
||||
let target_id = Ok(catch_id);
|
||||
let ret_expr = if target_id.is_ok() {
|
||||
self.arena.alloc(self.expr(
|
||||
try_span,
|
||||
hir::ExprKind::Break(
|
||||
|
|
@ -2044,11 +2073,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
yeeted_span,
|
||||
);
|
||||
|
||||
if let Some(catch_id) = self.catch_scope {
|
||||
let target_id = Ok(catch_id);
|
||||
hir::ExprKind::Break(hir::Destination { label: None, target_id }, Some(from_yeet_expr))
|
||||
} else {
|
||||
self.checked_return(Some(from_yeet_expr))
|
||||
match self.try_block_scope {
|
||||
TryBlockScope::Homogeneous(block_id) | TryBlockScope::Heterogeneous(block_id) => {
|
||||
hir::ExprKind::Break(
|
||||
hir::Destination { label: None, target_id: Ok(block_id) },
|
||||
Some(from_yeet_expr),
|
||||
)
|
||||
}
|
||||
TryBlockScope::Function => self.checked_return(Some(from_yeet_expr)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#![feature(if_let_guard)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
|
|
@ -117,7 +118,7 @@ struct LoweringContext<'a, 'hir> {
|
|||
/// outside of an `async fn`.
|
||||
current_item: Option<Span>,
|
||||
|
||||
catch_scope: Option<HirId>,
|
||||
try_block_scope: TryBlockScope,
|
||||
loop_scope: Option<HirId>,
|
||||
is_in_loop_condition: bool,
|
||||
is_in_dyn_type: bool,
|
||||
|
|
@ -173,7 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
trait_map: Default::default(),
|
||||
|
||||
// Lowering state.
|
||||
catch_scope: None,
|
||||
try_block_scope: TryBlockScope::Function,
|
||||
loop_scope: None,
|
||||
is_in_loop_condition: false,
|
||||
is_in_dyn_type: false,
|
||||
|
|
@ -416,6 +417,18 @@ enum AstOwner<'a> {
|
|||
ForeignItem(&'a ast::ForeignItem),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum TryBlockScope {
|
||||
/// There isn't a `try` block, so a `?` will use `return`.
|
||||
Function,
|
||||
/// We're inside a `try { … }` block, so a `?` will block-break
|
||||
/// from that block using a type depending only on the argument.
|
||||
Homogeneous(HirId),
|
||||
/// We're inside a `try as _ { … }` block, so a `?` will block-break
|
||||
/// from that block using the type specified.
|
||||
Heterogeneous(HirId),
|
||||
}
|
||||
|
||||
fn index_crate<'a>(
|
||||
node_id_to_def_id: &NodeMap<LocalDefId>,
|
||||
krate: &'a Crate,
|
||||
|
|
@ -936,10 +949,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
let old_contract = self.contract_ensures.take();
|
||||
|
||||
let catch_scope = self.catch_scope.take();
|
||||
let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);
|
||||
let loop_scope = self.loop_scope.take();
|
||||
let ret = f(self);
|
||||
self.catch_scope = catch_scope;
|
||||
self.try_block_scope = try_block_scope;
|
||||
self.loop_scope = loop_scope;
|
||||
|
||||
self.contract_ensures = old_contract;
|
||||
|
|
@ -1670,7 +1683,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let output = match coro {
|
||||
Some(coro) => {
|
||||
let fn_def_id = self.local_def_id(fn_node_id);
|
||||
self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
|
||||
self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)
|
||||
}
|
||||
None => match &decl.output {
|
||||
FnRetTy::Ty(ty) => {
|
||||
|
|
@ -1755,9 +1768,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn_def_id: LocalDefId,
|
||||
coro: CoroutineKind,
|
||||
fn_kind: FnDeclKind,
|
||||
fn_span: Span,
|
||||
) -> hir::FnRetTy<'hir> {
|
||||
let span = self.lower_span(fn_span);
|
||||
let span = self.lower_span(output.span());
|
||||
|
||||
let (opaque_ty_node_id, allowed_features) = match coro {
|
||||
CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ use rustc_session::Session;
|
|||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_session::lint::builtin::{
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY, UNUSED_VISIBILITIES,
|
||||
};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{Ident, Span, kw, sym};
|
||||
|
|
@ -1339,7 +1339,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
});
|
||||
}
|
||||
ItemKind::Const(box ConstItem { defaultness, rhs, .. }) => {
|
||||
ItemKind::Const(box ConstItem { defaultness, ident, rhs, .. }) => {
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
if rhs.is_none() {
|
||||
self.dcx().emit_err(errors::ConstWithoutBody {
|
||||
|
|
@ -1347,6 +1347,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
if ident.name == kw::Underscore
|
||||
&& !matches!(item.vis.kind, VisibilityKind::Inherited)
|
||||
&& ident.span.eq_ctxt(item.vis.span)
|
||||
{
|
||||
self.lint_buffer.buffer_lint(
|
||||
UNUSED_VISIBILITIES,
|
||||
item.id,
|
||||
item.vis.span,
|
||||
BuiltinLintDiag::UnusedVisibility(item.vis.span),
|
||||
)
|
||||
}
|
||||
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
ItemKind::Static(box StaticItem { expr, safety, .. }) => {
|
||||
|
|
|
|||
|
|
@ -301,17 +301,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
visit::walk_ty(self, ty)
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &'a ast::Generics) {
|
||||
for predicate in &g.where_clause.predicates {
|
||||
match &predicate.kind {
|
||||
ast::WherePredicateKind::BoundPredicate(bound_pred) => {
|
||||
// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
||||
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
fn visit_where_predicate_kind(&mut self, kind: &'a ast::WherePredicateKind) {
|
||||
if let ast::WherePredicateKind::BoundPredicate(bound) = kind {
|
||||
// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
||||
self.check_late_bound_lifetime_defs(&bound.bound_generic_params);
|
||||
}
|
||||
visit::walk_generics(self, g);
|
||||
visit::walk_where_predicate_kind(self, kind);
|
||||
}
|
||||
|
||||
fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) {
|
||||
|
|
@ -339,9 +334,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
|
||||
fn visit_expr(&mut self, e: &'a ast::Expr) {
|
||||
match e.kind {
|
||||
ast::ExprKind::TryBlock(_) => {
|
||||
ast::ExprKind::TryBlock(_, None) => {
|
||||
gate!(&self, try_blocks, e.span, "`try` expression is experimental");
|
||||
}
|
||||
ast::ExprKind::TryBlock(_, Some(_)) => {
|
||||
gate!(
|
||||
&self,
|
||||
try_blocks_heterogeneous,
|
||||
e.span,
|
||||
"`try bikeshed` expression is experimental"
|
||||
);
|
||||
}
|
||||
ast::ExprKind::Lit(token::Lit {
|
||||
kind: token::LitKind::Float | token::LitKind::Integer,
|
||||
suffix,
|
||||
|
|
|
|||
|
|
@ -818,10 +818,15 @@ impl<'a> State<'a> {
|
|||
);
|
||||
self.word("?")
|
||||
}
|
||||
ast::ExprKind::TryBlock(blk) => {
|
||||
ast::ExprKind::TryBlock(blk, opt_ty) => {
|
||||
let cb = self.cbox(0);
|
||||
let ib = self.ibox(0);
|
||||
self.word_nbsp("try");
|
||||
if let Some(ty) = opt_ty {
|
||||
self.word_nbsp("bikeshed");
|
||||
self.print_type(ty);
|
||||
self.space();
|
||||
}
|
||||
self.print_block_with_attrs(blk, attrs, cb, ib)
|
||||
}
|
||||
ast::ExprKind::UnsafeBinderCast(kind, expr, ty) => {
|
||||
|
|
|
|||
|
|
@ -14,18 +14,6 @@ attr_parsing_deprecated_item_suggestion =
|
|||
.help = add `#![feature(deprecated_suggestion)]` to the crate root
|
||||
.note = see #94785 for more details
|
||||
|
||||
attr_parsing_empty_attribute =
|
||||
unused attribute
|
||||
.suggestion = {$valid_without_list ->
|
||||
[true] remove these parentheses
|
||||
*[other] remove this attribute
|
||||
}
|
||||
.note = {$valid_without_list ->
|
||||
[true] using `{$attr_path}` with an empty list is equivalent to not using a list at all
|
||||
*[other] using `{$attr_path}` with an empty list has no effect
|
||||
}
|
||||
|
||||
|
||||
attr_parsing_empty_confusables =
|
||||
expected at least one confusable name
|
||||
attr_parsing_empty_link_name =
|
||||
|
|
@ -99,6 +87,7 @@ attr_parsing_invalid_link_modifier =
|
|||
attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr}
|
||||
.remove_neg_sugg = negative numbers are not literals, try removing the `-` sign
|
||||
.quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal
|
||||
.label = {$descr}s are not allowed here
|
||||
|
||||
attr_parsing_invalid_predicate =
|
||||
invalid predicate `{$predicate}`
|
||||
|
|
@ -119,19 +108,9 @@ attr_parsing_invalid_repr_hint_no_value =
|
|||
attr_parsing_invalid_since =
|
||||
'since' must be a Rust version number, such as "1.31.0"
|
||||
|
||||
attr_parsing_invalid_style = {$is_used_as_inner ->
|
||||
[false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]`
|
||||
*[other] the `#![{$name}]` attribute can only be used at the crate root
|
||||
}
|
||||
.note = This attribute does not have an `!`, which means it is applied to this {$target}
|
||||
|
||||
attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
|
||||
.help = `#[{$name}]` can {$only}be applied to {$applied}
|
||||
.suggestion = remove the attribute
|
||||
attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target}
|
||||
.warn = {-attr_parsing_previously_accepted}
|
||||
.help = `#[{$name}]` can {$only}be applied to {$applied}
|
||||
.suggestion = remove the attribute
|
||||
|
||||
attr_parsing_limit_invalid =
|
||||
`limit` must be a non-negative integer
|
||||
|
|
@ -250,19 +229,10 @@ attr_parsing_unsupported_literal_generic =
|
|||
attr_parsing_unsupported_literal_suggestion =
|
||||
consider removing the prefix
|
||||
|
||||
attr_parsing_unused_duplicate =
|
||||
unused attribute
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
.warn = {-attr_parsing_previously_accepted}
|
||||
|
||||
attr_parsing_unused_multiple =
|
||||
multiple `{$name}` attributes
|
||||
.suggestion = remove this attribute
|
||||
.note = attribute also specified here
|
||||
|
||||
-attr_parsing_previously_accepted =
|
||||
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
attr_parsing_whole_archive_needs_static =
|
||||
linking modifier `whole-archive` is only compatible with `static` linking kind
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ use std::convert::identity;
|
|||
|
||||
use rustc_ast::token::Delimiter;
|
||||
use rustc_ast::tokenstream::DelimSpan;
|
||||
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token};
|
||||
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template};
|
||||
use rustc_hir::attrs::CfgEntry;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_hir::{AttrPath, RustcVersion};
|
||||
use rustc_parse::parser::{ForceCollect, Parser};
|
||||
use rustc_parse::{exp, parse_in};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::ExpectedValues;
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
||||
use rustc_session::parse::{ParseSess, feature_err};
|
||||
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
|
||||
|
|
@ -23,10 +23,7 @@ use crate::session_diagnostics::{
|
|||
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
|
||||
ParsedDescription,
|
||||
};
|
||||
use crate::{
|
||||
AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics,
|
||||
try_gate_cfg,
|
||||
};
|
||||
use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics, try_gate_cfg};
|
||||
|
||||
pub const CFG_TEMPLATE: AttributeTemplate = template!(
|
||||
List: &["predicate"],
|
||||
|
|
@ -195,43 +192,46 @@ fn parse_name_value<S: Stage>(
|
|||
}
|
||||
};
|
||||
|
||||
Ok(CfgEntry::NameValue { name, name_span, value, span })
|
||||
match cx.sess.psess.check_config.expecteds.get(&name) {
|
||||
Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => cx
|
||||
.emit_lint(
|
||||
UNEXPECTED_CFGS,
|
||||
AttributeLintKind::UnexpectedCfgValue((name, name_span), value),
|
||||
span,
|
||||
),
|
||||
None if cx.sess.psess.check_config.exhaustive_names => cx.emit_lint(
|
||||
UNEXPECTED_CFGS,
|
||||
AttributeLintKind::UnexpectedCfgName((name, name_span), value),
|
||||
span,
|
||||
),
|
||||
_ => { /* not unexpected */ }
|
||||
}
|
||||
|
||||
Ok(CfgEntry::NameValue { name, value: value.map(|(v, _)| v), span })
|
||||
}
|
||||
|
||||
pub fn eval_config_entry(
|
||||
sess: &Session,
|
||||
cfg_entry: &CfgEntry,
|
||||
id: NodeId,
|
||||
emit_lints: ShouldEmit,
|
||||
) -> EvalConfigResult {
|
||||
pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResult {
|
||||
match cfg_entry {
|
||||
CfgEntry::All(subs, ..) => {
|
||||
let mut all = None;
|
||||
for sub in subs {
|
||||
let res = eval_config_entry(sess, sub, id, emit_lints);
|
||||
// We cannot short-circuit because `eval_config_entry` emits some lints
|
||||
let res = eval_config_entry(sess, sub);
|
||||
if !res.as_bool() {
|
||||
all.get_or_insert(res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
all.unwrap_or_else(|| EvalConfigResult::True)
|
||||
EvalConfigResult::True
|
||||
}
|
||||
CfgEntry::Any(subs, span) => {
|
||||
let mut any = None;
|
||||
for sub in subs {
|
||||
let res = eval_config_entry(sess, sub, id, emit_lints);
|
||||
// We cannot short-circuit because `eval_config_entry` emits some lints
|
||||
let res = eval_config_entry(sess, sub);
|
||||
if res.as_bool() {
|
||||
any.get_or_insert(res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
any.unwrap_or_else(|| EvalConfigResult::False {
|
||||
reason: cfg_entry.clone(),
|
||||
reason_span: *span,
|
||||
})
|
||||
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
|
||||
}
|
||||
CfgEntry::Not(sub, span) => {
|
||||
if eval_config_entry(sess, sub, id, emit_lints).as_bool() {
|
||||
if eval_config_entry(sess, sub).as_bool() {
|
||||
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
|
||||
} else {
|
||||
EvalConfigResult::True
|
||||
|
|
@ -244,32 +244,8 @@ pub fn eval_config_entry(
|
|||
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
|
||||
}
|
||||
}
|
||||
CfgEntry::NameValue { name, name_span, value, span } => {
|
||||
if let ShouldEmit::ErrorsAndLints = emit_lints {
|
||||
match sess.psess.check_config.expecteds.get(name) {
|
||||
Some(ExpectedValues::Some(values))
|
||||
if !values.contains(&value.map(|(v, _)| v)) =>
|
||||
{
|
||||
id.emit_span_lint(
|
||||
sess,
|
||||
UNEXPECTED_CFGS,
|
||||
*span,
|
||||
BuiltinLintDiag::UnexpectedCfgValue((*name, *name_span), *value),
|
||||
);
|
||||
}
|
||||
None if sess.psess.check_config.exhaustive_names => {
|
||||
id.emit_span_lint(
|
||||
sess,
|
||||
UNEXPECTED_CFGS,
|
||||
*span,
|
||||
BuiltinLintDiag::UnexpectedCfgName((*name, *name_span), *value),
|
||||
);
|
||||
}
|
||||
_ => { /* not unexpected */ }
|
||||
}
|
||||
}
|
||||
|
||||
if sess.psess.config.contains(&(*name, value.map(|(v, _)| v))) {
|
||||
CfgEntry::NameValue { name, value, span } => {
|
||||
if sess.psess.config.contains(&(*name, *value)) {
|
||||
EvalConfigResult::True
|
||||
} else {
|
||||
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, Nod
|
|||
use rustc_ast_pretty::pprust;
|
||||
use rustc_feature::{Features, GatedCfg, find_gated_cfg};
|
||||
use rustc_hir::RustcVersion;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::ExpectedValues;
|
||||
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
||||
|
|
@ -51,10 +52,10 @@ pub fn cfg_matches(
|
|||
sess,
|
||||
UNEXPECTED_CFGS,
|
||||
cfg.span,
|
||||
BuiltinLintDiag::UnexpectedCfgValue(
|
||||
BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgValue(
|
||||
(cfg.name, cfg.name_span),
|
||||
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
None if sess.psess.check_config.exhaustive_names => {
|
||||
|
|
@ -62,10 +63,10 @@ pub fn cfg_matches(
|
|||
sess,
|
||||
UNEXPECTED_CFGS,
|
||||
cfg.span,
|
||||
BuiltinLintDiag::UnexpectedCfgName(
|
||||
BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgName(
|
||||
(cfg.name, cfg.name_span),
|
||||
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
_ => { /* not unexpected */ }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// SingleAttributeParser which is what we have two of here.
|
||||
|
||||
use rustc_hir::attrs::{AttributeKind, InlineAttr};
|
||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
|
|
@ -56,9 +57,7 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
|
|||
}
|
||||
}
|
||||
ArgParser::NameValue(_) => {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_feature::Features;
|
|||
use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
|
||||
use rustc_hir::attrs::*;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::kw;
|
||||
use rustc_target::spec::{Arch, BinaryFormat};
|
||||
|
|
@ -71,9 +72,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
|
|||
// Specifically `#[link = "dl"]` is accepted with a FCW
|
||||
// For more information, see https://github.com/rust-lang/rust/pull/143193
|
||||
ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use rustc_errors::DiagArgValue;
|
||||
use rustc_hir::attrs::MacroUseArgs;
|
||||
use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS;
|
||||
|
||||
use super::prelude::*;
|
||||
use crate::session_diagnostics::IllFormedAttributeInputLint;
|
||||
|
|
@ -152,23 +153,13 @@ impl<S: Stage> SingleAttributeParser<S> for MacroExportParser {
|
|||
ArgParser::NoArgs => false,
|
||||
ArgParser::List(list) => {
|
||||
let Some(l) = list.single() else {
|
||||
let span = cx.attr_span;
|
||||
let suggestions = cx.suggestions();
|
||||
cx.emit_lint(
|
||||
AttributeLintKind::InvalidMacroExportArguments { suggestions },
|
||||
span,
|
||||
);
|
||||
cx.warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS);
|
||||
return None;
|
||||
};
|
||||
match l.meta_item().and_then(|i| i.path().word_sym()) {
|
||||
Some(sym::local_inner_macros) => true,
|
||||
_ => {
|
||||
let span = cx.attr_span;
|
||||
let suggestions = cx.suggestions();
|
||||
cx.emit_lint(
|
||||
AttributeLintKind::InvalidMacroExportArguments { suggestions },
|
||||
span,
|
||||
);
|
||||
cx.warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ pub(super) use rustc_feature::{AttributeTemplate, template};
|
|||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::attrs::AttributeKind;
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::lints::AttributeLintKind;
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::{MethodKind, Target};
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
pub(crate) struct IgnoreParser;
|
||||
|
|
@ -20,20 +22,13 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
|
|||
ArgParser::NoArgs => None,
|
||||
ArgParser::NameValue(name_value) => {
|
||||
let Some(str_value) = name_value.value_as_str() else {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions },
|
||||
span,
|
||||
);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
};
|
||||
Some(str_value)
|
||||
}
|
||||
ArgParser::List(_) => {
|
||||
let suggestions = cx.suggestions();
|
||||
let span = cx.attr_span;
|
||||
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
|
||||
cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use rustc_hir::attrs::AttributeKind;
|
|||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||
|
||||
use crate::AttributeParser;
|
||||
|
|
@ -381,7 +382,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
|
|||
/// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
|
||||
/// must be delayed until after HIR is built. This method will take care of the details of
|
||||
/// that.
|
||||
pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
|
||||
pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) {
|
||||
if !matches!(
|
||||
self.stage.should_emit(),
|
||||
ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true }
|
||||
|
|
@ -389,11 +390,12 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
|
|||
return;
|
||||
}
|
||||
let id = self.target_id;
|
||||
(self.emit_lint)(AttributeLint { id, span, kind: lint });
|
||||
(self.emit_lint)(AttributeLint { lint_id: LintId::of(lint), id, span, kind });
|
||||
}
|
||||
|
||||
pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
|
||||
self.emit_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
AttributeLintKind::UnusedDuplicate {
|
||||
this: unused_span,
|
||||
other: used_span,
|
||||
|
|
@ -409,6 +411,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
|
|||
unused_span: Span,
|
||||
) {
|
||||
self.emit_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
AttributeLintKind::UnusedDuplicate {
|
||||
this: unused_span,
|
||||
other: used_span,
|
||||
|
|
@ -632,14 +635,25 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
|
|||
}
|
||||
|
||||
pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
|
||||
let attr_path = self.attr_path.clone();
|
||||
let attr_path = self.attr_path.clone().to_string();
|
||||
let valid_without_list = self.template.word;
|
||||
self.emit_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list },
|
||||
span,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn warn_ill_formed_attribute_input(&mut self, lint: &'static Lint) {
|
||||
let suggestions = self.suggestions();
|
||||
let span = self.attr_span;
|
||||
self.emit_lint(
|
||||
lint,
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None },
|
||||
span,
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn suggestions(&self) -> Vec<String> {
|
||||
let style = match self.parsed_description {
|
||||
// If the outer and inner spans are equal, we are parsing an embedded attribute
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use rustc_hir::attrs::AttributeKind;
|
|||
use rustc_hir::lints::AttributeLint;
|
||||
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
|
||||
use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage};
|
||||
|
|
@ -115,7 +116,12 @@ impl<'sess> AttributeParser<'sess, Early> {
|
|||
OmitDoc::Skip,
|
||||
std::convert::identity,
|
||||
|lint| {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
sess.psess.buffer_lint(
|
||||
lint.lint_id.lint,
|
||||
lint.span,
|
||||
lint.id,
|
||||
BuiltinLintDiag::AttributeLint(lint.kind),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -183,8 +189,13 @@ impl<'sess> AttributeParser<'sess, Early> {
|
|||
sess,
|
||||
stage: Early { emit_errors },
|
||||
};
|
||||
let mut emit_lint = |lint| {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
let mut emit_lint = |lint: AttributeLint<NodeId>| {
|
||||
sess.psess.buffer_lint(
|
||||
lint.lint_id.lint,
|
||||
lint.span,
|
||||
lint.id,
|
||||
BuiltinLintDiag::AttributeLint(lint.kind),
|
||||
)
|
||||
};
|
||||
if let Some(safety) = attr_safety {
|
||||
parser.check_attribute_safety(
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ mod interface;
|
|||
/// like lists or name-value pairs.
|
||||
pub mod parser;
|
||||
|
||||
mod lints;
|
||||
mod safety;
|
||||
mod session_diagnostics;
|
||||
mod target_checking;
|
||||
|
|
@ -111,7 +110,6 @@ pub use attributes::cfg_select::*;
|
|||
pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version};
|
||||
pub use context::{Early, Late, OmitDoc, ShouldEmit};
|
||||
pub use interface::AttributeParser;
|
||||
pub use lints::emit_attribute_lint;
|
||||
pub use session_diagnostics::ParsedDescription;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
|
|
|||
|
|
@ -1,114 +0,0 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_errors::{DiagArgValue, LintEmitter};
|
||||
use rustc_hir::Target;
|
||||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::session_diagnostics;
|
||||
|
||||
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emitter: L) {
|
||||
let AttributeLint { id, span, kind } = lint;
|
||||
|
||||
match kind {
|
||||
&AttributeLintKind::UnusedDuplicate { this, other, warning } => lint_emitter
|
||||
.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::UnusedDuplicate { this, other, warning },
|
||||
),
|
||||
AttributeLintKind::IllFormedAttributeInput { suggestions } => {
|
||||
lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::IllFormedAttributeInput {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter
|
||||
.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::IllFormedAttributeInput {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
|
||||
),
|
||||
},
|
||||
),
|
||||
AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => {
|
||||
lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
*id,
|
||||
*first_span,
|
||||
session_diagnostics::EmptyAttributeList {
|
||||
attr_span: *first_span,
|
||||
attr_path: attr_path.clone(),
|
||||
valid_without_list: *valid_without_list,
|
||||
},
|
||||
)
|
||||
}
|
||||
AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter
|
||||
.emit_node_span_lint(
|
||||
// This check is here because `deprecated` had its own lint group and removing this would be a breaking change
|
||||
if name.segments[0].name == sym::deprecated
|
||||
&& ![
|
||||
Target::Closure,
|
||||
Target::Expression,
|
||||
Target::Statement,
|
||||
Target::Arm,
|
||||
Target::MacroCall,
|
||||
]
|
||||
.contains(target)
|
||||
{
|
||||
rustc_session::lint::builtin::USELESS_DEPRECATED
|
||||
} else {
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES
|
||||
},
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::InvalidTargetLint {
|
||||
name: name.clone(),
|
||||
target: target.plural_name(),
|
||||
applied: DiagArgValue::StrListSepByAnd(
|
||||
applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),
|
||||
),
|
||||
only,
|
||||
attr_span: *span,
|
||||
},
|
||||
),
|
||||
|
||||
&AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => {
|
||||
lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::InvalidAttrStyle {
|
||||
name: name.clone(),
|
||||
is_used_as_inner,
|
||||
target_span: (!is_used_as_inner).then_some(target_span),
|
||||
target,
|
||||
},
|
||||
)
|
||||
}
|
||||
&AttributeLintKind::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span,
|
||||
sugg_spans: (left, right),
|
||||
} => lint_emitter.emit_node_span_lint(
|
||||
rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE,
|
||||
*id,
|
||||
*span,
|
||||
session_diagnostics::UnsafeAttrOutsideUnsafeLint {
|
||||
span: attribute_name_span,
|
||||
suggestion: session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion { left, right },
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -8,12 +8,12 @@ use std::fmt::{Debug, Display};
|
|||
|
||||
use rustc_ast::token::{self, Delimiter, MetaVarKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path};
|
||||
use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path, StmtKind, UnOp};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Diag, PResult};
|
||||
use rustc_hir::{self as hir, AttrPath};
|
||||
use rustc_parse::exp;
|
||||
use rustc_parse::parser::{Parser, PathStyle, token_descr};
|
||||
use rustc_parse::parser::{ForceCollect, Parser, PathStyle, token_descr};
|
||||
use rustc_session::errors::{create_lit_error, report_lit_error};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym};
|
||||
|
|
@ -488,33 +488,55 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
|
|||
descr: token_descr(&self.parser.token),
|
||||
quote_ident_sugg: None,
|
||||
remove_neg_sugg: None,
|
||||
label: None,
|
||||
};
|
||||
|
||||
if let token::OpenInvisible(_) = self.parser.token.kind {
|
||||
// Do not attempt to suggest anything when encountered as part of a macro expansion.
|
||||
return self.parser.dcx().create_err(err);
|
||||
}
|
||||
|
||||
// Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and
|
||||
// don't `uninterpolate` the token to avoid suggesting anything butchered or questionable
|
||||
// when macro metavariables are involved.
|
||||
if self.parser.prev_token == token::Eq
|
||||
&& let token::Ident(..) = self.parser.token.kind
|
||||
{
|
||||
let before = self.parser.token.span.shrink_to_lo();
|
||||
while let token::Ident(..) = self.parser.token.kind {
|
||||
self.parser.bump();
|
||||
let snapshot = self.parser.create_snapshot_for_diagnostic();
|
||||
let stmt = self.parser.parse_stmt_without_recovery(false, ForceCollect::No, false);
|
||||
match stmt {
|
||||
Ok(Some(stmt)) => {
|
||||
// The user tried to write something like
|
||||
// `#[deprecated(note = concat!("a", "b"))]`.
|
||||
err.descr = stmt.kind.descr().to_string();
|
||||
err.label = Some(stmt.span);
|
||||
err.span = stmt.span;
|
||||
if let StmtKind::Expr(expr) = &stmt.kind
|
||||
&& let ExprKind::Unary(UnOp::Neg, val) = &expr.kind
|
||||
&& let ExprKind::Lit(_) = val.kind
|
||||
{
|
||||
err.remove_neg_sugg = Some(InvalidMetaItemRemoveNegSugg {
|
||||
negative_sign: expr.span.until(val.span),
|
||||
});
|
||||
} else if let StmtKind::Expr(expr) = &stmt.kind
|
||||
&& let ExprKind::Path(None, Path { segments, .. }) = &expr.kind
|
||||
&& segments.len() == 1
|
||||
{
|
||||
while let token::Ident(..) | token::Literal(_) | token::Dot =
|
||||
self.parser.token.kind
|
||||
{
|
||||
// We've got a word, so we try to consume the rest of a potential sentence.
|
||||
// We include `.` to correctly handle things like `A sentence here.`.
|
||||
self.parser.bump();
|
||||
}
|
||||
err.quote_ident_sugg = Some(InvalidMetaItemQuoteIdentSugg {
|
||||
before: expr.span.shrink_to_lo(),
|
||||
after: self.parser.prev_token.span.shrink_to_hi(),
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(None) => {}
|
||||
Err(e) => {
|
||||
e.cancel();
|
||||
self.parser.restore_snapshot(snapshot);
|
||||
}
|
||||
err.quote_ident_sugg = Some(InvalidMetaItemQuoteIdentSugg {
|
||||
before,
|
||||
after: self.parser.prev_token.span.shrink_to_hi(),
|
||||
});
|
||||
}
|
||||
|
||||
if self.parser.token == token::Minus
|
||||
&& self
|
||||
.parser
|
||||
.look_ahead(1, |t| matches!(t.kind, rustc_ast::token::TokenKind::Literal { .. }))
|
||||
{
|
||||
err.remove_neg_sugg =
|
||||
Some(InvalidMetaItemRemoveNegSugg { negative_sign: self.parser.token.span });
|
||||
self.parser.bump();
|
||||
self.parser.bump();
|
||||
}
|
||||
|
||||
self.parser.dcx().create_err(err)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ use rustc_ast::Safety;
|
|||
use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_session::lint::LintId;
|
||||
use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
use crate::context::Stage;
|
||||
|
|
@ -60,25 +62,39 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
Some(unsafe_since) => path_span.edition() >= unsafe_since,
|
||||
};
|
||||
|
||||
let mut not_from_proc_macro = true;
|
||||
if diag_span.from_expansion()
|
||||
&& let Ok(mut snippet) = self.sess.source_map().span_to_snippet(diag_span)
|
||||
{
|
||||
snippet.retain(|c| !c.is_whitespace());
|
||||
if snippet.contains("!(") || snippet.starts_with("#[") && snippet.ends_with("]")
|
||||
{
|
||||
not_from_proc_macro = false;
|
||||
}
|
||||
}
|
||||
|
||||
if emit_error {
|
||||
self.stage.emit_err(
|
||||
self.sess,
|
||||
crate::session_diagnostics::UnsafeAttrOutsideUnsafe {
|
||||
span: path_span,
|
||||
suggestion:
|
||||
suggestion: not_from_proc_macro.then(|| {
|
||||
crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion {
|
||||
left: diag_span.shrink_to_lo(),
|
||||
right: diag_span.shrink_to_hi(),
|
||||
},
|
||||
}
|
||||
}),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
emit_lint(AttributeLint {
|
||||
lint_id: LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE),
|
||||
id: target_id,
|
||||
span: path_span,
|
||||
kind: AttributeLintKind::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: path_span,
|
||||
sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
|
||||
sugg_spans: not_from_proc_macro
|
||||
.then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use rustc_errors::{
|
|||
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
|
||||
};
|
||||
use rustc_feature::AttributeTemplate;
|
||||
use rustc_hir::{AttrPath, Target};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::fluent_generated as fluent;
|
||||
|
|
@ -417,25 +417,6 @@ pub(crate) struct UnusedMultiple {
|
|||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_unused_duplicate)]
|
||||
pub(crate) struct UnusedDuplicate {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub this: Span,
|
||||
#[note]
|
||||
pub other: Span,
|
||||
#[warning]
|
||||
pub warning: bool,
|
||||
}
|
||||
|
||||
// FIXME(jdonszelmann): duplicated in rustc_lints, should be moved here completely.
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_ill_formed_attribute_input)]
|
||||
pub(crate) struct IllFormedAttributeInput {
|
||||
pub num_suggestions: usize,
|
||||
pub suggestions: DiagArgValue,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_ill_formed_attribute_input)]
|
||||
pub(crate) struct IllFormedAttributeInputLint {
|
||||
|
|
@ -501,29 +482,6 @@ pub(crate) struct EmptyConfusables {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_empty_attribute)]
|
||||
#[note]
|
||||
pub(crate) struct EmptyAttributeList {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub attr_span: Span,
|
||||
pub attr_path: AttrPath,
|
||||
pub valid_without_list: bool,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_invalid_target_lint)]
|
||||
#[warning]
|
||||
#[help]
|
||||
pub(crate) struct InvalidTargetLint {
|
||||
pub name: AttrPath,
|
||||
pub target: &'static str,
|
||||
pub applied: DiagArgValue,
|
||||
pub only: &'static str,
|
||||
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[help]
|
||||
#[diag(attr_parsing_invalid_target)]
|
||||
|
|
@ -800,16 +758,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafe {
|
|||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_unsafe_attr_outside_unsafe)]
|
||||
pub(crate) struct UnsafeAttrOutsideUnsafeLint {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
|
@ -855,6 +804,8 @@ pub(crate) struct InvalidMetaItem {
|
|||
pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>,
|
||||
#[subdiagnostic]
|
||||
pub remove_neg_sugg: Option<InvalidMetaItemRemoveNegSugg>,
|
||||
#[label]
|
||||
pub label: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
|
@ -881,16 +832,6 @@ pub(crate) struct SuffixedLiteralInAttribute {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(attr_parsing_invalid_style)]
|
||||
pub(crate) struct InvalidAttrStyle {
|
||||
pub name: AttrPath,
|
||||
pub is_used_as_inner: bool,
|
||||
#[note]
|
||||
pub target_span: Option<Span>,
|
||||
pub target: Target,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_empty_link_name, code = E0454)]
|
||||
pub(crate) struct EmptyLinkName {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use rustc_errors::DiagArgValue;
|
|||
use rustc_feature::Features;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_hir::{MethodKind, Target};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::AttributeParser;
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
|
|
@ -102,13 +103,31 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
let allowed_targets = allowed_targets.allowed_targets();
|
||||
let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
|
||||
let name = cx.attr_path.clone();
|
||||
|
||||
let lint = if name.segments[0].name == sym::deprecated
|
||||
&& ![
|
||||
Target::Closure,
|
||||
Target::Expression,
|
||||
Target::Statement,
|
||||
Target::Arm,
|
||||
Target::MacroCall,
|
||||
]
|
||||
.contains(&target)
|
||||
{
|
||||
rustc_session::lint::builtin::USELESS_DEPRECATED
|
||||
} else {
|
||||
rustc_session::lint::builtin::UNUSED_ATTRIBUTES
|
||||
};
|
||||
|
||||
let attr_span = cx.attr_span;
|
||||
cx.emit_lint(
|
||||
lint,
|
||||
AttributeLintKind::InvalidTarget {
|
||||
name,
|
||||
target,
|
||||
name: name.to_string(),
|
||||
target: target.plural_name(),
|
||||
only: if only { "only " } else { "" },
|
||||
applied,
|
||||
attr_span,
|
||||
},
|
||||
attr_span,
|
||||
);
|
||||
|
|
@ -145,15 +164,15 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
return;
|
||||
}
|
||||
|
||||
let lint = AttributeLintKind::InvalidStyle {
|
||||
name: cx.attr_path.clone(),
|
||||
let kind = AttributeLintKind::InvalidStyle {
|
||||
name: cx.attr_path.to_string(),
|
||||
is_used_as_inner: cx.attr_style == AttrStyle::Inner,
|
||||
target,
|
||||
target: target.name(),
|
||||
target_span: cx.target_span,
|
||||
};
|
||||
let attr_span = cx.attr_span;
|
||||
|
||||
cx.emit_lint(lint, attr_span);
|
||||
cx.emit_lint(rustc_session::lint::builtin::UNUSED_ATTRIBUTES, kind, attr_span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use rustc_ast::{
|
|||
use rustc_errors::{Applicability, FatalError, PResult};
|
||||
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_parse::parse_in;
|
||||
use rustc_session::errors::report_lit_error;
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
|
|
@ -202,10 +203,10 @@ fn emit_malformed_attribute(
|
|||
ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
span,
|
||||
ast::CRATE_NODE_ID,
|
||||
BuiltinLintDiag::IllFormedAttributeInput {
|
||||
BuiltinLintDiag::AttributeLint(AttributeLintKind::IllFormedAttributeInput {
|
||||
suggestions: suggestions.clone(),
|
||||
docs: template.docs,
|
||||
},
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
suggestions.sort();
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ impl<'tcx> UniverseInfo<'tcx> {
|
|||
pub(crate) fn report_erroneous_element(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
error_element: RegionElement,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
error_element: RegionElement<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
) {
|
||||
match *self {
|
||||
|
|
@ -152,8 +152,8 @@ pub(crate) trait TypeOpInfo<'tcx> {
|
|||
fn report_erroneous_element(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
error_element: RegionElement,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
error_element: RegionElement<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
) {
|
||||
let tcx = mbcx.infcx.tcx;
|
||||
|
|
@ -169,23 +169,22 @@ pub(crate) trait TypeOpInfo<'tcx> {
|
|||
|
||||
let placeholder_region = ty::Region::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
|
||||
ty::Placeholder::new(adjusted_universe.into(), placeholder.bound),
|
||||
);
|
||||
|
||||
let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
|
||||
error_element
|
||||
{
|
||||
let adjusted_universe =
|
||||
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
|
||||
adjusted_universe.map(|adjusted| {
|
||||
ty::Region::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let error_region =
|
||||
if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
|
||||
let adjusted_universe =
|
||||
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
|
||||
adjusted_universe.map(|adjusted| {
|
||||
ty::Region::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder::new(adjusted.into(), error_placeholder.bound),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
debug!(?placeholder_region);
|
||||
|
||||
|
|
@ -440,7 +439,7 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
|
|||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
region_constraints: &RegionConstraintData<'tcx>,
|
||||
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
|
||||
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin<'tcx>,
|
||||
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
|
||||
) -> Option<Diag<'a>> {
|
||||
let placeholder_universe = match placeholder_region.kind() {
|
||||
|
|
|
|||
|
|
@ -410,6 +410,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
cx.add_sized_or_copy_bound_info(err, category, &path);
|
||||
|
||||
if let ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: _,
|
||||
is_implicit_coercion: true,
|
||||
unsize_to: Some(unsize_ty),
|
||||
} = category
|
||||
|
|
|
|||
|
|
@ -109,15 +109,15 @@ pub(crate) enum RegionErrorKind<'tcx> {
|
|||
/// The placeholder free region.
|
||||
longer_fr: RegionVid,
|
||||
/// The region element that erroneously must be outlived by `longer_fr`.
|
||||
error_element: RegionElement,
|
||||
error_element: RegionElement<'tcx>,
|
||||
/// The placeholder region.
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
},
|
||||
|
||||
/// Any other lifetime error.
|
||||
RegionError {
|
||||
/// The origin of the region.
|
||||
fr_origin: NllRegionVariableOrigin,
|
||||
fr_origin: NllRegionVariableOrigin<'tcx>,
|
||||
/// The region that should outlive `shorter_fr`.
|
||||
longer_fr: RegionVid,
|
||||
/// The region that should be shorter, but we can't prove it.
|
||||
|
|
@ -427,7 +427,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
pub(crate) fn report_region_error(
|
||||
&mut self,
|
||||
fr: RegionVid,
|
||||
fr_origin: NllRegionVariableOrigin,
|
||||
fr_origin: NllRegionVariableOrigin<'tcx>,
|
||||
outlived_fr: RegionVid,
|
||||
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||
) {
|
||||
|
|
@ -541,6 +541,23 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
self.add_placeholder_from_predicate_note(&mut diag, &path);
|
||||
self.add_sized_or_copy_bound_info(&mut diag, category, &path);
|
||||
|
||||
for constraint in &path {
|
||||
if let ConstraintCategory::Cast { is_raw_ptr_dyn_type_cast: true, .. } =
|
||||
constraint.category
|
||||
{
|
||||
diag.span_note(
|
||||
constraint.span,
|
||||
format!("raw pointer casts of trait objects cannot extend lifetimes"),
|
||||
);
|
||||
diag.note(format!(
|
||||
"this was previously accepted by the compiler but was changed recently"
|
||||
));
|
||||
diag.help(format!(
|
||||
"see <https://github.com/rust-lang/rust/issues/141402> for more information"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
self.buffer_error(diag);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub(crate) struct LoweredConstraints<'tcx> {
|
|||
pub(crate) type_tests: Vec<TypeTest<'tcx>>,
|
||||
pub(crate) liveness_constraints: LivenessValues,
|
||||
pub(crate) universe_causes: FxIndexMap<UniverseIndex, UniverseInfo<'tcx>>,
|
||||
pub(crate) placeholder_indices: PlaceholderIndices,
|
||||
pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
|
||||
}
|
||||
|
||||
impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
|
||||
|
|
|
|||
|
|
@ -661,7 +661,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
|
|||
|
||||
pub(crate) fn next_region_var<F>(
|
||||
&self,
|
||||
origin: RegionVariableOrigin,
|
||||
origin: RegionVariableOrigin<'tcx>,
|
||||
get_ctxt_fn: F,
|
||||
) -> ty::Region<'tcx>
|
||||
where
|
||||
|
|
@ -683,7 +683,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
|
|||
#[instrument(skip(self, get_ctxt_fn), level = "debug")]
|
||||
pub(crate) fn next_nll_region_var<F>(
|
||||
&self,
|
||||
origin: NllRegionVariableOrigin,
|
||||
origin: NllRegionVariableOrigin<'tcx>,
|
||||
get_ctxt_fn: F,
|
||||
) -> ty::Region<'tcx>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::bit_set::SparseBitMatrix;
|
||||
use rustc_middle::mir::{Body, Location};
|
||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::relate::{
|
||||
self, Relate, RelateResult, TypeRelation, relate_args_with_variances,
|
||||
};
|
||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_mir_dataflow::points::PointIndex;
|
||||
|
||||
|
|
@ -256,6 +259,20 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for VarianceExtractor<'_, 'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn relate_ty_args(
|
||||
&mut self,
|
||||
a_ty: Ty<'tcx>,
|
||||
_: Ty<'tcx>,
|
||||
def_id: DefId,
|
||||
a_args: ty::GenericArgsRef<'tcx>,
|
||||
b_args: ty::GenericArgsRef<'tcx>,
|
||||
_: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>,
|
||||
) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
let variances = self.cx().variances_of(def_id);
|
||||
relate_args_with_variances(self, variances, a_args, b_args)?;
|
||||
Ok(a_ty)
|
||||
}
|
||||
|
||||
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
variance: ty::Variance,
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ pub struct RegionInferenceContext<'tcx> {
|
|||
/// The final inferred values of the region variables; we compute
|
||||
/// one value per SCC. To get the value for any given *region*,
|
||||
/// you first find which scc it is a part of.
|
||||
scc_values: RegionValues<ConstraintSccIndex>,
|
||||
scc_values: RegionValues<'tcx, ConstraintSccIndex>,
|
||||
|
||||
/// Type constraints that we check after solving.
|
||||
type_tests: Vec<TypeTest<'tcx>>,
|
||||
|
|
@ -125,7 +125,7 @@ pub(crate) struct RegionDefinition<'tcx> {
|
|||
/// What kind of variable is this -- a free region? existential
|
||||
/// variable? etc. (See the `NllRegionVariableOrigin` for more
|
||||
/// info.)
|
||||
pub(crate) origin: NllRegionVariableOrigin,
|
||||
pub(crate) origin: NllRegionVariableOrigin<'tcx>,
|
||||
|
||||
/// Which universe is this region variable defined in? This is
|
||||
/// most often `ty::UniverseIndex::ROOT`, but when we encounter
|
||||
|
|
@ -453,7 +453,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// Returns `true` if the region `r` contains the point `p`.
|
||||
///
|
||||
/// Panics if called before `solve()` executes,
|
||||
pub(crate) fn region_contains(&self, r: RegionVid, p: impl ToElementIndex) -> bool {
|
||||
pub(crate) fn region_contains(&self, r: RegionVid, p: impl ToElementIndex<'tcx>) -> bool {
|
||||
let scc = self.constraint_sccs.scc(r);
|
||||
self.scc_values.contains(scc, p)
|
||||
}
|
||||
|
|
@ -481,7 +481,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
pub(crate) fn placeholders_contained_in(
|
||||
&self,
|
||||
r: RegionVid,
|
||||
) -> impl Iterator<Item = ty::PlaceholderRegion> {
|
||||
) -> impl Iterator<Item = ty::PlaceholderRegion<'tcx>> {
|
||||
let scc = self.constraint_sccs.scc(r);
|
||||
self.scc_values.placeholders_contained_in(scc)
|
||||
}
|
||||
|
|
@ -1311,7 +1311,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn check_bound_universal_region(
|
||||
&self,
|
||||
longer_fr: RegionVid,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
errors_buffer: &mut RegionErrors<'tcx>,
|
||||
) {
|
||||
debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,);
|
||||
|
|
@ -1523,7 +1523,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
pub(crate) fn region_from_element(
|
||||
&self,
|
||||
longer_fr: RegionVid,
|
||||
element: &RegionElement,
|
||||
element: &RegionElement<'tcx>,
|
||||
) -> RegionVid {
|
||||
match *element {
|
||||
RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
|
||||
|
|
@ -1564,7 +1564,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
pub(crate) fn best_blame_constraint(
|
||||
&self,
|
||||
from_region: RegionVid,
|
||||
from_region_origin: NllRegionVariableOrigin,
|
||||
from_region_origin: NllRegionVariableOrigin<'tcx>,
|
||||
to_region: RegionVid,
|
||||
) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) {
|
||||
assert!(from_region != to_region, "Trying to blame a region for itself!");
|
||||
|
|
@ -1697,6 +1697,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// should be as limited as possible; the note is prone to false positives and this
|
||||
// constraint usually isn't best to blame.
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: _,
|
||||
unsize_to: Some(unsize_ty),
|
||||
is_implicit_coercion: true,
|
||||
} if to_region == self.universal_regions().fr_static
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ pub(super) struct RegionCtxt<'a, 'tcx> {
|
|||
pub(super) constraint_sccs: ConstraintSccs,
|
||||
pub(super) scc_annotations: IndexVec<ConstraintSccIndex, RegionTracker>,
|
||||
pub(super) rev_scc_graph: ReverseSccGraph,
|
||||
pub(super) scc_values: RegionValues<ConstraintSccIndex>,
|
||||
pub(super) scc_values: RegionValues<'tcx, ConstraintSccIndex>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use rustc_middle::ty::{self, RegionVid};
|
|||
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::BorrowIndex;
|
||||
use crate::polonius::LiveLoans;
|
||||
use crate::{BorrowIndex, TyCtxt};
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A single integer representing a `ty::Placeholder`.
|
||||
|
|
@ -22,7 +22,7 @@ rustc_index::newtype_index! {
|
|||
/// An individual element in a region value -- the value of a
|
||||
/// particular region variable consists of a set of these elements.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) enum RegionElement {
|
||||
pub(crate) enum RegionElement<'tcx> {
|
||||
/// A point in the control-flow graph.
|
||||
Location(Location),
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ pub(crate) enum RegionElement {
|
|||
|
||||
/// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)`
|
||||
/// type).
|
||||
PlaceholderRegion(ty::PlaceholderRegion),
|
||||
PlaceholderRegion(ty::PlaceholderRegion<'tcx>),
|
||||
}
|
||||
|
||||
/// Records the CFG locations where each region is live. When we initially compute liveness, we use
|
||||
|
|
@ -196,25 +196,28 @@ impl LivenessValues {
|
|||
/// NLL.
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Clone)] // FIXME(#146079)
|
||||
pub(crate) struct PlaceholderIndices {
|
||||
indices: FxIndexSet<ty::PlaceholderRegion>,
|
||||
pub(crate) struct PlaceholderIndices<'tcx> {
|
||||
indices: FxIndexSet<ty::PlaceholderRegion<'tcx>>,
|
||||
}
|
||||
|
||||
impl PlaceholderIndices {
|
||||
impl<'tcx> PlaceholderIndices<'tcx> {
|
||||
/// Returns the `PlaceholderIndex` for the inserted `PlaceholderRegion`
|
||||
pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
|
||||
pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion<'tcx>) -> PlaceholderIndex {
|
||||
let (index, _) = self.indices.insert_full(placeholder);
|
||||
index.into()
|
||||
}
|
||||
|
||||
pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
|
||||
pub(crate) fn lookup_index(
|
||||
&self,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
) -> PlaceholderIndex {
|
||||
self.indices.get_index_of(&placeholder).unwrap().into()
|
||||
}
|
||||
|
||||
pub(crate) fn lookup_placeholder(
|
||||
&self,
|
||||
placeholder: PlaceholderIndex,
|
||||
) -> ty::PlaceholderRegion {
|
||||
) -> ty::PlaceholderRegion<'tcx> {
|
||||
self.indices[placeholder.index()]
|
||||
}
|
||||
|
||||
|
|
@ -241,9 +244,9 @@ impl PlaceholderIndices {
|
|||
/// Here, the variable `'0` would contain the free region `'a`,
|
||||
/// because (since it is returned) it must live for at least `'a`. But
|
||||
/// it would also contain various points from within the function.
|
||||
pub(crate) struct RegionValues<N: Idx> {
|
||||
pub(crate) struct RegionValues<'tcx, N: Idx> {
|
||||
location_map: Rc<DenseLocationMap>,
|
||||
placeholder_indices: PlaceholderIndices,
|
||||
placeholder_indices: PlaceholderIndices<'tcx>,
|
||||
points: SparseIntervalMatrix<N, PointIndex>,
|
||||
free_regions: SparseBitMatrix<N, RegionVid>,
|
||||
|
||||
|
|
@ -252,14 +255,14 @@ pub(crate) struct RegionValues<N: Idx> {
|
|||
placeholders: SparseBitMatrix<N, PlaceholderIndex>,
|
||||
}
|
||||
|
||||
impl<N: Idx> RegionValues<N> {
|
||||
impl<'tcx, N: Idx> RegionValues<'tcx, N> {
|
||||
/// Creates a new set of "region values" that tracks causal information.
|
||||
/// Each of the regions in num_region_variables will be initialized with an
|
||||
/// empty set of points and no causal information.
|
||||
pub(crate) fn new(
|
||||
location_map: Rc<DenseLocationMap>,
|
||||
num_universal_regions: usize,
|
||||
placeholder_indices: PlaceholderIndices,
|
||||
placeholder_indices: PlaceholderIndices<'tcx>,
|
||||
) -> Self {
|
||||
let num_points = location_map.num_points();
|
||||
let num_placeholders = placeholder_indices.len();
|
||||
|
|
@ -274,7 +277,7 @@ impl<N: Idx> RegionValues<N> {
|
|||
|
||||
/// Adds the given element to the value for the given region. Returns whether
|
||||
/// the element is newly added (i.e., was not already present).
|
||||
pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool {
|
||||
pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex<'tcx>) -> bool {
|
||||
debug!("add(r={:?}, elem={:?})", r, elem);
|
||||
elem.add_to_row(self, r)
|
||||
}
|
||||
|
|
@ -293,7 +296,7 @@ impl<N: Idx> RegionValues<N> {
|
|||
}
|
||||
|
||||
/// Returns `true` if the region `r` contains the given element.
|
||||
pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex) -> bool {
|
||||
pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex<'tcx>) -> bool {
|
||||
elem.contained_in_row(self, r)
|
||||
}
|
||||
|
||||
|
|
@ -359,7 +362,7 @@ impl<N: Idx> RegionValues<N> {
|
|||
pub(crate) fn placeholders_contained_in(
|
||||
&self,
|
||||
r: N,
|
||||
) -> impl Iterator<Item = ty::PlaceholderRegion> {
|
||||
) -> impl Iterator<Item = ty::PlaceholderRegion<'tcx>> {
|
||||
self.placeholders
|
||||
.row(r)
|
||||
.into_iter()
|
||||
|
|
@ -368,7 +371,7 @@ impl<N: Idx> RegionValues<N> {
|
|||
}
|
||||
|
||||
/// Returns all the elements contained in a given region's value.
|
||||
pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator<Item = RegionElement> {
|
||||
pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator<Item = RegionElement<'tcx>> {
|
||||
let points_iter = self.locations_outlived_by(r).map(RegionElement::Location);
|
||||
|
||||
let free_regions_iter =
|
||||
|
|
@ -386,42 +389,50 @@ impl<N: Idx> RegionValues<N> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ToElementIndex: Debug + Copy {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool;
|
||||
pub(crate) trait ToElementIndex<'tcx>: Debug + Copy {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool;
|
||||
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool;
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<'tcx, N>, row: N) -> bool;
|
||||
}
|
||||
|
||||
impl ToElementIndex for Location {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
|
||||
impl ToElementIndex<'_> for Location {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'_, N>, row: N) -> bool {
|
||||
let index = values.location_map.point_from_location(self);
|
||||
values.points.insert(row, index)
|
||||
}
|
||||
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool {
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<'_, N>, row: N) -> bool {
|
||||
let index = values.location_map.point_from_location(self);
|
||||
values.points.contains(row, index)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToElementIndex for RegionVid {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
|
||||
impl ToElementIndex<'_> for RegionVid {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'_, N>, row: N) -> bool {
|
||||
values.free_regions.insert(row, self)
|
||||
}
|
||||
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool {
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<'_, N>, row: N) -> bool {
|
||||
values.free_regions.contains(row, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToElementIndex for ty::PlaceholderRegion {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
|
||||
let index = values.placeholder_indices.lookup_index(self);
|
||||
impl<'tcx> ToElementIndex<'tcx> for ty::PlaceholderRegion<'tcx> {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool
|
||||
where
|
||||
Self: Into<ty::Placeholder<TyCtxt<'tcx>, ty::BoundRegion>>,
|
||||
{
|
||||
let placeholder: ty::Placeholder<TyCtxt<'tcx>, ty::BoundRegion> = self.into();
|
||||
let index = values.placeholder_indices.lookup_index(placeholder);
|
||||
values.placeholders.insert(row, index)
|
||||
}
|
||||
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool {
|
||||
let index = values.placeholder_indices.lookup_index(self);
|
||||
fn contained_in_row<N: Idx>(self, values: &RegionValues<'tcx, N>, row: N) -> bool
|
||||
where
|
||||
Self: Into<ty::Placeholder<TyCtxt<'tcx>, ty::BoundRegion>>,
|
||||
{
|
||||
let placeholder: ty::Placeholder<TyCtxt<'tcx>, ty::BoundRegion> = self.into();
|
||||
let index = values.placeholder_indices.lookup_index(placeholder);
|
||||
values.placeholders.contains(row, index)
|
||||
}
|
||||
}
|
||||
|
|
@ -441,7 +452,9 @@ pub(crate) fn pretty_print_points(
|
|||
}
|
||||
|
||||
/// For debugging purposes, returns a pretty-printed string of the given region elements.
|
||||
fn pretty_print_region_elements(elements: impl IntoIterator<Item = RegionElement>) -> String {
|
||||
fn pretty_print_region_elements<'tcx>(
|
||||
elements: impl IntoIterator<Item = RegionElement<'tcx>>,
|
||||
) -> String {
|
||||
let mut result = String::new();
|
||||
result.push('{');
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
|
|||
///
|
||||
/// To keep everything in sync, do not insert this set
|
||||
/// directly. Instead, use the `placeholder_region` helper.
|
||||
pub(crate) placeholder_indices: PlaceholderIndices,
|
||||
pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
|
||||
|
||||
/// Each time we add a placeholder to `placeholder_indices`, we
|
||||
/// also create a corresponding "representative" region vid for
|
||||
|
|
@ -289,7 +289,7 @@ impl<'tcx> MirTypeckRegionConstraints<'tcx> {
|
|||
pub(crate) fn placeholder_region(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let placeholder_index = self.placeholder_indices.insert(placeholder);
|
||||
match self.placeholder_index_to_region.get(placeholder_index) {
|
||||
|
|
@ -1113,7 +1113,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
self.prove_predicate(
|
||||
ty::ClauseKind::WellFormed(src_ty.into()),
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
);
|
||||
|
||||
let src_ty = self.normalize(src_ty, location);
|
||||
|
|
@ -1121,7 +1125,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
src_ty,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
|
@ -1142,7 +1150,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
self.prove_predicate(
|
||||
ty::ClauseKind::WellFormed(src_ty.into()),
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
);
|
||||
|
||||
// The type that we see in the fcx is like
|
||||
|
|
@ -1155,7 +1167,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
src_ty,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
|
@ -1184,7 +1200,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
ty_fn_ptr_from,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
|
@ -1217,7 +1237,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
ty_fn_ptr_from,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
|
@ -1246,6 +1270,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
trait_ref,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: Some(unsize_to),
|
||||
},
|
||||
|
|
@ -1271,7 +1296,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
*ty_from,
|
||||
*ty_to,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
|
@ -1334,7 +1363,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
*ty_elem,
|
||||
*ty_to,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: None,
|
||||
},
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
|
|
@ -1491,55 +1524,90 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
trait_ref,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion: true,
|
||||
unsize_to: None,
|
||||
},
|
||||
);
|
||||
} else if let ty::Dynamic(src_tty, _src_lt) =
|
||||
} else if let ty::Dynamic(src_tty, src_lt) =
|
||||
*self.struct_tail(src.ty, location).kind()
|
||||
&& let ty::Dynamic(dst_tty, dst_lt) =
|
||||
*self.struct_tail(dst.ty, location).kind()
|
||||
&& src_tty.principal().is_some()
|
||||
&& dst_tty.principal().is_some()
|
||||
{
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on
|
||||
// both sides (aka only auto traits).
|
||||
//
|
||||
// Note that other checks (such as denying `dyn Send` -> `dyn
|
||||
// Debug`) are in `rustc_hir_typeck`.
|
||||
match (src_tty.principal(), dst_tty.principal()) {
|
||||
(Some(_), Some(_)) => {
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on
|
||||
// both sides (aka only auto traits).
|
||||
//
|
||||
// Note that other checks (such as denying `dyn Send` -> `dyn
|
||||
// Debug`) are in `rustc_hir_typeck`.
|
||||
|
||||
// Remove auto traits.
|
||||
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
|
||||
let src_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&src_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
// Remove auto traits.
|
||||
// Auto trait checks are handled in `rustc_hir_typeck`.
|
||||
let src_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&src_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
src_lt,
|
||||
);
|
||||
let dst_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
dst_lt,
|
||||
);
|
||||
|
||||
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
|
||||
|
||||
// Trait parameters are invariant, the only part that actually has
|
||||
// subtyping here is the lifetime bound of the dyn-type.
|
||||
//
|
||||
// For example in `dyn Trait<'a> + 'b <: dyn Trait<'c> + 'd` we would
|
||||
// require that `'a == 'c` but only that `'b: 'd`.
|
||||
//
|
||||
// We must not allow freely casting lifetime bounds of dyn-types as it
|
||||
// may allow for inaccessible VTable methods being callable: #136702
|
||||
self.sub_types(
|
||||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: true,
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
(None, None) => {
|
||||
// The principalless (no non-auto traits) case:
|
||||
// You can only cast `dyn Send + 'long` to `dyn Send + 'short`.
|
||||
self.constraints.outlives_constraints.push(
|
||||
OutlivesConstraint {
|
||||
sup: src_lt.as_var(),
|
||||
sub: dst_lt.as_var(),
|
||||
locations: location.to_locations(),
|
||||
span: location.to_locations().span(self.body),
|
||||
category: ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: true,
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
variance_info: ty::VarianceDiagInfo::default(),
|
||||
from_closure: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
(None, Some(_)) => bug!(
|
||||
"introducing a principal should have errored in HIR typeck"
|
||||
),
|
||||
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
|
||||
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
|
||||
dst_lt,
|
||||
);
|
||||
let dst_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
dst_lt,
|
||||
);
|
||||
|
||||
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
|
||||
|
||||
self.sub_types(
|
||||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
(Some(_), None) => {
|
||||
bug!("dropping the principal should have been an unsizing cast")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CastKind::Transmute => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::relate::{
|
||||
PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation,
|
||||
};
|
||||
|
|
@ -9,7 +10,8 @@ use rustc_infer::traits::solve::Goal;
|
|||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
|
||||
use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys};
|
||||
use rustc_middle::ty::relate::relate_args_invariantly;
|
||||
use rustc_middle::ty::{self, FnMutDelegate, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
|
|
@ -182,7 +184,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
|
|||
universe
|
||||
});
|
||||
|
||||
let placeholder = ty::PlaceholderRegion { universe, bound: br };
|
||||
let placeholder = ty::PlaceholderRegion::new(universe, br);
|
||||
debug!(?placeholder);
|
||||
let placeholder_reg = self.next_placeholder_region(placeholder);
|
||||
debug!(?placeholder_reg);
|
||||
|
|
@ -255,7 +257,10 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
|
||||
fn next_placeholder_region(
|
||||
&mut self,
|
||||
placeholder: ty::PlaceholderRegion<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let reg =
|
||||
self.type_checker.constraints.placeholder_region(self.type_checker.infcx, placeholder);
|
||||
|
||||
|
|
@ -303,6 +308,35 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
|
|||
self.type_checker.infcx.tcx
|
||||
}
|
||||
|
||||
fn relate_ty_args(
|
||||
&mut self,
|
||||
a_ty: Ty<'tcx>,
|
||||
b_ty: Ty<'tcx>,
|
||||
def_id: DefId,
|
||||
a_args: ty::GenericArgsRef<'tcx>,
|
||||
b_args: ty::GenericArgsRef<'tcx>,
|
||||
_: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>,
|
||||
) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
if self.ambient_variance == ty::Invariant {
|
||||
// Avoid fetching the variance if we are in an invariant context,
|
||||
// slightly improves perf.
|
||||
relate_args_invariantly(self, a_args, b_args)?;
|
||||
Ok(a_ty)
|
||||
} else {
|
||||
let variances = self.cx().variances_of(def_id);
|
||||
combine_ty_args(
|
||||
&self.type_checker.infcx.infcx,
|
||||
self,
|
||||
a_ty,
|
||||
b_ty,
|
||||
variances,
|
||||
a_args,
|
||||
b_args,
|
||||
|_| a_ty,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, info), level = "trace", ret)]
|
||||
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
|
|
@ -328,7 +362,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
|
|||
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
let infcx = self.type_checker.infcx;
|
||||
|
||||
let a = self.type_checker.infcx.shallow_resolve(a);
|
||||
let a = infcx.shallow_resolve(a);
|
||||
assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b);
|
||||
|
||||
if a == b {
|
||||
|
|
|
|||
|
|
@ -454,8 +454,6 @@ struct UniversalRegionsBuilder<'infcx, 'tcx> {
|
|||
mir_def: LocalDefId,
|
||||
}
|
||||
|
||||
const FR: NllRegionVariableOrigin = NllRegionVariableOrigin::FreeRegion;
|
||||
|
||||
impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
fn build(self) -> UniversalRegions<'tcx> {
|
||||
debug!("build(mir_def={:?})", self.mir_def);
|
||||
|
|
@ -466,8 +464,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars());
|
||||
|
||||
// Create the "global" region that is always free in all contexts: 'static.
|
||||
let fr_static =
|
||||
self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(kw::Static)).as_var();
|
||||
let fr_static = self
|
||||
.infcx
|
||||
.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
|
||||
RegionCtxt::Free(kw::Static)
|
||||
})
|
||||
.as_var();
|
||||
|
||||
// We've now added all the global regions. The next ones we
|
||||
// add will be external.
|
||||
|
|
@ -500,7 +502,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
debug!(?r);
|
||||
let region_vid = {
|
||||
let name = r.get_name_or_anon(self.infcx.tcx);
|
||||
self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
|
||||
self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
|
||||
RegionCtxt::LateBound(name)
|
||||
})
|
||||
};
|
||||
|
||||
debug!(?region_vid);
|
||||
|
|
@ -526,7 +530,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind);
|
||||
let region_vid = {
|
||||
let name = r.get_name_or_anon(self.infcx.tcx);
|
||||
self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
|
||||
self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
|
||||
RegionCtxt::LateBound(name)
|
||||
})
|
||||
};
|
||||
|
||||
debug!(?region_vid);
|
||||
|
|
@ -553,7 +559,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
|
||||
let reg_vid = self
|
||||
.infcx
|
||||
.next_nll_region_var(FR, || RegionCtxt::Free(sym::c_dash_variadic))
|
||||
.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
|
||||
RegionCtxt::Free(sym::c_dash_variadic)
|
||||
})
|
||||
.as_var();
|
||||
|
||||
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
|
||||
|
|
@ -569,8 +577,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let fr_fn_body =
|
||||
self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(sym::fn_body)).as_var();
|
||||
let fr_fn_body = self
|
||||
.infcx
|
||||
.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
|
||||
RegionCtxt::Free(sym::fn_body)
|
||||
})
|
||||
.as_var();
|
||||
|
||||
let num_universals = self.infcx.num_region_vars();
|
||||
|
||||
|
|
@ -613,8 +625,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
|
||||
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
|
||||
|
||||
let defining_ty =
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty);
|
||||
let defining_ty = self.infcx.replace_free_regions_with_nll_infer_vars(
|
||||
NllRegionVariableOrigin::FreeRegion,
|
||||
defining_ty,
|
||||
);
|
||||
|
||||
match *defining_ty.kind() {
|
||||
ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
|
||||
|
|
@ -638,8 +652,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
// Do not ICE when checking default_field_values consts with lifetimes (#135649)
|
||||
&& DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id))
|
||||
{
|
||||
let args =
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args);
|
||||
let args = self.infcx.replace_free_regions_with_nll_infer_vars(
|
||||
NllRegionVariableOrigin::FreeRegion,
|
||||
identity_args,
|
||||
);
|
||||
DefiningTy::Const(self.mir_def.to_def_id(), args)
|
||||
} else {
|
||||
// FIXME this line creates a dependency between borrowck and typeck.
|
||||
|
|
@ -659,7 +675,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
InlineConstArgsParts { parent_args: identity_args, ty },
|
||||
)
|
||||
.args;
|
||||
let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
|
||||
let args = self.infcx.replace_free_regions_with_nll_infer_vars(
|
||||
NllRegionVariableOrigin::FreeRegion,
|
||||
args,
|
||||
);
|
||||
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
|
||||
}
|
||||
}
|
||||
|
|
@ -856,7 +875,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
|
|||
#[instrument(skip(self), level = "debug")]
|
||||
fn replace_free_regions_with_nll_infer_vars<T>(
|
||||
&self,
|
||||
origin: NllRegionVariableOrigin,
|
||||
origin: NllRegionVariableOrigin<'tcx>,
|
||||
value: T,
|
||||
) -> T
|
||||
where
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||
| ExprKind::Path(_, _)
|
||||
| ExprKind::Ret(_)
|
||||
| ExprKind::Try(_)
|
||||
| ExprKind::TryBlock(_)
|
||||
| ExprKind::TryBlock(_, _)
|
||||
| ExprKind::Type(_, _)
|
||||
| ExprKind::Underscore
|
||||
| ExprKind::While(_, _, _)
|
||||
|
|
|
|||
|
|
@ -26,13 +26,7 @@ pub(crate) fn expand_cfg(
|
|||
|
||||
ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
|
||||
Ok(cfg) => {
|
||||
let matches_cfg = attr::eval_config_entry(
|
||||
cx.sess,
|
||||
&cfg,
|
||||
cx.current_expansion.lint_node_id,
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
)
|
||||
.as_bool();
|
||||
let matches_cfg = attr::eval_config_entry(cx.sess, &cfg).as_bool();
|
||||
|
||||
MacEager::expr(cx.expr_bool(sp, matches_cfg))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_attr_parsing::{
|
||||
CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, ShouldEmit, parse_cfg_select,
|
||||
CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, parse_cfg_select,
|
||||
};
|
||||
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
|
||||
use rustc_span::{Ident, Span, sym};
|
||||
|
|
@ -10,21 +10,13 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};
|
|||
|
||||
/// Selects the first arm whose predicate evaluates to true.
|
||||
fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
|
||||
let mut result = None;
|
||||
for (cfg, tt, arm_span) in branches.reachable {
|
||||
if let EvalConfigResult::True = attr::eval_config_entry(
|
||||
&ecx.sess,
|
||||
&cfg,
|
||||
ecx.current_expansion.lint_node_id,
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
) {
|
||||
// FIXME(#149215) Ideally we should short-circuit here, but `eval_config_entry` currently emits lints so we cannot do this yet.
|
||||
result.get_or_insert((tt, arm_span));
|
||||
if let EvalConfigResult::True = attr::eval_config_entry(&ecx.sess, &cfg) {
|
||||
return Some((tt, arm_span));
|
||||
}
|
||||
}
|
||||
|
||||
let wildcard = branches.wildcard.map(|(_, tt, span)| (tt, span));
|
||||
result.or(wildcard)
|
||||
branches.wildcard.map(|(_, tt, span)| (tt, span))
|
||||
}
|
||||
|
||||
pub(super) fn expand_cfg_select<'cx>(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
task:
|
||||
name: freebsd
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-15-0-amd64-ufs
|
||||
setup_rust_script:
|
||||
- pkg install -y git-tiny binutils
|
||||
- curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.98"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
|
||||
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
|
@ -37,48 +37,48 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.1"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-assembler-x64"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7"
|
||||
checksum = "bf7631e609c97f063f9777aae405e8492abf9bf92336d7aa3f875403dd4ffd7d"
|
||||
dependencies = [
|
||||
"cranelift-assembler-x64-meta",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-assembler-x64-meta"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830"
|
||||
checksum = "9c030edccdc4a5bbf28fbfe7701b5cd1f9854b4445184dd34af2a7e8f8db6f45"
|
||||
dependencies = [
|
||||
"cranelift-srcgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93"
|
||||
checksum = "bb544c1242d0ca98baf01873ebba96c79d5df155d5108d9bb699aefc741f5e6d"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bitset"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85"
|
||||
checksum = "f0325aecbafec053d3d3f082edfdca7937e2945e7f09c5ff9672e05198312282"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d"
|
||||
checksum = "abb3236fd319ae897ba00c8a25105081de5c1348576def0e96c062ad259f87a7"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"cranelift-assembler-x64",
|
||||
|
|
@ -102,9 +102,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca"
|
||||
checksum = "7b8791c911a361c539130ace34fb726b16aca4216470ec75d75264b1495c8a3a"
|
||||
dependencies = [
|
||||
"cranelift-assembler-x64-meta",
|
||||
"cranelift-codegen-shared",
|
||||
|
|
@ -114,33 +114,33 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2"
|
||||
checksum = "12ead718c2a10990870c19b2497b5a04b8aae6024485e33da25b5d02e35819e0"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-control"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b"
|
||||
checksum = "c0a57fc972b5651047efddccb99440d103d9d8c13393ccebde15ddd5b6a1181b"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b"
|
||||
checksum = "5aae980b4a1678b601eab2f52e372ed0b3c9565a31c17f380008cb97b3a699c5"
|
||||
dependencies = [
|
||||
"cranelift-bitset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3"
|
||||
checksum = "a78877016b607982ca1708c0dd4ce23bde04581a39854c9b43a1dca43625b54c"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
|
|
@ -150,15 +150,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688"
|
||||
checksum = "5dc46a68b46d4f53f9f2f02ab8d3a34b00f03a21c124a7a965b8cbf5fdb6773b"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d"
|
||||
checksum = "7df920009af919ad9df52eb7b47b1895145822e0c29da9b715a876fc8ecc6d82"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
|
@ -176,9 +176,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b"
|
||||
checksum = "ddcf313629071ce74de8e59f02092f5453d1a01047607fc4ad36886b8bd1486c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
|
@ -187,9 +187,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977"
|
||||
checksum = "03faa07ec8cf373250a8252eb773d098ff88259fa1c19ee1ecde8012839f4097"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
|
|
@ -198,9 +198,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf"
|
||||
checksum = "7cca62c14f3c2e4f438192562bbf82d1a98a59543cc66ba04fb658ba99f515a6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
|
@ -213,9 +213,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-srcgen"
|
||||
version = "0.125.1"
|
||||
version = "0.126.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf"
|
||||
checksum = "0484cb32c527a742e1bba09ef174acac0afb1dcf623ef1adda42849200edcd2e"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
|
|
@ -246,9 +246,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.32.0"
|
||||
version = "0.32.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe"
|
||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
||||
dependencies = [
|
||||
"fallible-iterator",
|
||||
"indexmap",
|
||||
|
|
@ -282,18 +282,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.174"
|
||||
version = "0.2.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.8"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
||||
checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.53.3",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -304,9 +304,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
|
|
@ -319,9 +319,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
|
|
@ -337,27 +337,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
version = "1.0.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regalloc2"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98"
|
||||
checksum = "4e249c660440317032a71ddac302f25f1d5dff387667bcc3978d1f77aa31ac34"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"bumpalo",
|
||||
|
|
@ -405,18 +405,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -431,15 +440,15 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.104"
|
||||
version = "2.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -448,21 +457,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
|
||||
checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-internal-jit-icache-coherence"
|
||||
version = "38.0.1"
|
||||
version = "39.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f"
|
||||
checksum = "3f67986f5c499274ae5b2ba5b173bba0b95d1381f5ca70d8eec657f2392117d8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
|
|
@ -472,9 +481,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasmtime-internal-math"
|
||||
version = "38.0.1"
|
||||
version = "39.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a"
|
||||
checksum = "a681733e9b5d5d8804ee6cacd59f92c0d87ba2274f42ee1d4e5a943828d0075d"
|
||||
dependencies = [
|
||||
"libm",
|
||||
]
|
||||
|
|
@ -485,6 +494,12 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
|
|
@ -525,7 +540,7 @@ version = "0.53.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.3",
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
|
|
|
|||
|
|
@ -8,28 +8,28 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
|
||||
cranelift-frontend = { version = "0.125.0" }
|
||||
cranelift-module = { version = "0.125.0" }
|
||||
cranelift-native = { version = "0.125.0" }
|
||||
cranelift-jit = { version = "0.125.0", optional = true }
|
||||
cranelift-object = { version = "0.125.0" }
|
||||
cranelift-codegen = { version = "0.126.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
|
||||
cranelift-frontend = { version = "0.126.0" }
|
||||
cranelift-module = { version = "0.126.0" }
|
||||
cranelift-native = { version = "0.126.0" }
|
||||
cranelift-jit = { version = "0.126.0", optional = true }
|
||||
cranelift-object = { version = "0.126.0" }
|
||||
target-lexicon = "0.13"
|
||||
gimli = { version = "0.32", default-features = false, features = ["write"] }
|
||||
object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
||||
indexmap = "2.0.0"
|
||||
libloading = { version = "0.8.0", optional = true }
|
||||
libloading = { version = "0.9.0", optional = true }
|
||||
smallvec = "1.8.1"
|
||||
|
||||
[patch.crates-io]
|
||||
# Uncomment to use an unreleased version of cranelift
|
||||
#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
|
||||
#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
|
||||
#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
|
||||
#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
|
||||
#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
|
||||
#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
|
||||
#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" }
|
||||
#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" }
|
||||
#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" }
|
||||
#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" }
|
||||
#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" }
|
||||
#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" }
|
||||
|
||||
# Uncomment to use local checkout of cranelift
|
||||
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ static ABI_CAFE_REPO: GitRepo = GitRepo::github(
|
|||
"abi-cafe",
|
||||
);
|
||||
|
||||
static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe_target");
|
||||
static ABI_CAFE: CargoProject = CargoProject::new(ABI_CAFE_REPO.source_dir(), "abi_cafe_target");
|
||||
|
||||
pub(crate) fn run(
|
||||
sysroot_kind: SysrootKind,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,26 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) {
|
|||
let rustc_clif = &compiler.rustc;
|
||||
let rustflags = &compiler.rustflags.join("\x1f");
|
||||
let manifest_path = SIMPLE_RAYTRACER_REPO.source_dir().to_path(dirs).join("Cargo.toml");
|
||||
let target_dir = dirs.build_dir.join("simple_raytracer");
|
||||
let target_dir = dirs.build_dir.join("simple-raytracer_target");
|
||||
|
||||
let raytracer_cg_llvm = dirs
|
||||
.build_dir
|
||||
.join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin"))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
let raytracer_cg_clif = dirs
|
||||
.build_dir
|
||||
.join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin"))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
let raytracer_cg_clif_opt = dirs
|
||||
.build_dir
|
||||
.join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin"))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
let clean_cmd = format!(
|
||||
"RUSTC=rustc cargo clean --manifest-path {manifest_path} --target-dir {target_dir}",
|
||||
|
|
@ -47,19 +66,19 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) {
|
|||
target_dir = target_dir.display(),
|
||||
);
|
||||
let llvm_build_cmd = format!(
|
||||
"RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_llvm || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_llvm",
|
||||
"RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_llvm} || true) && ln {target_dir}/debug/main {raytracer_cg_llvm}",
|
||||
manifest_path = manifest_path.display(),
|
||||
target_dir = target_dir.display(),
|
||||
);
|
||||
let clif_build_cmd = format!(
|
||||
"RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_clif || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_clif",
|
||||
"RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_clif} || true) && ln {target_dir}/debug/main {raytracer_cg_clif}",
|
||||
cargo_clif = cargo_clif.display(),
|
||||
rustc_clif = rustc_clif.display(),
|
||||
manifest_path = manifest_path.display(),
|
||||
target_dir = target_dir.display(),
|
||||
);
|
||||
let clif_build_opt_cmd = format!(
|
||||
"RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm build/raytracer_cg_clif_opt || true) && ln build/simple_raytracer/release/main build/raytracer_cg_clif_opt",
|
||||
"RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" CARGO_BUILD_INCREMENTAL=true {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm {raytracer_cg_clif_opt} || true) && ln {target_dir}/release/main {raytracer_cg_clif_opt}",
|
||||
cargo_clif = cargo_clif.display(),
|
||||
rustc_clif = rustc_clif.display(),
|
||||
manifest_path = manifest_path.display(),
|
||||
|
|
@ -92,20 +111,14 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) {
|
|||
|
||||
let bench_run_markdown = dirs.build_dir.join("bench_run.md");
|
||||
|
||||
let raytracer_cg_llvm =
|
||||
Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin"));
|
||||
let raytracer_cg_clif =
|
||||
Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin"));
|
||||
let raytracer_cg_clif_opt =
|
||||
Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin"));
|
||||
let mut bench_run = hyperfine_command(
|
||||
0,
|
||||
bench_runs,
|
||||
None,
|
||||
&[
|
||||
("", raytracer_cg_llvm.to_str().unwrap()),
|
||||
("", raytracer_cg_clif.to_str().unwrap()),
|
||||
("", raytracer_cg_clif_opt.to_str().unwrap()),
|
||||
("build/raytracer_cg_llvm", &raytracer_cg_llvm),
|
||||
("build/raytracer_cg_clif", &raytracer_cg_clif),
|
||||
("build/raytracer_cg_clif_opt", &raytracer_cg_clif_opt),
|
||||
],
|
||||
&bench_run_markdown,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use crate::rustc_info::get_file_name;
|
|||
use crate::shared_utils::{rustflags_from_env, rustflags_to_cmd_env};
|
||||
use crate::utils::{CargoProject, Compiler, LogGroup};
|
||||
|
||||
static CG_CLIF: CargoProject = CargoProject::new(&RelPath::source("."), "cg_clif");
|
||||
static CG_CLIF: CargoProject = CargoProject::new(RelPath::source("."), "cg_clif");
|
||||
|
||||
pub(crate) fn build_backend(
|
||||
dirs: &Dirs,
|
||||
|
|
@ -22,6 +22,11 @@ pub(crate) fn build_backend(
|
|||
rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned());
|
||||
rustflags_to_cmd_env(&mut cmd, "RUSTFLAGS", &rustflags);
|
||||
|
||||
// Use incr comp despite release mode unless incremental builds are explicitly disabled
|
||||
if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() {
|
||||
cmd.env("CARGO_BUILD_INCREMENTAL", "true");
|
||||
}
|
||||
|
||||
if env::var("CG_CLIF_EXPENSIVE_CHECKS").is_ok() {
|
||||
// Enabling debug assertions implicitly enables the clif ir verifier
|
||||
cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true");
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ impl SysrootTarget {
|
|||
|
||||
static STDLIB_SRC: RelPath = RelPath::build("stdlib");
|
||||
static STANDARD_LIBRARY: CargoProject =
|
||||
CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target");
|
||||
CargoProject::new(RelPath::build("stdlib/library/sysroot"), "stdlib_target");
|
||||
|
||||
fn build_sysroot_for_triple(
|
||||
dirs: &Dirs,
|
||||
|
|
@ -251,6 +251,10 @@ fn build_clif_sysroot_for_triple(
|
|||
if compiler.triple.contains("apple") {
|
||||
build_cmd.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed");
|
||||
}
|
||||
// Use incr comp despite release mode unless incremental builds are explicitly disabled
|
||||
if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() {
|
||||
build_cmd.env("CARGO_BUILD_INCREMENTAL", "true");
|
||||
}
|
||||
spawn_and_wait(build_cmd);
|
||||
|
||||
for entry in fs::read_dir(build_dir.join("deps")).unwrap() {
|
||||
|
|
|
|||
|
|
@ -59,11 +59,6 @@ fn main() {
|
|||
}
|
||||
env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
|
||||
|
||||
// Force incr comp even in release mode unless in CI or incremental builds are explicitly disabled
|
||||
if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() {
|
||||
env::set_var("CARGO_BUILD_INCREMENTAL", "true");
|
||||
}
|
||||
|
||||
let mut args = env::args().skip(1);
|
||||
let command = match args.next().as_deref() {
|
||||
Some("prepare") => Command::Prepare,
|
||||
|
|
@ -79,7 +74,7 @@ fn main() {
|
|||
}
|
||||
};
|
||||
|
||||
let mut out_dir = PathBuf::from(".");
|
||||
let mut out_dir = std::env::current_dir().unwrap();
|
||||
let mut download_dir = None;
|
||||
let mut sysroot_kind = SysrootKind::Clif;
|
||||
let mut use_unstable_features = true;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
|
|||
"rand",
|
||||
);
|
||||
|
||||
static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand_target");
|
||||
static RAND: CargoProject = CargoProject::new(RAND_REPO.source_dir(), "rand_target");
|
||||
|
||||
pub(crate) static REGEX_REPO: GitRepo = GitRepo::github(
|
||||
"rust-lang",
|
||||
|
|
@ -139,15 +139,15 @@ pub(crate) static REGEX_REPO: GitRepo = GitRepo::github(
|
|||
"regex",
|
||||
);
|
||||
|
||||
static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex_target");
|
||||
static REGEX: CargoProject = CargoProject::new(REGEX_REPO.source_dir(), "regex_target");
|
||||
|
||||
static PORTABLE_SIMD_SRC: RelPath = RelPath::build("portable-simd");
|
||||
|
||||
static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target");
|
||||
static PORTABLE_SIMD: CargoProject = CargoProject::new(PORTABLE_SIMD_SRC, "portable-simd_target");
|
||||
|
||||
static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests");
|
||||
|
||||
static SYSROOT_TESTS: CargoProject = CargoProject::new(&SYSROOT_TESTS_SRC, "sysroot_tests_target");
|
||||
static SYSROOT_TESTS: CargoProject = CargoProject::new(SYSROOT_TESTS_SRC, "sysroot_tests_target");
|
||||
|
||||
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
|
||||
TestCase::custom("test.rust-random/rand", &|runner| {
|
||||
|
|
|
|||
|
|
@ -75,12 +75,12 @@ impl Compiler {
|
|||
}
|
||||
|
||||
pub(crate) struct CargoProject {
|
||||
source: &'static RelPath,
|
||||
source: RelPath,
|
||||
target: &'static str,
|
||||
}
|
||||
|
||||
impl CargoProject {
|
||||
pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject {
|
||||
pub(crate) const fn new(path: RelPath, target: &'static str) -> CargoProject {
|
||||
CargoProject { source: path, target }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
From 5489384bc265e9e6fc2efaa63d93a4d51ebec2f5 Mon Sep 17 00:00:00 2001
|
||||
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
|
||||
Date: Thu, 22 Aug 2024 19:22:58 +0000
|
||||
Subject: [PATCH] Disable broken reduce_sum test
|
||||
|
||||
It was broken by an upstream change to the .sum() implementation on
|
||||
float iterators.
|
||||
---
|
||||
crates/core_simd/tests/ops_macros.rs | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
|
||||
index aa565a1..5e6ac41 100644
|
||||
--- a/crates/core_simd/tests/ops_macros.rs
|
||||
+++ b/crates/core_simd/tests/ops_macros.rs
|
||||
@@ -646,6 +646,7 @@ macro_rules! impl_float_tests {
|
||||
}
|
||||
|
||||
fn reduce_sum<const LANES: usize>() {
|
||||
+ return;
|
||||
test_helpers::test_1(&|x| {
|
||||
test_helpers::prop_assert_biteq! (
|
||||
Vector::<LANES>::from_array(x).reduce_sum(),
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2025-11-08"
|
||||
channel = "nightly-2025-12-08"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools"]
|
||||
profile = "minimal"
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ case $1 in
|
|||
|
||||
cg_clif=$(pwd)
|
||||
pushd ../rust
|
||||
git pull origin master
|
||||
git pull origin main
|
||||
branch=sync_cg_clif-$(date +%Y-%m-%d)
|
||||
git checkout -b "$branch"
|
||||
"$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main
|
||||
|
|
@ -63,7 +63,7 @@ case $1 in
|
|||
|
||||
cg_clif=$(pwd)
|
||||
pushd ../rust
|
||||
git fetch origin master
|
||||
git fetch origin main
|
||||
git -c advice.detachedHead=false checkout "$RUST_VERS"
|
||||
"$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust
|
||||
popd
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use rustc_ast::expand::allocator::{
|
|||
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
|
||||
};
|
||||
use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents};
|
||||
use rustc_session::config::OomStrategy;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
|
@ -15,16 +14,11 @@ use crate::prelude::*;
|
|||
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
|
||||
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
|
||||
let methods = allocator_shim_contents(tcx, kind);
|
||||
codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom);
|
||||
codegen_inner(tcx, module, &methods);
|
||||
true
|
||||
}
|
||||
|
||||
fn codegen_inner(
|
||||
tcx: TyCtxt<'_>,
|
||||
module: &mut dyn Module,
|
||||
methods: &[AllocatorMethod],
|
||||
oom_strategy: OomStrategy,
|
||||
) {
|
||||
fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, methods: &[AllocatorMethod]) {
|
||||
let usize_ty = module.target_config().pointer_type();
|
||||
|
||||
for method in methods {
|
||||
|
|
@ -65,35 +59,6 @@ fn codegen_inner(
|
|||
);
|
||||
}
|
||||
|
||||
{
|
||||
let sig = Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: vec![],
|
||||
returns: vec![AbiParam::new(types::I8)],
|
||||
};
|
||||
let func_id = module
|
||||
.declare_function(
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
Linkage::Export,
|
||||
&sig,
|
||||
)
|
||||
.unwrap();
|
||||
let mut ctx = Context::new();
|
||||
ctx.func.signature = sig;
|
||||
{
|
||||
let mut func_ctx = FunctionBuilderContext::new();
|
||||
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
|
||||
|
||||
let block = bcx.create_block();
|
||||
bcx.switch_to_block(block);
|
||||
let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64);
|
||||
bcx.ins().return_(&[value]);
|
||||
bcx.seal_all_blocks();
|
||||
bcx.finalize();
|
||||
}
|
||||
module.define_function(func_id, &mut ctx).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
let sig = Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
|
|
|
|||
|
|
@ -377,26 +377,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||
size.is_multiple_of(align),
|
||||
"size must be a multiple of alignment (size={size}, align={align})"
|
||||
);
|
||||
debug_assert!(align.is_power_of_two(), "alignment must be a power of two (align={align})");
|
||||
|
||||
let abi_align = if self.tcx.sess.target.arch == Arch::S390x { 8 } else { 16 };
|
||||
// Cranelift can only guarantee alignment up to the ABI alignment provided by the target.
|
||||
// If the requested alignment is less than the abi_align it can be used directly.
|
||||
if align <= abi_align {
|
||||
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of <abi_align> bytes once Cranelift gets
|
||||
// a way to specify stack slot alignment.
|
||||
size: size.div_ceil(abi_align) * abi_align,
|
||||
align_shift: 4,
|
||||
size,
|
||||
// The maximum value of ilog2 is 31 which will always fit in a u8.
|
||||
align_shift: align.ilog2().try_into().unwrap(),
|
||||
key: None,
|
||||
});
|
||||
Pointer::stack_slot(stack_slot)
|
||||
} else {
|
||||
// Alignment is too big to handle using the above hack. Dynamically realign a stack slot
|
||||
// Alignment is larger than the ABI alignment guaranteed. Dynamically realign a stack slot
|
||||
// instead. This wastes some space for the realignment.
|
||||
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of <abi_align> bytes once Cranelift gets
|
||||
// a way to specify stack slot alignment.
|
||||
size: (size + align) / abi_align * abi_align,
|
||||
align_shift: 4,
|
||||
size: size + align,
|
||||
align_shift: abi_align.ilog2().try_into().unwrap(),
|
||||
key: None,
|
||||
});
|
||||
let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0);
|
||||
let misalign_offset = self.bcx.ins().band_imm(base_ptr, i64::from(align - 1));
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::path::{Component, Path};
|
|||
|
||||
use cranelift_codegen::MachSrcLoc;
|
||||
use cranelift_codegen::binemit::CodeOffset;
|
||||
use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
|
||||
use gimli::write::{FileId, FileInfo, LineProgram, LineString, LineStringTable};
|
||||
use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene};
|
||||
|
||||
use crate::debuginfo::FunctionDebugContext;
|
||||
|
|
@ -117,8 +117,7 @@ impl DebugContext {
|
|||
}
|
||||
filename => {
|
||||
// For anonymous sources, create an empty directory instead of using the default
|
||||
let empty_dir = LineString::new(b"", line_program.encoding(), line_strings);
|
||||
let dir_id = line_program.add_directory(empty_dir);
|
||||
let dir_id = line_program.default_directory();
|
||||
|
||||
let dummy_file_name = LineString::new(
|
||||
filename.prefer_remapped_unconditionally().to_string().into_bytes(),
|
||||
|
|
@ -176,10 +175,6 @@ impl FunctionDebugContext {
|
|||
|
||||
assert_ne!(func_end, 0);
|
||||
|
||||
let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
||||
entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
|
||||
|
||||
func_end
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,14 +42,14 @@ pub(crate) struct DebugContext {
|
|||
created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>,
|
||||
stack_pointer_register: Register,
|
||||
namespace_map: DefIdMap<UnitEntryId>,
|
||||
array_size_type: UnitEntryId,
|
||||
array_size_type: Option<UnitEntryId>,
|
||||
|
||||
filename_display_preference: FileNameDisplayPreference,
|
||||
embed_source: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct FunctionDebugContext {
|
||||
entry_id: UnitEntryId,
|
||||
entry_id: Option<UnitEntryId>,
|
||||
function_source_loc: (FileId, u64, u64),
|
||||
source_loc_set: IndexSet<(FileId, u64, u64)>,
|
||||
}
|
||||
|
|
@ -154,18 +154,23 @@ impl DebugContext {
|
|||
root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0)));
|
||||
}
|
||||
|
||||
let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type);
|
||||
let array_size_type_entry = dwarf.unit.get_mut(array_size_type);
|
||||
array_size_type_entry.set(
|
||||
gimli::DW_AT_name,
|
||||
AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")),
|
||||
);
|
||||
array_size_type_entry
|
||||
.set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned));
|
||||
array_size_type_entry.set(
|
||||
gimli::DW_AT_byte_size,
|
||||
AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()),
|
||||
);
|
||||
let array_size_type = if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly {
|
||||
None
|
||||
} else {
|
||||
let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type);
|
||||
let array_size_type_entry = dwarf.unit.get_mut(array_size_type);
|
||||
array_size_type_entry.set(
|
||||
gimli::DW_AT_name,
|
||||
AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")),
|
||||
);
|
||||
array_size_type_entry
|
||||
.set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned));
|
||||
array_size_type_entry.set(
|
||||
gimli::DW_AT_byte_size,
|
||||
AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()),
|
||||
);
|
||||
Some(array_size_type)
|
||||
};
|
||||
|
||||
Some(DebugContext {
|
||||
endian,
|
||||
|
|
@ -217,6 +222,14 @@ impl DebugContext {
|
|||
) -> FunctionDebugContext {
|
||||
let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span);
|
||||
|
||||
if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly {
|
||||
return FunctionDebugContext {
|
||||
entry_id: None,
|
||||
function_source_loc: (file_id, line, column),
|
||||
source_loc_set: IndexSet::new(),
|
||||
};
|
||||
}
|
||||
|
||||
let scope = self.item_namespace(tcx, tcx.parent(instance.def_id()));
|
||||
|
||||
let mut name = String::new();
|
||||
|
|
@ -274,7 +287,7 @@ impl DebugContext {
|
|||
}
|
||||
|
||||
FunctionDebugContext {
|
||||
entry_id,
|
||||
entry_id: Some(entry_id),
|
||||
function_source_loc: (file_id, line, column),
|
||||
source_loc_set: IndexSet::new(),
|
||||
}
|
||||
|
|
@ -288,6 +301,10 @@ impl DebugContext {
|
|||
def_id: DefId,
|
||||
data_id: DataId,
|
||||
) {
|
||||
if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly {
|
||||
return;
|
||||
}
|
||||
|
||||
let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() };
|
||||
if nested {
|
||||
return;
|
||||
|
|
@ -353,10 +370,12 @@ impl FunctionDebugContext {
|
|||
.0
|
||||
.push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) });
|
||||
|
||||
let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
||||
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
|
||||
func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||
// Using Udata for DW_AT_high_pc requires at least DWARF4
|
||||
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
|
||||
if let Some(entry_id) = self.entry_id {
|
||||
let entry = debug_context.dwarf.unit.get_mut(entry_id);
|
||||
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
|
||||
entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||
// Using Udata for DW_AT_high_pc requires at least DWARF4
|
||||
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ impl DebugContext {
|
|||
|
||||
let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type);
|
||||
let subrange_entry = self.dwarf.unit.get_mut(subrange_id);
|
||||
subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type));
|
||||
subrange_entry
|
||||
.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type.unwrap()));
|
||||
subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0));
|
||||
subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
#[cfg(feature = "master")]
|
||||
use gccjit::FnAttribute;
|
||||
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
|
||||
use gccjit::{Context, FunctionType, ToRValue, Type};
|
||||
use rustc_ast::expand::allocator::{
|
||||
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
|
||||
};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::OomStrategy;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
|
||||
use crate::GccContext;
|
||||
|
|
@ -59,14 +58,6 @@ pub(crate) unsafe fn codegen(
|
|||
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
|
||||
}
|
||||
|
||||
create_const_value_function(
|
||||
tcx,
|
||||
context,
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
i8,
|
||||
context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
|
||||
);
|
||||
|
||||
create_wrapper_function(
|
||||
tcx,
|
||||
context,
|
||||
|
|
@ -77,34 +68,6 @@ pub(crate) unsafe fn codegen(
|
|||
);
|
||||
}
|
||||
|
||||
fn create_const_value_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
context: &Context<'_>,
|
||||
name: &str,
|
||||
output: Type<'_>,
|
||||
value: RValue<'_>,
|
||||
) {
|
||||
let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
{
|
||||
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
|
||||
tcx.sess.default_visibility(),
|
||||
)));
|
||||
|
||||
// FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using
|
||||
// it here will causes linking errors when using LTO.
|
||||
func.add_attribute(FnAttribute::Inline);
|
||||
}
|
||||
|
||||
if tcx.sess.must_emit_unwind_tables() {
|
||||
// TODO(antoyo): emit unwind tables.
|
||||
}
|
||||
|
||||
let block = func.new_block("entry");
|
||||
block.end_with_return(None, value);
|
||||
}
|
||||
|
||||
fn create_wrapper_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
context: &Context<'_>,
|
||||
|
|
|
|||
|
|
@ -500,11 +500,11 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
fn set_rvalue_location<'a, 'gcc, 'tcx>(
|
||||
bx: &mut Builder<'a, 'gcc, 'tcx>,
|
||||
_bx: &mut Builder<'a, 'gcc, 'tcx>,
|
||||
rvalue: RValue<'gcc>,
|
||||
) -> RValue<'gcc> {
|
||||
if let Some(location) = bx.location {
|
||||
#[cfg(feature = "master")]
|
||||
#[cfg(feature = "master")]
|
||||
if let Some(location) = _bx.location {
|
||||
rvalue.set_location(location);
|
||||
}
|
||||
rvalue
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ use rustc_middle::ty::TyCtxt;
|
|||
use rustc_middle::util::Providers;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{OptLevel, OutputFilenames};
|
||||
use rustc_session::filesearch::make_target_lib_path;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::spec::{Arch, RelocModel};
|
||||
use tempfile::TempDir;
|
||||
|
|
@ -181,18 +182,12 @@ pub struct GccCodegenBackend {
|
|||
|
||||
static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
fn libgccjit_path(sysroot_path: &Path) -> PathBuf {
|
||||
let sysroot_lib_dir = sysroot_path.join("lib");
|
||||
sysroot_lib_dir.join("libgccjit.so")
|
||||
}
|
||||
|
||||
fn load_libgccjit_if_needed(sysroot_path: &Path) {
|
||||
fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) {
|
||||
if gccjit::is_loaded() {
|
||||
// Do not load a libgccjit second time.
|
||||
return;
|
||||
}
|
||||
|
||||
let libgccjit_target_lib_file = libgccjit_path(sysroot_path);
|
||||
let path = libgccjit_target_lib_file.to_str().expect("libgccjit path");
|
||||
|
||||
let string = CString::new(path).expect("string to libgccjit path");
|
||||
|
|
@ -216,9 +211,10 @@ impl CodegenBackend for GccCodegenBackend {
|
|||
// invalid.
|
||||
// This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null.
|
||||
for path in sess.opts.sysroot.all_paths() {
|
||||
let libgccjit_target_lib_file = libgccjit_path(path);
|
||||
if let Ok(true) = fs::exists(libgccjit_target_lib_file) {
|
||||
load_libgccjit_if_needed(path);
|
||||
let libgccjit_target_lib_file =
|
||||
make_target_lib_path(path, &sess.target.llvm_target).join("libgccjit.so");
|
||||
if let Ok(true) = fs::exists(&libgccjit_target_lib_file) {
|
||||
load_libgccjit_if_needed(&libgccjit_target_lib_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{DebugInfo, OomStrategy};
|
||||
use rustc_session::config::DebugInfo;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
|
||||
use crate::attributes::llfn_attrs_from_instance;
|
||||
use crate::builder::SBuilder;
|
||||
use crate::declare::declare_simple_fn;
|
||||
use crate::llvm::{self, FALSE, FromGeneric, TRUE, Type, Value};
|
||||
use crate::llvm::{self, FromGeneric, TRUE, Type};
|
||||
use crate::{SimpleCx, attributes, debuginfo};
|
||||
|
||||
pub(crate) unsafe fn codegen(
|
||||
|
|
@ -28,7 +28,6 @@ pub(crate) unsafe fn codegen(
|
|||
64 => cx.type_i64(),
|
||||
tws => bug!("Unsupported target word size for int: {}", tws),
|
||||
};
|
||||
let i8 = cx.type_i8();
|
||||
let i8p = cx.type_ptr();
|
||||
|
||||
for method in methods {
|
||||
|
|
@ -87,17 +86,6 @@ pub(crate) unsafe fn codegen(
|
|||
);
|
||||
}
|
||||
|
||||
// __rust_alloc_error_handler_should_panic_v2
|
||||
create_const_value_function(
|
||||
tcx,
|
||||
&cx,
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
&i8,
|
||||
unsafe {
|
||||
llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, FALSE)
|
||||
},
|
||||
);
|
||||
|
||||
// __rust_no_alloc_shim_is_unstable_v2
|
||||
create_wrapper_function(
|
||||
tcx,
|
||||
|
|
@ -117,34 +105,6 @@ pub(crate) unsafe fn codegen(
|
|||
}
|
||||
}
|
||||
|
||||
fn create_const_value_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
cx: &SimpleCx<'_>,
|
||||
name: &str,
|
||||
output: &Type,
|
||||
value: &Value,
|
||||
) {
|
||||
let ty = cx.type_func(&[], output);
|
||||
let llfn = declare_simple_fn(
|
||||
&cx,
|
||||
name,
|
||||
llvm::CallConv::CCallConv,
|
||||
llvm::UnnamedAddr::Global,
|
||||
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
|
||||
ty,
|
||||
);
|
||||
|
||||
attributes::apply_to_llfn(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
&[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)],
|
||||
);
|
||||
|
||||
let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
|
||||
let mut bx = SBuilder::build(&cx, llbb);
|
||||
bx.ret(value);
|
||||
}
|
||||
|
||||
fn create_wrapper_function(
|
||||
tcx: TyCtxt<'_>,
|
||||
cx: &SimpleCx<'_>,
|
||||
|
|
|
|||
|
|
@ -257,10 +257,6 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
}
|
||||
writeln!(out).unwrap();
|
||||
}
|
||||
PrintKind::BackendHasZstd => {
|
||||
let has_zstd = llvm::LLVMRustLLVMHasZstdCompression();
|
||||
writeln!(out, "{has_zstd}").unwrap();
|
||||
}
|
||||
PrintKind::CodeModels => {
|
||||
writeln!(out, "Available code models:").unwrap();
|
||||
for name in &["tiny", "small", "kernel", "medium", "large"] {
|
||||
|
|
@ -314,6 +310,10 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
llvm_util::print_version();
|
||||
}
|
||||
|
||||
fn has_zstd(&self) -> bool {
|
||||
llvm::LLVMRustLLVMHasZstdCompression()
|
||||
}
|
||||
|
||||
fn target_config(&self, sess: &Session) -> TargetConfig {
|
||||
target_config(sess)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ use find_msvc_tools;
|
|||
use itertools::Itertools;
|
||||
use regex::Regex;
|
||||
use rustc_arena::TypedArena;
|
||||
use rustc_ast::CRATE_NODE_ID;
|
||||
use rustc_attr_parsing::{ShouldEmit, eval_config_entry};
|
||||
use rustc_attr_parsing::eval_config_entry;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||
|
|
@ -3029,9 +3028,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
|
|||
|
||||
fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
|
||||
match lib.cfg {
|
||||
Some(ref cfg) => {
|
||||
eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool()
|
||||
}
|
||||
Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use rustc_middle::middle::exported_symbols::{
|
|||
use rustc_middle::query::LocalCrate;
|
||||
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt};
|
||||
use rustc_middle::util::Providers;
|
||||
use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::spec::{Arch, Os, TlsModel};
|
||||
use tracing::debug;
|
||||
|
|
@ -493,7 +493,6 @@ pub(crate) fn allocator_shim_symbols(
|
|||
.map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
|
||||
.chain([
|
||||
mangle_internal_symbol(tcx, global_fn_name(ALLOC_ERROR_HANDLER).as_str()),
|
||||
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
|
||||
])
|
||||
.map(move |symbol_name| {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,14 @@ pub trait CodegenBackend {
|
|||
|
||||
fn print_version(&self) {}
|
||||
|
||||
/// Value printed by `--print=backend-has-zstd`.
|
||||
///
|
||||
/// Used by compiletest to determine whether tests involving zstd compression
|
||||
/// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped.
|
||||
fn has_zstd(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The metadata loader used to load rlib and dylib metadata.
|
||||
///
|
||||
/// Alternative codegen backends may want to use different rlib or dylib formats than the
|
||||
|
|
|
|||
|
|
@ -95,8 +95,10 @@ pub fn rustc_allow_const_fn_unstable(
|
|||
/// unstable features, not even recursively), and those that are not.
|
||||
pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
// A default body in a `const trait` is const-stable when the trait is const-stable.
|
||||
if tcx.is_const_default_method(def_id) {
|
||||
return is_fn_or_trait_safe_to_expose_on_stable(tcx, tcx.parent(def_id));
|
||||
if let Some(trait_id) = tcx.trait_of_assoc(def_id)
|
||||
&& tcx.is_const_trait(trait_id)
|
||||
{
|
||||
return is_fn_or_trait_safe_to_expose_on_stable(tcx, trait_id);
|
||||
}
|
||||
|
||||
match tcx.lookup_const_stability(def_id) {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(rustc::default_hash_types)]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![cfg_attr(bootstrap, feature(array_windows))]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(ascii_char)]
|
||||
#![feature(ascii_char_variants)]
|
||||
#![feature(assert_matches)]
|
||||
|
|
|
|||
|
|
@ -798,8 +798,11 @@ fn print_crate_info(
|
|||
let calling_conventions = rustc_abi::all_names();
|
||||
println_info!("{}", calling_conventions.join("\n"));
|
||||
}
|
||||
BackendHasZstd => {
|
||||
let has_zstd: bool = codegen_backend.has_zstd();
|
||||
println_info!("{has_zstd}");
|
||||
}
|
||||
RelocationModels
|
||||
| BackendHasZstd
|
||||
| CodeModels
|
||||
| TlsModels
|
||||
| TargetCPUs
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::direct_use_of_rustc_type_ir)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![feature(array_windows)]
|
||||
#![cfg_attr(bootstrap, feature(array_windows))]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(box_patterns)]
|
||||
|
|
@ -64,8 +64,8 @@ pub use rustc_error_messages::{
|
|||
fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display,
|
||||
};
|
||||
use rustc_hashes::Hash128;
|
||||
use rustc_lint_defs::LintExpectationId;
|
||||
pub use rustc_lint_defs::{Applicability, listify, pluralize};
|
||||
use rustc_lint_defs::{Lint, LintExpectationId};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
pub use rustc_span::ErrorGuaranteed;
|
||||
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
|
||||
|
|
@ -106,20 +106,6 @@ rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
|
|||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
|
||||
|
||||
/// Used to avoid depending on `rustc_middle` in `rustc_attr_parsing`.
|
||||
/// Always the `TyCtxt`.
|
||||
pub trait LintEmitter: Copy {
|
||||
type Id: Copy;
|
||||
#[track_caller]
|
||||
fn emit_node_span_lint(
|
||||
self,
|
||||
lint: &'static Lint,
|
||||
hir_id: Self::Id,
|
||||
span: impl Into<MultiSpan>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()> + DynSend + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
|
||||
pub enum SuggestionStyle {
|
||||
/// Hide the suggested code when displaying this suggestion inline.
|
||||
|
|
|
|||
|
|
@ -163,10 +163,7 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
|
|||
.iter()
|
||||
.flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
|
||||
.take_while(|attr| {
|
||||
!is_cfg(attr)
|
||||
|| strip_unconfigured
|
||||
.cfg_true(attr, strip_unconfigured.lint_node_id, ShouldEmit::Nothing)
|
||||
.as_bool()
|
||||
!is_cfg(attr) || strip_unconfigured.cfg_true(attr, ShouldEmit::Nothing).as_bool()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -309,14 +306,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||
);
|
||||
}
|
||||
|
||||
if !attr::eval_config_entry(
|
||||
self.sess,
|
||||
&cfg_predicate,
|
||||
ast::CRATE_NODE_ID,
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
)
|
||||
.as_bool()
|
||||
{
|
||||
if !attr::eval_config_entry(self.sess, &cfg_predicate).as_bool() {
|
||||
return vec![trace_attr];
|
||||
}
|
||||
|
||||
|
|
@ -400,23 +390,17 @@ impl<'a> StripUnconfigured<'a> {
|
|||
|
||||
/// Determines if a node with the given attributes should be included in this configuration.
|
||||
fn in_cfg(&self, attrs: &[Attribute]) -> bool {
|
||||
attrs.iter().all(|attr| {
|
||||
!is_cfg(attr)
|
||||
|| self.cfg_true(attr, self.lint_node_id, ShouldEmit::ErrorsAndLints).as_bool()
|
||||
})
|
||||
attrs
|
||||
.iter()
|
||||
.all(|attr| !is_cfg(attr) || self.cfg_true(attr, ShouldEmit::ErrorsAndLints).as_bool())
|
||||
}
|
||||
|
||||
pub(crate) fn cfg_true(
|
||||
&self,
|
||||
attr: &Attribute,
|
||||
node: NodeId,
|
||||
emit_errors: ShouldEmit,
|
||||
) -> EvalConfigResult {
|
||||
pub(crate) fn cfg_true(&self, attr: &Attribute, emit_errors: ShouldEmit) -> EvalConfigResult {
|
||||
let Some(cfg) = AttributeParser::parse_single(
|
||||
self.sess,
|
||||
attr,
|
||||
attr.span,
|
||||
node,
|
||||
self.lint_node_id,
|
||||
self.features,
|
||||
emit_errors,
|
||||
parse_cfg,
|
||||
|
|
@ -426,7 +410,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||
return EvalConfigResult::True;
|
||||
};
|
||||
|
||||
eval_config_entry(self.sess, &cfg, self.lint_node_id, emit_errors)
|
||||
eval_config_entry(self.sess, &cfg)
|
||||
}
|
||||
|
||||
/// If attributes are not allowed on expressions, emit an error for `attr`
|
||||
|
|
|
|||
|
|
@ -2213,7 +2213,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
attr: ast::Attribute,
|
||||
pos: usize,
|
||||
) -> EvalConfigResult {
|
||||
let res = self.cfg().cfg_true(&attr, node.node_id(), ShouldEmit::ErrorsAndLints);
|
||||
let res = self.cfg().cfg_true(&attr, ShouldEmit::ErrorsAndLints);
|
||||
if res.as_bool() {
|
||||
// A trace attribute left in AST in place of the original `cfg` attribute.
|
||||
// It can later be used by lints or other diagnostics.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![feature(array_windows)]
|
||||
#![cfg_attr(bootstrap, feature(array_windows))]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(macro_metavar_expr)]
|
||||
|
|
|
|||
|
|
@ -663,6 +663,8 @@ declare_features! (
|
|||
(unstable, trivial_bounds, "1.28.0", Some(48214)),
|
||||
/// Allows using `try {...}` expressions.
|
||||
(unstable, try_blocks, "1.29.0", Some(31436)),
|
||||
/// Allows using `try bikeshed TargetType {...}` expressions.
|
||||
(unstable, try_blocks_heterogeneous, "CURRENT_RUSTC_VERSION", Some(149488)),
|
||||
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
|
||||
(unstable, type_alias_impl_trait, "1.38.0", Some(63063)),
|
||||
/// Allows creation of instances of a struct by moving fields that have
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ use fluent_syntax::ast::{
|
|||
Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern, PatternElement,
|
||||
};
|
||||
use fluent_syntax::parser::ParserError;
|
||||
#[cfg(not(bootstrap))]
|
||||
use proc_macro::tracked::path;
|
||||
#[cfg(bootstrap)]
|
||||
use proc_macro::tracked_path::path;
|
||||
use proc_macro::{Diagnostic, Level, Span};
|
||||
use proc_macro2::TokenStream;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(rustc::default_hash_types)]
|
||||
#![cfg_attr(bootstrap, feature(track_path))]
|
||||
#![cfg_attr(not(bootstrap), feature(proc_macro_tracked_path))]
|
||||
#![feature(proc_macro_diagnostic)]
|
||||
#![feature(track_path)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ rustc_error_messages = { path = "../rustc_error_messages" }
|
|||
rustc_hashes = { path = "../rustc_hashes" }
|
||||
rustc_hir_id = { path = "../rustc_hir_id" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ pub enum CfgEntry {
|
|||
Any(ThinVec<CfgEntry>, Span),
|
||||
Not(Box<CfgEntry>, Span),
|
||||
Bool(bool, Span),
|
||||
NameValue { name: Symbol, name_span: Span, value: Option<(Symbol, Span)>, span: Span },
|
||||
NameValue { name: Symbol, value: Option<Symbol>, span: Span },
|
||||
Version(Option<RustcVersion>, Span),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
|
|||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hashes::Hash64;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_macros::{BlobDecodable, Decodable, Encodable};
|
||||
use rustc_span::{Symbol, kw, sym};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ pub struct Definitions {
|
|||
/// A unique identifier that we can use to lookup a definition
|
||||
/// precisely. It combines the index of the definition's parent (if
|
||||
/// any) with a `DisambiguatedDefPathData`.
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)]
|
||||
pub struct DefKey {
|
||||
/// The parent path.
|
||||
pub parent: Option<DefIndex>,
|
||||
|
|
@ -176,7 +176,7 @@ impl DefKey {
|
|||
/// between them. This introduces some artificial ordering dependency
|
||||
/// but means that if you have, e.g., two impls for the same type in
|
||||
/// the same module, they do get distinct `DefId`s.
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)]
|
||||
pub struct DisambiguatedDefPathData {
|
||||
pub data: DefPathData,
|
||||
pub disambiguator: u32,
|
||||
|
|
@ -270,7 +270,7 @@ impl DefPath {
|
|||
}
|
||||
|
||||
/// New variants should only be added in synchronization with `enum DefKind`.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
|
||||
pub enum DefPathData {
|
||||
// Root: these should only be used for the root nodes, because
|
||||
// they are treated specially by the `def_path` function.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
use rustc_ast::attr::AttributeExt;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic};
|
||||
use rustc_span::{Span, Symbol, kw, sym};
|
||||
|
||||
use crate::def_id::DefId;
|
||||
|
|
@ -75,7 +75,7 @@ macro_rules! language_item_table {
|
|||
$( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
|
||||
) => {
|
||||
/// A representation of all the valid lang items in Rust.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
|
||||
pub enum LangItem {
|
||||
$(
|
||||
#[doc = concat!("The `", stringify!($name), "` lang item.")]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
pub use rustc_lint_defs::AttributeLintKind;
|
||||
use rustc_lint_defs::LintId;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::{AttrPath, HirId, Target};
|
||||
use crate::HirId;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DelayedLints {
|
||||
|
|
@ -24,46 +26,8 @@ pub enum DelayedLint {
|
|||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub struct AttributeLint<Id> {
|
||||
pub lint_id: LintId,
|
||||
pub id: Id,
|
||||
pub span: Span,
|
||||
pub kind: AttributeLintKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub enum AttributeLintKind {
|
||||
/// Copy of `IllFormedAttributeInput`
|
||||
/// specifically for the `invalid_macro_export_arguments` lint until that is removed,
|
||||
/// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
|
||||
InvalidMacroExportArguments {
|
||||
suggestions: Vec<String>,
|
||||
},
|
||||
UnusedDuplicate {
|
||||
this: Span,
|
||||
other: Span,
|
||||
warning: bool,
|
||||
},
|
||||
IllFormedAttributeInput {
|
||||
suggestions: Vec<String>,
|
||||
},
|
||||
EmptyAttribute {
|
||||
first_span: Span,
|
||||
attr_path: AttrPath,
|
||||
valid_without_list: bool,
|
||||
},
|
||||
InvalidTarget {
|
||||
name: AttrPath,
|
||||
target: Target,
|
||||
applied: Vec<String>,
|
||||
only: &'static str,
|
||||
},
|
||||
InvalidStyle {
|
||||
name: AttrPath,
|
||||
is_used_as_inner: bool,
|
||||
target: Target,
|
||||
target_span: Span,
|
||||
},
|
||||
UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: Span,
|
||||
sugg_spans: (Span, Span),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::num::NonZero;
|
||||
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
|
||||
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic, PrintAttribute};
|
||||
use rustc_span::{ErrorGuaranteed, Symbol, sym};
|
||||
|
||||
use crate::RustcVersion;
|
||||
|
|
@ -21,7 +21,7 @@ pub const VERSION_PLACEHOLDER: &str = concat!("CURRENT_RUSTC_VERSIO", "N");
|
|||
///
|
||||
/// - `#[stable]`
|
||||
/// - `#[unstable]`
|
||||
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
pub struct Stability {
|
||||
pub level: StabilityLevel,
|
||||
|
|
@ -103,7 +103,7 @@ impl PartialConstStability {
|
|||
}
|
||||
|
||||
/// The available stability levels.
|
||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
pub enum StabilityLevel {
|
||||
/// `#[unstable]`
|
||||
|
|
@ -146,7 +146,7 @@ pub enum StabilityLevel {
|
|||
}
|
||||
|
||||
/// Rust release in which a feature is stabilized.
|
||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
pub enum StableSince {
|
||||
/// also stores the original symbol for printing
|
||||
|
|
@ -172,7 +172,7 @@ impl StabilityLevel {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
pub enum UnstableReason {
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ use std::sync::OnceLock;
|
|||
|
||||
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_macros::{
|
||||
Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
|
||||
BlobDecodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
|
||||
};
|
||||
|
||||
use crate::attrs::PrintAttribute;
|
||||
|
||||
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
pub struct RustcVersion {
|
||||
pub major: u16,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ itertools = "0.12"
|
|||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_arena = { path = "../rustc_arena" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
|
|
@ -21,6 +20,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
|||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_infer = { path = "../rustc_infer" }
|
||||
rustc_lint = { path = "../rustc_lint" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
|
|
|
|||
|
|
@ -590,10 +590,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
ty,
|
||||
Ty::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder {
|
||||
ty::Placeholder::new(
|
||||
universe,
|
||||
bound: ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon },
|
||||
},
|
||||
ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon },
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ struct BoundVarContext<'a, 'tcx> {
|
|||
rbv: &'a mut ResolveBoundVars,
|
||||
disambiguator: &'a mut DisambiguatorState,
|
||||
scope: ScopeRef<'a>,
|
||||
opaque_capture_errors: RefCell<Option<OpaqueHigherRankedLifetimeCaptureErrors>>,
|
||||
}
|
||||
|
||||
struct OpaqueHigherRankedLifetimeCaptureErrors {
|
||||
bad_place: &'static str,
|
||||
capture_spans: Vec<Span>,
|
||||
decl_spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -253,6 +260,7 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
|
|||
rbv: &mut rbv,
|
||||
scope: &Scope::Root { opt_parent_item: None },
|
||||
disambiguator: &mut DisambiguatorState::new(),
|
||||
opaque_capture_errors: RefCell::new(None),
|
||||
};
|
||||
match tcx.hir_owner_node(local_def_id) {
|
||||
hir::OwnerNode::Item(item) => visitor.visit_item(item),
|
||||
|
|
@ -597,6 +605,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
})
|
||||
});
|
||||
|
||||
self.emit_opaque_capture_errors();
|
||||
|
||||
let captures = captures.into_inner().into_iter().collect();
|
||||
debug!(?captures);
|
||||
self.rbv.opaque_captured_lifetimes.insert(opaque.def_id, captures);
|
||||
|
|
@ -1089,12 +1099,20 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
|
||||
{
|
||||
let BoundVarContext { tcx, rbv, disambiguator, .. } = self;
|
||||
let mut this = BoundVarContext { tcx: *tcx, rbv, disambiguator, scope: &wrap_scope };
|
||||
let nested_errors = RefCell::new(self.opaque_capture_errors.borrow_mut().take());
|
||||
let mut this = BoundVarContext {
|
||||
tcx: *tcx,
|
||||
rbv,
|
||||
disambiguator,
|
||||
scope: &wrap_scope,
|
||||
opaque_capture_errors: nested_errors,
|
||||
};
|
||||
let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
|
||||
{
|
||||
let _enter = span.enter();
|
||||
f(&mut this);
|
||||
}
|
||||
*self.opaque_capture_errors.borrow_mut() = this.opaque_capture_errors.into_inner();
|
||||
}
|
||||
|
||||
fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) {
|
||||
|
|
@ -1424,21 +1442,52 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let decl_span = self.tcx.def_span(lifetime_def_id);
|
||||
let (span, label) = if capture_span != decl_span {
|
||||
(capture_span, None)
|
||||
} else {
|
||||
let opaque_span = self.tcx.def_span(opaque_def_id);
|
||||
(opaque_span, Some(opaque_span))
|
||||
};
|
||||
let opaque_span = self.tcx.def_span(opaque_def_id);
|
||||
|
||||
let mut errors = self.opaque_capture_errors.borrow_mut();
|
||||
let error_info = errors.get_or_insert_with(|| OpaqueHigherRankedLifetimeCaptureErrors {
|
||||
bad_place,
|
||||
capture_spans: Vec::new(),
|
||||
decl_spans: Vec::new(),
|
||||
});
|
||||
|
||||
if error_info.capture_spans.is_empty() {
|
||||
error_info.capture_spans.push(opaque_span);
|
||||
}
|
||||
|
||||
if capture_span != decl_span && capture_span != opaque_span {
|
||||
error_info.capture_spans.push(capture_span);
|
||||
}
|
||||
|
||||
if !error_info.decl_spans.contains(&decl_span) {
|
||||
error_info.decl_spans.push(decl_span);
|
||||
}
|
||||
|
||||
// Errors should be emitted by `emit_opaque_capture_errors`.
|
||||
Err(self.tcx.dcx().span_delayed_bug(capture_span, "opaque capture error not emitted"))
|
||||
}
|
||||
|
||||
fn emit_opaque_capture_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
let errors = self.opaque_capture_errors.borrow_mut().take()?;
|
||||
if errors.capture_spans.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut span = rustc_errors::MultiSpan::from_span(errors.capture_spans[0]);
|
||||
for &capture_span in &errors.capture_spans[1..] {
|
||||
span.push_span_label(capture_span, "");
|
||||
}
|
||||
let decl_span = rustc_errors::MultiSpan::from_spans(errors.decl_spans);
|
||||
|
||||
// Ensure that the parent of the def is an item, not HRTB
|
||||
let guar = self.tcx.dcx().emit_err(errors::OpaqueCapturesHigherRankedLifetime {
|
||||
span,
|
||||
label,
|
||||
label: Some(errors.capture_spans[0]),
|
||||
decl_span,
|
||||
bad_place,
|
||||
bad_place: errors.bad_place,
|
||||
});
|
||||
Err(guar)
|
||||
|
||||
Some(guar)
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, opaque_capture_scopes), ret)]
|
||||
|
|
|
|||
|
|
@ -1551,11 +1551,11 @@ pub(crate) struct UnconstrainedGenericParameter {
|
|||
#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
|
||||
pub(crate) struct OpaqueCapturesHigherRankedLifetime {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub span: MultiSpan,
|
||||
#[label]
|
||||
pub label: Option<Span>,
|
||||
#[note]
|
||||
pub decl_span: Span,
|
||||
pub decl_span: MultiSpan,
|
||||
pub bad_place: &'static str,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,19 @@ pub fn provide(providers: &mut Providers) {
|
|||
fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
|
||||
match lint {
|
||||
DelayedLint::AttributeParsing(attribute_lint) => {
|
||||
rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx)
|
||||
tcx.node_span_lint(
|
||||
attribute_lint.lint_id.lint,
|
||||
attribute_lint.id,
|
||||
attribute_lint.span,
|
||||
|diag| {
|
||||
rustc_lint::decorate_attribute_lint(
|
||||
tcx.sess,
|
||||
Some(tcx),
|
||||
&attribute_lint.kind,
|
||||
diag,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2191,7 +2191,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
};
|
||||
self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys);
|
||||
} else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() {
|
||||
} else if adt_kind != AdtKind::Union
|
||||
&& !remaining_fields.is_empty()
|
||||
//~ non_exhaustive already reported, which will only happen for extern modules
|
||||
&& !variant.field_list_has_applicable_non_exhaustive()
|
||||
{
|
||||
debug!(?remaining_fields);
|
||||
let private_fields: Vec<&ty::FieldDef> = variant
|
||||
.fields
|
||||
|
|
|
|||
|
|
@ -2296,7 +2296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let suggested_name =
|
||||
find_best_match_for_name(&[field.name], pat_field.ident.name, None);
|
||||
if let Some(suggested_name) = suggested_name {
|
||||
err.span_suggestion(
|
||||
err.span_suggestion_verbose(
|
||||
pat_field.ident.span,
|
||||
"a field with a similar name exists",
|
||||
suggested_name,
|
||||
|
|
|
|||
|
|
@ -1043,7 +1043,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
lint.note("for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
|
||||
|
||||
let diagnostic_msg = format!(
|
||||
"add a dummy let to cause {migrated_variables_concat} to be fully captured"
|
||||
|
|
|
|||
|
|
@ -684,22 +684,22 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
|
||||
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderTy(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
CanonicalVarKind::PlaceholderTy(ty::Placeholder::new(
|
||||
reverse_universe_map[&placeholder.universe],
|
||||
placeholder.bound,
|
||||
))
|
||||
}
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderRegion(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
CanonicalVarKind::PlaceholderRegion(ty::Placeholder::new(
|
||||
reverse_universe_map[&placeholder.universe],
|
||||
placeholder.bound,
|
||||
))
|
||||
}
|
||||
CanonicalVarKind::PlaceholderConst(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderConst(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
CanonicalVarKind::PlaceholderConst(ty::Placeholder::new(
|
||||
reverse_universe_map[&placeholder.universe],
|
||||
placeholder.bound,
|
||||
))
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
|
|
|||
|
|
@ -109,9 +109,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
CanonicalVarKind::Float => self.next_float_var().into(),
|
||||
|
||||
CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound }) => {
|
||||
CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound, .. }) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, bound };
|
||||
let placeholder_mapped = ty::PlaceholderType::new(universe_mapped, bound);
|
||||
Ty::new_placeholder(self.tcx, placeholder_mapped).into()
|
||||
}
|
||||
|
||||
|
|
@ -119,18 +119,22 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
.next_region_var_in_universe(RegionVariableOrigin::Misc(span), universe_map(ui))
|
||||
.into(),
|
||||
|
||||
CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, bound }) => {
|
||||
CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion {
|
||||
universe, bound, ..
|
||||
}) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, bound };
|
||||
let placeholder_mapped = ty::PlaceholderRegion::new(universe_mapped, bound);
|
||||
ty::Region::new_placeholder(self.tcx, placeholder_mapped).into()
|
||||
}
|
||||
|
||||
CanonicalVarKind::Const(ui) => {
|
||||
self.next_const_var_in_universe(span, universe_map(ui)).into()
|
||||
}
|
||||
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => {
|
||||
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst {
|
||||
universe, bound, ..
|
||||
}) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound };
|
||||
let placeholder_mapped = ty::PlaceholderConst::new(universe_mapped, bound);
|
||||
ty::Const::new_placeholder(self.tcx, placeholder_mapped).into()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
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