diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dfaa70bb9db00..eeff563d8ecdf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,7 +15,7 @@ standard library in the [Standard library developers Guide][std-dev-guide], comm
## About the [rustc-dev-guide]
The [rustc-dev-guide] is meant to help document how rustc –the Rust compiler– works,
-as well as to help new contributors get involved in rustc development. It is recommend
+as well as to help new contributors get involved in rustc development. It is recommended
to read and understand the [rustc-dev-guide] before making a contribution. This guide
talks about the different bots in the Rust ecosystem, the Rust development tools,
bootstrapping, the compiler architecture, source code representation, and more.
diff --git a/Cargo.lock b/Cargo.lock
index da8ef2bf3bd3c..9fe70870140d8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -553,7 +553,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "clippy"
-version = "0.1.75"
+version = "0.1.76"
dependencies = [
"anstream",
"clippy_config",
@@ -581,7 +581,7 @@ dependencies = [
[[package]]
name = "clippy_config"
-version = "0.1.75"
+version = "0.1.76"
dependencies = [
"rustc-semver",
"serde",
@@ -604,14 +604,13 @@ dependencies = [
[[package]]
name = "clippy_lints"
-version = "0.1.75"
+version = "0.1.76"
dependencies = [
"arrayvec",
"cargo_metadata 0.15.4",
"clippy_config",
"clippy_utils",
"declare_clippy_lint",
- "if_chain",
"itertools",
"quine-mc_cluskey",
"regex",
@@ -630,11 +629,10 @@ dependencies = [
[[package]]
name = "clippy_utils"
-version = "0.1.75"
+version = "0.1.76"
dependencies = [
"arrayvec",
"clippy_config",
- "if_chain",
"itertools",
"rustc-semver",
]
@@ -1016,7 +1014,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
[[package]]
name = "declare_clippy_lint"
-version = "0.1.75"
+version = "0.1.76"
dependencies = [
"itertools",
"quote",
@@ -3817,6 +3815,7 @@ dependencies = [
"rustc_query_system",
"rustc_resolve",
"rustc_session",
+ "rustc_smir",
"rustc_span",
"rustc_symbol_mangling",
"rustc_target",
@@ -4191,7 +4190,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 2.0.29",
- "synstructure 0.13.0",
+ "synstructure",
]
[[package]]
@@ -5233,18 +5232,6 @@ dependencies = [
"unicode-ident",
]
-[[package]]
-name = "synstructure"
-version = "0.12.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "unicode-xid",
-]
-
[[package]]
name = "synstructure"
version = "0.13.0"
@@ -6386,35 +6373,35 @@ dependencies = [
[[package]]
name = "yoke-derive"
-version = "0.7.1"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af46c169923ed7516eef0aa32b56d2651b229f57458ebe46b49ddd6efef5b7a2"
+checksum = "d5e19fb6ed40002bab5403ffa37e53e0e56f914a4450c8765f533018db1db35f"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
- "synstructure 0.12.6",
+ "syn 2.0.29",
+ "synstructure",
]
[[package]]
name = "zerofrom"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df54d76c3251de27615dfcce21e636c172dafb2549cd7fd93e21c66f6ca6bea2"
+checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4eae7c1f7d4b8eafce526bc0771449ddc2f250881ae31c50d22c032b5a1c499"
+checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
- "synstructure 0.12.6",
+ "syn 2.0.29",
+ "synstructure",
]
[[package]]
@@ -6430,14 +6417,13 @@ dependencies = [
[[package]]
name = "zerovec-derive"
-version = "0.9.4"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "486558732d5dde10d0f8cb2936507c1bb21bc539d924c949baf5f36a58e51bac"
+checksum = "acabf549809064225ff8878baedc4ce3732ac3b07e7c7ce6e5c2ccdbc485c324"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
- "synstructure 0.12.6",
+ "syn 2.0.29",
]
[[package]]
diff --git a/RELEASES.md b/RELEASES.md
index 1cc110e6607f9..9de9eb67bba1b 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,120 @@
+Version 1.74.0 (2023-11-16)
+==========================
+
+
+
+Language
+--------
+
+- [Codify that `std::mem::Discriminant` does not depend on any lifetimes in T](https://github.com/rust-lang/rust/pull/104299/)
+- [Replace `private_in_public` lint with `private_interfaces` and `private_bounds` per RFC 2145.](https://github.com/rust-lang/rust/pull/113126/)
+ Read more in [RFC 2145](https://rust-lang.github.io/rfcs/2145-type-privacy.html).
+- [Allow explicit `#[repr(Rust)]`](https://github.com/rust-lang/rust/pull/114201/)
+- [closure field capturing: don't depend on alignment of packed fields](https://github.com/rust-lang/rust/pull/115315/)
+- [Enable MIR-based drop-tracking for `async` blocks](https://github.com/rust-lang/rust/pull/107421/)
+- [Stabilize `impl_trait_projections`](https://github.com/rust-lang/rust/pull/115659)
+
+
+
+Compiler
+--------
+
+- [stabilize combining +bundle and +whole-archive link modifiers](https://github.com/rust-lang/rust/pull/113301/)
+- [Stabilize `PATH` option for `--print KIND=PATH`](https://github.com/rust-lang/rust/pull/114183/)
+- [Enable ASAN/LSAN/TSAN for `*-apple-ios-macabi`](https://github.com/rust-lang/rust/pull/115644/)
+- [Promote loongarch64-unknown-none* to Tier 2](https://github.com/rust-lang/rust/pull/115368/)
+- [Add `i686-pc-windows-gnullvm` as a tier 3 target](https://github.com/rust-lang/rust/pull/115687/)
+
+
+
+Libraries
+---------
+
+- [Implement `From` for ChildStdin/out/err](https://github.com/rust-lang/rust/pull/98704/)
+- [Implement `From<{&,&mut} [T; N]>` for `Vec` where `T: Clone`](https://github.com/rust-lang/rust/pull/111278/)
+- [impl Step for IP addresses](https://github.com/rust-lang/rust/pull/113748/)
+- [Implement `From<[T; N]>` for `Rc<[T]>` and `Arc<[T]>`](https://github.com/rust-lang/rust/pull/114041/)
+- [`impl TryFrom for u16`](https://github.com/rust-lang/rust/pull/114065/)
+- [Stabilize `io_error_other` feature](https://github.com/rust-lang/rust/pull/115453/)
+- [Stabilize the `Saturating` type](https://github.com/rust-lang/rust/pull/115477/)
+- [Stabilize const_transmute_copy](https://github.com/rust-lang/rust/pull/115520/)
+
+
+
+Stabilized APIs
+---------------
+
+- [`core::num::Saturating`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html)
+- [`impl From for std::process::Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStdout%3E-for-Stdio)
+- [`impl From for std::process::Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStderr%3E-for-Stdio)
+- [`impl From for std::process::Child{Stdin, Stdout, Stderr}`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStderr%3E-for-Stdio)
+- [`impl From for std::process::Child{Stdin, Stdout, Stderr}`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStderr%3E-for-Stdio)
+- [`std::ffi::OsString::from_encoded_bytes_unchecked`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.from_encoded_bytes_unchecked)
+- [`std::ffi::OsString::into_encoded_bytes`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.into_encoded_bytes)
+- [`std::ffi::OsStr::from_encoded_bytes_unchecked`](https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.from_encoded_bytes_unchecked)
+- [`std::ffi::OsStr::as_encoded_bytes`](https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.as_encoded_bytes)
+- [`std::io::Error::other`](https://doc.rust-lang.org/stable/std/io/struct.Error.html#method.other)
+- [`impl TryFrom for u16`](https://doc.rust-lang.org/stable/std/primitive.u16.html#impl-TryFrom%3Cchar%3E-for-u16)
+- [`impl From<&[T; N]> for Vec`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#impl-From%3C%26%5BT;+N%5D%3E-for-Vec%3CT,+Global%3E)
+- [`impl From<&mut [T; N]> for Vec`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#impl-From%3C%26mut+%5BT;+N%5D%3E-for-Vec%3CT,+Global%3E)
+- [`impl From<[T; N]> for Arc<[T]>`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#impl-From%3C%5BT;+N%5D%3E-for-Arc%3C%5BT%5D,+Global%3E)
+- [`impl From<[T; N]> for Rc<[T]>`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#impl-From%3C%5BT;+N%5D%3E-for-Rc%3C%5BT%5D,+Global%3E)
+
+These APIs are now stable in const contexts:
+
+- [`core::mem::transmute_copy`](https://doc.rust-lang.org/beta/std/mem/fn.transmute_copy.html)
+- [`str::is_ascii`](https://doc.rust-lang.org/beta/std/primitive.str.html#method.is_ascii)
+- [`[u8]::is_ascii`](https://doc.rust-lang.org/beta/std/primitive.slice.html#method.is_ascii)
+
+
+
+Cargo
+-----
+
+- [In `Cargo.toml`, stabilize `[lints]`](https://github.com/rust-lang/cargo/pull/12648/)
+- [Stabilize credential-process and registry-auth](https://github.com/rust-lang/cargo/pull/12649/)
+- [Stabilize `--keep-going` build flag](https://github.com/rust-lang/cargo/pull/12568/)
+- [Add styling to `--help` output](https://github.com/rust-lang/cargo/pull/12578/)
+- [For `cargo clean`, add `--dry-run` flag and summary line at the end](https://github.com/rust-lang/cargo/pull/12638)
+- [For `cargo update`, make `--package` more convenient by being positional](https://github.com/rust-lang/cargo/pull/12545/)
+- [For `cargo update`, clarify meaning of --aggressive as --recursive](https://github.com/rust-lang/cargo/pull/12544/)
+- [Add '-n' as an alias for `--dry-run`](https://github.com/rust-lang/cargo/pull/12660/)
+- [Allow version-prefixes in pkgid's (e.g. `--package` flags) to resolve ambiguities](https://github.com/rust-lang/cargo/pull/12614/)
+- [In `.cargo/config.toml`, merge lists in precedence order](https://github.com/rust-lang/cargo/pull/12515/)
+- [Add support for `target.'cfg(..)'.linker`](https://github.com/rust-lang/cargo/pull/12535/)
+
+
+
+Rustdoc
+-------
+
+- [Add warning block support in rustdoc](https://github.com/rust-lang/rust/pull/106561/)
+- [Accept additional user-defined syntax classes in fenced code blocks](https://github.com/rust-lang/rust/pull/110800/)
+- [rustdoc-search: add support for type parameters](https://github.com/rust-lang/rust/pull/112725/)
+- [rustdoc: show inner enum and struct in type definition for concrete type](https://github.com/rust-lang/rust/pull/114855/)
+
+
+
+Compatibility Notes
+-------------------
+
+- [Raise minimum supported Apple OS versions](https://github.com/rust-lang/rust/pull/104385/)
+- [make Cell::swap panic if the Cells partially overlap](https://github.com/rust-lang/rust/pull/114795/)
+- [Reject invalid crate names in `--extern`](https://github.com/rust-lang/rust/pull/116001/)
+- [Don't resolve generic impls that may be shadowed by dyn built-in impls](https://github.com/rust-lang/rust/pull/114941/)
+- [The new `impl From<{&,&mut} [T; N]> for Vec` is known to cause some inference failures with overly-generic code.](https://github.com/rust-lang/rust/issues/117054) In those examples using the `tui` crate, the combination of `AsRef<_>` and `Into` leaves the middle type ambiguous, and the new `impl` adds another possibility, so it now requires an explicit type annotation.
+
+
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+None this cycle.
+
Version 1.73.0 (2023-10-05)
==========================
@@ -83,7 +200,6 @@ These APIs are now stable in const contexts:
Cargo
-----
-- [Encode URL params correctly for `SourceId` in `Cargo.lock`.](https://github.com/rust-lang/cargo/pull/12280/)
- [Bail out an error when using `cargo::` in custom build script.](https://github.com/rust-lang/cargo/pull/12332/)
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 09a87cf8e2f09..eb42803f93e4e 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1,7 +1,7 @@
#![cfg_attr(feature = "nightly", feature(step_trait))]
#![cfg_attr(feature = "nightly", allow(internal_features))]
-#![cfg_attr(all(not(bootstrap), feature = "nightly"), doc(rust_logo))]
-#![cfg_attr(all(not(bootstrap), feature = "nightly"), feature(rustdoc_internals))]
+#![cfg_attr(feature = "nightly", doc(rust_logo))]
+#![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
use std::fmt;
use std::num::{NonZeroUsize, ParseIntError};
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index a53fd4ae95a5d..bd35364509a26 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -11,8 +11,8 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(no_crate_inject, attr(deny(warnings)))
)]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(new_uninit)]
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index c1f6ad6a27db0..34303cbbc9a18 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -8,9 +8,9 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(deny(warnings)))
)]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(const_trait_impl)]
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 914c97a14ac0d..707238e6c0275 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -238,9 +238,9 @@ pub enum TokenKind {
EqEq,
/// `!=`
Ne,
- /// `>`
- Ge,
/// `>=`
+ Ge,
+ /// `>`
Gt,
/// `&&`
AndAnd,
@@ -388,7 +388,8 @@ impl TokenKind {
match *self {
Comma => Some(vec![Dot, Lt, Semi]),
Semi => Some(vec![Colon, Comma]),
- FatArrow => Some(vec![Eq, RArrow]),
+ Colon => Some(vec![Semi]),
+ FatArrow => Some(vec![Eq, RArrow, Ge, Gt]),
_ => None,
}
}
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 0fff9a6be926d..c07dbbc9d67ed 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -792,8 +792,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
// debuggers and debugger extensions expect it to be called `__awaitee`. They use
// this name to identify what is being awaited by a suspended async functions.
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
- let (awaitee_pat, awaitee_pat_hid) =
- self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::MUT);
+ let (awaitee_pat, awaitee_pat_hid) = self.pat_ident_binding_mode(
+ gen_future_span,
+ awaitee_ident,
+ hir::BindingAnnotation::MUT,
+ );
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index a88493acf982f..b8e18d3434a17 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -30,9 +30,9 @@
//! get confused if the spans from leaf AST nodes occur in multiple places
//! in the HIR, especially for multiple identifiers.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(let_chains)]
#![feature(never_type)]
@@ -443,11 +443,6 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
drop(ast_index);
sess.time("drop_ast", || drop(krate));
- // Discard hygiene data, which isn't required after lowering to HIR.
- if !sess.opts.unstable_opts.keep_hygiene_data {
- rustc_span::hygiene::clear_syntax_context_map();
- }
-
// Don't hash unless necessary, because it's expensive.
let opt_hir_hash =
if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index d22bae816ef41..876126b02ea95 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -218,9 +218,12 @@ ast_passes_static_without_body =
.suggestion = provide a definition for the static
ast_passes_tilde_const_disallowed = `~const` is not allowed here
- .trait = trait objects cannot have `~const` trait bounds
.closure = closures cannot have `~const` trait bounds
.function = this function is not `const`, so it cannot have `~const` trait bounds
+ .trait = this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
+ .impl = this impl is not `const`, so it cannot have `~const` trait bounds
+ .object = trait objects cannot have `~const` trait bounds
+ .item = this item cannot have `~const` trait bounds
ast_passes_trait_fn_const =
functions in traits cannot be declared const
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 3d0513c89230d..f73d791db49eb 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -40,6 +40,9 @@ enum SelfSemantic {
enum DisallowTildeConstContext<'a> {
TraitObject,
Fn(FnKind<'a>),
+ Trait(Span),
+ Impl(Span),
+ Item,
}
struct AstValidator<'a> {
@@ -110,18 +113,6 @@ impl<'a> AstValidator<'a> {
self.disallow_tilde_const = old;
}
- fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
- self.with_tilde_const(None, f)
- }
-
- fn with_banned_tilde_const(
- &mut self,
- ctx: DisallowTildeConstContext<'a>,
- f: impl FnOnce(&mut Self),
- ) {
- self.with_tilde_const(Some(ctx), f)
- }
-
fn check_type_alias_where_clause_location(
&mut self,
ty_alias: &TyAlias,
@@ -173,7 +164,7 @@ impl<'a> AstValidator<'a> {
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
}
TyKind::TraitObject(..) => self
- .with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
+ .with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {
visit::walk_ty(this, t)
}),
TyKind::Path(qself, path) => {
@@ -845,11 +836,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
this.visit_vis(&item.vis);
this.visit_ident(item.ident);
- if let Const::Yes(_) = constness {
- this.with_tilde_const_allowed(|this| this.visit_generics(generics));
- } else {
- this.visit_generics(generics);
- }
+ let disallowed = matches!(constness, Const::No)
+ .then(|| DisallowTildeConstContext::Impl(item.span));
+ this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
this.visit_trait_ref(t);
this.visit_ty(self_ty);
@@ -863,10 +852,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
polarity,
defaultness,
constness,
- generics: _,
+ generics,
of_trait: None,
self_ty,
- items: _,
+ items,
}) => {
let error =
|annotation_span, annotation, only_trait: bool| errors::InherentImplCannot {
@@ -898,6 +887,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let &Const::Yes(span) = constness {
self.err_handler().emit_err(error(span, "`const`", true));
}
+
+ self.visit_vis(&item.vis);
+ self.visit_ident(item.ident);
+ self.with_tilde_const(None, |this| this.visit_generics(generics));
+ self.visit_ty(self_ty);
+ walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
+ walk_list!(self, visit_attribute, &item.attrs);
+ return; // Avoid visiting again.
}
ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
self.check_defaultness(item.span, *defaultness);
@@ -978,8 +975,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
// context for the supertraits.
this.visit_vis(&item.vis);
this.visit_ident(item.ident);
- this.visit_generics(generics);
- this.with_tilde_const_allowed(|this| {
+ let disallowed =
+ (!is_const_trait).then(|| DisallowTildeConstContext::Trait(item.span));
+ this.with_tilde_const(disallowed, |this| {
+ this.visit_generics(generics);
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
});
walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
@@ -999,16 +998,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
ItemKind::Struct(vdata, generics) => match vdata {
- // Duplicating the `Visitor` logic allows catching all cases
- // of `Anonymous(Struct, Union)` outside of a field struct or union.
- //
- // Inside `visit_ty` the validator catches every `Anonymous(Struct, Union)` it
- // encounters, and only on `ItemKind::Struct` and `ItemKind::Union`
- // it uses `visit_ty_common`, which doesn't contain that specific check.
VariantData::Struct(fields, ..) => {
self.visit_vis(&item.vis);
self.visit_ident(item.ident);
self.visit_generics(generics);
+ // Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields);
walk_list!(self, visit_attribute, &item.attrs);
return;
@@ -1024,6 +1018,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.visit_vis(&item.vis);
self.visit_ident(item.ident);
self.visit_generics(generics);
+ // Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields);
walk_list!(self, visit_attribute, &item.attrs);
return;
@@ -1212,15 +1207,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let Some(reason) = &self.disallow_tilde_const =>
{
let reason = match reason {
- DisallowTildeConstContext::TraitObject => {
- errors::TildeConstReason::TraitObject
- }
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
errors::TildeConstReason::Closure
}
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
errors::TildeConstReason::Function { ident: ident.span }
}
+ &DisallowTildeConstContext::Trait(span) => {
+ errors::TildeConstReason::Trait { span }
+ }
+ &DisallowTildeConstContext::Impl(span) => {
+ errors::TildeConstReason::Impl { span }
+ }
+ DisallowTildeConstContext::TraitObject => {
+ errors::TildeConstReason::TraitObject
+ }
+ DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
};
self.err_handler()
.emit_err(errors::TildeConstDisallowed { span: bound.span(), reason });
@@ -1328,7 +1330,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl);
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
-
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
}
@@ -1397,18 +1398,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
match &item.kind {
- AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. })
- if ctxt == AssocCtxt::Trait =>
- {
- self.visit_vis(&item.vis);
- self.visit_ident(item.ident);
- walk_list!(self, visit_attribute, &item.attrs);
- self.with_tilde_const_allowed(|this| {
- this.visit_generics(generics);
- walk_list!(this, visit_param_bound, bounds, BoundKind::Bound);
- });
- walk_list!(self, visit_ty, ty);
- }
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
if self.in_const_trait_or_impl
|| ctxt == AssocCtxt::Trait
@@ -1461,9 +1450,7 @@ fn deny_equality_constraints(
id: rustc_ast::node_id::DUMMY_NODE_ID,
ident: *ident,
gen_args,
- kind: AssocConstraintKind::Equality {
- term: predicate.rhs_ty.clone().into(),
- },
+ kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() },
span: ident.span,
});
// Add `` to `Foo`.
@@ -1476,11 +1463,7 @@ fn deny_equality_constraints(
},
empty_args => {
*empty_args = Some(
- AngleBracketedArgs {
- span: ident.span,
- args: thin_vec![arg],
- }
- .into(),
+ AngleBracketedArgs { span: ident.span, args: thin_vec![arg] }.into(),
);
}
}
@@ -1552,7 +1535,7 @@ pub fn check_crate(
in_const_trait_or_impl: false,
has_proc_macro_decls: false,
outer_impl_trait: None,
- disallow_tilde_const: None,
+ disallow_tilde_const: Some(DisallowTildeConstContext::Item),
is_impl_trait_banned: false,
lint_buffer: lints,
};
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index d14b62d6bdc66..7f6fcb493171c 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -551,8 +551,6 @@ pub struct TildeConstDisallowed {
#[derive(Subdiagnostic)]
pub enum TildeConstReason {
- #[note(ast_passes_trait)]
- TraitObject,
#[note(ast_passes_closure)]
Closure,
#[note(ast_passes_function)]
@@ -560,6 +558,20 @@ pub enum TildeConstReason {
#[primary_span]
ident: Span,
},
+ #[note(ast_passes_trait)]
+ Trait {
+ #[primary_span]
+ span: Span,
+ },
+ #[note(ast_passes_impl)]
+ Impl {
+ #[primary_span]
+ span: Span,
+ },
+ #[note(ast_passes_object)]
+ TraitObject,
+ #[note(ast_passes_item)]
+ Item,
}
#[derive(Diagnostic)]
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 5147e672f5f37..6187258a95008 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -4,9 +4,9 @@
//!
//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 475bdb0237866..9e4ffd8dd6a3d 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -1,6 +1,6 @@
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(associated_type_bounds)]
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index 868c041225581..5da5a3cb342c4 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -4,9 +4,9 @@
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
//! to this crate.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![feature(let_chains)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs
index ae8c062d25d81..ffcb290685a19 100644
--- a/compiler/rustc_baked_icu_data/src/lib.rs
+++ b/compiler/rustc_baked_icu_data/src/lib.rs
@@ -20,9 +20,9 @@
//! --cldr-tag latest --icuexport-tag latest -o src/data
//! ```
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![allow(elided_lifetimes_in_paths)]
mod data {
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index cfcf31fce32bd..03172ef34b969 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -10,6 +10,8 @@ use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::RePlaceholder;
+use rustc_middle::ty::Region;
use rustc_middle::ty::RegionVid;
use rustc_middle::ty::UniverseIndex;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
@@ -205,6 +207,8 @@ trait TypeOpInfo<'tcx> {
let span = cause.span;
let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region);
+ debug!(?nice_error);
+
if let Some(nice_error) = nice_error {
mbcx.buffer_error(nice_error);
} else {
@@ -404,19 +408,41 @@ fn try_extract_error_from_region_constraints<'tcx>(
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
) -> Option> {
- let (sub_region, cause) =
- region_constraints.constraints.iter().find_map(|(constraint, cause)| {
- match *constraint {
- Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => {
- Some((sub, cause.clone()))
- }
- // FIXME: Should this check the universe of the var?
- Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
- Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
- }
- _ => None,
+ let matches =
+ |a_region: Region<'tcx>, b_region: Region<'tcx>| match (a_region.kind(), b_region.kind()) {
+ (RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
+ _ => a_region == b_region,
+ };
+ let check = |constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| {
+ match *constraint {
+ Constraint::RegSubReg(sub, sup)
+ if ((exact && sup == placeholder_region)
+ || (!exact && matches(sup, placeholder_region)))
+ && sup != sub =>
+ {
+ Some((sub, cause.clone()))
+ }
+ // FIXME: Should this check the universe of the var?
+ Constraint::VarSubReg(vid, sup)
+ if ((exact && sup == placeholder_region)
+ || (!exact && matches(sup, placeholder_region))) =>
+ {
+ Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
}
- })?;
+ _ => None,
+ }
+ };
+ let mut info = region_constraints
+ .constraints
+ .iter()
+ .find_map(|(constraint, cause)| check(constraint, cause, true));
+ if info.is_none() {
+ info = region_constraints
+ .constraints
+ .iter()
+ .find_map(|(constraint, cause)| check(constraint, cause, false));
+ }
+ let (sub_region, cause) = info?;
debug!(?sub_region, "cause = {:#?}", cause);
let error = match (error_region, *sub_region) {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index c4323fef93558..c85b2f0a9d751 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -10,7 +10,7 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::CoroutineKind;
use rustc_index::IndexSlice;
-use rustc_infer::infer::LateBoundRegionConversionTime;
+use rustc_infer::infer::BoundRegionConversionTime;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
AggregateKind, CallSource, ConstOperand, FakeReadCause, Local, LocalInfo, LocalKind, Location,
@@ -462,7 +462,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// lifetimes without names with the value `'0`.
if let ty::Ref(region, ..) = ty.kind() {
match **region {
- ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
+ ty::ReBound(_, ty::BoundRegion { kind: br, .. })
| ty::RePlaceholder(ty::PlaceholderRegion {
bound: ty::BoundRegion { kind: br, .. },
..
@@ -482,7 +482,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let region = if let ty::Ref(region, ..) = ty.kind() {
match **region {
- ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
+ ty::ReBound(_, ty::BoundRegion { kind: br, .. })
| ty::RePlaceholder(ty::PlaceholderRegion {
bound: ty::BoundRegion { kind: br, .. },
..
@@ -1113,7 +1113,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&& let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind()
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span,
- LateBoundRegionConversionTime::FnCall,
+ BoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
)
&& self.infcx.can_eq(self.param_env, ty, self_ty)
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 41d6b98d7cfa9..aec1cd504c172 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -607,7 +607,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(adt) = local_ty.ty_adt_def()
&& adt.repr().packed()
- && let ExpnKind::Macro(MacroKind::Derive, name) = self.body.span.ctxt().outer_expn_data().kind
+ && let ExpnKind::Macro(MacroKind::Derive, name) =
+ self.body.span.ctxt().outer_expn_data().kind
{
err.note(format!("`#[derive({name})]` triggers a move because taking references to the fields of a packed struct is undefined behaviour"));
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index b6eb9ae980e4e..94981c4558204 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -50,8 +50,8 @@ impl OutlivesSuggestionBuilder {
// naming the `'self` lifetime in methods, etc.
fn region_name_is_suggestable(name: &RegionName) -> bool {
match name.source {
- RegionNameSource::NamedEarlyBoundRegion(..)
- | RegionNameSource::NamedFreeRegion(..)
+ RegionNameSource::NamedEarlyParamRegion(..)
+ | RegionNameSource::NamedLateParamRegion(..)
| RegionNameSource::Static => true,
// Don't give suggestions for upvars, closure return types, or other unnameable
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index a0a809123c0f9..76c5a06c80db2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -95,6 +95,12 @@ impl<'tcx> RegionErrors<'tcx> {
}
}
+impl std::fmt::Debug for RegionErrors<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_tuple("RegionErrors").field(&self.0).finish()
+ }
+}
+
#[derive(Clone, Debug)]
pub(crate) enum RegionErrorKind<'tcx> {
/// A generic bound failure for a type test (`T: 'a`).
@@ -181,8 +187,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
- if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref()
- && let ty::BoundRegionKind::BrEnv = free_region.bound_region
+ if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref()
+ && let ty::BoundRegionKind::BrEnv = late_param.bound_region
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
{
return args.as_closure().kind() == ty::ClosureKind::FnMut;
@@ -995,7 +1001,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
.infcx
.tcx
.is_suitable_region(sub)
- .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.boundregion))
+ .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.bound_region))
else {
return;
};
@@ -1004,7 +1010,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
.infcx
.tcx
.is_suitable_region(sup)
- .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.boundregion))
+ .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.bound_region))
else {
return;
};
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index d38cfbc54d7ac..fee35485cd7ee 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -23,14 +23,14 @@ pub(crate) struct RegionName {
}
/// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
-/// was named by the user would get `NamedFreeRegion` and `'static` lifetime would get `Static`.
+/// was named by the user would get `NamedLateParamRegion` and `'static` lifetime would get `Static`.
/// This helps to print the right kinds of diagnostics.
#[derive(Debug, Clone)]
pub(crate) enum RegionNameSource {
/// A bound (not free) region that was instantiated at the def site (not an HRTB).
- NamedEarlyBoundRegion(Span),
+ NamedEarlyParamRegion(Span),
/// A free region that the user has a name (`'a`) for.
- NamedFreeRegion(Span),
+ NamedLateParamRegion(Span),
/// The `'static` region.
Static,
/// The free region corresponding to the environment of a closure.
@@ -69,8 +69,8 @@ pub(crate) enum RegionNameHighlight {
impl RegionName {
pub(crate) fn was_named(&self) -> bool {
match self.source {
- RegionNameSource::NamedEarlyBoundRegion(..)
- | RegionNameSource::NamedFreeRegion(..)
+ RegionNameSource::NamedEarlyParamRegion(..)
+ | RegionNameSource::NamedLateParamRegion(..)
| RegionNameSource::Static => true,
RegionNameSource::SynthesizedFreeEnvRegion(..)
| RegionNameSource::AnonRegionFromArgument(..)
@@ -85,8 +85,8 @@ impl RegionName {
pub(crate) fn span(&self) -> Option {
match self.source {
RegionNameSource::Static => None,
- RegionNameSource::NamedEarlyBoundRegion(span)
- | RegionNameSource::NamedFreeRegion(span)
+ RegionNameSource::NamedEarlyParamRegion(span)
+ | RegionNameSource::NamedLateParamRegion(span)
| RegionNameSource::SynthesizedFreeEnvRegion(span, _)
| RegionNameSource::AnonRegionFromUpvar(span, _)
| RegionNameSource::AnonRegionFromYieldTy(span, _)
@@ -104,8 +104,8 @@ impl RegionName {
pub(crate) fn highlight_region_name(&self, diag: &mut Diagnostic) {
match &self.source {
- RegionNameSource::NamedFreeRegion(span)
- | RegionNameSource::NamedEarlyBoundRegion(span) => {
+ RegionNameSource::NamedLateParamRegion(span)
+ | RegionNameSource::NamedEarlyParamRegion(span) => {
diag.span_label(*span, format!("lifetime `{self}` defined here"));
}
RegionNameSource::SynthesizedFreeEnvRegion(span, note) => {
@@ -280,28 +280,31 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
debug!("give_region_a_name: error_region = {:?}", error_region);
match *error_region {
- ty::ReEarlyBound(ebr) => ebr.has_name().then(|| {
+ ty::ReEarlyParam(ebr) => ebr.has_name().then(|| {
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
- RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyBoundRegion(span) }
+ RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) }
}),
ty::ReStatic => {
Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static })
}
- ty::ReFree(free_region) => match free_region.bound_region {
+ ty::ReLateParam(late_param) => match late_param.bound_region {
ty::BoundRegionKind::BrNamed(region_def_id, name) => {
// Get the span to point to, even if we don't use the name.
let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP);
debug!(
"bound region named: {:?}, is_named: {:?}",
name,
- free_region.bound_region.is_named()
+ late_param.bound_region.is_named()
);
- if free_region.bound_region.is_named() {
+ if late_param.bound_region.is_named() {
// A named region that is actually named.
- Some(RegionName { name, source: RegionNameSource::NamedFreeRegion(span) })
+ Some(RegionName {
+ name,
+ source: RegionNameSource::NamedLateParamRegion(span),
+ })
} else if tcx.asyncness(self.mir_hir_id().owner).is_async() {
// If we spuriously thought that the region is named, we should let the
// system generate a true name for error messages. Currently this can
@@ -357,7 +360,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
ty::BoundRegionKind::BrAnon => None,
},
- ty::ReLateBound(..)
+ ty::ReBound(..)
| ty::ReVar(..)
| ty::RePlaceholder(..)
| ty::ReErased
@@ -847,7 +850,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
&self,
fr: RegionVid,
) -> Option {
- let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else {
+ let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else {
return None;
};
if region.has_name() {
@@ -862,7 +865,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let found = tcx
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
- *r == ty::ReEarlyBound(region)
+ *r == ty::ReEarlyParam(region)
});
Some(RegionName {
@@ -881,7 +884,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
&self,
fr: RegionVid,
) -> Option {
- let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else {
+ let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else {
return None;
};
if region.has_name() {
@@ -943,7 +946,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
&self,
clauses: &[ty::Clause<'tcx>],
ty: Ty<'tcx>,
- region: ty::EarlyBoundRegion,
+ region: ty::EarlyParamRegion,
) -> bool {
let tcx = self.infcx.tcx;
ty.walk().any(|arg| {
@@ -956,7 +959,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
_ => return false,
}
- tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyBound(region))
+ tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region))
})
} else {
false
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 5787ea13e7939..353e4cf0829df 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1,8 +1,8 @@
//! This query borrow-checks the MIR to (further) ensure it is not broken.
#![allow(internal_features)]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(let_chains)]
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index b1f91a0562822..9e35433bb7e4f 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -151,6 +151,7 @@ pub(crate) struct AppliedMemberConstraint {
pub(crate) member_constraint_index: NllMemberConstraintIndex,
}
+#[derive(Debug)]
pub(crate) struct RegionDefinition<'tcx> {
/// What kind of variable is this -- a free region? existential
/// variable? etc. (See the `NllRegionVariableOrigin` for more
@@ -687,6 +688,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&mut errors_buffer,
);
+ debug!(?errors_buffer);
+ debug!(?outlives_requirements);
+
// In Polonius mode, the errors about missing universal region relations are in the output
// and need to be emitted or propagated. Otherwise, we need to check whether the
// constraints were too strong, and if so, emit or propagate those errors.
@@ -700,10 +704,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
}
+ debug!(?errors_buffer);
+
if errors_buffer.is_empty() {
self.check_member_constraints(infcx, &mut errors_buffer);
}
+ debug!(?errors_buffer);
+
let outlives_requirements = outlives_requirements.unwrap_or_default();
if outlives_requirements.is_empty() {
@@ -1457,6 +1465,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
errors_buffer: &mut RegionErrors<'tcx>,
) {
for (fr, fr_definition) in self.definitions.iter_enumerated() {
+ debug!(?fr, ?fr_definition);
match fr_definition.origin {
NllRegionVariableOrigin::FreeRegion => {
// Go through each of the universal regions `fr` and check that
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index fb0e5811c2679..c93cfa78832a2 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -36,7 +36,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// call `infer_opaque_definition_from_instantiation` to get the inferred
/// type of `_Return<'_a>`. `infer_opaque_definition_from_instantiation`
/// compares lifetimes directly, so we need to map the inference variables
- /// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
+ /// back to concrete lifetimes: `'static`, `ReEarlyParam` or `ReLateParam`.
///
/// First we map all the lifetimes in the concrete type to an equal
/// universal region that occurs in the concrete type's args, in this case
@@ -386,7 +386,7 @@ fn check_opaque_type_parameter_valid(
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(lt) if is_ty_alias => {
- matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
+ matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_))
}
// FIXME(#113916): we can't currently check for unique lifetime params,
// see that issue for more. We will also have to ignore unused lifetime
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index ec0131c5349a1..a31d39e14cd28 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -28,6 +28,9 @@ pub fn renumber_mir<'tcx>(
renumberer.visit_body(body);
}
+// FIXME(@lcnr): A lot of these variants overlap and it seems like
+// this type is only used to decide which region should be used
+// as representative. This should be cleaned up.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) enum RegionCtxt {
Location(Location),
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index d053d0a4b3bad..28cc8be8ac95b 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -7,7 +7,7 @@
//! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
//! contain revealed `impl Trait` values).
-use rustc_infer::infer::LateBoundRegionConversionTime;
+use rustc_infer::infer::BoundRegionConversionTime;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
@@ -35,7 +35,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.instantiate_canonical_with_fresh_inference_vars(body.span, &user_provided_poly_sig);
let user_provided_sig = self.infcx.instantiate_binder_with_fresh_vars(
body.span,
- LateBoundRegionConversionTime::FnCall,
+ BoundRegionConversionTime::FnCall,
user_provided_sig,
);
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 608d010394f66..b7ce2f3cca4cc 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -21,7 +21,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::region_constraints::RegionConstraintData;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{
- InferCtxt, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
+ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin,
};
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
@@ -1202,7 +1202,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.infcx.tcx
}
- #[instrument(skip(self, body, location), level = "debug")]
+ #[instrument(skip(self, body), level = "debug")]
fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
let tcx = self.tcx();
debug!("stmt kind: {:?}", stmt.kind);
@@ -1401,10 +1401,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
};
self.infcx.next_region_var(
- LateBoundRegion(
+ BoundRegion(
term.source_info.span,
br.kind,
- LateBoundRegionConversionTime::FnCall,
+ BoundRegionConversionTime::FnCall,
),
region_ctxt_fn,
)
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index c1f82e19c02e2..ee0bd13109bb6 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -107,12 +107,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
fn next_existential_region_var(
&mut self,
from_forall: bool,
- _name: Option,
+ name: Option,
) -> ty::Region<'tcx> {
let origin = NllRegionVariableOrigin::Existential { from_forall };
let reg_var =
- self.type_checker.infcx.next_nll_region_var(origin, || RegionCtxt::Existential(_name));
+ self.type_checker.infcx.next_nll_region_var(origin, || RegionCtxt::Existential(name));
reg_var
}
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 7897a5a63ba8f..02f94e5b97280 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -462,7 +462,6 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
// "Liberate" the late-bound regions. These correspond to
// "local" free regions.
-
let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
@@ -665,7 +664,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind: ty::BrEnv,
};
- let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
+ let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
let closure_ty = tcx.closure_env_ty(def_id, args, env_region).unwrap();
// The "inputs" of the closure in the
@@ -784,7 +783,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
debug!(?br);
let liberated_region =
- ty::Region::new_free(self.tcx, all_outlive_scope.to_def_id(), br.kind);
+ ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), br.kind);
let region_vid = {
let name = match br.kind.get_name() {
Some(name) => name,
@@ -854,7 +853,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
/// Initially, the `UniversalRegionIndices` map contains only the
/// early-bound regions in scope. Once that is all setup, we come
/// in later and instantiate the late-bound regions, and then we
- /// insert the `ReFree` version of those into the map as
+ /// insert the `ReLateParam` version of those into the map as
/// well. These are used for error reporting.
fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
debug!("insert_late_bound_region({:?}, {:?})", r, vid);
@@ -933,7 +932,8 @@ fn for_each_late_bound_region_in_item<'tcx>(
let ty::BoundVariableKind::Region(bound_region) = bound_var else {
continue;
};
- let liberated_region = ty::Region::new_free(tcx, mir_def_id.to_def_id(), bound_region);
+ let liberated_region =
+ ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), bound_region);
f(liberated_region);
}
}
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 214fed8e2d827..8a3e15ee24a9d 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -617,10 +617,17 @@ fn report_missing_placeholders(
let placeholders = pieces
.iter()
.filter_map(|piece| {
- if let parse::Piece::NextArgument(argument) = piece && let ArgumentNamed(binding) = argument.position {
- let span = fmt_span.from_inner(InnerSpan::new(argument.position_span.start, argument.position_span.end));
+ if let parse::Piece::NextArgument(argument) = piece
+ && let ArgumentNamed(binding) = argument.position
+ {
+ let span = fmt_span.from_inner(InnerSpan::new(
+ argument.position_span.start,
+ argument.position_span.end,
+ ));
Some((span, binding))
- } else { None }
+ } else {
+ None
+ }
})
.collect::>();
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index d84742c9b8293..ae097dec8f1ec 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -1,9 +1,9 @@
//! This crate contains implementations of built-in macros and other code generating facilities
//! injecting code into the crate before it is lowered to HIR.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(box_patterns)]
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
index 12aa69d3c7956..bd3b051185b46 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
@@ -35,6 +35,10 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: CPU features
+ if: matrix.os == 'ubuntu-latest'
+ run: cat /proc/cpuinfo
+
- name: Cache cargo target dir
uses: actions/cache@v3
with:
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index 47d9a3b93f729..05dc28d074530 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -66,6 +66,10 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: CPU features
+ if: matrix.os == 'ubuntu-latest'
+ run: cat /proc/cpuinfo
+
- name: Cache cargo target dir
uses: actions/cache@v3
with:
@@ -136,6 +140,9 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: CPU features
+ run: cat /proc/cpuinfo
+
- name: Prepare dependencies
run: ./y.sh prepare
@@ -159,6 +166,9 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: CPU features
+ run: cat /proc/cpuinfo
+
- name: Cache cargo target dir
uses: actions/cache@v3
with:
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
index b49dc3aff7aaa..cb5dd51fee310 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
@@ -11,6 +11,9 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: CPU features
+ run: cat /proc/cpuinfo
+
- name: Cache cargo target dir
uses: actions/cache@v3
with:
@@ -31,6 +34,9 @@ jobs:
steps:
- uses: actions/checkout@v3
+ - name: CPU features
+ run: cat /proc/cpuinfo
+
- name: Cache cargo target dir
uses: actions/cache@v3
with:
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index 5664cbe7d4fac..ca6ecdf1d0e88 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -5,8 +5,48 @@ This has the potential to improve compilation times in debug mode.
If your project doesn't use any of the things listed under "Not yet supported", it should work fine.
If not please open an issue.
+## Download using Rustup
+
+The Cranelift codegen backend is distributed in nightly builds on Linux and x86_64 macOS. If you want to
+install it using Rustup, you can do that by running:
+
+```bash
+$ rustup component add rustc-codegen-cranelift-preview --toolchain nightly
+```
+
+Once it is installed, you can enable it with one of the following approaches:
+- `CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly build -Zcodegen-backend`
+- `RUSTFLAGS="-Zcodegen-backend=cranelift" cargo +nightly build`
+- Add the following to `.cargo/config.toml`:
+ ```toml
+ [unstable]
+ codegen-backend = true
+
+ [profile.dev]
+ codegen-backend = "cranelift"
+ ```
+- Add the following to `Cargo.toml`:
+ ```toml
+ # This line needs to come before anything else in Cargo.toml
+ cargo-features = ["codegen-backend"]
+
+ [profile.dev]
+ codegen-backend = "cranelift"
+ ```
+
+## Precompiled builds
+
+You can also download a pre-built version from the [releases] page.
+Extract the `dist` directory in the archive anywhere you want.
+If you want to use `cargo clif build` instead of having to specify the full path to the `cargo-clif` executable, you can add the `bin` subdirectory of the extracted `dist` directory to your `PATH`.
+(tutorial [for Windows](https://stackoverflow.com/a/44272417), and [for Linux/MacOS](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path/26059#26059)).
+
+[releases]: https://github.com/rust-lang/rustc_codegen_cranelift/releases/tag/dev
+
## Building and testing
+If you want to build the backend manually, you can download it from GitHub and build it yourself:
+
```bash
$ git clone https://github.com/rust-lang/rustc_codegen_cranelift
$ cd rustc_codegen_cranelift
@@ -22,15 +62,6 @@ $ ./test.sh
For more docs on how to build and test see [build_system/usage.txt](build_system/usage.txt) or the help message of `./y.sh`.
-## Precompiled builds
-
-Alternatively you can download a pre built version from the [releases] page.
-Extract the `dist` directory in the archive anywhere you want.
-If you want to use `cargo clif build` instead of having to specify the full path to the `cargo-clif` executable, you can add the `bin` subdirectory of the extracted `dist` directory to your `PATH`.
-(tutorial [for Windows](https://stackoverflow.com/a/44272417), and [for Linux/MacOS](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path/26059#26059)).
-
-[releases]: https://github.com/rust-lang/rustc_codegen_cranelift/releases/tag/dev
-
## Usage
rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
@@ -76,8 +107,6 @@ configuration options.
## Not yet supported
-* Inline assembly ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1041))
- * On UNIX there is support for invoking an external assembler for `global_asm!` and `asm!`.
* SIMD ([tracked here](https://github.com/rust-lang/rustc_codegen_cranelift/issues/171), `std::simd` fully works, `std::arch` is partially supported)
* Unwinding on panics ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1677), `-Cpanic=abort` is enabled by default)
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index 1e24d1b113fe6..ff71a567ed3ac 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -99,6 +99,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
TestCase::build_bin_and_run("aot.mod_bench", "example/mod_bench.rs", &[]),
TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"),
+ TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]),
];
pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
@@ -456,6 +457,8 @@ impl<'a> TestRunner<'a> {
cmd.arg("--target");
cmd.arg(&self.target_compiler.triple);
cmd.arg("-Cpanic=abort");
+ cmd.arg("--check-cfg=cfg(no_unstable_features)");
+ cmd.arg("--check-cfg=cfg(jit)");
cmd.args(args);
cmd
}
diff --git a/compiler/rustc_codegen_cranelift/config.txt b/compiler/rustc_codegen_cranelift/config.txt
index 7ff805e58d967..2ccdc7d78748a 100644
--- a/compiler/rustc_codegen_cranelift/config.txt
+++ b/compiler/rustc_codegen_cranelift/config.txt
@@ -42,6 +42,7 @@ aot.float-minmax-pass
aot.mod_bench
aot.issue-72793
aot.issue-59326
+aot.neon
testsuite.extended_sysroot
test.rust-random/rand
diff --git a/compiler/rustc_codegen_cranelift/example/neon.rs b/compiler/rustc_codegen_cranelift/example/neon.rs
new file mode 100644
index 0000000000000..bad26947967dc
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/example/neon.rs
@@ -0,0 +1,234 @@
+// Most of these tests are copied from https://github.com/japaric/stdsimd/blob/0f4413d01c4f0c3ffbc5a69e9a37fbc7235b31a9/coresimd/arm/neon.rs
+
+#![feature(portable_simd)]
+
+#[cfg(target_arch = "aarch64")]
+use std::arch::aarch64::*;
+use std::mem::transmute;
+use std::simd::*;
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_s8() {
+ let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]);
+ let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
+ let e = i8x8::from([-2, -4, 5, 7, 0, 2, 4, 6]);
+ let r: i8x8 = transmute(vpmin_s8(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_s16() {
+ let a = i16x4::from([1, 2, 3, -4]);
+ let b = i16x4::from([0, 3, 2, 5]);
+ let e = i16x4::from([1, -4, 0, 2]);
+ let r: i16x4 = transmute(vpmin_s16(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_s32() {
+ let a = i32x2::from([1, -2]);
+ let b = i32x2::from([0, 3]);
+ let e = i32x2::from([-2, 0]);
+ let r: i32x2 = transmute(vpmin_s32(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_u8() {
+ let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
+ let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
+ let e = u8x8::from([1, 3, 5, 7, 0, 2, 4, 6]);
+ let r: u8x8 = transmute(vpmin_u8(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_u16() {
+ let a = u16x4::from([1, 2, 3, 4]);
+ let b = u16x4::from([0, 3, 2, 5]);
+ let e = u16x4::from([1, 3, 0, 2]);
+ let r: u16x4 = transmute(vpmin_u16(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_u32() {
+ let a = u32x2::from([1, 2]);
+ let b = u32x2::from([0, 3]);
+ let e = u32x2::from([1, 0]);
+ let r: u32x2 = transmute(vpmin_u32(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmin_f32() {
+ let a = f32x2::from([1., -2.]);
+ let b = f32x2::from([0., 3.]);
+ let e = f32x2::from([-2., 0.]);
+ let r: f32x2 = transmute(vpmin_f32(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_s8() {
+ let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]);
+ let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
+ let e = i8x8::from([1, 3, 6, 8, 3, 5, 7, 9]);
+ let r: i8x8 = transmute(vpmax_s8(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_s16() {
+ let a = i16x4::from([1, 2, 3, -4]);
+ let b = i16x4::from([0, 3, 2, 5]);
+ let e = i16x4::from([2, 3, 3, 5]);
+ let r: i16x4 = transmute(vpmax_s16(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_s32() {
+ let a = i32x2::from([1, -2]);
+ let b = i32x2::from([0, 3]);
+ let e = i32x2::from([1, 3]);
+ let r: i32x2 = transmute(vpmax_s32(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_u8() {
+ let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
+ let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
+ let e = u8x8::from([2, 4, 6, 8, 3, 5, 7, 9]);
+ let r: u8x8 = transmute(vpmax_u8(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_u16() {
+ let a = u16x4::from([1, 2, 3, 4]);
+ let b = u16x4::from([0, 3, 2, 5]);
+ let e = u16x4::from([2, 4, 3, 5]);
+ let r: u16x4 = transmute(vpmax_u16(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_u32() {
+ let a = u32x2::from([1, 2]);
+ let b = u32x2::from([0, 3]);
+ let e = u32x2::from([2, 3]);
+ let r: u32x2 = transmute(vpmax_u32(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpmax_f32() {
+ let a = f32x2::from([1., -2.]);
+ let b = f32x2::from([0., 3.]);
+ let e = f32x2::from([1., 3.]);
+ let r: f32x2 = transmute(vpmax_f32(transmute(a), transmute(b)));
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpadd_s16() {
+ let a = i16x4::from([1, 2, 3, 4]);
+ let b = i16x4::from([0, -1, -2, -3]);
+ let r: i16x4 = transmute(vpadd_s16(transmute(a), transmute(b)));
+ let e = i16x4::from([3, 7, -1, -5]);
+ assert_eq!(r, e);
+}
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpadd_s32() {
+ let a = i32x2::from([1, 2]);
+ let b = i32x2::from([0, -1]);
+ let r: i32x2 = transmute(vpadd_s32(transmute(a), transmute(b)));
+ let e = i32x2::from([3, -1]);
+ assert_eq!(r, e);
+}
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpadd_s8() {
+ let a = i8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
+ let b = i8x8::from([0, -1, -2, -3, -4, -5, -6, -7]);
+ let r: i8x8 = transmute(vpadd_s8(transmute(a), transmute(b)));
+ let e = i8x8::from([3, 7, 11, 15, -1, -5, -9, -13]);
+ assert_eq!(r, e);
+}
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpadd_u16() {
+ let a = u16x4::from([1, 2, 3, 4]);
+ let b = u16x4::from([30, 31, 32, 33]);
+ let r: u16x4 = transmute(vpadd_u16(transmute(a), transmute(b)));
+ let e = u16x4::from([3, 7, 61, 65]);
+ assert_eq!(r, e);
+}
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpadd_u32() {
+ let a = u32x2::from([1, 2]);
+ let b = u32x2::from([30, 31]);
+ let r: u32x2 = transmute(vpadd_u32(transmute(a), transmute(b)));
+ let e = u32x2::from([3, 61]);
+ assert_eq!(r, e);
+}
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vpadd_u8() {
+ let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
+ let b = u8x8::from([30, 31, 32, 33, 34, 35, 36, 37]);
+ let r: u8x8 = transmute(vpadd_u8(transmute(a), transmute(b)));
+ let e = u8x8::from([3, 7, 11, 15, 61, 65, 69, 73]);
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vqsub_u8() {
+ let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]);
+ let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]);
+ let r: u8x8 = transmute(vqsub_u8(transmute(a), transmute(b)));
+ let e = u8x8::from([0, 1, 2, 3, 0, 0, 0, 218]);
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+unsafe fn test_vqadd_u8() {
+ let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]);
+ let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]);
+ let r: u8x8 = transmute(vqadd_u8(transmute(a), transmute(b)));
+ let e = u8x8::from([31, 3, 4, 5, 39, 0xff, 43, 0xff]);
+ assert_eq!(r, e);
+}
+
+#[cfg(target_arch = "aarch64")]
+fn main() {
+ unsafe {
+ test_vpmin_s8();
+ test_vpmin_s16();
+ test_vpmin_s32();
+ test_vpmin_u8();
+ test_vpmin_u16();
+ test_vpmin_u32();
+ test_vpmin_f32();
+ test_vpmax_s8();
+ test_vpmax_s16();
+ test_vpmax_s32();
+ test_vpmax_u8();
+ test_vpmax_u16();
+ test_vpmax_u32();
+ test_vpmax_f32();
+
+ test_vpadd_s16();
+ test_vpadd_s32();
+ test_vpadd_s8();
+ test_vpadd_u16();
+ test_vpadd_u32();
+ test_vpadd_u8();
+
+ test_vqsub_u8();
+ test_vqadd_u8();
+ }
+}
+
+#[cfg(not(target_arch = "aarch64"))]
+fn main() {}
diff --git a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
index 9902bca8eab27..8a690bada0df5 100644
--- a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
+++ b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
@@ -58,9 +58,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
-version = "0.1.100"
+version = "0.1.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6c0f24437059853f0fa64afc51f338f93647a3de4cf3358ba1bb4171a199775"
+checksum = "a3b73c3443a5fd2438d7ba4853c64e4c8efc2404a9e28a9234cc2d5eebc6c242"
dependencies = [
"cc",
"rustc-std-workspace-core",
@@ -158,9 +158,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.149"
+version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
+checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
dependencies = [
"rustc-std-workspace-core",
]
@@ -415,7 +415,6 @@ dependencies = [
name = "unwind"
version = "0.0.0"
dependencies = [
- "cc",
"cfg-if",
"compiler_builtins",
"core",
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 7e3eaacf8ef08..80ef1e49f2319 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2023-10-29"
+channel = "nightly-2023-11-16"
components = ["rust-src", "rustc-dev", "llvm-tools"]
diff --git a/compiler/rustc_codegen_cranelift/scripts/rustup.sh b/compiler/rustc_codegen_cranelift/scripts/rustup.sh
index e62788f2e507d..355282911c255 100755
--- a/compiler/rustc_codegen_cranelift/scripts/rustup.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/rustup.sh
@@ -46,7 +46,7 @@ case $1 in
git pull origin master
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/bjorn3/rustc_codegen_cranelift.git master
+ "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git master
git push -u my "$branch"
# immediately merge the merge commit into cg_clif to prevent merge conflicts when syncing
diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
index bbb8a010d965f..731828caae2c4 100644
--- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
@@ -1,15 +1,17 @@
#!/usr/bin/env bash
set -e
+# CG_CLIF_FORCE_GNU_AS will force usage of as instead of the LLVM backend of rustc as we
+# the LLVM backend isn't compiled in here.
+export CG_CLIF_FORCE_GNU_AS=1
+
# Compiletest expects all standard library paths to start with /rustc/FAKE_PREFIX.
# CG_CLIF_STDLIB_REMAP_PATH_PREFIX will cause cg_clif's build system to pass
# --remap-path-prefix to handle this.
-# CG_CLIF_FORCE_GNU_AS will force usage of as instead of the LLVM backend of rustc as we
-# the LLVM backend isn't compiled in here.
-CG_CLIF_FORCE_GNU_AS=1 CG_CLIF_STDLIB_REMAP_PATH_PREFIX=/rustc/FAKE_PREFIX ./y.sh build
+CG_CLIF_STDLIB_REMAP_PATH_PREFIX=/rustc/FAKE_PREFIX ./y.sh build
echo "[SETUP] Rust fork"
-git clone https://github.com/rust-lang/rust.git || true
+git clone https://github.com/rust-lang/rust.git --filter=tree:0 || true
pushd rust
git fetch
git checkout -- .
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_bootstrap.sh b/compiler/rustc_codegen_cranelift/scripts/test_bootstrap.sh
index a8f6d7a202486..791d457993de3 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_bootstrap.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_bootstrap.sh
@@ -11,7 +11,5 @@ rm -r compiler/rustc_codegen_cranelift/{Cargo.*,src}
cp ../Cargo.* compiler/rustc_codegen_cranelift/
cp -r ../src compiler/rustc_codegen_cranelift/src
-# CG_CLIF_FORCE_GNU_AS will force usage of as instead of the LLVM backend of rustc as we
-# the LLVM backend isn't compiled in here.
-CG_CLIF_FORCE_GNU_AS=1 ./x.py build --stage 1 library/std
+./x.py build --stage 1 library/std
popd
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index a299b6de6b1cd..cdc78adcf85e3 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -146,6 +146,11 @@ rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
+# rustc bugs
+# ==========
+# https://github.com/rust-lang/rust/pull/116447#issuecomment-1790451463
+rm tests/ui/coroutine/gen_block_*.rs
+
cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist
# prevent $(RUSTDOC) from picking up the sysroot built by x.py. It conflicts with the one used by
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index c4572e035258d..0ff1473da4313 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -383,6 +383,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
args,
ret_place,
target,
+ source_info.span,
);
return;
}
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 91b1547cb6ea6..71557d49ef2c3 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -456,7 +456,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
);
}
- crate::inline_asm::codegen_inline_asm(
+ crate::inline_asm::codegen_inline_asm_terminator(
fx,
source_info.span,
template,
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index b0853d30e03b8..cf68a3857c58c 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -1,10 +1,13 @@
//! Handling of `static`s, `const`s and promoted allocations
+use std::cmp::Ordering;
+
use cranelift_module::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar};
use rustc_middle::mir::ConstValue;
+use rustc_middle::ty::ScalarInt;
use crate::prelude::*;
@@ -430,9 +433,9 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
pub(crate) fn mir_operand_get_const_val<'tcx>(
fx: &FunctionCx<'_, '_, 'tcx>,
operand: &Operand<'tcx>,
-) -> Option> {
+) -> Option {
match operand {
- Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).0),
+ Operand::Constant(const_) => eval_mir_constant(fx, const_).0.try_to_scalar_int(),
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
// inside a temporary before being passed to the intrinsic requiring the const argument.
// This code tries to find a single constant defining definition of the referenced local.
@@ -440,7 +443,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
if !place.projection.is_empty() {
return None;
}
- let mut computed_const_val = None;
+ let mut computed_scalar_int = None;
for bb_data in fx.mir.basic_blocks.iter() {
for stmt in &bb_data.statements {
match &stmt.kind {
@@ -456,22 +459,38 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
operand,
ty,
) => {
- if computed_const_val.is_some() {
+ if computed_scalar_int.is_some() {
return None; // local assigned twice
}
if !matches!(ty.kind(), ty::Uint(_) | ty::Int(_)) {
return None;
}
- let const_val = mir_operand_get_const_val(fx, operand)?;
- if fx.layout_of(*ty).size
- != const_val.try_to_scalar_int()?.size()
+ let scalar_int = mir_operand_get_const_val(fx, operand)?;
+ let scalar_int = match fx
+ .layout_of(*ty)
+ .size
+ .cmp(&scalar_int.size())
{
- return None;
- }
- computed_const_val = Some(const_val);
+ Ordering::Equal => scalar_int,
+ Ordering::Less => match ty.kind() {
+ ty::Uint(_) => ScalarInt::try_from_uint(
+ scalar_int.try_to_uint(scalar_int.size()).unwrap(),
+ fx.layout_of(*ty).size,
+ )
+ .unwrap(),
+ ty::Int(_) => ScalarInt::try_from_int(
+ scalar_int.try_to_int(scalar_int.size()).unwrap(),
+ fx.layout_of(*ty).size,
+ )
+ .unwrap(),
+ _ => unreachable!(),
+ },
+ Ordering::Greater => return None,
+ };
+ computed_scalar_int = Some(scalar_int);
}
Rvalue::Use(operand) => {
- computed_const_val = mir_operand_get_const_val(fx, operand)
+ computed_scalar_int = mir_operand_get_const_val(fx, operand)
}
_ => return None,
}
@@ -522,7 +541,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
TerminatorKind::Call { .. } => {}
}
}
- computed_const_val
+ computed_scalar_int
}
}
}
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 331649b2ec24f..25d14319f5791 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -10,10 +10,10 @@ use target_lexicon::BinaryFormat;
use crate::prelude::*;
-enum CInlineAsmOperand<'tcx> {
+pub(crate) enum CInlineAsmOperand<'tcx> {
In {
reg: InlineAsmRegOrRegClass,
- value: CValue<'tcx>,
+ value: Value,
},
Out {
reg: InlineAsmRegOrRegClass,
@@ -23,7 +23,7 @@ enum CInlineAsmOperand<'tcx> {
InOut {
reg: InlineAsmRegOrRegClass,
_late: bool,
- in_value: CValue<'tcx>,
+ in_value: Value,
out_place: Option>,
},
Const {
@@ -34,7 +34,7 @@ enum CInlineAsmOperand<'tcx> {
},
}
-pub(crate) fn codegen_inline_asm<'tcx>(
+pub(crate) fn codegen_inline_asm_terminator<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
span: Span,
template: &[InlineAsmTemplatePiece],
@@ -42,12 +42,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
options: InlineAsmOptions,
destination: Option,
) {
- // FIXME add .eh_frame unwind info directives
-
// Used by panic_abort on Windows, but uses a syntax which only happens to work with
// asm!() by accident and breaks with the GNU assembler as well as global_asm!() for
// the LLVM backend.
- if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
+ if template.len() == 1
+ && template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string())
+ {
fx.bcx.ins().trap(TrapCode::User(1));
return;
}
@@ -55,9 +55,10 @@ pub(crate) fn codegen_inline_asm<'tcx>(
let operands = operands
.into_iter()
.map(|operand| match *operand {
- InlineAsmOperand::In { reg, ref value } => {
- CInlineAsmOperand::In { reg, value: crate::base::codegen_operand(fx, value) }
- }
+ InlineAsmOperand::In { reg, ref value } => CInlineAsmOperand::In {
+ reg,
+ value: crate::base::codegen_operand(fx, value).load_scalar(fx),
+ },
InlineAsmOperand::Out { reg, late, ref place } => CInlineAsmOperand::Out {
reg,
late,
@@ -67,7 +68,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
CInlineAsmOperand::InOut {
reg,
_late: late,
- in_value: crate::base::codegen_operand(fx, in_value),
+ in_value: crate::base::codegen_operand(fx, in_value).load_scalar(fx),
out_place: out_place.map(|place| crate::base::codegen_place(fx, place)),
}
}
@@ -132,15 +133,33 @@ pub(crate) fn codegen_inline_asm<'tcx>(
})
.collect::>();
- let mut inputs = Vec::new();
- let mut outputs = Vec::new();
+ codegen_inline_asm_inner(fx, template, &operands, options);
+
+ match destination {
+ Some(destination) => {
+ let destination_block = fx.get_block(destination);
+ fx.bcx.ins().jump(destination_block, &[]);
+ }
+ None => {
+ fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+ }
+ }
+}
+
+pub(crate) fn codegen_inline_asm_inner<'tcx>(
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ template: &[InlineAsmTemplatePiece],
+ operands: &[CInlineAsmOperand<'tcx>],
+ options: InlineAsmOptions,
+) {
+ // FIXME add .eh_frame unwind info directives
let mut asm_gen = InlineAssemblyGenerator {
tcx: fx.tcx,
arch: fx.tcx.sess.asm_arch.unwrap(),
enclosing_def_id: fx.instance.def_id(),
template,
- operands: &operands,
+ operands,
options,
registers: Vec::new(),
stack_slots_clobber: Vec::new(),
@@ -162,10 +181,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
let generated_asm = asm_gen.generate_asm_wrapper(&asm_name);
fx.cx.global_asm.push_str(&generated_asm);
+ let mut inputs = Vec::new();
+ let mut outputs = Vec::new();
for (i, operand) in operands.iter().enumerate() {
match operand {
CInlineAsmOperand::In { reg: _, value } => {
- inputs.push((asm_gen.stack_slots_input[i].unwrap(), value.load_scalar(fx)));
+ inputs.push((asm_gen.stack_slots_input[i].unwrap(), *value));
}
CInlineAsmOperand::Out { reg: _, late: _, place } => {
if let Some(place) = place {
@@ -173,7 +194,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
}
}
CInlineAsmOperand::InOut { reg: _, _late: _, in_value, out_place } => {
- inputs.push((asm_gen.stack_slots_input[i].unwrap(), in_value.load_scalar(fx)));
+ inputs.push((asm_gen.stack_slots_input[i].unwrap(), *in_value));
if let Some(out_place) = out_place {
outputs.push((asm_gen.stack_slots_output[i].unwrap(), *out_place));
}
@@ -183,16 +204,6 @@ pub(crate) fn codegen_inline_asm<'tcx>(
}
call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs);
-
- match destination {
- Some(destination) => {
- let destination_block = fx.get_block(destination);
- fx.bcx.ins().jump(destination_block, &[]);
- }
- None => {
- fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
- }
- }
}
struct InlineAssemblyGenerator<'a, 'tcx> {
@@ -634,8 +645,21 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
) {
match arch {
InlineAsmArch::X86_64 => {
- write!(generated_asm, " mov [rbx+0x{:x}], ", offset.bytes()).unwrap();
- reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
+ match reg {
+ InlineAsmReg::X86(reg)
+ if reg as u32 >= X86InlineAsmReg::xmm0 as u32
+ && reg as u32 <= X86InlineAsmReg::xmm15 as u32 =>
+ {
+ // rustc emits x0 rather than xmm0
+ write!(generated_asm, " movups [rbx+0x{:x}], ", offset.bytes()).unwrap();
+ write!(generated_asm, "xmm{}", reg as u32 - X86InlineAsmReg::xmm0 as u32)
+ .unwrap();
+ }
+ _ => {
+ write!(generated_asm, " mov [rbx+0x{:x}], ", offset.bytes()).unwrap();
+ reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
+ }
+ }
generated_asm.push('\n');
}
InlineAsmArch::AArch64 => {
@@ -660,8 +684,24 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
) {
match arch {
InlineAsmArch::X86_64 => {
- generated_asm.push_str(" mov ");
- reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
+ match reg {
+ InlineAsmReg::X86(reg)
+ if reg as u32 >= X86InlineAsmReg::xmm0 as u32
+ && reg as u32 <= X86InlineAsmReg::xmm15 as u32 =>
+ {
+ // rustc emits x0 rather than xmm0
+ write!(
+ generated_asm,
+ " movups xmm{}",
+ reg as u32 - X86InlineAsmReg::xmm0 as u32
+ )
+ .unwrap();
+ }
+ _ => {
+ generated_asm.push_str(" mov ");
+ reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap()
+ }
+ }
writeln!(generated_asm, ", [rbx+0x{:x}]", offset.bytes()).unwrap();
}
InlineAsmArch::AArch64 => {
@@ -717,7 +757,12 @@ fn call_inline_asm<'tcx>(
fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]);
for (offset, place) in outputs {
- let ty = fx.clif_type(place.layout().ty).unwrap();
+ let ty = if place.layout().ty.is_simd() {
+ let (lane_count, lane_type) = place.layout().ty.simd_size_and_type(fx.tcx);
+ fx.clif_type(lane_type).unwrap().by(lane_count.try_into().unwrap()).unwrap()
+ } else {
+ fx.clif_type(place.layout().ty).unwrap()
+ };
let value = stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).load(
fx,
ty,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index c169476099806..659e6c133ef5e 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -12,6 +12,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: Option,
+ span: Span,
) {
if intrinsic.starts_with("llvm.aarch64") {
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
@@ -31,6 +32,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
args,
ret,
target,
+ span,
);
}
@@ -51,6 +53,21 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
});
}
+ _ if intrinsic.starts_with("llvm.fma.v") => {
+ intrinsic_args!(fx, args => (x,y,z); intrinsic);
+
+ simd_trio_for_each_lane(
+ fx,
+ x,
+ y,
+ z,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, lane_x, lane_y, lane_z| {
+ fx.bcx.ins().fma(lane_x, lane_y, lane_z)
+ },
+ );
+ }
+
_ => {
fx.tcx
.sess
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
index 0c211a06dc4a7..ee098be1fce6b 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -44,7 +44,9 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
});
}
- _ if intrinsic.starts_with("llvm.aarch64.neon.sqadd.v") => {
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sqadd.v")
+ || intrinsic.starts_with("llvm.aarch64.neon.uqadd.v") =>
+ {
intrinsic_args!(fx, args => (x, y); intrinsic);
simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
@@ -52,7 +54,9 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
});
}
- _ if intrinsic.starts_with("llvm.aarch64.neon.sqsub.v") => {
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sqsub.v")
+ || intrinsic.starts_with("llvm.aarch64.neon.uqsub.v") =>
+ {
intrinsic_args!(fx, args => (x, y); intrinsic);
simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
@@ -156,6 +160,90 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
});
}
+ _ if intrinsic.starts_with("llvm.aarch64.neon.umaxp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().umax(x_lane, y_lane),
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.smaxp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().smax(x_lane, y_lane),
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.uminp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().umin(x_lane, y_lane),
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sminp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().smin(x_lane, y_lane),
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.fminp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().fmin(x_lane, y_lane),
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.fmaxp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().fmax(x_lane, y_lane),
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.addp.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_horizontal_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().iadd(x_lane, y_lane),
+ );
+ }
+
// FIXME generalize vector types
"llvm.aarch64.neon.tbl1.v16i8" => {
intrinsic_args!(fx, args => (t, idx); intrinsic);
@@ -172,25 +260,6 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
}
}
- // FIXME generalize vector types
- "llvm.aarch64.neon.umaxp.v16i8" => {
- intrinsic_args!(fx, args => (a, b); intrinsic);
-
- // FIXME add helper for horizontal pairwise operations
- for i in 0..8 {
- let lane1 = a.value_lane(fx, i * 2).load_scalar(fx);
- let lane2 = a.value_lane(fx, i * 2 + 1).load_scalar(fx);
- let res = fx.bcx.ins().umax(lane1, lane2);
- ret.place_lane(fx, i).to_ptr().store(fx, res, MemFlags::trusted());
- }
- for i in 0..8 {
- let lane1 = b.value_lane(fx, i * 2).load_scalar(fx);
- let lane2 = b.value_lane(fx, i * 2 + 1).load_scalar(fx);
- let res = fx.bcx.ins().umax(lane1, lane2);
- ret.place_lane(fx, 8 + i).to_ptr().store(fx, res, MemFlags::trusted());
- }
- }
-
/*
_ if intrinsic.starts_with("llvm.aarch64.neon.sshl.v")
|| intrinsic.starts_with("llvm.aarch64.neon.sqshl.v")
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index ea5997a14bb74..8dd2b6ed014e6 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -1,7 +1,10 @@
//! Emulate x86 LLVM intrinsics
+use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_middle::ty::GenericArgsRef;
+use rustc_target::asm::*;
+use crate::inline_asm::{codegen_inline_asm_inner, CInlineAsmOperand};
use crate::intrinsics::*;
use crate::prelude::*;
@@ -12,6 +15,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: Option,
+ span: Span,
) {
match intrinsic {
"llvm.x86.sse2.pause" | "llvm.aarch64.isb" => {
@@ -20,16 +24,49 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
// Used by is_x86_feature_detected!();
"llvm.x86.xgetbv" => {
- // FIXME use the actual xgetbv instruction
- intrinsic_args!(fx, args => (v); intrinsic);
+ intrinsic_args!(fx, args => (xcr_no); intrinsic);
- let v = v.load_scalar(fx);
+ let xcr_no = xcr_no.load_scalar(fx);
- // As of writing on XCR0 exists
- fx.bcx.ins().trapnz(v, TrapCode::UnreachableCodeReached);
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String(
+ "
+ xgetbv
+ // out = rdx << 32 | rax
+ shl rdx, 32
+ or rax, rdx
+ "
+ .to_string(),
+ )],
+ &[
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
+ value: xcr_no,
+ },
+ CInlineAsmOperand::Out {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
+ late: true,
+ place: Some(ret),
+ },
+ CInlineAsmOperand::Out {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
+ late: true,
+ place: None,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.sse3.ldu.dq" | "llvm.x86.avx.ldu.dq.256" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_lddqu_si128&ig_expand=4009
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_lddqu_si256&ig_expand=4010
+ intrinsic_args!(fx, args => (ptr); intrinsic);
- let res = fx.bcx.ins().iconst(types::I64, 1 /* bit 0 must be set */);
- ret.write_cvalue(fx, CValue::by_val(res, fx.layout_of(fx.tcx.types.i64)));
+ // FIXME correctly handle unalignedness
+ let val = CValue::by_ref(Pointer::new(ptr.load_scalar(fx)), ret.layout());
+ ret.write_cvalue(fx, val);
}
"llvm.x86.sse.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
@@ -177,8 +214,12 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
}
}
}
- "llvm.x86.avx2.vperm2i128" => {
+ "llvm.x86.avx2.vperm2i128"
+ | "llvm.x86.avx.vperm2f128.ps.256"
+ | "llvm.x86.avx.vperm2f128.pd.256" => {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permute2x128_si256
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permute2f128_ps
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permute2f128_pd
let (a, b, imm8) = match args {
[a, b, imm8] => (a, b, imm8),
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
@@ -187,19 +228,11 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
let b = codegen_operand(fx, b);
let imm8 = codegen_operand(fx, imm8).load_scalar(fx);
- let a_0 = a.value_lane(fx, 0).load_scalar(fx);
- let a_1 = a.value_lane(fx, 1).load_scalar(fx);
- let a_low = fx.bcx.ins().iconcat(a_0, a_1);
- let a_2 = a.value_lane(fx, 2).load_scalar(fx);
- let a_3 = a.value_lane(fx, 3).load_scalar(fx);
- let a_high = fx.bcx.ins().iconcat(a_2, a_3);
+ let a_low = a.value_typed_lane(fx, fx.tcx.types.u128, 0).load_scalar(fx);
+ let a_high = a.value_typed_lane(fx, fx.tcx.types.u128, 1).load_scalar(fx);
- let b_0 = b.value_lane(fx, 0).load_scalar(fx);
- let b_1 = b.value_lane(fx, 1).load_scalar(fx);
- let b_low = fx.bcx.ins().iconcat(b_0, b_1);
- let b_2 = b.value_lane(fx, 2).load_scalar(fx);
- let b_3 = b.value_lane(fx, 3).load_scalar(fx);
- let b_high = fx.bcx.ins().iconcat(b_2, b_3);
+ let b_low = b.value_typed_lane(fx, fx.tcx.types.u128, 0).load_scalar(fx);
+ let b_high = b.value_typed_lane(fx, fx.tcx.types.u128, 1).load_scalar(fx);
fn select4(
fx: &mut FunctionCx<'_, '_, '_>,
@@ -224,16 +257,20 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
let control0 = imm8;
let res_low = select4(fx, a_high, a_low, b_high, b_low, control0);
- let (res_0, res_1) = fx.bcx.ins().isplit(res_low);
let control1 = fx.bcx.ins().ushr_imm(imm8, 4);
let res_high = select4(fx, a_high, a_low, b_high, b_low, control1);
- let (res_2, res_3) = fx.bcx.ins().isplit(res_high);
- ret.place_lane(fx, 0).to_ptr().store(fx, res_0, MemFlags::trusted());
- ret.place_lane(fx, 1).to_ptr().store(fx, res_1, MemFlags::trusted());
- ret.place_lane(fx, 2).to_ptr().store(fx, res_2, MemFlags::trusted());
- ret.place_lane(fx, 3).to_ptr().store(fx, res_3, MemFlags::trusted());
+ ret.place_typed_lane(fx, fx.tcx.types.u128, 0).to_ptr().store(
+ fx,
+ res_low,
+ MemFlags::trusted(),
+ );
+ ret.place_typed_lane(fx, fx.tcx.types.u128, 1).to_ptr().store(
+ fx,
+ res_high,
+ MemFlags::trusted(),
+ );
}
"llvm.x86.ssse3.pabs.b.128" | "llvm.x86.ssse3.pabs.w.128" | "llvm.x86.ssse3.pabs.d.128" => {
let a = match args {
@@ -309,7 +346,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
fx.bcx.ins().sshr(a_lane, saturated_count)
});
}
- "llvm.x86.sse2.psad.bw" => {
+ "llvm.x86.sse2.psad.bw" | "llvm.x86.avx2.psad.bw" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8&ig_expand=5770
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8&ig_expand=5771
intrinsic_args!(fx, args => (a, b); intrinsic);
assert_eq!(a.layout(), b.layout());
@@ -340,7 +379,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
ret.place_lane(fx, out_lane_idx).write_cvalue(fx, res_lane);
}
}
- "llvm.x86.ssse3.pmadd.ub.sw.128" => {
+ "llvm.x86.ssse3.pmadd.ub.sw.128" | "llvm.x86.avx2.pmadd.ub.sw" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16&ig_expand=4267
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_maddubs_epi16&ig_expand=4270
intrinsic_args!(fx, args => (a, b); intrinsic);
let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
@@ -379,7 +420,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
ret.place_lane(fx, out_lane_idx).write_cvalue(fx, res_lane);
}
}
- "llvm.x86.sse2.pmadd.wd" => {
+ "llvm.x86.sse2.pmadd.wd" | "llvm.x86.avx2.pmadd.wd" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_madd_epi16&ig_expand=4231
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_madd_epi16&ig_expand=4234
intrinsic_args!(fx, args => (a, b); intrinsic);
assert_eq!(a.layout(), b.layout());
@@ -412,6 +455,583 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
ret.place_lane(fx, out_lane_idx).write_cvalue(fx, res_lane);
}
}
+
+ "llvm.x86.ssse3.pmul.hr.sw.128" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16&ig_expand=4782
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i16);
+ assert_eq!(ret_lane_ty, fx.tcx.types.i16);
+ assert_eq!(lane_count, ret_lane_count);
+
+ let ret_lane_layout = fx.layout_of(fx.tcx.types.i16);
+ for out_lane_idx in 0..lane_count {
+ let a_lane = a.value_lane(fx, out_lane_idx).load_scalar(fx);
+ let a_lane = fx.bcx.ins().sextend(types::I32, a_lane);
+ let b_lane = b.value_lane(fx, out_lane_idx).load_scalar(fx);
+ let b_lane = fx.bcx.ins().sextend(types::I32, b_lane);
+
+ let mul: Value = fx.bcx.ins().imul(a_lane, b_lane);
+ let shifted = fx.bcx.ins().ushr_imm(mul, 14);
+ let incremented = fx.bcx.ins().iadd_imm(shifted, 1);
+ let shifted_again = fx.bcx.ins().ushr_imm(incremented, 1);
+
+ let res_lane = fx.bcx.ins().ireduce(types::I16, shifted_again);
+ let res_lane = CValue::by_val(res_lane, ret_lane_layout);
+
+ ret.place_lane(fx, out_lane_idx).write_cvalue(fx, res_lane);
+ }
+ }
+
+ "llvm.x86.sse2.packuswb.128" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi16&ig_expand=4903
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i16);
+ assert_eq!(ret_lane_ty, fx.tcx.types.u8);
+ assert_eq!(lane_count * 2, ret_lane_count);
+
+ let zero = fx.bcx.ins().iconst(types::I16, 0);
+ let max_u8 = fx.bcx.ins().iconst(types::I16, 255);
+ let ret_lane_layout = fx.layout_of(fx.tcx.types.u8);
+
+ for idx in 0..lane_count {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, zero);
+ let sat = fx.bcx.ins().umin(sat, max_u8);
+ let res = fx.bcx.ins().ireduce(types::I8, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, zero);
+ let sat = fx.bcx.ins().umin(sat, max_u8);
+ let res = fx.bcx.ins().ireduce(types::I8, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count + idx).write_cvalue(fx, res_lane);
+ }
+ }
+
+ "llvm.x86.avx2.packuswb" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi16&ig_expand=4906
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i16);
+ assert_eq!(ret_lane_ty, fx.tcx.types.u8);
+ assert_eq!(lane_count * 2, ret_lane_count);
+
+ let zero = fx.bcx.ins().iconst(types::I16, 0);
+ let max_u8 = fx.bcx.ins().iconst(types::I16, 255);
+ let ret_lane_layout = fx.layout_of(fx.tcx.types.u8);
+
+ for idx in 0..lane_count / 2 {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, zero);
+ let sat = fx.bcx.ins().umin(sat, max_u8);
+ let res = fx.bcx.ins().ireduce(types::I8, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count / 2 {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, zero);
+ let sat = fx.bcx.ins().umin(sat, max_u8);
+ let res = fx.bcx.ins().ireduce(types::I8, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count / 2 + idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count / 2 {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, zero);
+ let sat = fx.bcx.ins().umin(sat, max_u8);
+ let res = fx.bcx.ins().ireduce(types::I8, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count / 2 * 2 + idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count / 2 {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, zero);
+ let sat = fx.bcx.ins().umin(sat, max_u8);
+ let res = fx.bcx.ins().ireduce(types::I8, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count / 2 * 3 + idx).write_cvalue(fx, res_lane);
+ }
+ }
+
+ "llvm.x86.sse2.packssdw.128" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi32&ig_expand=4889
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i32);
+ assert_eq!(ret_lane_ty, fx.tcx.types.i16);
+ assert_eq!(lane_count * 2, ret_lane_count);
+
+ let min_i16 = fx.bcx.ins().iconst(types::I32, i64::from(i16::MIN as u16));
+ let max_i16 = fx.bcx.ins().iconst(types::I32, i64::from(i16::MAX as u16));
+ let ret_lane_layout = fx.layout_of(fx.tcx.types.i16);
+
+ for idx in 0..lane_count {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, min_i16);
+ let sat = fx.bcx.ins().umin(sat, max_i16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, min_i16);
+ let sat = fx.bcx.ins().umin(sat, max_i16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count + idx).write_cvalue(fx, res_lane);
+ }
+ }
+
+ "llvm.x86.sse41.packusdw" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi32&ig_expand=4912
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i32);
+ assert_eq!(ret_lane_ty, fx.tcx.types.u16);
+ assert_eq!(lane_count * 2, ret_lane_count);
+
+ let min_u16 = fx.bcx.ins().iconst(types::I32, i64::from(u16::MIN));
+ let max_u16 = fx.bcx.ins().iconst(types::I32, i64::from(u16::MAX));
+ let ret_lane_layout = fx.layout_of(fx.tcx.types.u16);
+
+ for idx in 0..lane_count {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().umax(lane, min_u16);
+ let sat = fx.bcx.ins().umin(sat, max_u16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().umax(lane, min_u16);
+ let sat = fx.bcx.ins().umin(sat, max_u16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count + idx).write_cvalue(fx, res_lane);
+ }
+ }
+
+ "llvm.x86.avx2.packssdw" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi32&ig_expand=4892
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i32);
+ assert_eq!(ret_lane_ty, fx.tcx.types.i16);
+ assert_eq!(lane_count * 2, ret_lane_count);
+
+ let min_i16 = fx.bcx.ins().iconst(types::I32, i64::from(i16::MIN as u16));
+ let max_i16 = fx.bcx.ins().iconst(types::I32, i64::from(i16::MAX as u16));
+ let ret_lane_layout = fx.layout_of(fx.tcx.types.i16);
+
+ for idx in 0..lane_count / 2 {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, min_i16);
+ let sat = fx.bcx.ins().umin(sat, max_i16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count / 2 {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, min_i16);
+ let sat = fx.bcx.ins().umin(sat, max_i16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count / 2 + idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count / 2 {
+ let lane = a.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, min_i16);
+ let sat = fx.bcx.ins().umin(sat, max_i16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count / 2 * 2 + idx).write_cvalue(fx, res_lane);
+ }
+
+ for idx in 0..lane_count / 2 {
+ let lane = b.value_lane(fx, idx).load_scalar(fx);
+ let sat = fx.bcx.ins().smax(lane, min_i16);
+ let sat = fx.bcx.ins().umin(sat, max_i16);
+ let res = fx.bcx.ins().ireduce(types::I16, sat);
+
+ let res_lane = CValue::by_val(res, ret_lane_layout);
+ ret.place_lane(fx, lane_count / 2 * 3 + idx).write_cvalue(fx, res_lane);
+ }
+ }
+
+ "llvm.x86.pclmulqdq" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_clmulepi64_si128&ig_expand=772
+ intrinsic_args!(fx, args => (a, b, _imm8); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let b = b.load_scalar(fx);
+
+ let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[2])
+ {
+ imm8
+ } else {
+ fx.tcx.sess.span_fatal(
+ span,
+ "Index argument for `_mm_clmulepi64_si128` is not a constant",
+ );
+ };
+
+ let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String(format!("pclmulqdq xmm0, xmm1, {imm8}"))],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ value: b,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.aesni.aeskeygenassist" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aeskeygenassist_si128&ig_expand=261
+ intrinsic_args!(fx, args => (a, _imm8); intrinsic);
+
+ let a = a.load_scalar(fx);
+
+ let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1])
+ {
+ imm8
+ } else {
+ fx.tcx.sess.span_fatal(
+ span,
+ "Index argument for `_mm_aeskeygenassist_si128` is not a constant",
+ );
+ };
+
+ let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String(format!("aeskeygenassist xmm0, xmm0, {imm8}"))],
+ &[CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ }],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.aesni.aesimc" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesimc_si128&ig_expand=260
+ intrinsic_args!(fx, args => (a); intrinsic);
+
+ let a = a.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("aesimc xmm0, xmm0".to_string())],
+ &[CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ }],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.aesni.aesenc" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128&ig_expand=252
+ intrinsic_args!(fx, args => (a, round_key); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let round_key = round_key.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("aesenc xmm0, xmm1".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ value: round_key,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.aesni.aesenclast" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128&ig_expand=257
+ intrinsic_args!(fx, args => (a, round_key); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let round_key = round_key.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("aesenclast xmm0, xmm1".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ value: round_key,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.aesni.aesdec" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128&ig_expand=242
+ intrinsic_args!(fx, args => (a, round_key); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let round_key = round_key.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("aesdec xmm0, xmm1".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ value: round_key,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.aesni.aesdeclast" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128&ig_expand=247
+ intrinsic_args!(fx, args => (a, round_key); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let round_key = round_key.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("aesdeclast xmm0, xmm1".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ value: round_key,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.sha256rnds2" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha256rnds2_epu32&ig_expand=5977
+ intrinsic_args!(fx, args => (a, b, k); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let b = b.load_scalar(fx);
+ let k = k.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("sha256rnds2 xmm1, xmm2".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+ value: b,
+ },
+ // Implicit argument to the sha256rnds2 instruction
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
+ value: k,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.sha256msg1" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha256msg1_epu32&ig_expand=5975
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let b = b.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("sha256msg1 xmm1, xmm2".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+ value: b,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.sha256msg2" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha256msg2_epu32&ig_expand=5976
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ let a = a.load_scalar(fx);
+ let b = b.load_scalar(fx);
+
+ codegen_inline_asm_inner(
+ fx,
+ &[InlineAsmTemplatePiece::String("sha256msg2 xmm1, xmm2".to_string())],
+ &[
+ CInlineAsmOperand::InOut {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+ _late: true,
+ in_value: a,
+ out_place: Some(ret),
+ },
+ CInlineAsmOperand::In {
+ reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+ value: b,
+ },
+ ],
+ InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+ );
+ }
+
+ "llvm.x86.avx.ptestz.256" => {
+ // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_testz_si256&ig_expand=6945
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ assert_eq!(a.layout(), b.layout());
+ let layout = a.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ assert_eq!(lane_ty, fx.tcx.types.i64);
+ assert_eq!(ret.layout().ty, fx.tcx.types.i32);
+ assert_eq!(lane_count, 4);
+
+ let a_lane0 = a.value_lane(fx, 0).load_scalar(fx);
+ let a_lane1 = a.value_lane(fx, 1).load_scalar(fx);
+ let a_lane2 = a.value_lane(fx, 2).load_scalar(fx);
+ let a_lane3 = a.value_lane(fx, 3).load_scalar(fx);
+ let b_lane0 = b.value_lane(fx, 0).load_scalar(fx);
+ let b_lane1 = b.value_lane(fx, 1).load_scalar(fx);
+ let b_lane2 = b.value_lane(fx, 2).load_scalar(fx);
+ let b_lane3 = b.value_lane(fx, 3).load_scalar(fx);
+
+ let zero0 = fx.bcx.ins().band(a_lane0, b_lane0);
+ let zero1 = fx.bcx.ins().band(a_lane1, b_lane1);
+ let zero2 = fx.bcx.ins().band(a_lane2, b_lane2);
+ let zero3 = fx.bcx.ins().band(a_lane3, b_lane3);
+
+ let all_zero0 = fx.bcx.ins().bor(zero0, zero1);
+ let all_zero1 = fx.bcx.ins().bor(zero2, zero3);
+ let all_zero = fx.bcx.ins().bor(all_zero0, all_zero1);
+
+ let res = fx.bcx.ins().icmp_imm(IntCC::Equal, all_zero, 0);
+ let res = CValue::by_val(
+ fx.bcx.ins().uextend(types::I32, res),
+ fx.layout_of(fx.tcx.types.i32),
+ );
+ ret.write_cvalue(fx, res);
+ }
+
_ => {
fx.tcx
.sess
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 83d5d53624eb1..bfeeb117ff5b3 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -132,6 +132,65 @@ fn simd_pair_for_each_lane<'tcx>(
}
}
+fn simd_horizontal_pair_for_each_lane<'tcx>(
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ x: CValue<'tcx>,
+ y: CValue<'tcx>,
+ ret: CPlace<'tcx>,
+ f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, Ty<'tcx>, Ty<'tcx>, Value, Value) -> Value,
+) {
+ assert_eq!(x.layout(), y.layout());
+ let layout = x.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let lane_layout = fx.layout_of(lane_ty);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ let ret_lane_layout = fx.layout_of(ret_lane_ty);
+ assert_eq!(lane_count, ret_lane_count);
+
+ for lane_idx in 0..lane_count {
+ let src = if lane_idx < (lane_count / 2) { x } else { y };
+ let src_idx = lane_idx % (lane_count / 2);
+
+ let lhs_lane = src.value_lane(fx, src_idx * 2).load_scalar(fx);
+ let rhs_lane = src.value_lane(fx, src_idx * 2 + 1).load_scalar(fx);
+
+ let res_lane = f(fx, lane_layout.ty, ret_lane_layout.ty, lhs_lane, rhs_lane);
+ let res_lane = CValue::by_val(res_lane, ret_lane_layout);
+
+ ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
+ }
+}
+
+fn simd_trio_for_each_lane<'tcx>(
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ x: CValue<'tcx>,
+ y: CValue<'tcx>,
+ z: CValue<'tcx>,
+ ret: CPlace<'tcx>,
+ f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, Ty<'tcx>, Ty<'tcx>, Value, Value, Value) -> Value,
+) {
+ assert_eq!(x.layout(), y.layout());
+ let layout = x.layout();
+
+ let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let lane_layout = fx.layout_of(lane_ty);
+ let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+ let ret_lane_layout = fx.layout_of(ret_lane_ty);
+ assert_eq!(lane_count, ret_lane_count);
+
+ for lane_idx in 0..lane_count {
+ let x_lane = x.value_lane(fx, lane_idx).load_scalar(fx);
+ let y_lane = y.value_lane(fx, lane_idx).load_scalar(fx);
+ let z_lane = z.value_lane(fx, lane_idx).load_scalar(fx);
+
+ let res_lane = f(fx, lane_layout.ty, ret_lane_layout.ty, x_lane, y_lane, z_lane);
+ let res_lane = CValue::by_val(res_lane, ret_lane_layout);
+
+ ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
+ }
+}
+
fn simd_reduce<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
val: CValue<'tcx>,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index ea137c4ca1e8c..0bd211fd614f0 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -282,11 +282,11 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
fx.tcx.sess.span_fatal(span, "Index argument for `simd_insert` is not a constant");
};
- let idx = idx_const
- .try_to_bits(Size::from_bytes(4 /* u32*/))
- .unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
+ let idx: u32 = idx_const
+ .try_to_u32()
+ .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const));
let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx);
- if idx >= lane_count.into() {
+ if u64::from(idx) >= lane_count {
fx.tcx.sess.span_fatal(
fx.mir.span,
format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count),
@@ -331,10 +331,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
};
let idx = idx_const
- .try_to_bits(Size::from_bytes(4 /* u32*/))
- .unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
+ .try_to_u32()
+ .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const));
let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx);
- if idx >= lane_count.into() {
+ if u64::from(idx) >= lane_count {
fx.tcx.sess.span_fatal(
fx.mir.span,
format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count),
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index 5f0aa6c5581dd..21ad2a835fc96 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -243,6 +243,34 @@ impl<'tcx> CValue<'tcx> {
let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
let lane_layout = fx.layout_of(lane_ty);
assert!(lane_idx < lane_count);
+
+ match self.0 {
+ CValueInner::ByVal(_) | CValueInner::ByValPair(_, _) => unreachable!(),
+ CValueInner::ByRef(ptr, None) => {
+ let field_offset = lane_layout.size * lane_idx;
+ let field_ptr = ptr.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap());
+ CValue::by_ref(field_ptr, lane_layout)
+ }
+ CValueInner::ByRef(_, Some(_)) => unreachable!(),
+ }
+ }
+
+ /// Like [`CValue::value_field`] except using the passed type as lane type instead of the one
+ /// specified by the vector type.
+ pub(crate) fn value_typed_lane(
+ self,
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ lane_ty: Ty<'tcx>,
+ lane_idx: u64,
+ ) -> CValue<'tcx> {
+ let layout = self.1;
+ assert!(layout.ty.is_simd());
+ let (orig_lane_count, orig_lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let lane_layout = fx.layout_of(lane_ty);
+ assert!(
+ (lane_idx + 1) * lane_layout.size <= orig_lane_count * fx.layout_of(orig_lane_ty).size
+ );
+
match self.0 {
CValueInner::ByVal(_) | CValueInner::ByValPair(_, _) => unreachable!(),
CValueInner::ByRef(ptr, None) => {
@@ -734,6 +762,34 @@ impl<'tcx> CPlace<'tcx> {
}
}
+ /// Like [`CPlace::place_field`] except using the passed type as lane type instead of the one
+ /// specified by the vector type.
+ pub(crate) fn place_typed_lane(
+ self,
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ lane_ty: Ty<'tcx>,
+ lane_idx: u64,
+ ) -> CPlace<'tcx> {
+ let layout = self.layout();
+ assert!(layout.ty.is_simd());
+ let (orig_lane_count, orig_lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+ let lane_layout = fx.layout_of(lane_ty);
+ assert!(
+ (lane_idx + 1) * lane_layout.size <= orig_lane_count * fx.layout_of(orig_lane_ty).size
+ );
+
+ match self.inner {
+ CPlaceInner::Var(_, _) => unreachable!(),
+ CPlaceInner::VarPair(_, _, _) => unreachable!(),
+ CPlaceInner::Addr(ptr, None) => {
+ let field_offset = lane_layout.size * lane_idx;
+ let field_ptr = ptr.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap());
+ CPlace::for_ptr(field_ptr, lane_layout)
+ }
+ CPlaceInner::Addr(_, Some(_)) => unreachable!(),
+ }
+ }
+
pub(crate) fn place_index(
self,
fx: &mut FunctionCx<'_, '_, 'tcx>,
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index a530fc994a22b..fd4af984bc039 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -12,9 +12,9 @@
* TODO(antoyo): remove the patches.
*/
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(
rustc_private,
decl_macro,
@@ -384,7 +384,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool, target_info: &Locke
.iter()
.filter_map(
|&(feature, gate)| {
- if sess.is_nightly_build() || allow_unstable || gate.is_none() { Some(feature) } else { None }
+ if sess.is_nightly_build() || allow_unstable || gate.is_stable() { Some(feature) } else { None }
},
)
.filter(|_feature| {
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index d5778757caae7..0c9f7f1955191 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -59,7 +59,7 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
// To avoid this, we set the Storage Class to "DllImport" so that
// LLVM will prefix the name with `__imp_`. Ideally, we'd like the
// existing logic below to set the Storage Class, but it has an
- // exemption for MinGW for backwards compatability.
+ // exemption for MinGW for backwards compatibility.
let llfn = cx.declare_fn(
&common::i686_decorated_name(
&dllimport,
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 0b0816c27b6df..d1b643f49677a 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -203,6 +203,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
unsafe {
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
+ llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
}
(s.to_owned(), g)
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 4dd6372b5e045..242c6aed906b4 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -368,6 +368,24 @@ pub unsafe fn create_module<'ll>(
llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
);
+ // Add module flags specified via -Z llvm_module_flag
+ for (key, value, behavior) in &sess.opts.unstable_opts.llvm_module_flag {
+ let key = format!("{key}\0");
+ let behavior = match behavior.as_str() {
+ "error" => llvm::LLVMModFlagBehavior::Error,
+ "warning" => llvm::LLVMModFlagBehavior::Warning,
+ "require" => llvm::LLVMModFlagBehavior::Require,
+ "override" => llvm::LLVMModFlagBehavior::Override,
+ "append" => llvm::LLVMModFlagBehavior::Append,
+ "appendunique" => llvm::LLVMModFlagBehavior::AppendUnique,
+ "max" => llvm::LLVMModFlagBehavior::Max,
+ "min" => llvm::LLVMModFlagBehavior::Min,
+ // We already checked this during option parsing
+ _ => unreachable!(),
+ };
+ llvm::LLVMRustAddModuleFlag(llmod, behavior, key.as_ptr().cast(), *value)
+ }
+
llmod
}
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 8a6a5f79b3bb9..3242e78ab7e44 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -4,9 +4,9 @@
//!
//! This API is completely unstable and subject to change.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(exact_size_is_empty)]
#![feature(extern_types)]
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index cc4ccaf19c282..c86bf81fc131e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -293,7 +293,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec {
supported_target_features(sess)
.iter()
.filter_map(|&(feature, gate)| {
- if sess.is_nightly_build() || allow_unstable || gate.is_none() {
+ if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
Some(feature)
} else {
None
@@ -554,7 +554,8 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec>(
// Arguments get assigned to by means of the function being called
for arg in mir.args_iter() {
- analyzer.assign(arg, DefLocation::Argument);
+ analyzer.define(arg, DefLocation::Argument);
}
// If there exists a local definition that dominates all uses of that local,
@@ -74,7 +74,7 @@ struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
}
impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
- fn assign(&mut self, local: mir::Local, location: DefLocation) {
+ fn define(&mut self, local: mir::Local, location: DefLocation) {
let kind = &mut self.locals[local];
match *kind {
LocalKind::ZST => {}
@@ -162,7 +162,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue);
if let Some(local) = place.as_local() {
- self.assign(local, DefLocation::Body(location));
+ self.define(local, DefLocation::Assignment(location));
if self.locals[local] != LocalKind::Memory {
let decl_span = self.fx.mir.local_decls[local].source_info.span;
if !self.fx.rvalue_creates_operand(rvalue, decl_span) {
@@ -183,9 +183,14 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
fn visit_local(&mut self, local: mir::Local, context: PlaceContext, location: Location) {
match context {
- PlaceContext::MutatingUse(MutatingUseContext::Call)
- | PlaceContext::MutatingUse(MutatingUseContext::Yield) => {
- self.assign(local, DefLocation::Body(location));
+ PlaceContext::MutatingUse(MutatingUseContext::Call) => {
+ let call = location.block;
+ let TerminatorKind::Call { target, .. } =
+ self.fx.mir.basic_blocks[call].terminator().kind
+ else {
+ bug!()
+ };
+ self.define(local, DefLocation::CallReturn { call, target });
}
PlaceContext::NonUse(_)
@@ -237,6 +242,8 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
}
}
}
+
+ PlaceContext::MutatingUse(MutatingUseContext::Yield) => bug!(),
}
}
}
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 2936f1de3cbf8..d802816bb7561 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -19,10 +19,44 @@ use rustc_span::Span;
/// Features that control behaviour of rustc, rather than the codegen.
pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
+/// Stability information for target features.
+#[derive(Debug, Clone, Copy)]
+pub enum Stability {
+ /// This target feature is stable, it can be used in `#[target_feature]` and
+ /// `#[cfg(target_feature)]`.
+ Stable,
+ /// This target feature is unstable; using it in `#[target_feature]` or `#[cfg(target_feature)]`
+ /// requires enabling the given nightly feature.
+ Unstable(Symbol),
+}
+use Stability::*;
+
+impl Stability {
+ fn as_feature_name(self) -> Option {
+ match self {
+ Stable => None,
+ Unstable(s) => Some(s),
+ }
+ }
+
+ pub fn is_stable(self) -> bool {
+ matches!(self, Stable)
+ }
+}
+
+// Here we list target features that rustc "understands": they can be used in `#[target_feature]`
+// and `#[cfg(target_feature)]`. They also do not trigger any warnings when used with
+// `-Ctarget-feature`.
+//
// When adding features to the below lists
// check whether they're named already elsewhere in rust
// e.g. in stdarch and whether the given name matches LLVM's
-// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted
+// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted.
+//
+// Also note that all target features listed here must be purely additive: for target_feature 1.1 to
+// be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a
+// per-function level, since we would then allow safe calls from functions with `+soft-float` to
+// functions without that feature!
//
// When adding a new feature, be particularly mindful of features that affect function ABIs. Those
// need to be treated very carefully to avoid introducing unsoundness! This often affects features
@@ -30,139 +64,138 @@ pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
// example of this going wrong), but features enabling new SIMD registers are also a concern (see
// https://github.com/rust-lang/rust/issues/116558 for an example of this going wrong).
//
-// Stabilizing a target feature (setting the 2nd component of the pair to `None`) requires t-lang
-// approval.
+// Stabilizing a target feature requires t-lang approval.
-const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const ARM_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("aclass", Some(sym::arm_target_feature)),
- ("aes", Some(sym::arm_target_feature)),
- ("crc", Some(sym::arm_target_feature)),
- ("d32", Some(sym::arm_target_feature)),
- ("dotprod", Some(sym::arm_target_feature)),
- ("dsp", Some(sym::arm_target_feature)),
- ("fp-armv8", Some(sym::arm_target_feature)),
- ("i8mm", Some(sym::arm_target_feature)),
- ("mclass", Some(sym::arm_target_feature)),
- ("neon", Some(sym::arm_target_feature)),
- ("rclass", Some(sym::arm_target_feature)),
- ("sha2", Some(sym::arm_target_feature)),
+ ("aclass", Unstable(sym::arm_target_feature)),
+ ("aes", Unstable(sym::arm_target_feature)),
+ ("crc", Unstable(sym::arm_target_feature)),
+ ("d32", Unstable(sym::arm_target_feature)),
+ ("dotprod", Unstable(sym::arm_target_feature)),
+ ("dsp", Unstable(sym::arm_target_feature)),
+ ("fp-armv8", Unstable(sym::arm_target_feature)),
+ ("i8mm", Unstable(sym::arm_target_feature)),
+ ("mclass", Unstable(sym::arm_target_feature)),
+ ("neon", Unstable(sym::arm_target_feature)),
+ ("rclass", Unstable(sym::arm_target_feature)),
+ ("sha2", Unstable(sym::arm_target_feature)),
// This is needed for inline assembly, but shouldn't be stabilized as-is
// since it should be enabled per-function using #[instruction_set], not
// #[target_feature].
- ("thumb-mode", Some(sym::arm_target_feature)),
- ("thumb2", Some(sym::arm_target_feature)),
- ("trustzone", Some(sym::arm_target_feature)),
- ("v5te", Some(sym::arm_target_feature)),
- ("v6", Some(sym::arm_target_feature)),
- ("v6k", Some(sym::arm_target_feature)),
- ("v6t2", Some(sym::arm_target_feature)),
- ("v7", Some(sym::arm_target_feature)),
- ("v8", Some(sym::arm_target_feature)),
- ("vfp2", Some(sym::arm_target_feature)),
- ("vfp3", Some(sym::arm_target_feature)),
- ("vfp4", Some(sym::arm_target_feature)),
- ("virtualization", Some(sym::arm_target_feature)),
+ ("thumb-mode", Unstable(sym::arm_target_feature)),
+ ("thumb2", Unstable(sym::arm_target_feature)),
+ ("trustzone", Unstable(sym::arm_target_feature)),
+ ("v5te", Unstable(sym::arm_target_feature)),
+ ("v6", Unstable(sym::arm_target_feature)),
+ ("v6k", Unstable(sym::arm_target_feature)),
+ ("v6t2", Unstable(sym::arm_target_feature)),
+ ("v7", Unstable(sym::arm_target_feature)),
+ ("v8", Unstable(sym::arm_target_feature)),
+ ("vfp2", Unstable(sym::arm_target_feature)),
+ ("vfp3", Unstable(sym::arm_target_feature)),
+ ("vfp4", Unstable(sym::arm_target_feature)),
+ ("virtualization", Unstable(sym::arm_target_feature)),
// tidy-alphabetical-end
];
-const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const AARCH64_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
// FEAT_AES
- ("aes", None),
+ ("aes", Stable),
// FEAT_BF16
- ("bf16", None),
+ ("bf16", Stable),
// FEAT_BTI
- ("bti", None),
+ ("bti", Stable),
// FEAT_CRC
- ("crc", None),
+ ("crc", Stable),
// FEAT_DIT
- ("dit", None),
+ ("dit", Stable),
// FEAT_DotProd
- ("dotprod", None),
+ ("dotprod", Stable),
// FEAT_DPB
- ("dpb", None),
+ ("dpb", Stable),
// FEAT_DPB2
- ("dpb2", None),
+ ("dpb2", Stable),
// FEAT_F32MM
- ("f32mm", None),
+ ("f32mm", Stable),
// FEAT_F64MM
- ("f64mm", None),
+ ("f64mm", Stable),
// FEAT_FCMA
- ("fcma", None),
+ ("fcma", Stable),
// FEAT_FHM
- ("fhm", None),
+ ("fhm", Stable),
// FEAT_FLAGM
- ("flagm", None),
+ ("flagm", Stable),
// FEAT_FP16
- ("fp16", None),
+ ("fp16", Stable),
// FEAT_FRINTTS
- ("frintts", None),
+ ("frintts", Stable),
// FEAT_I8MM
- ("i8mm", None),
+ ("i8mm", Stable),
// FEAT_JSCVT
- ("jsconv", None),
+ ("jsconv", Stable),
// FEAT_LOR
- ("lor", None),
+ ("lor", Stable),
// FEAT_LSE
- ("lse", None),
+ ("lse", Stable),
// FEAT_MTE
- ("mte", None),
+ ("mte", Stable),
// FEAT_AdvSimd & FEAT_FP
- ("neon", None),
+ ("neon", Stable),
// FEAT_PAUTH (address authentication)
- ("paca", None),
+ ("paca", Stable),
// FEAT_PAUTH (generic authentication)
- ("pacg", None),
+ ("pacg", Stable),
// FEAT_PAN
- ("pan", None),
+ ("pan", Stable),
// FEAT_PMUv3
- ("pmuv3", None),
+ ("pmuv3", Stable),
// FEAT_RAND
- ("rand", None),
+ ("rand", Stable),
// FEAT_RAS
- ("ras", None),
+ ("ras", Stable),
// FEAT_RCPC
- ("rcpc", None),
+ ("rcpc", Stable),
// FEAT_RCPC2
- ("rcpc2", None),
+ ("rcpc2", Stable),
// FEAT_RDM
- ("rdm", None),
+ ("rdm", Stable),
// FEAT_SB
- ("sb", None),
+ ("sb", Stable),
// FEAT_SHA1 & FEAT_SHA256
- ("sha2", None),
+ ("sha2", Stable),
// FEAT_SHA512 & FEAT_SHA3
- ("sha3", None),
+ ("sha3", Stable),
// FEAT_SM3 & FEAT_SM4
- ("sm4", None),
+ ("sm4", Stable),
// FEAT_SPE
- ("spe", None),
+ ("spe", Stable),
// FEAT_SSBS
- ("ssbs", None),
+ ("ssbs", Stable),
// FEAT_SVE
- ("sve", None),
+ ("sve", Stable),
// FEAT_SVE2
- ("sve2", None),
+ ("sve2", Stable),
// FEAT_SVE2_AES
- ("sve2-aes", None),
+ ("sve2-aes", Stable),
// FEAT_SVE2_BitPerm
- ("sve2-bitperm", None),
+ ("sve2-bitperm", Stable),
// FEAT_SVE2_SHA3
- ("sve2-sha3", None),
+ ("sve2-sha3", Stable),
// FEAT_SVE2_SM4
- ("sve2-sm4", None),
+ ("sve2-sm4", Stable),
// FEAT_TME
- ("tme", None),
- ("v8.1a", Some(sym::aarch64_ver_target_feature)),
- ("v8.2a", Some(sym::aarch64_ver_target_feature)),
- ("v8.3a", Some(sym::aarch64_ver_target_feature)),
- ("v8.4a", Some(sym::aarch64_ver_target_feature)),
- ("v8.5a", Some(sym::aarch64_ver_target_feature)),
- ("v8.6a", Some(sym::aarch64_ver_target_feature)),
- ("v8.7a", Some(sym::aarch64_ver_target_feature)),
+ ("tme", Stable),
+ ("v8.1a", Unstable(sym::aarch64_ver_target_feature)),
+ ("v8.2a", Unstable(sym::aarch64_ver_target_feature)),
+ ("v8.3a", Unstable(sym::aarch64_ver_target_feature)),
+ ("v8.4a", Unstable(sym::aarch64_ver_target_feature)),
+ ("v8.5a", Unstable(sym::aarch64_ver_target_feature)),
+ ("v8.6a", Unstable(sym::aarch64_ver_target_feature)),
+ ("v8.7a", Unstable(sym::aarch64_ver_target_feature)),
// FEAT_VHE
- ("vh", None),
+ ("vh", Stable),
// tidy-alphabetical-end
];
@@ -170,197 +203,197 @@ const AARCH64_TIED_FEATURES: &[&[&str]] = &[
&["paca", "pacg"], // Together these represent `pauth` in LLVM
];
-const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("adx", None),
- ("aes", None),
- ("avx", None),
- ("avx2", None),
- ("avx512bf16", Some(sym::avx512_target_feature)),
- ("avx512bitalg", Some(sym::avx512_target_feature)),
- ("avx512bw", Some(sym::avx512_target_feature)),
- ("avx512cd", Some(sym::avx512_target_feature)),
- ("avx512dq", Some(sym::avx512_target_feature)),
- ("avx512er", Some(sym::avx512_target_feature)),
- ("avx512f", Some(sym::avx512_target_feature)),
- ("avx512ifma", Some(sym::avx512_target_feature)),
- ("avx512pf", Some(sym::avx512_target_feature)),
- ("avx512vbmi", Some(sym::avx512_target_feature)),
- ("avx512vbmi2", Some(sym::avx512_target_feature)),
- ("avx512vl", Some(sym::avx512_target_feature)),
- ("avx512vnni", Some(sym::avx512_target_feature)),
- ("avx512vp2intersect", Some(sym::avx512_target_feature)),
- ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
- ("bmi1", None),
- ("bmi2", None),
- ("cmpxchg16b", None),
- ("ermsb", Some(sym::ermsb_target_feature)),
- ("f16c", None),
- ("fma", None),
- ("fxsr", None),
- ("gfni", Some(sym::avx512_target_feature)),
- ("lzcnt", None),
- ("movbe", None),
- ("pclmulqdq", None),
- ("popcnt", None),
- ("rdrand", None),
- ("rdseed", None),
- ("rtm", Some(sym::rtm_target_feature)),
- ("sha", None),
- ("sse", None),
- ("sse2", None),
- ("sse3", None),
- ("sse4.1", None),
- ("sse4.2", None),
- ("sse4a", Some(sym::sse4a_target_feature)),
- ("ssse3", None),
- ("tbm", Some(sym::tbm_target_feature)),
- ("vaes", Some(sym::avx512_target_feature)),
- ("vpclmulqdq", Some(sym::avx512_target_feature)),
- ("xsave", None),
- ("xsavec", None),
- ("xsaveopt", None),
- ("xsaves", None),
+ ("adx", Stable),
+ ("aes", Stable),
+ ("avx", Stable),
+ ("avx2", Stable),
+ ("avx512bf16", Unstable(sym::avx512_target_feature)),
+ ("avx512bitalg", Unstable(sym::avx512_target_feature)),
+ ("avx512bw", Unstable(sym::avx512_target_feature)),
+ ("avx512cd", Unstable(sym::avx512_target_feature)),
+ ("avx512dq", Unstable(sym::avx512_target_feature)),
+ ("avx512er", Unstable(sym::avx512_target_feature)),
+ ("avx512f", Unstable(sym::avx512_target_feature)),
+ ("avx512ifma", Unstable(sym::avx512_target_feature)),
+ ("avx512pf", Unstable(sym::avx512_target_feature)),
+ ("avx512vbmi", Unstable(sym::avx512_target_feature)),
+ ("avx512vbmi2", Unstable(sym::avx512_target_feature)),
+ ("avx512vl", Unstable(sym::avx512_target_feature)),
+ ("avx512vnni", Unstable(sym::avx512_target_feature)),
+ ("avx512vp2intersect", Unstable(sym::avx512_target_feature)),
+ ("avx512vpopcntdq", Unstable(sym::avx512_target_feature)),
+ ("bmi1", Stable),
+ ("bmi2", Stable),
+ ("cmpxchg16b", Stable),
+ ("ermsb", Unstable(sym::ermsb_target_feature)),
+ ("f16c", Stable),
+ ("fma", Stable),
+ ("fxsr", Stable),
+ ("gfni", Unstable(sym::avx512_target_feature)),
+ ("lzcnt", Stable),
+ ("movbe", Stable),
+ ("pclmulqdq", Stable),
+ ("popcnt", Stable),
+ ("rdrand", Stable),
+ ("rdseed", Stable),
+ ("rtm", Unstable(sym::rtm_target_feature)),
+ ("sha", Stable),
+ ("sse", Stable),
+ ("sse2", Stable),
+ ("sse3", Stable),
+ ("sse4.1", Stable),
+ ("sse4.2", Stable),
+ ("sse4a", Unstable(sym::sse4a_target_feature)),
+ ("ssse3", Stable),
+ ("tbm", Unstable(sym::tbm_target_feature)),
+ ("vaes", Unstable(sym::avx512_target_feature)),
+ ("vpclmulqdq", Unstable(sym::avx512_target_feature)),
+ ("xsave", Stable),
+ ("xsavec", Stable),
+ ("xsaveopt", Stable),
+ ("xsaves", Stable),
// tidy-alphabetical-end
];
-const HEXAGON_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const HEXAGON_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("hvx", Some(sym::hexagon_target_feature)),
- ("hvx-length128b", Some(sym::hexagon_target_feature)),
+ ("hvx", Unstable(sym::hexagon_target_feature)),
+ ("hvx-length128b", Unstable(sym::hexagon_target_feature)),
// tidy-alphabetical-end
];
-const POWERPC_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const POWERPC_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("altivec", Some(sym::powerpc_target_feature)),
- ("power10-vector", Some(sym::powerpc_target_feature)),
- ("power8-altivec", Some(sym::powerpc_target_feature)),
- ("power8-vector", Some(sym::powerpc_target_feature)),
- ("power9-altivec", Some(sym::powerpc_target_feature)),
- ("power9-vector", Some(sym::powerpc_target_feature)),
- ("vsx", Some(sym::powerpc_target_feature)),
+ ("altivec", Unstable(sym::powerpc_target_feature)),
+ ("power10-vector", Unstable(sym::powerpc_target_feature)),
+ ("power8-altivec", Unstable(sym::powerpc_target_feature)),
+ ("power8-vector", Unstable(sym::powerpc_target_feature)),
+ ("power9-altivec", Unstable(sym::powerpc_target_feature)),
+ ("power9-vector", Unstable(sym::powerpc_target_feature)),
+ ("vsx", Unstable(sym::powerpc_target_feature)),
// tidy-alphabetical-end
];
-const MIPS_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const MIPS_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("fp64", Some(sym::mips_target_feature)),
- ("msa", Some(sym::mips_target_feature)),
- ("virt", Some(sym::mips_target_feature)),
+ ("fp64", Unstable(sym::mips_target_feature)),
+ ("msa", Unstable(sym::mips_target_feature)),
+ ("virt", Unstable(sym::mips_target_feature)),
// tidy-alphabetical-end
];
-const RISCV_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const RISCV_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("a", None),
- ("c", None),
- ("d", Some(sym::riscv_target_feature)),
- ("e", Some(sym::riscv_target_feature)),
- ("f", Some(sym::riscv_target_feature)),
- ("m", None),
- ("relax", Some(sym::riscv_target_feature)),
- ("unaligned-scalar-mem", Some(sym::riscv_target_feature)),
- ("v", Some(sym::riscv_target_feature)),
- ("zba", None),
- ("zbb", None),
- ("zbc", None),
- ("zbkb", None),
- ("zbkc", None),
- ("zbkx", None),
- ("zbs", None),
- ("zdinx", Some(sym::riscv_target_feature)),
- ("zfh", Some(sym::riscv_target_feature)),
- ("zfhmin", Some(sym::riscv_target_feature)),
- ("zfinx", Some(sym::riscv_target_feature)),
- ("zhinx", Some(sym::riscv_target_feature)),
- ("zhinxmin", Some(sym::riscv_target_feature)),
- ("zk", None),
- ("zkn", None),
- ("zknd", None),
- ("zkne", None),
- ("zknh", None),
- ("zkr", None),
- ("zks", None),
- ("zksed", None),
- ("zksh", None),
- ("zkt", None),
+ ("a", Stable),
+ ("c", Stable),
+ ("d", Unstable(sym::riscv_target_feature)),
+ ("e", Unstable(sym::riscv_target_feature)),
+ ("f", Unstable(sym::riscv_target_feature)),
+ ("m", Stable),
+ ("relax", Unstable(sym::riscv_target_feature)),
+ ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature)),
+ ("v", Unstable(sym::riscv_target_feature)),
+ ("zba", Stable),
+ ("zbb", Stable),
+ ("zbc", Stable),
+ ("zbkb", Stable),
+ ("zbkc", Stable),
+ ("zbkx", Stable),
+ ("zbs", Stable),
+ ("zdinx", Unstable(sym::riscv_target_feature)),
+ ("zfh", Unstable(sym::riscv_target_feature)),
+ ("zfhmin", Unstable(sym::riscv_target_feature)),
+ ("zfinx", Unstable(sym::riscv_target_feature)),
+ ("zhinx", Unstable(sym::riscv_target_feature)),
+ ("zhinxmin", Unstable(sym::riscv_target_feature)),
+ ("zk", Stable),
+ ("zkn", Stable),
+ ("zknd", Stable),
+ ("zkne", Stable),
+ ("zknh", Stable),
+ ("zkr", Stable),
+ ("zks", Stable),
+ ("zksed", Stable),
+ ("zksh", Stable),
+ ("zkt", Stable),
// tidy-alphabetical-end
];
-const WASM_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const WASM_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("atomics", Some(sym::wasm_target_feature)),
- ("bulk-memory", Some(sym::wasm_target_feature)),
- ("exception-handling", Some(sym::wasm_target_feature)),
- ("multivalue", Some(sym::wasm_target_feature)),
- ("mutable-globals", Some(sym::wasm_target_feature)),
- ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
- ("reference-types", Some(sym::wasm_target_feature)),
- ("relaxed-simd", Some(sym::wasm_target_feature)),
- ("sign-ext", Some(sym::wasm_target_feature)),
- ("simd128", None),
+ ("atomics", Unstable(sym::wasm_target_feature)),
+ ("bulk-memory", Unstable(sym::wasm_target_feature)),
+ ("exception-handling", Unstable(sym::wasm_target_feature)),
+ ("multivalue", Unstable(sym::wasm_target_feature)),
+ ("mutable-globals", Unstable(sym::wasm_target_feature)),
+ ("nontrapping-fptoint", Unstable(sym::wasm_target_feature)),
+ ("reference-types", Unstable(sym::wasm_target_feature)),
+ ("relaxed-simd", Unstable(sym::wasm_target_feature)),
+ ("sign-ext", Unstable(sym::wasm_target_feature)),
+ ("simd128", Stable),
// tidy-alphabetical-end
];
-const BPF_ALLOWED_FEATURES: &[(&str, Option)] = &[("alu32", Some(sym::bpf_target_feature))];
+const BPF_ALLOWED_FEATURES: &[(&str, Stability)] = &[("alu32", Unstable(sym::bpf_target_feature))];
-const CSKY_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const CSKY_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("10e60", Some(sym::csky_target_feature)),
- ("2e3", Some(sym::csky_target_feature)),
- ("3e3r1", Some(sym::csky_target_feature)),
- ("3e3r2", Some(sym::csky_target_feature)),
- ("3e3r3", Some(sym::csky_target_feature)),
- ("3e7", Some(sym::csky_target_feature)),
- ("7e10", Some(sym::csky_target_feature)),
- ("cache", Some(sym::csky_target_feature)),
- ("doloop", Some(sym::csky_target_feature)),
- ("dsp1e2", Some(sym::csky_target_feature)),
- ("dspe60", Some(sym::csky_target_feature)),
- ("e1", Some(sym::csky_target_feature)),
- ("e2", Some(sym::csky_target_feature)),
- ("edsp", Some(sym::csky_target_feature)),
- ("elrw", Some(sym::csky_target_feature)),
- ("float1e2", Some(sym::csky_target_feature)),
- ("float1e3", Some(sym::csky_target_feature)),
- ("float3e4", Some(sym::csky_target_feature)),
- ("float7e60", Some(sym::csky_target_feature)),
- ("floate1", Some(sym::csky_target_feature)),
- ("hard-tp", Some(sym::csky_target_feature)),
- ("high-registers", Some(sym::csky_target_feature)),
- ("hwdiv", Some(sym::csky_target_feature)),
- ("mp", Some(sym::csky_target_feature)),
- ("mp1e2", Some(sym::csky_target_feature)),
- ("nvic", Some(sym::csky_target_feature)),
- ("trust", Some(sym::csky_target_feature)),
- ("vdsp2e60f", Some(sym::csky_target_feature)),
- ("vdspv1", Some(sym::csky_target_feature)),
- ("vdspv2", Some(sym::csky_target_feature)),
+ ("10e60", Unstable(sym::csky_target_feature)),
+ ("2e3", Unstable(sym::csky_target_feature)),
+ ("3e3r1", Unstable(sym::csky_target_feature)),
+ ("3e3r2", Unstable(sym::csky_target_feature)),
+ ("3e3r3", Unstable(sym::csky_target_feature)),
+ ("3e7", Unstable(sym::csky_target_feature)),
+ ("7e10", Unstable(sym::csky_target_feature)),
+ ("cache", Unstable(sym::csky_target_feature)),
+ ("doloop", Unstable(sym::csky_target_feature)),
+ ("dsp1e2", Unstable(sym::csky_target_feature)),
+ ("dspe60", Unstable(sym::csky_target_feature)),
+ ("e1", Unstable(sym::csky_target_feature)),
+ ("e2", Unstable(sym::csky_target_feature)),
+ ("edsp", Unstable(sym::csky_target_feature)),
+ ("elrw", Unstable(sym::csky_target_feature)),
+ ("float1e2", Unstable(sym::csky_target_feature)),
+ ("float1e3", Unstable(sym::csky_target_feature)),
+ ("float3e4", Unstable(sym::csky_target_feature)),
+ ("float7e60", Unstable(sym::csky_target_feature)),
+ ("floate1", Unstable(sym::csky_target_feature)),
+ ("hard-tp", Unstable(sym::csky_target_feature)),
+ ("high-registers", Unstable(sym::csky_target_feature)),
+ ("hwdiv", Unstable(sym::csky_target_feature)),
+ ("mp", Unstable(sym::csky_target_feature)),
+ ("mp1e2", Unstable(sym::csky_target_feature)),
+ ("nvic", Unstable(sym::csky_target_feature)),
+ ("trust", Unstable(sym::csky_target_feature)),
+ ("vdsp2e60f", Unstable(sym::csky_target_feature)),
+ ("vdspv1", Unstable(sym::csky_target_feature)),
+ ("vdspv2", Unstable(sym::csky_target_feature)),
// tidy-alphabetical-end
//fpu
// tidy-alphabetical-start
- ("fdivdu", Some(sym::csky_target_feature)),
- ("fpuv2_df", Some(sym::csky_target_feature)),
- ("fpuv2_sf", Some(sym::csky_target_feature)),
- ("fpuv3_df", Some(sym::csky_target_feature)),
- ("fpuv3_hf", Some(sym::csky_target_feature)),
- ("fpuv3_hi", Some(sym::csky_target_feature)),
- ("fpuv3_sf", Some(sym::csky_target_feature)),
- ("hard-float", Some(sym::csky_target_feature)),
- ("hard-float-abi", Some(sym::csky_target_feature)),
+ ("fdivdu", Unstable(sym::csky_target_feature)),
+ ("fpuv2_df", Unstable(sym::csky_target_feature)),
+ ("fpuv2_sf", Unstable(sym::csky_target_feature)),
+ ("fpuv3_df", Unstable(sym::csky_target_feature)),
+ ("fpuv3_hf", Unstable(sym::csky_target_feature)),
+ ("fpuv3_hi", Unstable(sym::csky_target_feature)),
+ ("fpuv3_sf", Unstable(sym::csky_target_feature)),
+ ("hard-float", Unstable(sym::csky_target_feature)),
+ ("hard-float-abi", Unstable(sym::csky_target_feature)),
// tidy-alphabetical-end
];
-const LOONGARCH_ALLOWED_FEATURES: &[(&str, Option)] = &[
+const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[
// tidy-alphabetical-start
- ("d", Some(sym::loongarch_target_feature)),
- ("f", Some(sym::loongarch_target_feature)),
- ("lasx", Some(sym::loongarch_target_feature)),
- ("lbt", Some(sym::loongarch_target_feature)),
- ("lsx", Some(sym::loongarch_target_feature)),
- ("lvz", Some(sym::loongarch_target_feature)),
- ("ual", Some(sym::loongarch_target_feature)),
+ ("d", Unstable(sym::loongarch_target_feature)),
+ ("f", Unstable(sym::loongarch_target_feature)),
+ ("lasx", Unstable(sym::loongarch_target_feature)),
+ ("lbt", Unstable(sym::loongarch_target_feature)),
+ ("lsx", Unstable(sym::loongarch_target_feature)),
+ ("lvz", Unstable(sym::loongarch_target_feature)),
+ ("ual", Unstable(sym::loongarch_target_feature)),
// tidy-alphabetical-end
];
@@ -368,7 +401,7 @@ const LOONGARCH_ALLOWED_FEATURES: &[(&str, Option)] = &[
/// primitives may be documented.
///
/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
-pub fn all_known_features() -> impl Iterator- )> {
+pub fn all_known_features() -> impl Iterator
- {
std::iter::empty()
.chain(ARM_ALLOWED_FEATURES.iter())
.chain(AARCH64_ALLOWED_FEATURES.iter())
@@ -384,7 +417,7 @@ pub fn all_known_features() -> impl Iterator
- &'static [(&'static str, Option)] {
+pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Stability)] {
match &*sess.target.arch {
"arm" => ARM_ALLOWED_FEATURES,
"aarch64" => AARCH64_ALLOWED_FEATURES,
@@ -529,11 +562,11 @@ pub(crate) fn provide(providers: &mut Providers) {
if tcx.sess.opts.actually_rustdoc {
// rustdoc needs to be able to document functions that use all the features, so
// whitelist them all
- all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
+ all_known_features().map(|(a, b)| (a.to_string(), b.as_feature_name())).collect()
} else {
supported_target_features(tcx.sess)
.iter()
- .map(|&(a, b)| (a.to_string(), b))
+ .map(|&(a, b)| (a.to_string(), b.as_feature_name()))
.collect()
}
},
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index fd17367037438..d9f583c1d1f68 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -119,7 +119,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if matches!(ty.kind(), ty::Adt(def, ..) if def.variants().is_empty()) {
throw_ub!(UninhabitedEnumVariantRead(index))
}
- // For consisteny with `write_discriminant`, and to make sure that
+ // For consistency with `write_discriminant`, and to make sure that
// `project_downcast` cannot fail due to strange layouts, we declare immediate UB
// for uninhabited variants.
if op.layout().for_variant(self, index).abi.is_uninhabited() {
@@ -236,7 +236,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
variant
}
};
- // For consisteny with `write_discriminant`, and to make sure that `project_downcast` cannot fail due to strange layouts, we declare immediate UB for uninhabited variants.
+ // For consistency with `write_discriminant`, and to make sure that `project_downcast` cannot fail due to strange layouts, we declare immediate UB for uninhabited variants.
if op.layout().for_variant(self, index).abi.is_uninhabited() {
throw_ub!(UninhabitedEnumVariantRead(index))
}
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index a3ba9530f9dc7..128b548f43d49 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -114,9 +114,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
use rustc_middle::mir::BinOp::*;
// Performs appropriate non-deterministic adjustments of NaN results.
- let adjust_nan = |f: F| -> F {
- if f.is_nan() { M::generate_nan(self, &[l, r]) } else { f }
- };
+ let adjust_nan =
+ |f: F| -> F { if f.is_nan() { M::generate_nan(self, &[l, r]) } else { f } };
let val = match bin_op {
Eq => ImmTy::from_bool(l == r, *self.tcx),
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 1e21c49407074..26ff757ca5907 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -4,9 +4,9 @@ Rust MIR: a lowered representation of Rust.
*/
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![deny(rustc::untranslatable_diagnostic)]
#![feature(assert_matches)]
#![feature(box_patterns)]
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index d09c026c4b4e1..3ef87684fa5d7 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -10,12 +10,11 @@
#![allow(internal_features)]
#![allow(rustc::default_hash_types)]
#![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
#![deny(rustc::diagnostic_outside_of_impl)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![doc(rust_logo)]
#![feature(allocator_api)]
#![feature(array_windows)]
#![feature(auto_traits)]
@@ -34,6 +33,7 @@
#![feature(never_type)]
#![feature(ptr_alignment_type)]
#![feature(rustc_attrs)]
+#![feature(rustdoc_internals)]
#![feature(strict_provenance)]
#![feature(test)]
#![feature(thread_id_value)]
diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs
index 29516fffd6a62..639f05c9e524a 100644
--- a/compiler/rustc_data_structures/src/sharded.rs
+++ b/compiler/rustc_data_structures/src/sharded.rs
@@ -79,7 +79,7 @@ impl Sharded {
pub fn lock_shard_by_value(&self, _val: &K) -> LockGuard<'_, T> {
match self {
Self::Single(single) => {
- // Syncronization is disabled so use the `lock_assume_no_sync` method optimized
+ // Synchronization is disabled so use the `lock_assume_no_sync` method optimized
// for that case.
// SAFETY: We know `is_dyn_thread_safe` was false when creating the lock thus
@@ -102,7 +102,7 @@ impl Sharded {
pub fn lock_shard_by_index(&self, _i: usize) -> LockGuard<'_, T> {
match self {
Self::Single(single) => {
- // Syncronization is disabled so use the `lock_assume_no_sync` method optimized
+ // Synchronization is disabled so use the `lock_assume_no_sync` method optimized
// for that case.
// SAFETY: We know `is_dyn_thread_safe` was false when creating the lock thus
@@ -111,7 +111,7 @@ impl Sharded {
}
#[cfg(parallel_compiler)]
Self::Shards(shards) => {
- // Syncronization is enabled so use the `lock_assume_sync` method optimized
+ // Synchronization is enabled so use the `lock_assume_sync` method optimized
// for that case.
// SAFETY (get_unchecked): The index gets ANDed with the shard mask, ensuring it is
diff --git a/compiler/rustc_data_structures/src/sync/lock.rs b/compiler/rustc_data_structures/src/sync/lock.rs
index 339aebbf81aae..040a8aa6b6380 100644
--- a/compiler/rustc_data_structures/src/sync/lock.rs
+++ b/compiler/rustc_data_structures/src/sync/lock.rs
@@ -38,7 +38,7 @@ mod maybe_sync {
lock: &'a Lock,
marker: PhantomData<&'a mut T>,
- /// The syncronization mode of the lock. This is explicitly passed to let LLVM relate it
+ /// The synchronization mode of the lock. This is explicitly passed to let LLVM relate it
/// to the original lock operation.
mode: Mode,
}
@@ -142,7 +142,7 @@ mod maybe_sync {
.then(|| LockGuard { lock: self, marker: PhantomData, mode })
}
- /// This acquires the lock assuming syncronization is in a specific mode.
+ /// This acquires the lock assuming synchronization is in a specific mode.
///
/// Safety
/// This method must only be called with `Mode::Sync` if `might_be_dyn_thread_safe` was
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 27f08fe7eefba..acd93b0b2a60f 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -1,8 +1,8 @@
// This crate is intentionally empty and a re-export of `rustc_driver_impl` to allow the code in
// `rustc_driver_impl` to be compiled in parallel with other crates.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
pub use rustc_driver_impl::*;
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index da7c2440faad4..545ff32e598ae 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -43,6 +43,7 @@ rustc_privacy = { path = "../rustc_privacy" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }
+rustc_smir ={ path = "../rustc_smir" }
rustc_span = { path = "../rustc_span" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 84ae45d6a2b6f..4ad7b9f6cd186 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -5,9 +5,9 @@
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(decl_macro)]
#![feature(lazy_cell)]
#![feature(let_chains)]
@@ -33,7 +33,7 @@ use rustc_feature::find_gated_cfg;
use rustc_fluent_macro::fluent_messages;
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
use rustc_interface::{interface, Queries};
-use rustc_lint::{unerased_lint_store, LintStore};
+use rustc_lint::unerased_lint_store;
use rustc_metadata::locator;
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
@@ -356,16 +356,7 @@ fn run_compiler(
let handler = EarlyErrorHandler::new(sopts.error_format);
if sopts.describe_lints {
- let mut lint_store =
- rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
- let registered_lints =
- if let Some(register_lints) = compiler.register_lints() {
- register_lints(compiler.session(), &mut lint_store);
- true
- } else {
- false
- };
- describe_lints(compiler.session(), &lint_store, registered_lints);
+ describe_lints(compiler.session());
return;
}
let should_stop = print_crate_info(
@@ -442,9 +433,7 @@ fn run_compiler(
}
if sess.opts.describe_lints {
- queries
- .global_ctxt()?
- .enter(|tcx| describe_lints(sess, unerased_lint_store(tcx), true));
+ describe_lints(sess);
return early_exit();
}
@@ -496,10 +485,6 @@ fn run_compiler(
linker.link()?
}
- if sess.opts.unstable_opts.perf_stats {
- sess.print_perf_stats();
- }
-
if sess.opts.unstable_opts.print_fuel.is_some() {
eprintln!(
"Fuel used by {}: {}",
@@ -995,7 +980,7 @@ the command line flag directly.
}
/// Write to stdout lint command options, together with a list of all available lints
-pub fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_lints: bool) {
+pub fn describe_lints(sess: &Session) {
safe_println!(
"
Available lint options:
@@ -1021,6 +1006,7 @@ Available lint options:
lints
}
+ let lint_store = unerased_lint_store(sess);
let (loaded, builtin): (Vec<_>, _) =
lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_loaded);
let loaded = sort_lints(sess, loaded);
@@ -1098,7 +1084,7 @@ Available lint options:
print_lint_groups(builtin_groups, true);
- match (loaded_lints, loaded.len(), loaded_groups.len()) {
+ match (sess.registered_lints, loaded.len(), loaded_groups.len()) {
(false, 0, _) | (false, _, 0) => {
safe_println!("Lint tools like Clippy can load additional lints and lint groups.");
}
@@ -1524,14 +1510,14 @@ fn report_ice(
/// This allows tools to enable rust logging without having to magically match rustc's
/// tracing crate version.
pub fn init_rustc_env_logger(handler: &EarlyErrorHandler) {
- init_env_logger(handler, "RUSTC_LOG");
+ init_logger(handler, rustc_log::LoggerConfig::from_env("RUSTC_LOG"));
}
/// This allows tools to enable rust logging without having to magically match rustc's
-/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var
-/// other than `RUSTC_LOG`.
-pub fn init_env_logger(handler: &EarlyErrorHandler, env: &str) {
- if let Err(error) = rustc_log::init_env_logger(env) {
+/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose
+/// the values directly rather than having to set an environment variable.
+pub fn init_logger(handler: &EarlyErrorHandler, cfg: rustc_log::LoggerConfig) {
+ if let Err(error) = rustc_log::init_logger(cfg) {
handler.early_error(error.to_string());
}
}
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index cc533b9941ab4..7cd63bc6422c3 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -9,6 +9,7 @@ use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
use rustc_session::Session;
+use rustc_smir::rustc_internal::pretty::write_smir_pretty;
use rustc_span::symbol::Ident;
use rustc_span::FileName;
@@ -325,6 +326,11 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
write_mir_graphviz(ex.tcx(), None, &mut out).unwrap();
String::from_utf8(out).unwrap()
}
+ StableMir => {
+ let mut out = Vec::new();
+ write_smir_pretty(ex.tcx(), &mut out).unwrap();
+ String::from_utf8(out).unwrap()
+ }
ThirTree => {
let tcx = ex.tcx();
let mut out = String::new();
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 81ad661286e5d..dd2818116368b 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -1,6 +1,6 @@
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![deny(rustdoc::invalid_codeblock_attributes)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 6249c1e79613a..35bd45e64a269 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,5 +1,5 @@
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(let_chains)]
#![feature(lazy_cell)]
#![feature(rustc_attrs)]
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index dd462cc64865f..1cee57843f073 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -3,14 +3,13 @@
//! This module contains the code for creating and emitting diagnostics.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(array_windows)]
#![feature(extract_if)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(never_type)]
-#![feature(result_option_inspect)]
#![feature(rustc_attrs)]
#![feature(yeet_expr)]
#![feature(try_blocks)]
diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs
index d3a08da628394..67e4963fddf7f 100644
--- a/compiler/rustc_errors/src/markdown/parse.rs
+++ b/compiler/rustc_errors/src/markdown/parse.rs
@@ -329,7 +329,7 @@ fn parse_with_end_pat<'a>(
end_sep: &[u8],
ignore_esc: bool,
) -> Option<(&'a [u8], &'a [u8])> {
- // Find positions that start with the end seperator
+ // Find positions that start with the end separator
for idx in (0..buf.len()).filter(|idx| buf[*idx..].starts_with(end_sep)) {
if !ignore_esc && idx > 0 && buf[idx - 1] == b'\\' {
continue;
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index bef48765937f5..0d76b1b29746a 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -74,7 +74,9 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
let mut edition_enabled_features = FxHashSet::default();
for f in UNSTABLE_FEATURES {
- if let Some(edition) = f.feature.edition && edition <= features_edition {
+ if let Some(edition) = f.feature.edition
+ && edition <= features_edition
+ {
// FIXME(Manishearth) there is currently no way to set lib features by
// edition.
edition_enabled_features.insert(f.feature.name);
@@ -251,8 +253,7 @@ impl<'a> StripUnconfigured<'a> {
let trees: Vec<_> = stream
.0
.iter()
- .flat_map(|tree| {
- match tree.clone() {
+ .flat_map(|tree| match tree.clone() {
AttrTokenTree::Attributes(mut data) => {
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
@@ -277,7 +278,6 @@ impl<'a> StripUnconfigured<'a> {
AttrTokenTree::Token(token, spacing) => {
Some(AttrTokenTree::Token(token, spacing)).into_iter()
}
- }
})
.collect();
AttrTokenStream::new(trees)
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 5a774164a4bb8..cb084a85e47da 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,5 +1,5 @@
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(array_windows)]
#![feature(associated_type_bounds)]
#![feature(associated_type_defaults)]
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index f07022733d495..577657ff7947b 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -65,7 +65,7 @@ declare_features! (
/// Allows free and inherent `async fn`s, `async` blocks, and `.await` expressions.
(accepted, async_await, "1.39.0", Some(50547), None),
/// Allows async functions to be declared, implemented, and used in traits.
- (accepted, async_fn_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None),
+ (accepted, async_fn_in_trait, "1.75.0", Some(91611), None),
/// Allows all literals in attribute lists and values of key-value pairs.
(accepted, attr_literals, "1.30.0", Some(34981), None),
/// Allows overloading augmented assignment operations like `a += b`.
@@ -306,7 +306,7 @@ declare_features! (
/// Allows `#[repr(transparent)]` attribute on newtype structs.
(accepted, repr_transparent, "1.28.0", Some(43036), None),
/// Allows return-position `impl Trait` in traits.
- (accepted, return_position_impl_trait_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None),
+ (accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611), None),
/// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
(accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
/// Allows `Self` in type definitions (RFC 2300).
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 070234df94c4f..73d51d9f80e6e 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -11,9 +11,9 @@
//! even if it is stabilized or removed, *do not remove it*. Instead, move the
//! symbol to the `accepted` or `removed` modules respectively.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
#![feature(lazy_cell)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 03f92f69b41ef..4385e745bacfa 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -153,7 +153,7 @@ declare_features! (
(removed, panic_implementation, "1.28.0", Some(44489), None,
Some("subsumed by `#[panic_handler]`")),
/// Allows using `#![plugin(myplugin)]`.
- (removed, plugin, "CURRENT_RUSTC_VERSION", Some(29597), None,
+ (removed, plugin, "1.75.0", Some(29597), None,
Some("plugins are no longer supported")),
/// Allows using `#[plugin_registrar]` on functions.
(removed, plugin_registrar, "1.54.0", Some(29597), None,
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 64b5a7d2921a6..b11b190bdedad 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -457,7 +457,7 @@ declare_features! (
/// Allows using `#[repr(align(...))]` on function items
(unstable, fn_align, "1.53.0", Some(82232), None),
/// Allows defining gen blocks and `gen fn`.
- (unstable, gen_blocks, "CURRENT_RUSTC_VERSION", Some(117078), None),
+ (unstable, gen_blocks, "1.75.0", Some(117078), None),
/// Infer generic args for both consts and types.
(unstable, generic_arg_infer, "1.55.0", Some(85077), None),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
@@ -527,7 +527,7 @@ declare_features! (
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
(unstable, object_safe_for_dispatch, "1.40.0", Some(43561), None),
/// Allows using enums in offset_of!
- (unstable, offset_of_enum, "CURRENT_RUSTC_VERSION", Some(106655), None),
+ (unstable, offset_of_enum, "1.75.0", Some(106655), None),
/// Allows using `#[optimize(X)]`.
(unstable, optimize_attribute, "1.34.0", Some(54882), None),
/// Allows exhaustive integer pattern matching on `usize` and `isize`.
diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs
index 191fb787f706d..b041fad1f13eb 100644
--- a/compiler/rustc_fluent_macro/src/lib.rs
+++ b/compiler/rustc_fluent_macro/src/lib.rs
@@ -1,7 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![allow(internal_features)]
+#![feature(rustdoc_internals)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_span)]
#![deny(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index 9cb279e3efdba..9abd7aec98d1c 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -273,9 +273,9 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![feature(rustdoc_internals)]
+#![doc(rust_logo)]
+#![allow(internal_features)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 3e700f2da8696..f6907019d6e84 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -194,8 +194,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
self.add_bounds(
param_ty,
- ast_bounds.iter().filter(|bound| {
- match filter {
+ ast_bounds.iter().filter(|bound| match filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
@@ -209,7 +208,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
false
}
}
- }
}),
&mut bounds,
ty::List::empty(),
@@ -350,7 +348,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let args =
candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
let subst = match param.kind {
- ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
+ ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion {
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index 32be7e0837b6d..7ced37e5694e5 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -206,15 +206,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&& let parent = hir.get_parent_item(hir.local_def_id_to_hir_id(def_id))
&& let Some(generics) = hir.get_generics(parent.def_id)
{
- if generics.bounds_for_param(def_id)
- .flat_map(|pred| pred.bounds.iter())
- .any(|b| match b {
+ if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(
+ |b| match b {
hir::GenericBound::Trait(t, ..) => {
t.trait_ref.trait_def_id().as_ref() == Some(best_trait)
}
_ => false,
- })
- {
+ },
+ ) {
// The type param already has a bound for `trait_name`, we just need to
// change the associated type.
err.span_suggestion_verbose(
@@ -227,15 +226,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Applicability::MaybeIncorrect,
);
} else if suggest_constraining_type_param(
- self.tcx(),
- generics,
- &mut err,
- &ty_param_name,
- &trait_name,
- None,
- None,
- )
- && suggested_name != assoc_name.name
+ self.tcx(),
+ generics,
+ &mut err,
+ &ty_param_name,
+ &trait_name,
+ None,
+ None,
+ ) && suggested_name != assoc_name.name
{
// We suggested constraining a type parameter, but the associated type on it
// was also not an exact match, so we also suggest changing it.
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 2fcb45ef8aa12..8126b45118138 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -250,7 +250,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
var: ty::BoundVar::from_u32(index),
kind: ty::BrNamed(def_id, name),
};
- ty::Region::new_late_bound(tcx, debruijn, br)
+ ty::Region::new_bound(tcx, debruijn, br)
}
Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
@@ -258,12 +258,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
- ty::Region::new_early_bound(tcx, ty::EarlyBoundRegion { def_id, index, name })
+ ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name })
}
Some(rbv::ResolvedArg::Free(scope, id)) => {
let name = lifetime_name(id.expect_local());
- ty::Region::new_free(tcx, scope, ty::BrNamed(id, name))
+ ty::Region::new_late_param(tcx, scope, ty::BrNamed(id, name))
// (*) -- not late-bound, won't change
}
@@ -1622,7 +1622,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r }
+ // FIXME(@lcnr): This is broken, erasing bound regions
+ // impacts selection as it results in different types.
+ if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
@@ -2845,6 +2847,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// provided, if they provided one, and otherwise search the supertypes of trait bounds
/// for region bounds. It may be that we can derive no bound at all, in which case
/// we return `None`.
+ #[instrument(level = "debug", skip(self, span), ret)]
fn compute_object_lifetime_bound(
&self,
span: Span,
@@ -2853,8 +2856,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
{
let tcx = self.tcx();
- debug!("compute_opt_region_bound(existential_predicates={:?})", existential_predicates);
-
// No explicit region bound specified. Therefore, examine trait
// bounds and see if we can derive region bounds from those.
let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 857515f971a85..f026f78cc2b42 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -532,8 +532,8 @@ impl<'tcx> TypeFolder> for RemapLateBound<'_, 'tcx> {
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- if let ty::ReFree(fr) = *r {
- ty::Region::new_free(
+ if let ty::ReLateParam(fr) = *r {
+ ty::Region::new_late_param(
self.tcx,
fr.scope,
self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region),
@@ -1078,20 +1078,20 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> {
region: ty::Region<'tcx>,
) -> Result, Self::Error> {
match region.kind() {
- // Remap all free regions, which correspond to late-bound regions in the function.
- ty::ReFree(_) => {}
+ // Remap late-bound regions from the function.
+ ty::ReLateParam(_) => {}
// Remap early-bound regions as long as they don't come from the `impl` itself,
// in which case we don't really need to renumber them.
- ty::ReEarlyBound(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
+ ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
_ => return Ok(region),
}
let e = if let Some(region) = self.map.get(®ion) {
- if let ty::ReEarlyBound(e) = region.kind() { e } else { bug!() }
+ if let ty::ReEarlyParam(e) = region.kind() { e } else { bug!() }
} else {
let guar = match region.kind() {
- ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. })
- | ty::ReFree(ty::FreeRegion {
+ ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
+ | ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
..
}) => {
@@ -1119,9 +1119,9 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> {
return Err(guar);
};
- Ok(ty::Region::new_early_bound(
+ Ok(ty::Region::new_early_param(
self.tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: e.def_id,
name: e.name,
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
@@ -2345,7 +2345,7 @@ fn param_env_with_gat_bounds<'tcx>(
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Region(kind);
bound_vars.push(bound_var);
- ty::Region::new_late_bound(
+ ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion {
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index dda3f7425697b..0a05c1039b6e3 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -81,8 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
self_type_did: DefId,
adt_to_impl_args: GenericArgsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
- let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyEarlyBound)
- else {
+ let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else {
return Ok(());
};
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index c61719c1fd293..eb009b9368f98 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -143,12 +143,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
]);
let mk_va_list_ty = |mutbl| {
tcx.lang_items().va_list().map(|did| {
- let region = ty::Region::new_late_bound(
+ let region = ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
);
- let env_region = ty::Region::new_late_bound(
+ let env_region = ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
@@ -411,7 +411,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
1,
vec![Ty::new_imm_ref(
tcx,
- ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
+ ty::Region::new_bound(tcx, ty::INNERMOST, br),
param(0),
)],
Ty::new_projection(tcx, discriminant_def_id, tcx.mk_args(&[param(0).into()])),
@@ -465,11 +465,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
sym::raw_eq => {
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
- let param_ty = Ty::new_imm_ref(
- tcx,
- ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
- param(0),
- );
+ let param_ty =
+ Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
(1, vec![param_ty; 2], tcx.types.bool)
}
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index eb4491b89bf1e..d7b50d127cd83 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -595,9 +595,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>(
// Same for the region. In our example, 'a corresponds
// to the 'me parameter.
let region_param = gat_generics.param_at(*region_a_idx, tcx);
- let region_param = ty::Region::new_early_bound(
+ let region_param = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: region_param.def_id,
index: region_param.index,
name: region_param.name,
@@ -628,9 +628,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>(
debug!("required clause: {region_a} must outlive {region_b}");
// Translate into the generic parameters of the GAT.
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
- let region_a_param = ty::Region::new_early_bound(
+ let region_a_param = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: region_a_param.def_id,
index: region_a_param.index,
name: region_a_param.name,
@@ -638,9 +638,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>(
);
// Same for the region.
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
- let region_b_param = ty::Region::new_early_bound(
+ let region_b_param = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: region_b_param.def_id,
index: region_b_param.index,
name: region_b_param.name,
@@ -763,7 +763,7 @@ impl<'tcx> TypeVisitor> for GATSubstCollector<'tcx> {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
for (idx, subst) in p.args.iter().enumerate() {
match subst.unpack() {
- GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
+ GenericArgKind::Lifetime(lt) if !lt.is_bound() => {
self.regions.insert((lt, idx));
}
GenericArgKind::Type(t) => {
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index e5e192e0079bd..f277badf275b7 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -550,7 +550,7 @@ fn infringing_fields_error(
.entry((ty.clone(), predicate.clone()))
.or_default()
.push(origin.span());
- if let ty::RegionKind::ReEarlyBound(ebr) = *b
+ if let ty::RegionKind::ReEarlyParam(ebr) = *b
&& ebr.has_name()
{
bounds.push((b.to_string(), a.to_string(), None));
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 7eeb7837467fd..8d87cb57b9077 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -452,7 +452,13 @@ fn lint_auto_trait_impl<'tcx>(
trait_ref: ty::TraitRef<'tcx>,
impl_def_id: LocalDefId,
) {
- assert_eq!(trait_ref.args.len(), 1);
+ if trait_ref.args.len() != 1 {
+ tcx.sess.diagnostic().delay_span_bug(
+ tcx.def_span(impl_def_id),
+ "auto traits cannot have generic parameters",
+ );
+ return;
+ }
let self_ty = trait_ref.self_ty();
let (self_type_did, args) = match self_ty.kind() {
ty::Adt(def, args) => (def.did(), args),
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 9636c6144461b..1e75b8631655e 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -443,7 +443,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
self.tcx.replace_late_bound_regions_uncached(
poly_trait_ref,
|_| {
- ty::Region::new_early_bound(self.tcx, ty::EarlyBoundRegion {
+ ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
def_id: item_def_id,
index: 0,
name: Symbol::intern(<_name),
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 104da581e019d..68d040d58460e 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -362,10 +362,10 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
) {
for param in opaque_own_params {
let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
- if let ty::ReEarlyBound(..) = *orig_lifetime {
- let dup_lifetime = ty::Region::new_early_bound(
+ if let ty::ReEarlyParam(..) = *orig_lifetime {
+ let dup_lifetime = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion { def_id: param.def_id, index: param.index, name: param.name },
+ ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name },
);
let span = tcx.def_span(param.def_id);
predicates.push((
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 6424d1c793112..53efc2c6e828b 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1848,8 +1848,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
- debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref);
let mut late_depth = 0;
let mut scope = self.scope;
let lifetime = loop {
@@ -2012,7 +2012,7 @@ fn is_late_bound_map(
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
debug!("r={:?}", r.kind());
- if let ty::RegionKind::ReEarlyBound(region) = r.kind() {
+ if let ty::RegionKind::ReEarlyParam(region) = r.kind() {
self.arg_is_constrained[region.index as usize] = true;
}
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index ed5e9dd2b5add..65d1ffa40e2ed 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -13,8 +13,8 @@ impl From for Parameter {
}
}
-impl From for Parameter {
- fn from(param: ty::EarlyBoundRegion) -> Self {
+impl From for Parameter {
+ fn from(param: ty::EarlyParamRegion) -> Self {
Parameter(param.index)
}
}
@@ -73,7 +73,7 @@ impl<'tcx> TypeVisitor> for ParameterCollector {
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
- if let ty::ReEarlyBound(data) = *r {
+ if let ty::ReEarlyParam(data) = *r {
self.parameters.push(Parameter::from(data));
}
ControlFlow::Continue(())
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index ca7679cfba06e..d5fb4340e1c8c 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -196,6 +196,7 @@ impl<'tcx> TypeFolder> for EraseAllBoundRegions<'tcx> {
self.tcx
}
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
- if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r }
+ // FIXME(@lcnr): only erase escaping bound regions!
+ if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
}
}
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 2b8219c01c769..bcc2051888b2b 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -57,9 +57,9 @@ This API is completely unstable and subject to change.
#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index a6410c944f778..218f658b061ce 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -146,11 +146,11 @@ fn is_free_region(region: Region<'_>) -> bool {
// These correspond to `T: 'a` relationships:
//
// struct Foo<'a, T> {
- // field: &'a T, // this would generate a ReEarlyBound referencing `'a`
+ // field: &'a T, // this would generate a ReEarlyParam referencing `'a`
// }
//
// We care about these, so fall through.
- ty::ReEarlyBound(_) => true,
+ ty::ReEarlyParam(_) => true,
// These correspond to `T: 'static` relationships which can be
// rather surprising.
@@ -167,13 +167,13 @@ fn is_free_region(region: Region<'_>) -> bool {
// }
//
// The type above might generate a `T: 'b` bound, but we can
- // ignore it. We can't put it on the struct header anyway.
- ty::ReLateBound(..) => false,
+ // ignore it. We can't name this lifetime pn the struct header anyway.
+ ty::ReBound(..) => false,
ty::ReError(_) => false,
// These regions don't appear in types from type declarations:
- ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
+ ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReLateParam(..) => {
bug!("unexpected region in outlives inference: {:?}", region);
}
}
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 5f8b1ace68b77..f09594cbbc667 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -413,20 +413,22 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
variance: VarianceTermPtr<'a>,
) {
match *region {
- ty::ReEarlyBound(ref data) => {
+ ty::ReEarlyParam(ref data) => {
self.add_constraint(current, data.index, variance);
}
ty::ReStatic => {}
- ty::ReLateBound(..) => {
- // Late-bound regions do not get substituted the same
- // way early-bound regions do, so we skip them here.
+ ty::ReBound(..) => {
+ // Either a higher-ranked region inside of a type or a
+ // late-bound function parameter.
+ //
+ // We do not compute constraints for either of these.
}
ty::ReError(_) => {}
- ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
+ ty::ReLateParam(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
// We don't expect to see anything but 'static or bound
// regions when visiting member types or method types.
bug!(
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 9fb39a0e93b6c..410706110c96e 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -106,7 +106,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
impl<'tcx> ty::TypeVisitor> for OpaqueTypeLifetimeCollector<'tcx> {
#[instrument(level = "trace", skip(self), ret)]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
- if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() {
+ if let ty::RegionKind::ReEarlyParam(ebr) = r.kind() {
self.variances[ebr.index as usize] = ty::Invariant;
}
ControlFlow::Continue(())
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index b8a265d4971d2..1edc3efbc778c 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -214,7 +214,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
tcx,
- &[ty::GenericArg::from(ty::Region::new_late_bound(
+ &[ty::GenericArg::from(ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon },
@@ -222,7 +222,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
);
let panic_info_ref_ty = Ty::new_imm_ref(
tcx,
- ty::Region::new_late_bound(
+ ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index a70ead8e57d60..7807ff6547d27 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -7,7 +7,7 @@ use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_infer::infer::{DefineOpaqueTypes, LateBoundRegionConversionTime};
+use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
use rustc_infer::infer::{InferOk, InferResult};
use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
@@ -558,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Instantiate (this part of..) S to S', i.e., with fresh variables.
self.instantiate_binder_with_fresh_vars(
hir_ty.span,
- LateBoundRegionConversionTime::FnCall,
+ BoundRegionConversionTime::FnCall,
// (*) binder moved to here
supplied_sig.inputs().rebind(supplied_ty),
)
@@ -583,7 +583,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let supplied_output_ty = self.instantiate_binder_with_fresh_vars(
decl.output.span(),
- LateBoundRegionConversionTime::FnCall,
+ BoundRegionConversionTime::FnCall,
supplied_sig.output(),
);
let cause = &self.misc(decl.output.span());
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index acaa3e02f092f..386e4b4642a82 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -31,9 +31,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
self.annotate_alternative_method_deref(err, expr, error);
+ self.explain_self_literal(err, expr, expected, expr_ty);
// Use `||` to give these suggestions a precedence
let suggested = self.suggest_missing_parentheses(err, expr)
+ || self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty)
|| self.suggest_remove_last_method_call(err, expr, expected)
|| self.suggest_associated_const(err, expr, expected)
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
@@ -49,8 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|| self.suggest_into(err, expr, expr_ty, expected)
|| self.suggest_floating_point_literal(err, expr, expected)
|| self.suggest_null_ptr_for_literal_zero_given_to_ptr_arg(err, expr, expected)
- || self.suggest_coercing_result_via_try_operator(err, expr, expected, expr_ty)
- || self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty);
+ || self.suggest_coercing_result_via_try_operator(err, expr, expected, expr_ty);
if !suggested {
self.note_source_of_type_mismatch_constraint(
@@ -1027,6 +1028,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false;
}
+ fn explain_self_literal(
+ &self,
+ err: &mut Diagnostic,
+ expr: &hir::Expr<'tcx>,
+ expected: Ty<'tcx>,
+ found: Ty<'tcx>,
+ ) {
+ match expr.peel_drop_temps().kind {
+ hir::ExprKind::Struct(
+ hir::QPath::Resolved(
+ None,
+ hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, span, .. },
+ ),
+ ..,
+ )
+ | hir::ExprKind::Call(
+ hir::Expr {
+ kind:
+ hir::ExprKind::Path(hir::QPath::Resolved(
+ None,
+ hir::Path {
+ res: hir::def::Res::SelfTyAlias { alias_to, .. },
+ span,
+ ..
+ },
+ )),
+ ..
+ },
+ ..,
+ ) => {
+ if let Some(hir::Node::Item(hir::Item {
+ kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
+ ..
+ })) = self.tcx.hir().get_if_local(*alias_to)
+ {
+ err.span_label(self_ty.span, "this is the type of the `Self` literal");
+ }
+ if let ty::Adt(e_def, e_args) = expected.kind()
+ && let ty::Adt(f_def, _f_args) = found.kind()
+ && e_def == f_def
+ {
+ err.span_suggestion_verbose(
+ *span,
+ "use the type name directly",
+ self.tcx.value_path_str_with_args(*alias_to, e_args),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ _ => {}
+ }
+ }
+
fn note_wrong_return_ty_due_to_generic_arg(
&self,
err: &mut Diagnostic,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 9f439a2b32aaf..eaf5e938d3cf9 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -21,7 +21,7 @@ use crate::{
TupleArgumentsFlag::DontTupleArguments,
};
use rustc_ast as ast;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{
pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
@@ -564,7 +564,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = args.get(i).map(|a| a.span).unwrap_or(expr.span);
let input = self.instantiate_binder_with_fresh_vars(
span,
- infer::LateBoundRegionConversionTime::FnCall,
+ infer::BoundRegionConversionTime::FnCall,
fn_sig.input(i),
);
self.require_type_is_sized_deferred(
@@ -582,7 +582,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// with fresh vars.
let output = self.instantiate_binder_with_fresh_vars(
expr.span,
- infer::LateBoundRegionConversionTime::FnCall,
+ infer::BoundRegionConversionTime::FnCall,
fn_sig.output(),
);
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
@@ -2877,7 +2877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// two-phase not needed because index_ty is never mutable
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
self.select_obligations_where_possible(|errors| {
- self.point_at_index_if_possible(errors, idx.span)
+ self.point_at_index(errors, idx.span);
});
element_ty
}
@@ -3036,16 +3036,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.ok()
}
- fn point_at_index_if_possible(
- &self,
- errors: &mut Vec>,
- span: Span,
- ) {
+ fn point_at_index(&self, errors: &mut Vec>, span: Span) {
+ let mut seen_preds = FxHashSet::default();
+ // We re-sort here so that the outer most root obligations comes first, as we have the
+ // subsequent weird logic to identify *every* relevant obligation for proper deduplication
+ // of diagnostics.
+ errors.sort_by_key(|error| error.root_obligation.recursion_depth);
for error in errors {
- match error.obligation.predicate.kind().skip_binder() {
- ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate))
- if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) => {
+ match (
+ error.root_obligation.predicate.kind().skip_binder(),
+ error.obligation.predicate.kind().skip_binder(),
+ ) {
+ (ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)), _)
+ if self.tcx.lang_items().index_trait() == Some(predicate.trait_ref.def_id) =>
+ {
+ seen_preds.insert(error.obligation.predicate.kind().skip_binder());
+ }
+ (_, ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)))
+ if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) =>
+ {
+ seen_preds.insert(error.obligation.predicate.kind().skip_binder());
}
+ (root, pred) if seen_preds.contains(&pred) || seen_preds.contains(&root) => {}
_ => continue,
}
error.obligation.cause.span = span;
@@ -3173,19 +3185,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sym::offset_of_enum,
ident.span,
"using enums in offset_of is experimental",
- ).emit();
+ )
+ .emit();
}
- let Some((index, variant)) = container_def.variants()
+ let Some((index, variant)) = container_def
+ .variants()
.iter_enumerated()
- .find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident) else {
+ .find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident)
+ else {
let mut err = type_error_struct!(
self.tcx().sess,
ident.span,
container,
E0599,
"no variant named `{ident}` found for enum `{container}`",
- );
+ );
err.span_label(field.span, "variant not found");
err.emit();
break;
@@ -3197,7 +3212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
container,
E0795,
"`{ident}` is an enum variant; expected field at end of `offset_of`",
- );
+ );
err.span_label(field.span, "enum variant");
err.emit();
break;
@@ -3205,16 +3220,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (subident, sub_def_scope) =
self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, block);
- let Some((subindex, field)) = variant.fields
+ let Some((subindex, field)) = variant
+ .fields
.iter_enumerated()
- .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident) else {
+ .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident)
+ else {
let mut err = type_error_struct!(
self.tcx().sess,
ident.span,
container,
E0609,
"no field named `{subfield}` on enum variant `{container}::{ident}`",
- );
+ );
err.span_label(field.span, "this enum variant...");
err.span_label(subident.span, "...does not have this field");
err.emit();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 33dfa16a651fb..f31e50fd35210 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1864,35 +1864,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let ExprBindingObligation(_, _, hir_id, ..) = code
&& !fn_sig.output().is_unit()
{
- let mut block_num = 0;
- let mut found_semi = false;
- for (_, node) in self.tcx.hir().parent_iter(hir_id) {
- match node {
- hir::Node::Stmt(stmt) => if let hir::StmtKind::Semi(ref expr) = stmt.kind {
+ let mut block_num = 0;
+ let mut found_semi = false;
+ for (_, node) in self.tcx.hir().parent_iter(hir_id) {
+ match node {
+ hir::Node::Stmt(stmt) => {
+ if let hir::StmtKind::Semi(ref expr) = stmt.kind {
let expr_ty = self.typeck_results.borrow().expr_ty(expr);
let return_ty = fn_sig.output();
- if !matches!(expr.kind, hir::ExprKind::Ret(..)) &&
- self.can_coerce(expr_ty, return_ty) {
+ if !matches!(expr.kind, hir::ExprKind::Ret(..))
+ && self.can_coerce(expr_ty, return_ty)
+ {
found_semi = true;
}
- },
- hir::Node::Block(_block) => if found_semi {
+ }
+ }
+ hir::Node::Block(_block) => {
+ if found_semi {
block_num += 1;
}
- hir::Node::Item(item) => if let hir::ItemKind::Fn(..) = item.kind {
+ }
+ hir::Node::Item(item) => {
+ if let hir::ItemKind::Fn(..) = item.kind {
break;
}
- _ => {}
}
+ _ => {}
}
- if block_num > 1 && found_semi {
- diag.span_suggestion_verbose(
- span.shrink_to_lo(),
- "you might have meant to return this to infer its type parameters",
- "return ",
- Applicability::MaybeIncorrect,
- );
- }
+ }
+ if block_num > 1 && found_semi {
+ diag.span_suggestion_verbose(
+ span.shrink_to_lo(),
+ "you might have meant to return this to infer its type parameters",
+ "return ",
+ Applicability::MaybeIncorrect,
+ );
+ }
}
diag.emit();
}
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index e93d180fc139e..bd653e7991320 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -238,7 +238,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option> {
let v = match def {
- Some(def) => infer::EarlyBoundRegion(span, def.name),
+ Some(def) => infer::RegionParameterDefinition(span, def.name),
None => infer::MiscVariable(span),
};
Some(self.next_region_var(v))
@@ -289,7 +289,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let trait_ref = self.instantiate_binder_with_fresh_vars(
span,
- infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
+ infer::BoundRegionConversionTime::AssocTypeProjection(item_def_id),
poly_trait_ref,
);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index c43d4932fb9f2..2e0ab1560f4b3 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2326,14 +2326,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
));
}
- let needs_parens = match expr.kind {
- // parenthesize if needed (Issue #46756)
- hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
- // parenthesize borrows of range literals (Issue #54505)
- _ if is_range_literal(expr) => true,
- _ => false,
- };
-
if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
return Some((
sugg,
@@ -2361,18 +2353,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- let sugg = mutability.ref_prefix_str();
- let (sugg, verbose) = if needs_parens {
- (
- vec![
- (sp.shrink_to_lo(), format!("{prefix}{sugg}(")),
- (sp.shrink_to_hi(), ")".to_string()),
- ],
- false,
- )
- } else {
- (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+ let make_sugg = |expr: &Expr<'_>, span: Span, sugg: &str| {
+ let needs_parens = match expr.kind {
+ // parenthesize if needed (Issue #46756)
+ hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
+ // parenthesize borrows of range literals (Issue #54505)
+ _ if is_range_literal(expr) => true,
+ _ => false,
+ };
+
+ if needs_parens {
+ (
+ vec![
+ (span.shrink_to_lo(), format!("{prefix}{sugg}(")),
+ (span.shrink_to_hi(), ")".to_string()),
+ ],
+ false,
+ )
+ } else {
+ (vec![(span.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+ }
};
+
+ // Suggest dereferencing the lhs for expressions such as `&T == T`
+ if let Some(hir::Node::Expr(hir::Expr {
+ kind: hir::ExprKind::Binary(_, lhs, ..),
+ ..
+ })) = self.tcx.hir().find_parent(expr.hir_id)
+ && let &ty::Ref(..) = self.check_expr(lhs).kind()
+ {
+ let (sugg, verbose) = make_sugg(lhs, lhs.span, "*");
+
+ return Some((
+ sugg,
+ "consider dereferencing the borrow".to_string(),
+ Applicability::MachineApplicable,
+ verbose,
+ false,
+ ));
+ }
+
+ let sugg = mutability.ref_prefix_str();
+ let (sugg, verbose) = make_sugg(expr, sp, sugg);
return Some((
sugg,
format!("consider {}borrowing here", mutability.mutably_str()),
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 74f469cb39cbf..a51fa8354c9e9 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -801,7 +801,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// a `&self` method will wind up with an argument type like `&dyn Trait`.
let trait_ref = principal.with_self_ty(self.tcx, self_ty);
self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
- if new_trait_ref.has_non_region_late_bound() {
+ if new_trait_ref.has_non_region_bound_vars() {
this.tcx.sess.delay_span_bug(
this.span,
"tried to select method from HRTB with non-lifetime bound vars",
@@ -853,7 +853,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
let trait_ref = this.instantiate_binder_with_fresh_vars(
this.span,
- infer::LateBoundRegionConversionTime::FnCall,
+ infer::BoundRegionConversionTime::FnCall,
poly_trait_ref,
);
@@ -971,7 +971,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
} else {
let new_trait_ref = self.instantiate_binder_with_fresh_vars(
self.span,
- infer::LateBoundRegionConversionTime::FnCall,
+ infer::BoundRegionConversionTime::FnCall,
bound_trait_ref,
);
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index b1a2df8ace40a..3624b86b57563 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1,6 +1,8 @@
//! Give useful errors and suggestions to users when an item can't be
//! found or is otherwise invalid.
+// ignore-tidy-filelength
+
use crate::errors;
use crate::errors::{CandidateTraitNote, NoAssociatedItem};
use crate::Expectation;
@@ -369,25 +371,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.is_diagnostic_item(sym::write_macro, def_id)
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
}) && item_name.name == Symbol::intern("write_fmt");
- let mut err =
- if is_write && let SelfSource::MethodCall(rcvr_expr) = source
- {
- self.suggest_missing_writer(rcvr_ty, rcvr_expr)
- } else {
- tcx.sess.create_err(NoAssociatedItem {
- span,
- item_kind,
- item_name,
- ty_prefix: if trait_missing_method {
- // FIXME(mu001999) E0599 maybe not suitable here because it is for types
- Cow::from("trait")
- } else {
- rcvr_ty.prefix_string(self.tcx)
- },
- ty_str: ty_str_reported,
- trait_missing_method,
- })
- };
+ let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
+ self.suggest_missing_writer(rcvr_ty, rcvr_expr)
+ } else {
+ tcx.sess.create_err(NoAssociatedItem {
+ span,
+ item_kind,
+ item_name,
+ ty_prefix: if trait_missing_method {
+ // FIXME(mu001999) E0599 maybe not suitable here because it is for types
+ Cow::from("trait")
+ } else {
+ rcvr_ty.prefix_string(self.tcx)
+ },
+ ty_str: ty_str_reported,
+ trait_missing_method,
+ })
+ };
if tcx.sess.source_map().is_multiline(sugg_span) {
err.span_label(sugg_span.with_hi(span.lo()), "");
}
@@ -481,7 +481,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
probe.is_ok()
});
-
self.note_internal_mutation_in_method(
&mut err,
rcvr_expr,
@@ -1240,7 +1239,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
+ // If an appropriate error source is not found, check method chain for possible candiates
+ if unsatisfied_predicates.is_empty()
+ && let Mode::MethodCall = mode
+ && let SelfSource::MethodCall(mut source_expr) = source
+ {
+ let mut stack_methods = vec![];
+ while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, method_span) =
+ source_expr.kind
+ {
+ // Pop the matching receiver, to align on it's notional span
+ if let Some(prev_match) = stack_methods.pop() {
+ err.span_label(
+ method_span,
+ format!("{item_kind} `{item_name}` is available on `{prev_match}`"),
+ );
+ }
+ let rcvr_ty = self.resolve_vars_if_possible(
+ self.typeck_results
+ .borrow()
+ .expr_ty_adjusted_opt(rcvr_expr)
+ .unwrap_or(Ty::new_misc_error(self.tcx)),
+ );
+ for _matched_method in self.probe_for_name_many(
+ Mode::MethodCall,
+ item_name,
+ None,
+ IsSuggestion(true),
+ rcvr_ty,
+ source_expr.hir_id,
+ ProbeScope::TraitsInScope,
+ ) {
+ // found a match, push to stack
+ stack_methods.push(rcvr_ty);
+ }
+ source_expr = rcvr_expr;
+ }
+ // If there is a match at the start of the chain, add a label for it too!
+ if let Some(prev_match) = stack_methods.pop() {
+ err.span_label(
+ source_expr.span,
+ format!("{item_kind} `{item_name}` is available on `{prev_match}`"),
+ );
+ }
+ }
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
return Some(err);
}
@@ -1325,10 +1368,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err,
self_source,
args,
- trait_ref.instantiate(
- self.tcx,
- self.fresh_args_for_item(sugg_span, impl_did)
- ).with_self_ty(self.tcx, rcvr_ty),
+ trait_ref
+ .instantiate(
+ self.tcx,
+ self.fresh_args_for_item(sugg_span, impl_did),
+ )
+ .with_self_ty(self.tcx, rcvr_ty),
idx,
sugg_span,
item,
@@ -1365,8 +1410,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::TraitRef::new(
self.tcx,
trait_did,
- self.fresh_args_for_item(sugg_span, trait_did)
- ).with_self_ty(self.tcx, rcvr_ty),
+ self.fresh_args_for_item(sugg_span, trait_did),
+ )
+ .with_self_ty(self.tcx, rcvr_ty),
idx,
sugg_span,
item,
@@ -1377,7 +1423,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
- if !suggs.is_empty() && let Some(span) = sugg_span {
+ if !suggs.is_empty()
+ && let Some(span) = sugg_span
+ {
err.span_suggestions(
span.with_hi(item_name.span.lo()),
"use fully-qualified syntax to disambiguate",
@@ -1553,39 +1601,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let mut applicability = Applicability::MachineApplicable;
let args = if let SelfSource::MethodCall(receiver) = source
- && let Some(args) = args
- {
- // The first arg is the same kind as the receiver
- let explicit_args = if first_arg.is_some() {
- std::iter::once(receiver).chain(args.iter()).collect::>()
- } else {
- // There is no `Self` kind to infer the arguments from
- if has_unsuggestable_args {
- applicability = Applicability::HasPlaceholders;
- }
- args.iter().collect()
- };
- format!(
- "({}{})",
- first_arg.unwrap_or(""),
- explicit_args
- .iter()
- .map(|arg| self
- .tcx
- .sess
- .source_map()
- .span_to_snippet(arg.span)
- .unwrap_or_else(|_| {
- applicability = Applicability::HasPlaceholders;
- "_".to_owned()
- }))
- .collect::>()
- .join(", "),
- )
+ && let Some(args) = args
+ {
+ // The first arg is the same kind as the receiver
+ let explicit_args = if first_arg.is_some() {
+ std::iter::once(receiver).chain(args.iter()).collect::>()
} else {
- applicability = Applicability::HasPlaceholders;
- "(...)".to_owned()
+ // There is no `Self` kind to infer the arguments from
+ if has_unsuggestable_args {
+ applicability = Applicability::HasPlaceholders;
+ }
+ args.iter().collect()
};
+ format!(
+ "({}{})",
+ first_arg.unwrap_or(""),
+ explicit_args
+ .iter()
+ .map(|arg| self
+ .tcx
+ .sess
+ .source_map()
+ .span_to_snippet(arg.span)
+ .unwrap_or_else(|_| {
+ applicability = Applicability::HasPlaceholders;
+ "_".to_owned()
+ }))
+ .collect::>()
+ .join(", "),
+ )
+ } else {
+ applicability = Applicability::HasPlaceholders;
+ "(...)".to_owned()
+ };
err.span_suggestion(
sugg_span,
"use associated function syntax instead",
@@ -3264,8 +3312,13 @@ fn print_disambiguation_help<'tcx>(
{
let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id);
let item_name = item.ident(tcx);
- let rcvr_ref = tcx.fn_sig(item.def_id).skip_binder().skip_binder().inputs()[0]
- .ref_mutability()
+ let rcvr_ref = tcx
+ .fn_sig(item.def_id)
+ .skip_binder()
+ .skip_binder()
+ .inputs()
+ .get(0)
+ .and_then(|ty| ty.ref_mutability())
.map_or("", |mutbl| mutbl.ref_prefix_str());
let args = format!(
"({}{})",
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 896aacc699312..2dfe72726734a 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -784,7 +784,7 @@ impl<'tcx> TypeFolder> for EraseEarlyRegions<'tcx> {
}
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- if r.is_late_bound() { r } else { self.tcx.lifetimes.re_erased }
+ if r.is_bound() { r } else { self.tcx.lifetimes.re_erased }
}
}
@@ -822,7 +822,7 @@ impl<'cx, 'tcx> TypeFolder> for Resolver<'cx, 'tcx> {
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
+ debug_assert!(!r.is_bound(), "Should not be resolving bound region.");
self.fcx.tcx.lifetimes.re_erased
}
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index dde138973b931..81d4d914287eb 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -2,9 +2,9 @@
#![deny(missing_docs)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![recursion_limit = "256"]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index ece61ff12520c..d0b4889b45fa9 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -237,23 +237,12 @@ impl BitSet {
new_word != word
}
- /// Gets a slice of the underlying words.
- pub fn words(&self) -> &[Word] {
- &self.words
- }
-
/// Iterates over the indices of set bits in a sorted order.
#[inline]
pub fn iter(&self) -> BitIter<'_, T> {
BitIter::new(&self.words)
}
- /// Duplicates the set as a hybrid set.
- pub fn to_hybrid(&self) -> HybridBitSet {
- // Note: we currently don't bother trying to make a Sparse set.
- HybridBitSet::Dense(self.to_owned())
- }
-
/// Set `self = self | other`. In contrast to `union` returns `true` if the set contains at
/// least one bit that is not in `other` (i.e. `other` is not a superset of `self`).
///
@@ -1601,11 +1590,11 @@ impl BitMatrix {
pub fn from_row_n(row: &BitSet, num_rows: usize) -> BitMatrix {
let num_columns = row.domain_size();
let words_per_row = num_words(num_columns);
- assert_eq!(words_per_row, row.words().len());
+ assert_eq!(words_per_row, row.words.len());
BitMatrix {
num_rows,
num_columns,
- words: iter::repeat(row.words()).take(num_rows).flatten().cloned().collect(),
+ words: iter::repeat(&row.words).take(num_rows).flatten().cloned().collect(),
marker: PhantomData,
}
}
@@ -1700,9 +1689,9 @@ impl BitMatrix {
assert_eq!(with.domain_size(), self.num_columns);
let (write_start, write_end) = self.range(write);
let mut changed = false;
- for (read_index, write_index) in iter::zip(0..with.words().len(), write_start..write_end) {
+ for (read_index, write_index) in iter::zip(0..with.words.len(), write_start..write_end) {
let word = self.words[write_index];
- let new_word = word | with.words()[read_index];
+ let new_word = word | with.words[read_index];
self.words[write_index] = new_word;
changed |= word != new_word;
}
@@ -2002,54 +1991,6 @@ impl std::fmt::Debug for FiniteBitSet {
}
}
-impl FiniteBitSetTy for u64 {
- const DOMAIN_SIZE: u32 = 64;
-
- const FILLED: Self = Self::MAX;
- const EMPTY: Self = Self::MIN;
-
- const ONE: Self = 1u64;
- const ZERO: Self = 0u64;
-
- fn checked_shl(self, rhs: u32) -> Option {
- self.checked_shl(rhs)
- }
-
- fn checked_shr(self, rhs: u32) -> Option {
- self.checked_shr(rhs)
- }
-}
-
-impl std::fmt::Debug for FiniteBitSet {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:064b}", self.0)
- }
-}
-
-impl FiniteBitSetTy for u128 {
- const DOMAIN_SIZE: u32 = 128;
-
- const FILLED: Self = Self::MAX;
- const EMPTY: Self = Self::MIN;
-
- const ONE: Self = 1u128;
- const ZERO: Self = 0u128;
-
- fn checked_shl(self, rhs: u32) -> Option {
- self.checked_shl(rhs)
- }
-
- fn checked_shr(self, rhs: u32) -> Option {
- self.checked_shr(rhs)
- }
-}
-
-impl std::fmt::Debug for FiniteBitSet {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:0128b}", self.0)
- }
-}
-
/// A fixed-sized bitset type represented by an integer type. Indices outwith than the range
/// representable by `T` are considered set.
#[derive(Copy, Clone, Eq, PartialEq, Decodable, Encodable)]
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index 99e72e49f8eb8..66c5cc774b224 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -137,10 +137,6 @@ impl IndexVec {
self.raw.truncate(a)
}
- pub fn convert_index_type(self) -> IndexVec {
- IndexVec::from_raw(self.raw)
- }
-
/// Grows the index vector so that it contains an entry for
/// `elem`; if that is already true, then has no
/// effect. Otherwise, inserts new values as needed by invoking
diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs
index cb0f0db220d97..7e5e41bd2d19e 100644
--- a/compiler/rustc_index/src/vec/tests.rs
+++ b/compiler/rustc_index/src/vec/tests.rs
@@ -1,5 +1,3 @@
-#![allow(dead_code)]
-
// Allows the macro invocation below to work
use crate as rustc_index;
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index 57bc14ebcb3fe..294bd9d1d54be 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -17,7 +17,7 @@ impl<'a> DescriptionCtx<'a> {
alt_span: Option,
) -> Option {
let (span, kind, arg) = match *region {
- ty::ReEarlyBound(ref br) => {
+ ty::ReEarlyParam(ref br) => {
let scope = region.free_region_binding_scope(tcx).expect_local();
let span = if let Some(param) =
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
@@ -32,7 +32,7 @@ impl<'a> DescriptionCtx<'a> {
(Some(span), "as_defined_anon", String::new())
}
}
- ty::ReFree(ref fr) => {
+ ty::ReLateParam(ref fr) => {
if !fr.bound_region.is_named()
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
{
@@ -70,11 +70,14 @@ impl<'a> DescriptionCtx<'a> {
ty::RePlaceholder(_) | ty::ReError(_) => return None,
// FIXME(#13998) RePlaceholder should probably print like
- // ReFree rather than dumping Debug output on the user.
+ // ReLateParam rather than dumping Debug output on the user.
//
// We shouldn't really be having unification failures with ReVar
- // and ReLateBound though.
- ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
+ // and ReBound though.
+ //
+ // FIXME(@lcnr): figure out why we `ReBound` have to handle `ReBound`
+ // here, this feels somewhat off.
+ ty::ReVar(_) | ty::ReBound(..) | ty::ReErased => {
(alt_span, "revar", format!("{region:?}"))
}
};
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 0e2f9ba70fecb..b502590c1bfb9 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -13,7 +13,6 @@ use rustc_middle::ty::flags::FlagComputation;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::GenericArg;
use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
-use std::sync::atomic::Ordering;
use rustc_data_structures::fx::FxHashMap;
use rustc_index::Idx;
@@ -43,8 +42,6 @@ impl<'tcx> InferCtxt<'tcx> {
where
V: TypeFoldable>,
{
- self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
-
Canonicalizer::canonicalize(value, self, self.tcx, &CanonicalizeAllFreeRegions, query_state)
}
@@ -62,8 +59,6 @@ impl<'tcx> InferCtxt<'tcx> {
where
V: TypeFoldable>,
{
- self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
-
Canonicalizer::canonicalize(
value,
self,
@@ -138,8 +133,6 @@ impl<'tcx> InferCtxt<'tcx> {
where
V: TypeFoldable>,
{
- self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
-
Canonicalizer::canonicalize(
value,
self,
@@ -179,7 +172,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match *r {
- ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r,
+ ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
@@ -230,9 +223,13 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match *r {
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReError(_) => r,
+ ty::ReEarlyParam(_)
+ | ty::ReLateParam(_)
+ | ty::ReErased
+ | ty::ReStatic
+ | ty::ReError(_) => r,
ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r),
- ty::RePlaceholder(..) | ty::ReLateBound(..) => {
+ ty::RePlaceholder(..) | ty::ReBound(..) => {
// We only expect region names that the user can type.
bug!("unexpected region in query response: `{:?}`", r)
}
@@ -343,7 +340,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(index, ..) => {
+ ty::ReBound(index, ..) => {
if index >= self.binder_index {
bug!("escaping late-bound region during canonicalization");
} else {
@@ -366,9 +363,9 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> {
}
ty::ReStatic
- | ty::ReEarlyBound(..)
+ | ty::ReEarlyParam(..)
| ty::ReError(_)
- | ty::ReFree(_)
+ | ty::ReLateParam(_)
| ty::RePlaceholder(..)
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
}
@@ -776,7 +773,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
) -> ty::Region<'tcx> {
let var = self.canonical_var(info, r.into());
let br = ty::BoundRegion { var, kind: ty::BrAnon };
- ty::Region::new_late_bound(self.interner(), self.binder_index, br)
+ ty::Region::new_bound(self.interner(), self.binder_index, br)
}
/// Given a type variable `ty_var` of the given kind, first check
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index ed101082130c6..d911e28484c2b 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -460,7 +460,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
GenericArgKind::Lifetime(result_value) => {
// e.g., here `result_value` might be `'?1` in the example above...
- if let ty::ReLateBound(debruijn, br) = *result_value {
+ if let ty::ReBound(debruijn, br) = *result_value {
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
// We only allow a `ty::INNERMOST` index in substitutions.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 26d071a01397a..0546f4e1afc3b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -168,17 +168,17 @@ pub(super) fn note_and_explain_region<'tcx>(
alt_span: Option,
) {
let (description, span) = match *region {
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::RePlaceholder(_) | ty::ReStatic => {
+ ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
msg_span_from_named_region(tcx, region, alt_span)
}
ty::ReError(_) => return,
// We shouldn't really be having unification failures with ReVar
- // and ReLateBound though.
- ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
- (format!("lifetime `{region}`"), alt_span)
- }
+ // and ReBound though.
+ //
+ // FIXME(@lcnr): Figure out whether this is reachable and if so, why.
+ ty::ReVar(_) | ty::ReBound(..) | ty::ReErased => (format!("lifetime `{region}`"), alt_span),
};
emit_msg_span(err, prefix, description, span, suffix);
@@ -202,7 +202,7 @@ fn msg_span_from_named_region<'tcx>(
alt_span: Option,
) -> (String, Option) {
match *region {
- ty::ReEarlyBound(ref br) => {
+ ty::ReEarlyParam(ref br) => {
let scope = region.free_region_binding_scope(tcx).expect_local();
let span = if let Some(param) =
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
@@ -218,7 +218,7 @@ fn msg_span_from_named_region<'tcx>(
};
(text, Some(span))
}
- ty::ReFree(ref fr) => {
+ ty::ReLateParam(ref fr) => {
if !fr.bound_region.is_named()
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
{
@@ -315,7 +315,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
// Explain the region we are capturing.
match *hidden_region {
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
+ ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
// Assuming regionck succeeded (*), we ought to always be
// capturing *some* region from the fn header, and hence it
// ought to be free. So under normal circumstances, we will go
@@ -1285,7 +1285,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if lifetimes.0 != lifetimes.1 {
values.0.push_highlighted(l1);
values.1.push_highlighted(l2);
- } else if lifetimes.0.is_late_bound() {
+ } else if lifetimes.0.is_bound() {
values.0.push_normal(l1);
values.1.push_normal(l2);
} else {
@@ -2364,7 +2364,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span,
format!("{labeled_user_string} may not live long enough"),
match sub.kind() {
- ty::ReEarlyBound(_) | ty::ReFree(_) if sub.has_name() => error_code!(E0309),
+ ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => error_code!(E0309),
ty::ReStatic => error_code!(E0310),
_ => error_code!(E0311),
},
@@ -2372,7 +2372,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
'_explain: {
let (description, span) = match sub.kind() {
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
+ ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
msg_span_from_named_region(self.tcx, sub, Some(span))
}
_ => (format!("lifetime `{sub}`"), Some(span)),
@@ -2515,7 +2515,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let (lifetime_def_id, lifetime_scope) = match self.tcx.is_suitable_region(lifetime) {
Some(info) if !lifetime.has_name() => {
- (info.boundregion.get_id().unwrap().expect_local(), info.def_id)
+ (info.bound_region.get_id().unwrap().expect_local(), info.def_id)
}
_ => return lifetime.get_name_or_anon().to_string(),
};
@@ -2714,8 +2714,8 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
a: ty::Region<'tcx>,
b: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> {
- if (a.is_var() && b.is_free_or_static())
- || (b.is_var() && a.is_free_or_static())
+ if (a.is_var() && b.is_free())
+ || (b.is_var() && a.is_free())
|| (a.is_var() && b.is_var())
|| a == b
{
@@ -2768,18 +2768,20 @@ impl<'tcx> InferCtxt<'tcx> {
infer::AddrOfRegion(_) => " for borrow expression".to_string(),
infer::Autoref(_) => " for autoref".to_string(),
infer::Coercion(_) => " for automatic coercion".to_string(),
- infer::LateBoundRegion(_, br, infer::FnCall) => {
+ infer::BoundRegion(_, br, infer::FnCall) => {
format!(" for lifetime parameter {}in function call", br_string(br))
}
- infer::LateBoundRegion(_, br, infer::HigherRankedType) => {
+ infer::BoundRegion(_, br, infer::HigherRankedType) => {
format!(" for lifetime parameter {}in generic type", br_string(br))
}
- infer::LateBoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!(
+ infer::BoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!(
" for lifetime parameter {}in trait containing associated type `{}`",
br_string(br),
self.tcx.associated_item(def_id).name
),
- infer::EarlyBoundRegion(_, name) => format!(" for lifetime parameter `{name}`"),
+ infer::RegionParameterDefinition(_, name) => {
+ format!(" for lifetime parameter `{name}`")
+ }
infer::UpvarRegion(ref upvar_id, _) => {
let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
format!(" for capture of `{var_name}` by closure")
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
index 1a60bab18dbda..f56d5d7d345b2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -70,9 +70,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let anon_reg_sub = self.tcx().is_suitable_region(sub)?;
let scope_def_id_sup = anon_reg_sup.def_id;
- let bregion_sup = anon_reg_sup.boundregion;
+ let bregion_sup = anon_reg_sup.bound_region;
let scope_def_id_sub = anon_reg_sub.def_id;
- let bregion_sub = anon_reg_sub.boundregion;
+ let bregion_sub = anon_reg_sub.bound_region;
let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index be6d1a3750cdb..7252a812466c7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -41,8 +41,8 @@ pub fn find_param_with_region<'tcx>(
replace_region: Region<'tcx>,
) -> Option> {
let (id, bound_region) = match *anon_region {
- ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
- ty::ReEarlyBound(ebr) => {
+ ty::ReLateParam(late_param) => (late_param.scope, late_param.bound_region),
+ ty::ReEarlyParam(ebr) => {
(tcx.parent(ebr.def_id), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name))
}
_ => return None, // not a free region
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index a8ae43d52978d..59e9cbf7da6a7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -87,7 +87,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
| (ty::Alias(ty::Projection, proj), ty::Param(p))
if !tcx.is_impl_trait_in_trait(proj.def_id) =>
{
- let parent = tcx.generics_of(body_owner_def_id)
+ let parent = tcx
+ .generics_of(body_owner_def_id)
.opt_type_param(p, tcx)
.and_then(|param| {
let p_def_id = param.def_id;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index fe18d00293aa3..f0b33d30e2c63 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -572,8 +572,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let ty::Ref(expected_region, _, _) = expected.kind()
&& let ty::Ref(found_region, _, _) = found.kind()
- && expected_region.is_late_bound()
- && !found_region.is_late_bound()
+ && expected_region.is_bound()
+ && !found_region.is_bound()
&& let hir::TyKind::Infer = arg_hir.kind
{
// If the expected region is late bound, the found region is not, and users are asking compiler
diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs
index ed1a2a1171909..0dde3082d48dc 100644
--- a/compiler/rustc_infer/src/infer/free_regions.rs
+++ b/compiler/rustc_infer/src/infer/free_regions.rs
@@ -22,8 +22,8 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
Self { tcx, free_regions }
}
- pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
- self.free_regions.lub_free_regions(self.tcx, r_a, r_b)
+ pub fn lub_param_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
+ self.free_regions.lub_param_regions(self.tcx, r_a, r_b)
}
}
@@ -59,7 +59,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
r_a: Region<'tcx>,
r_b: Region<'tcx>,
) -> bool {
- assert!(r_a.is_free_or_static() && r_b.is_free_or_static());
+ assert!(r_a.is_free() && r_b.is_free());
let re_static = tcx.lifetimes.re_static;
if self.check_relation(re_static, r_b) {
// `'a <= 'static` is always true, and not stored in the
@@ -80,15 +80,15 @@ impl<'tcx> FreeRegionMap<'tcx> {
/// cases, this is more conservative than necessary, in order to
/// avoid making arbitrary choices. See
/// `TransitiveRelation::postdom_upper_bound` for more details.
- pub fn lub_free_regions(
+ pub fn lub_param_regions(
&self,
tcx: TyCtxt<'tcx>,
r_a: Region<'tcx>,
r_b: Region<'tcx>,
) -> Region<'tcx> {
- debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
- assert!(r_a.is_free());
- assert!(r_b.is_free());
+ debug!("lub_param_regions(r_a={:?}, r_b={:?})", r_a, r_b);
+ assert!(r_a.is_param());
+ assert!(r_b.is_param());
let result = if r_a == r_b {
r_a
} else {
@@ -97,7 +97,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
Some(r) => r,
}
};
- debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
+ debug!("lub_param_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
result
}
}
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 35204478c54dd..11ab86277c1b1 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -110,13 +110,13 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(..) => {
+ ty::ReBound(..) => {
// leave bound regions alone
r
}
- ty::ReEarlyBound(..)
- | ty::ReFree(_)
+ ty::ReEarlyParam(..)
+ | ty::ReLateParam(_)
| ty::ReVar(_)
| ty::RePlaceholder(..)
| ty::ReStatic
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs
index 17fe3aa7b44c1..9e24b020510d5 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/generalize.rs
@@ -327,7 +327,7 @@ where
match *r {
// Never make variables for regions bound within the type itself,
// nor for erased regions.
- ty::ReLateBound(..) | ty::ReErased => {
+ ty::ReBound(..) | ty::ReErased => {
return Ok(r);
}
@@ -340,8 +340,8 @@ where
ty::RePlaceholder(..)
| ty::ReVar(..)
| ty::ReStatic
- | ty::ReEarlyBound(..)
- | ty::ReFree(..) => {
+ | ty::ReEarlyParam(..)
+ | ty::ReLateParam(..) => {
// see common code below
}
}
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index bee0a978ad04f..800aee1f4d3bf 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -16,8 +16,8 @@ use rustc_data_structures::intern::Interned;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_middle::ty::{ReEarlyBound, ReErased, ReError, ReFree, ReStatic};
-use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar};
+use rustc_middle::ty::{ReBound, RePlaceholder, ReVar};
+use rustc_middle::ty::{ReEarlyParam, ReErased, ReError, ReLateParam, ReStatic};
use rustc_middle::ty::{Region, RegionVid};
use rustc_span::Span;
use std::fmt;
@@ -378,7 +378,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// so it doesn't really matter if it's shorter or longer than an empty region
ReError(_) => false,
- ReLateBound(..) | ReErased => {
+ ReBound(..) | ReErased => {
bug!("cannot relate region: {:?}", a);
}
@@ -390,7 +390,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
);
}
- ReStatic | ReEarlyBound(_) | ReFree(_) => {
+ ReStatic | ReEarlyParam(_) | ReLateParam(_) => {
// nothing lives longer than `'static`
// All empty regions are less than early-bound, free,
@@ -411,7 +411,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// so it doesn't really matter if it's shorter or longer than an empty region
ReError(_) => false,
- ReLateBound(..) | ReErased => {
+ ReBound(..) | ReErased => {
bug!("cannot relate region: {:?}", b);
}
@@ -423,9 +423,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
);
}
- ReStatic | ReEarlyBound(_) | ReFree(_) => {
+ ReStatic | ReEarlyParam(_) | ReLateParam(_) => {
// nothing lives longer than `'static`
- // All empty regions are less than early-bound, free,
+ // All empty regions are less than early-bound, late-bound,
// and scope regions.
true
}
@@ -450,8 +450,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// Check for the case where we know that `'b: 'static` -- in that case,
// `a <= b` for all `a`.
- let b_free_or_static = b.is_free_or_static();
- if b_free_or_static && sub_free_regions(tcx.lifetimes.re_static, b) {
+ if b.is_free() && sub_free_regions(tcx.lifetimes.re_static, b) {
return true;
}
@@ -460,8 +459,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// `lub` relationship defined below, since sometimes the "lub"
// is actually the `postdom_upper_bound` (see
// `TransitiveRelation` for more details).
- let a_free_or_static = a.is_free_or_static();
- if a_free_or_static && b_free_or_static {
+ if a.is_free() && b.is_free() {
return sub_free_regions(a, b);
}
@@ -478,7 +476,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
#[instrument(level = "trace", skip(self), ret)]
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
match (*a, *b) {
- (ReLateBound(..), _) | (_, ReLateBound(..)) | (ReErased, _) | (_, ReErased) => {
+ (ReBound(..), _) | (_, ReBound(..)) | (ReErased, _) | (_, ReErased) => {
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
}
@@ -501,8 +499,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
self.tcx().lifetimes.re_static
}
- (ReEarlyBound(_) | ReFree(_), ReEarlyBound(_) | ReFree(_)) => {
- self.region_rels.lub_free_regions(a, b)
+ (ReEarlyParam(_) | ReLateParam(_), ReEarlyParam(_) | ReLateParam(_)) => {
+ self.region_rels.lub_param_regions(a, b)
}
// For these types, we cannot define any additional
@@ -723,13 +721,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
return;
}
- // We place free regions first because we are special casing
- // SubSupConflict(ReFree, ReFree) when reporting error, and so
+ // We place late-bound regions first because we are special casing
+ // SubSupConflict(ReLateParam, ReLateParam) when reporting error, and so
// the user will more likely get a specific suggestion.
fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 {
match *x.region {
- ReEarlyBound(_) => 0,
- ReFree(_) => 1,
+ ReEarlyParam(_) => 0,
+ ReLateParam(_) => 1,
_ => 2,
}
}
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 4ee897ffe9843..956d097a5b2e2 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1,7 +1,7 @@
pub use self::at::DefineOpaqueTypes;
pub use self::freshen::TypeFreshener;
pub use self::lexical_region_resolve::RegionResolutionError;
-pub use self::LateBoundRegionConversionTime::*;
+pub use self::BoundRegionConversionTime::*;
pub use self::RegionVariableOrigin::*;
pub use self::SubregionOrigin::*;
pub use self::ValuePairs::*;
@@ -472,9 +472,9 @@ impl<'tcx> SubregionOrigin<'tcx> {
}
}
-/// Times when we replace late-bound regions with variables:
+/// Times when we replace bound regions with existentials:
#[derive(Clone, Copy, Debug)]
-pub enum LateBoundRegionConversionTime {
+pub enum BoundRegionConversionTime {
/// when a fn is called
FnCall,
@@ -508,11 +508,14 @@ pub enum RegionVariableOrigin {
Coercion(Span),
/// Region variables created as the values for early-bound regions.
- EarlyBoundRegion(Span, Symbol),
+ ///
+ /// FIXME(@lcnr): This can also store a `DefId`, similar to
+ /// `TypeVariableOriginKind::TypeParameterDefinition`.
+ RegionParameterDefinition(Span, Symbol),
- /// Region variables created for bound regions
- /// in a function or method that is called.
- LateBoundRegion(Span, ty::BoundRegionKind, LateBoundRegionConversionTime),
+ /// Region variables created when instantiating a binder with
+ /// existential variables, e.g. when calling a function or method.
+ BoundRegion(Span, ty::BoundRegionKind, BoundRegionConversionTime),
UpvarRegion(ty::UpvarId, Span),
@@ -1165,7 +1168,7 @@ impl<'tcx> InferCtxt<'tcx> {
GenericParamDefKind::Lifetime => {
// Create a region inference variable for the given
// region parameter definition.
- self.next_region_var(EarlyBoundRegion(span, param.name)).into()
+ self.next_region_var(RegionParameterDefinition(span, param.name)).into()
}
GenericParamDefKind::Type { .. } => {
// Create a type inference variable for the given
@@ -1456,13 +1459,13 @@ impl<'tcx> InferCtxt<'tcx> {
// variables in the current universe.
//
// Use this method if you'd like to find some substitution of the binder's
- // variables (e.g. during a method call). If there isn't a [`LateBoundRegionConversionTime`]
+ // variables (e.g. during a method call). If there isn't a [`BoundRegionConversionTime`]
// that corresponds to your use case, consider whether or not you should
// use [`InferCtxt::instantiate_binder_with_placeholders`] instead.
pub fn instantiate_binder_with_fresh_vars(
&self,
span: Span,
- lbrct: LateBoundRegionConversionTime,
+ lbrct: BoundRegionConversionTime,
value: ty::Binder<'tcx, T>,
) -> T
where
@@ -1475,7 +1478,7 @@ impl<'tcx> InferCtxt<'tcx> {
struct ToFreshVars<'a, 'tcx> {
infcx: &'a InferCtxt<'tcx>,
span: Span,
- lbrct: LateBoundRegionConversionTime,
+ lbrct: BoundRegionConversionTime,
map: FxHashMap>,
}
@@ -1485,7 +1488,7 @@ impl<'tcx> InferCtxt<'tcx> {
.entry(br.var)
.or_insert_with(|| {
self.infcx
- .next_region_var(LateBoundRegion(self.span, br.kind, self.lbrct))
+ .next_region_var(BoundRegion(self.span, br.kind, self.lbrct))
.into()
})
.expect_region()
@@ -2041,8 +2044,8 @@ impl RegionVariableOrigin {
| AddrOfRegion(a)
| Autoref(a)
| Coercion(a)
- | EarlyBoundRegion(a, ..)
- | LateBoundRegion(a, ..)
+ | RegionParameterDefinition(a, ..)
+ | BoundRegion(a, ..)
| UpvarRegion(_, a) => a,
Nll(..) => bug!("NLL variable used with `span`"),
}
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 7a5dec22fe049..7a792d30cc749 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -432,7 +432,7 @@ where
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
match *r {
// ignore bound regions, keep visiting
- ty::ReLateBound(_, _) => ControlFlow::Continue(()),
+ ty::ReBound(_, _) => ControlFlow::Continue(()),
_ => {
(self.op)(r);
ControlFlow::Continue(())
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index 38819e8ad8a62..f867876a2e63f 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -213,8 +213,8 @@ pub(super) fn compute_alias_components_recursive<'tcx>(
compute_components(tcx, ty, out, visited);
}
GenericArgKind::Lifetime(lt) => {
- // Ignore late-bound regions.
- if !lt.is_late_bound() {
+ // Ignore higher ranked regions.
+ if !lt.is_bound() {
out.push(Component::Region(lt));
}
}
@@ -241,8 +241,8 @@ fn compute_components_recursive<'tcx>(
compute_components(tcx, ty, out, visited);
}
GenericArgKind::Lifetime(lt) => {
- // Ignore late-bound regions.
- if !lt.is_late_bound() {
+ // Ignore higher ranked regions.
+ if !lt.is_bound() {
out.push(Component::Region(lt));
}
}
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index 47e3dd762b08b..f8dbfdde30c50 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -138,8 +138,8 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
}
OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) {
(
- ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_),
- ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_),
+ ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
+ ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
) => self.region_relation.add(r_a, r_b),
(ty::ReError(_), _) | (_, ty::ReError(_)) => {}
// FIXME(#109628): We shouldn't have existential variables in implied bounds.
diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
index 398ac94ee3685..52cc107ae52c3 100644
--- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
+++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
@@ -37,7 +37,7 @@ where
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
match *r {
// ignore bound regions, keep visiting
- ty::ReLateBound(_, _) => ControlFlow::Continue(()),
+ ty::ReBound(_, _) => ControlFlow::Continue(()),
_ => {
(self.op)(r);
ControlFlow::Continue(())
@@ -112,7 +112,9 @@ where
};
for (idx, s) in args.iter().enumerate() {
- if variances.map(|variances| variances[idx]) != Some(ty::Variance::Bivariant) {
+ if variances.map(|variances| variances[idx])
+ != Some(ty::Variance::Bivariant)
+ {
s.visit_with(self)?;
}
}
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index 6f973ee37f5e9..959b34aa14574 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -48,7 +48,7 @@ pub fn extract_verify_if_eq<'tcx>(
let verify_if_eq = verify_if_eq_b.skip_binder();
m.relate(verify_if_eq.ty, test_ty).ok()?;
- if let ty::RegionKind::ReLateBound(depth, br) = verify_if_eq.bound.kind() {
+ if let ty::RegionKind::ReBound(depth, br) = verify_if_eq.bound.kind() {
assert!(depth == ty::INNERMOST);
match m.map.get(&br) {
Some(&r) => Some(r),
@@ -177,7 +177,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
value: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("self.pattern_depth = {:?}", self.pattern_depth);
- if let ty::RegionKind::ReLateBound(depth, br) = pattern.kind()
+ if let ty::RegionKind::ReBound(depth, br) = pattern.kind()
&& depth == self.pattern_depth
{
self.bind(br, value)
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 3fa9a7333a453..e888340bde3fe 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -16,7 +16,7 @@ use rustc_index::IndexVec;
use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
use rustc_middle::ty::ReStatic;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_middle::ty::{ReLateBound, ReVar};
+use rustc_middle::ty::{ReBound, ReVar};
use rustc_middle::ty::{Region, RegionVid};
use rustc_span::Span;
@@ -531,7 +531,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
debug!("origin = {:#?}", origin);
match (*sub, *sup) {
- (ReLateBound(..), _) | (_, ReLateBound(..)) => {
+ (ReBound(..), _) | (_, ReBound(..)) => {
span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup);
}
(_, ReStatic) => {
@@ -662,12 +662,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
match *region {
ty::ReStatic
| ty::ReErased
- | ty::ReFree(..)
- | ty::ReEarlyBound(..)
+ | ty::ReLateParam(..)
+ | ty::ReEarlyParam(..)
| ty::ReError(_) => ty::UniverseIndex::ROOT,
ty::RePlaceholder(placeholder) => placeholder.universe,
ty::ReVar(vid) => self.var_universe(vid),
- ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
+ ty::ReBound(..) => bug!("universe(): encountered bound region {:?}", region),
}
}
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 4a6d1bc682b39..4ca3ced21ee23 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -13,9 +13,9 @@
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 3c566e0dd6da6..8cee13ce4ec75 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -340,7 +340,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
// consider this as evidence that `T: 'static`, but
// I'm a bit wary of such constructions and so for now
// I want to be conservative. --nmatsakis
- if r_min.is_late_bound() {
+ if r_min.is_bound() {
return;
}
@@ -351,7 +351,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
.into_iter()
.filter_map(|component| match component {
Component::Region(r) => {
- if r.is_late_bound() {
+ if r.is_bound() {
None
} else {
Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index c4962707f69a8..d113e03896668 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -40,7 +40,6 @@ pub type Result = result::Result;
pub struct Compiler {
pub(crate) sess: Lrc,
codegen_backend: Lrc,
- pub(crate) register_lints: Option>,
pub(crate) override_queries: Option,
}
@@ -51,9 +50,6 @@ impl Compiler {
pub fn codegen_backend(&self) -> &Lrc {
&self.codegen_backend
}
- pub fn register_lints(&self) -> &Option> {
- &self.register_lints
- }
pub fn build_output_filenames(
&self,
sess: &Session,
@@ -178,7 +174,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -
check_cfg.exhaustive_names = true;
for arg in args {
- if arg.is_word() && let Some(ident) = arg.ident() {
+ if arg.is_word()
+ && let Some(ident) = arg.ident()
+ {
check_cfg.expecteds.entry(ident.name).or_insert(ExpectedValues::Any);
} else {
error!("`names()` arguments must be simple identifiers");
@@ -188,7 +186,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -
set_old_syntax();
if let Some((name, values)) = args.split_first() {
- if name.is_word() && let Some(ident) = name.ident() {
+ if name.is_word()
+ && let Some(ident) = name.ident()
+ {
let expected_values = check_cfg
.expecteds
.entry(ident.name)
@@ -236,12 +236,16 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -
let mut values_any_specified = false;
for arg in args {
- if arg.is_word() && let Some(ident) = arg.ident() {
+ if arg.is_word()
+ && let Some(ident) = arg.ident()
+ {
if values_specified {
error!("`cfg()` names cannot be after values");
}
names.push(ident);
- } else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() {
+ } else if arg.has_name(sym::any)
+ && let Some(args) = arg.meta_item_list()
+ {
if any_specified {
error!("`any()` cannot be specified multiple times");
}
@@ -249,7 +253,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -
if !args.is_empty() {
error!("`any()` must be empty");
}
- } else if arg.has_name(sym::values) && let Some(args) = arg.meta_item_list() {
+ } else if arg.has_name(sym::values)
+ && let Some(args) = arg.meta_item_list()
+ {
if names.is_empty() {
error!("`values()` cannot be specified before the names");
} else if values_specified {
@@ -260,7 +266,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -
for arg in args {
if let Some(LitKind::Str(s, _)) = arg.lit().map(|lit| &lit.kind) {
values.insert(Some(*s));
- } else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() {
+ } else if arg.has_name(sym::any)
+ && let Some(args) = arg.meta_item_list()
+ {
if values_any_specified {
error!("`any()` in `values()` cannot be specified multiple times");
}
@@ -473,10 +481,19 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se
sess.opts.untracked_state_hash = hasher.finish()
}
+ // Even though the session holds the lint store, we can't build the
+ // lint store until after the session exists. And we wait until now
+ // so that `register_lints` sees the fully initialized session.
+ let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
+ if let Some(register_lints) = config.register_lints.as_deref() {
+ register_lints(&sess, &mut lint_store);
+ sess.registered_lints = true;
+ }
+ sess.lint_store = Some(Lrc::new(lint_store));
+
let compiler = Compiler {
sess: Lrc::new(sess),
codegen_backend: Lrc::from(codegen_backend),
- register_lints: config.register_lints,
override_queries: config.override_queries,
};
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 7d14d088e595e..0baf77c4f7e19 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -72,17 +72,6 @@ fn count_nodes(krate: &ast::Crate) -> usize {
counter.count
}
-pub(crate) fn create_lint_store(
- sess: &Session,
- register_lints: Option,
-) -> LintStore {
- let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
- if let Some(register_lints) = register_lints {
- register_lints(sess, &mut lint_store);
- }
- lint_store
-}
-
fn pre_expansion_lint<'a>(
sess: &Session,
features: &Features,
@@ -138,7 +127,7 @@ fn configure_and_expand(
let tcx = resolver.tcx();
let sess = tcx.sess;
let features = tcx.features();
- let lint_store = unerased_lint_store(tcx);
+ let lint_store = unerased_lint_store(&tcx.sess);
let crate_name = tcx.crate_name(LOCAL_CRATE);
let lint_check_node = (&krate, pre_configured_attrs);
pre_expansion_lint(
@@ -330,7 +319,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
}
});
- let lint_store = unerased_lint_store(tcx);
+ let lint_store = unerased_lint_store(&tcx.sess);
rustc_lint::check_ast_node(
sess,
tcx.features(),
@@ -645,7 +634,6 @@ pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
crate_types: Vec,
stable_crate_id: StableCrateId,
- lint_store: Lrc,
dep_graph: DepGraph,
untracked: Untracked,
gcx_cell: &'tcx OnceLock>,
@@ -676,7 +664,6 @@ pub fn create_global_ctxt<'tcx>(
sess,
crate_types,
stable_crate_id,
- lint_store,
arena,
hir_arena,
untracked,
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 3a5f788e8ddb6..ace5ec732fbc5 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -148,8 +148,6 @@ impl<'tcx> Queries<'tcx> {
);
let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
- let lint_store =
- Lrc::new(passes::create_lint_store(sess, self.compiler.register_lints.as_deref()));
let cstore = FreezeLock::new(Box::new(CStore::new(
self.codegen_backend().metadata_loader(),
stable_crate_id,
@@ -164,7 +162,6 @@ impl<'tcx> Queries<'tcx> {
self.compiler,
crate_types,
stable_crate_id,
- lint_store,
dep_graph,
untracked,
&self.gcx_cell,
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index d308169552317..e6e132978edde 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -679,7 +679,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(incremental_info, true);
untracked!(incremental_verify_ich, true);
untracked!(input_stats, true);
- untracked!(keep_hygiene_data, true);
untracked!(link_native_libraries, false);
untracked!(llvm_time_trace, true);
untracked!(ls, vec!["all".to_owned()]);
@@ -691,7 +690,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(no_leak_check, true);
untracked!(no_parallel_llvm, true);
untracked!(parse_only, true);
- untracked!(perf_stats, true);
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
untracked!(print_codegen_stats, true);
@@ -771,6 +769,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(instrument_xray, Some(InstrumentXRay::default()));
tracked!(link_directives, false);
tracked!(link_only, true);
+ tracked!(llvm_module_flag, vec![("bar".to_string(), 123, "max".to_string())]);
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
tracked!(maximal_hir_to_mir_coverage, true);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 22d12793464a8..8df3648a065de 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -415,7 +415,9 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec match *a {
- ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b),
+ ty::ReEarlyParam(ebr) if ebr.def_id == def_id => Some(b),
_ => None,
},
_ => None,
@@ -1953,7 +1953,7 @@ impl ExplicitOutlivesRequirements {
let is_inferred = match tcx.named_bound_var(lifetime.hir_id) {
Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives
.iter()
- .any(|r| matches!(**r, ty::ReEarlyBound(ebr) if { ebr.def_id == def_id })),
+ .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { ebr.def_id == def_id })),
_ => false,
};
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index a5f4c5ff0459e..cd4c0d07e55f5 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -497,9 +497,6 @@ pub struct LateContext<'tcx> {
/// Items accessible from the crate being checked.
pub effective_visibilities: &'tcx EffectiveVisibilities,
- /// The store of registered lints and the lint levels.
- pub lint_store: &'tcx LintStore,
-
pub last_node_with_lint_attrs: hir::HirId,
/// Generic type parameters in scope for the item we are in.
@@ -515,21 +512,14 @@ pub struct EarlyContext<'a> {
pub buffered: LintBuffer,
}
-pub trait LintPassObject: Sized {}
-
-impl LintPassObject for EarlyLintPassObject {}
-
-impl LintPassObject for LateLintPassObject<'_> {}
-
-pub trait LintContext: Sized {
- type PassObject: LintPassObject;
-
+pub trait LintContext {
fn sess(&self) -> &Session;
- fn lints(&self) -> &LintStore;
- /// Emit a lint at the appropriate level, with an optional associated span and an existing diagnostic.
+ /// Emit a lint at the appropriate level, with an optional associated span and an existing
+ /// diagnostic.
///
- /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
+ /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed
+ /// explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
@@ -1059,17 +1049,11 @@ impl<'a> EarlyContext<'a> {
}
impl<'tcx> LintContext for LateContext<'tcx> {
- type PassObject = LateLintPassObject<'tcx>;
-
/// Gets the overall compiler `Session` object.
fn sess(&self) -> &Session {
&self.tcx.sess
}
- fn lints(&self) -> &LintStore {
- &*self.lint_store
- }
-
#[rustc_lint_diagnostics]
fn lookup>(
&self,
@@ -1094,17 +1078,11 @@ impl<'tcx> LintContext for LateContext<'tcx> {
}
impl LintContext for EarlyContext<'_> {
- type PassObject = EarlyLintPassObject;
-
/// Gets the overall compiler `Session` object.
fn sess(&self) -> &Session {
&self.builder.sess()
}
- fn lints(&self) -> &LintStore {
- self.builder.lint_store()
- }
-
#[rustc_lint_diagnostics]
fn lookup>(
&self,
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index 6c8b60c8d7413..10c4c0dc79f9f 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -17,22 +17,25 @@
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
use rustc_ast as ast;
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_data_structures::sync::join;
+use rustc_data_structures::sync::{join, Lrc};
use rustc_hir as hir;
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
use rustc_hir::intravisit as hir_visit;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::LintPass;
+use rustc_session::Session;
use rustc_span::Span;
use std::any::Any;
use std::cell::Cell;
/// Extract the `LintStore` from the query context.
-/// This function exists because we've erased `LintStore` as `dyn Any` in the context.
-pub fn unerased_lint_store(tcx: TyCtxt<'_>) -> &LintStore {
- let store: &dyn Any = &*tcx.lint_store;
+/// This function exists because we've erased `LintStore` as `dyn Any` in the session.
+pub fn unerased_lint_store(sess: &Session) -> &LintStore {
+ assert!(sess.lint_store.is_some());
+ let store: &Lrc<_> = sess.lint_store.as_ref().unwrap();
+ let store: &dyn Any = &**store;
store.downcast_ref().unwrap()
}
@@ -353,7 +356,6 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
effective_visibilities: &tcx.effective_visibilities(()),
- lint_store: unerased_lint_store(tcx),
last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id),
generics: None,
only_module: true,
@@ -362,8 +364,11 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
// Note: `passes` is often empty. In that case, it's faster to run
// `builtin_lints` directly rather than bundling it up into the
// `RuntimeCombinedLateLintPass`.
- let mut passes: Vec<_> =
- unerased_lint_store(tcx).late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
+ let mut passes: Vec<_> = unerased_lint_store(&tcx.sess)
+ .late_module_passes
+ .iter()
+ .map(|mk_pass| (mk_pass)(tcx))
+ .collect();
if passes.is_empty() {
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
} else {
@@ -400,7 +405,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>(
fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) {
// Note: `passes` is often empty.
let mut passes: Vec<_> =
- unerased_lint_store(tcx).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
+ unerased_lint_store(&tcx.sess).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
if passes.is_empty() {
return;
@@ -412,7 +417,6 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) {
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
effective_visibilities: &tcx.effective_visibilities(()),
- lint_store: unerased_lint_store(tcx),
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
generics: None,
only_module: false,
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 0d20f6232db15..ee5fa87e45db1 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -123,7 +123,7 @@ impl LintLevelSets {
}
fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> {
- let store = unerased_lint_store(tcx);
+ let store = unerased_lint_store(&tcx.sess);
let mut builder = LintLevelsBuilder {
sess: tcx.sess,
@@ -152,7 +152,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
#[instrument(level = "trace", skip(tcx), ret)]
fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap {
- let store = unerased_lint_store(tcx);
+ let store = unerased_lint_store(&tcx.sess);
let attrs = tcx.hir_attrs(owner);
let mut levels = LintLevelsBuilder {
@@ -548,10 +548,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
self.features
}
- pub(crate) fn lint_store(&self) -> &LintStore {
- self.store
- }
-
fn current_specs(&self) -> &FxHashMap {
self.provider.current_specs()
}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 54adedd3c0988..606e18866165c 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -27,8 +27,8 @@
#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(array_windows)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index d44691b5e9bac..82483ac7dc0fd 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -155,7 +155,7 @@ fn is_cast_from_const_to_mut<'tcx>(
let start_ty = cx.typeck_results().node_type(e.hir_id);
if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
- // If an UnsafeCell method is involved we need to additionaly check the
+ // If an UnsafeCell method is involved we need to additionally check the
// inner type for the presence of the Freeze trait (ie does NOT contain
// an UnsafeCell), since in that case we would incorrectly lint on valid casts.
//
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index fe13162cd4a3c..ed1e87713237b 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -242,6 +242,12 @@ fn main() {
cmd.arg("--system-libs");
}
+ // We need libkstat for getHostCPUName on SPARC builds.
+ // See also: https://github.com/llvm/llvm-project/issues/64186
+ if target.starts_with("sparcv9") && target.contains("solaris") {
+ println!("cargo:rustc-link-lib=kstat");
+ }
+
if (target.starts_with("arm") && !target.contains("freebsd"))
|| target.starts_with("mips-")
|| target.starts_with("mipsel-")
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 4390486b0deb1..7ada2eff593c6 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -983,6 +983,9 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
unwrapDI(Ty),
fromRust(Flags),
unwrap(val),
+#if LLVM_VERSION_GE(18, 0)
+ llvm::dwarf::DW_TAG_member,
+#endif
AlignInBits
));
}
@@ -1105,7 +1108,11 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
unwrapDI(Scope), StringRef(Name, NameLen),
unwrapDI(File), LineNumber,
SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)),
- unwrapDI(ClassTy), "", IsScoped));
+ unwrapDI(ClassTy),
+#if LLVM_VERSION_GE(18, 0)
+ /* RunTimeLang */ 0,
+#endif
+ "", IsScoped));
}
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index 518c20c9fa8bf..ca0aec71052d0 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,9 +1,9 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
// NOTE: This crate only exists to allow linking on mingw targets.
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index 0c9ec556549fa..e3464cb8a2df6 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -14,7 +14,7 @@
//!
//! ```
//! fn main() {
-//! rustc_log::init_env_logger("LOG").unwrap();
+//! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap();
//!
//! let edition = rustc_span::edition::Edition::Edition2021;
//! rustc_span::create_session_globals_then(edition, || {
@@ -52,13 +52,36 @@ use tracing_subscriber::fmt::{
};
use tracing_subscriber::layer::SubscriberExt;
-pub fn init_env_logger(env: &str) -> Result<(), Error> {
- let filter = match env::var(env) {
+/// The values of all the environment variables that matter for configuring a logger.
+/// Errors are explicitly preserved so that we can share error handling.
+pub struct LoggerConfig {
+ pub filter: Result,
+ pub color_logs: Result,
+ pub verbose_entry_exit: Result,
+ pub verbose_thread_ids: Result,
+ pub backtrace: Result,
+}
+
+impl LoggerConfig {
+ pub fn from_env(env: &str) -> Self {
+ LoggerConfig {
+ filter: env::var(env),
+ color_logs: env::var(format!("{env}_COLOR")),
+ verbose_entry_exit: env::var(format!("{env}_ENTRY_EXIT")),
+ verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")),
+ backtrace: env::var(format!("{env}_BACKTRACE")),
+ }
+ }
+}
+
+/// Initialize the logger with the given values for the filter, coloring, and other options env variables.
+pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> {
+ let filter = match cfg.filter {
Ok(env) => EnvFilter::new(env),
_ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)),
};
- let color_logs = match env::var(String::from(env) + "_COLOR") {
+ let color_logs = match cfg.color_logs {
Ok(value) => match value.as_ref() {
"always" => true,
"never" => false,
@@ -69,14 +92,14 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> {
Err(VarError::NotUnicode(_value)) => return Err(Error::NonUnicodeColorValue),
};
- let verbose_entry_exit = match env::var_os(String::from(env) + "_ENTRY_EXIT") {
- None => false,
- Some(v) => &v != "0",
+ let verbose_entry_exit = match cfg.verbose_entry_exit {
+ Ok(v) => &v != "0",
+ Err(_) => false,
};
- let verbose_thread_ids = match env::var_os(String::from(env) + "_THREAD_IDS") {
- None => false,
- Some(v) => &v == "1",
+ let verbose_thread_ids = match cfg.verbose_thread_ids {
+ Ok(v) => &v == "1",
+ Err(_) => false,
};
let layer = tracing_tree::HierarchicalLayer::default()
@@ -91,7 +114,7 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> {
.with_thread_names(verbose_thread_ids);
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
- match env::var(format!("{env}_BACKTRACE")) {
+ match cfg.backtrace {
Ok(str) => {
let fmt_layer = tracing_subscriber::fmt::layer()
.with_writer(io::stderr)
diff --git a/compiler/rustc_macros/src/current_version.rs b/compiler/rustc_macros/src/current_version.rs
index 5e3b91c17bf6c..42ca60a6d8ab8 100644
--- a/compiler/rustc_macros/src/current_version.rs
+++ b/compiler/rustc_macros/src/current_version.rs
@@ -1,37 +1,16 @@
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
-use syn::parse::{Parse, ParseStream};
-use syn::{parenthesized, parse_macro_input, LitStr, Token};
-pub struct Input {
- variable: LitStr,
-}
-
-mod kw {
- syn::custom_keyword!(env);
-}
-
-impl Parse for Input {
- // Input syntax is `env!("CFG_RELEASE")` to facilitate grepping.
- fn parse(input: ParseStream<'_>) -> syn::Result {
- let paren;
- input.parse::()?;
- input.parse::()?;
- parenthesized!(paren in input);
- let variable: LitStr = paren.parse()?;
- Ok(Input { variable })
- }
-}
-
-pub(crate) fn current_version(input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as Input);
-
- TokenStream::from(match RustcVersion::parse_env_var(&input.variable) {
+pub(crate) fn current_version(_input: TokenStream) -> TokenStream {
+ let env_var = "CFG_RELEASE";
+ TokenStream::from(match RustcVersion::parse_cfg_release(env_var) {
Ok(RustcVersion { major, minor, patch }) => quote!(
+ // The produced literal has type `rustc_session::RustcVersion`.
Self { major: #major, minor: #minor, patch: #patch }
),
- Err(err) => syn::Error::new(Span::call_site(), err).into_compile_error(),
+ Err(err) => syn::Error::new(Span::call_site(), format!("{env_var} env var: {err}"))
+ .into_compile_error(),
})
}
@@ -42,8 +21,8 @@ struct RustcVersion {
}
impl RustcVersion {
- fn parse_env_var(env_var: &LitStr) -> Result> {
- let value = proc_macro::tracked_env::var(env_var.value())?;
+ fn parse_cfg_release(env_var: &str) -> Result> {
+ let value = proc_macro::tracked_env::var(env_var)?;
Self::parse_str(&value)
.ok_or_else(|| format!("failed to parse rustc version: {:?}", value).into())
}
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 1a8174bfd9681..31ad9cdb21619 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -229,8 +229,8 @@ fn generate_test(slug: &syn::Path, structure: &Structure<'_>) -> TokenStream {
}
}
use std::sync::atomic::{AtomicUsize, Ordering};
- // We need to make sure that the same diagnostic slug can be used multiple times without causing an
- // error, so just have a global counter here.
+ // We need to make sure that the same diagnostic slug can be used multiple times without
+ // causing an error, so just have a global counter here.
static COUNTER: AtomicUsize = AtomicUsize::new(0);
let slug = slug.get_ident().unwrap();
let ident = quote::format_ident!("verify_{slug}_{}", COUNTER.fetch_add(1, Ordering::Relaxed));
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index e9a5cd9de97b0..2755a161d91e7 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -53,6 +53,7 @@ pub(crate) struct DiagnosticDeriveVariantBuilder<'parent> {
/// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
/// has the actual diagnostic message.
pub slug: SpannedOption,
+
/// Error codes are a optional part of the struct attribute - this is only set to detect
/// multiple specifications.
pub code: SpannedOption<()>,
@@ -68,7 +69,7 @@ impl DiagnosticDeriveBuilder {
/// Call `f` for the struct or for each variant of the enum, returning a `TokenStream` with the
/// tokens from `f` wrapped in an `match` expression. Emits errors for use of derive on unions
/// or attributes on the type itself when input is an enum.
- pub fn each_variant<'s, F>(&mut self, structure: &mut Structure<'s>, f: F) -> TokenStream
+ pub(crate) fn each_variant<'s, F>(&mut self, structure: &mut Structure<'s>, f: F) -> TokenStream
where
F: for<'a, 'v> Fn(DiagnosticDeriveVariantBuilder<'a>, &VariantInfo<'v>) -> TokenStream,
{
@@ -121,7 +122,7 @@ impl DiagnosticDeriveBuilder {
impl<'a> DiagnosticDeriveVariantBuilder<'a> {
/// Generates calls to `code` and similar functions based on the attributes on the type or
/// variant.
- pub fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
+ pub(crate) fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
let ast = variant.ast();
let attrs = &ast.attrs;
let preamble = attrs.iter().map(|attr| {
@@ -135,7 +136,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
/// Generates calls to `span_label` and similar functions based on the attributes on fields or
/// calls to `set_arg` when no attributes are present.
- pub fn body(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
+ pub(crate) fn body(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
let mut body = quote! {};
// Generate `set_arg` calls first..
for binding in variant.bindings().iter().filter(|bi| should_generate_set_arg(bi.ast())) {
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index 877271ff0774c..0f9e68cdc5018 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -478,7 +478,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
}
}
- pub fn into_tokens(&mut self) -> Result {
+ pub(crate) fn into_tokens(&mut self) -> Result {
let kind_slugs = self.identify_kind()?;
if kind_slugs.is_empty() {
if self.is_enum {
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index 125632921816b..2700f02e33a66 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -17,7 +17,7 @@ use synstructure::{BindingInfo, VariantInfo};
use super::error::invalid_attr;
thread_local! {
- pub static CODE_IDENT_COUNT: RefCell = RefCell::new(0);
+ pub(crate) static CODE_IDENT_COUNT: RefCell = RefCell::new(0);
}
/// Returns an ident of the form `__code_N` where `N` is incremented once with every call.
@@ -208,7 +208,7 @@ impl<'ty> FieldInnerTy<'ty> {
}
}
- pub fn span(&self) -> proc_macro2::Span {
+ pub(crate) fn span(&self) -> proc_macro2::Span {
match self {
FieldInnerTy::Option(ty) | FieldInnerTy::Vec(ty) | FieldInnerTy::Plain(ty) => ty.span(),
}
@@ -537,7 +537,7 @@ impl fmt::Display for SuggestionKind {
}
impl SuggestionKind {
- pub fn to_suggestion_style(&self) -> TokenStream {
+ pub(crate) fn to_suggestion_style(&self) -> TokenStream {
match self {
SuggestionKind::Normal => {
quote! { rustc_errors::SuggestionStyle::ShowCode }
diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs
index 75a2f7009c258..6d23b9ac99d24 100644
--- a/compiler/rustc_macros/src/hash_stable.rs
+++ b/compiler/rustc_macros/src/hash_stable.rs
@@ -38,33 +38,16 @@ fn parse_attributes(field: &syn::Field) -> Attributes {
attrs
}
-pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+pub(crate) fn hash_stable_generic_derive(
+ mut s: synstructure::Structure<'_>,
+) -> proc_macro2::TokenStream {
let generic: syn::GenericParam = parse_quote!(__CTX);
s.add_bounds(synstructure::AddBounds::Generics);
s.add_impl_generic(generic);
s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext });
- let body = s.each(|bi| {
- let attrs = parse_attributes(bi.ast());
- if attrs.ignore {
- quote! {}
- } else if let Some(project) = attrs.project {
- quote! {
- (bi.#project).hash_stable(__hcx, __hasher);
- }
- } else {
- quote! {
- #bi.hash_stable(__hcx, __hasher);
- }
- }
- });
- let discriminant = match s.ast().data {
- syn::Data::Enum(_) => quote! {
- ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
- },
- syn::Data::Struct(_) => quote! {},
- syn::Data::Union(_) => panic!("cannot derive on union"),
- };
+ let discriminant = hash_stable_discriminant(&mut s);
+ let body = hash_stable_body(&mut s);
s.bound_impl(
quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>),
@@ -81,32 +64,13 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma
)
}
-pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+pub(crate) fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let generic: syn::GenericParam = parse_quote!('__ctx);
s.add_bounds(synstructure::AddBounds::Generics);
s.add_impl_generic(generic);
- let body = s.each(|bi| {
- let attrs = parse_attributes(bi.ast());
- if attrs.ignore {
- quote! {}
- } else if let Some(project) = attrs.project {
- quote! {
- (bi.#project).hash_stable(__hcx, __hasher);
- }
- } else {
- quote! {
- #bi.hash_stable(__hcx, __hasher);
- }
- }
- });
- let discriminant = match s.ast().data {
- syn::Data::Enum(_) => quote! {
- ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
- },
- syn::Data::Struct(_) => quote! {},
- syn::Data::Union(_) => panic!("cannot derive on union"),
- };
+ let discriminant = hash_stable_discriminant(&mut s);
+ let body = hash_stable_body(&mut s);
s.bound_impl(
quote!(
@@ -126,3 +90,30 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To
},
)
}
+
+fn hash_stable_discriminant(s: &mut synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+ match s.ast().data {
+ syn::Data::Enum(_) => quote! {
+ ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
+ },
+ syn::Data::Struct(_) => quote! {},
+ syn::Data::Union(_) => panic!("cannot derive on union"),
+ }
+}
+
+fn hash_stable_body(s: &mut synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+ s.each(|bi| {
+ let attrs = parse_attributes(bi.ast());
+ if attrs.ignore {
+ quote! {}
+ } else if let Some(project) = attrs.project {
+ quote! {
+ (bi.#project).hash_stable(__hcx, __hasher);
+ }
+ } else {
+ quote! {
+ #bi.hash_stable(__hcx, __hasher);
+ }
+ }
+ })
+}
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 193dbd75fbd57..a66666360324e 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -26,6 +26,9 @@ mod symbols;
mod type_foldable;
mod type_visitable;
+// Reads the rust version (e.g. "1.75.0") from the CFG_RELEASE env var and
+// produces a `RustcVersion` literal containing that version (e.g.
+// `RustcVersion { major: 1, minor: 75, patch: 0 }`).
#[proc_macro]
pub fn current_rustc_version(input: TokenStream) -> TokenStream {
current_version::current_version(input)
diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs
index 4129712a6b218..488d4504a2d11 100644
--- a/compiler/rustc_macros/src/symbols.rs
+++ b/compiler/rustc_macros/src/symbols.rs
@@ -19,7 +19,9 @@
//! ```bash
//! cargo install cargo-expand # this is necessary only once
//! cd compiler/rustc_span
-//! cargo expand > /tmp/rustc_span.rs # it's a big file
+//! # The specific version number in CFG_RELEASE doesn't matter.
+//! # The output is large.
+//! CFG_RELEASE="0.0.0" cargo +nightly expand > /tmp/rustc_span.rs
//! ```
use proc_macro2::{Span, TokenStream};
@@ -83,7 +85,9 @@ impl Parse for Value {
}
}
Expr::Macro(expr) => {
- if expr.mac.path.is_ident("env") && let Ok(lit) = expr.mac.parse_body() {
+ if expr.mac.path.is_ident("env")
+ && let Ok(lit) = expr.mac.parse_body()
+ {
return Ok(Value::Env(lit, expr.mac.clone()));
}
}
@@ -318,13 +322,4 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) {
};
(output, errors.list)
-
- // To see the generated code, use the "cargo expand" command.
- // Do this once to install:
- // cargo install cargo-expand
- //
- // Then, cd to rustc_span and run:
- // cargo expand > /tmp/rustc_span_expanded.rs
- //
- // and read that file.
}
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index b06b4fb87cde2..d326a3aa8d026 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -1,11 +1,10 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(decl_macro)]
#![feature(extract_if)]
-#![cfg_attr(bootstrap, feature(generators))]
-#![cfg_attr(not(bootstrap), feature(coroutines))]
+#![feature(coroutines)]
#![feature(iter_from_coroutine)]
#![feature(let_chains)]
#![feature(if_let_guard)]
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 2042863d189db..b6ffdc7378f6a 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2396,8 +2396,10 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String {
// * character escapes
//
// FIXME: This passes through `-/*spacer*/0` verbatim.
- Literal if !value.span.from_expansion()
- && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) => {
+ Literal
+ if !value.span.from_expansion()
+ && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) =>
+ {
snippet
}
@@ -2408,10 +2410,12 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String {
// FIXME: Omit the curly braces if the enclosing expression is an array literal
// with a repeated element (an `ExprKind::Repeat`) as in such case it
// would not actually need any disambiguation.
- Complex => if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
- "{ _ }".to_owned()
- } else {
- "_".to_owned()
+ Complex => {
+ if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
+ "{ _ }".to_owned()
+ } else {
+ "_".to_owned()
+ }
}
}
}
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 76ef62f9f2728..dc0da165af67d 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -8,8 +8,8 @@ mod dep_node;
pub use rustc_query_system::dep_graph::debug::EdgeFilter;
pub use rustc_query_system::dep_graph::{
- debug::DepNodeFilter, hash_result, DepContext, DepGraphQuery, DepNodeColor, DepNodeIndex, Deps,
- SerializedDepGraph, SerializedDepNodeIndex, TaskDeps, TaskDepsRef, WorkProduct, WorkProductId,
+ debug::DepNodeFilter, hash_result, DepContext, DepGraphQuery, DepNodeIndex, Deps,
+ SerializedDepGraph, SerializedDepNodeIndex, TaskDepsRef, WorkProduct, WorkProductId,
WorkProductMap,
};
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 64b63f4c5eb4f..5a957d2c26d61 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -63,7 +63,7 @@ impl CanonicalVarValues<'_> {
pub fn is_identity(&self) -> bool {
self.var_values.iter().enumerate().all(|(bv, arg)| match arg.unpack() {
ty::GenericArgKind::Lifetime(r) => {
- matches!(*r, ty::ReLateBound(ty::INNERMOST, br) if br.var.as_usize() == bv)
+ matches!(*r, ty::ReBound(ty::INNERMOST, br) if br.var.as_usize() == bv)
}
ty::GenericArgKind::Type(ty) => {
matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var.as_usize() == bv)
@@ -79,7 +79,7 @@ impl CanonicalVarValues<'_> {
for arg in self.var_values {
match arg.unpack() {
ty::GenericArgKind::Lifetime(r) => {
- if let ty::ReLateBound(ty::INNERMOST, br) = *r
+ if let ty::ReBound(ty::INNERMOST, br) = *r
&& var == br.var
{
var = var + 1;
@@ -389,7 +389,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
var: ty::BoundVar::from_usize(i),
kind: ty::BrAnon,
};
- ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into()
+ ty::Region::new_bound(tcx, ty::INNERMOST, br).into()
}
CanonicalVarKind::Effect => ty::Const::new_bound(
tcx,
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index 041a63776d113..6e50e89404648 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -58,18 +58,17 @@ impl<'tcx> UnifyValue for UnifiedRegion<'tcx> {
fn unify_values(value1: &Self, value2: &Self) -> Result {
// We pick the value of the least universe because it is compatible with more variables.
- // This is *not* necessary for soundness, but it allows more region variables to be
- // resolved to the said value.
+ // This is *not* necessary for completeness.
#[cold]
fn min_universe<'tcx>(r1: Region<'tcx>, r2: Region<'tcx>) -> Region<'tcx> {
cmp::min_by_key(r1, r2, |r| match r.kind() {
ty::ReStatic
| ty::ReErased
- | ty::ReFree(..)
- | ty::ReEarlyBound(..)
+ | ty::ReLateParam(..)
+ | ty::ReEarlyParam(..)
| ty::ReError(_) => ty::UniverseIndex::ROOT,
ty::RePlaceholder(placeholder) => placeholder.universe,
- ty::ReVar(..) | ty::ReLateBound(..) => bug!("not a universal region"),
+ ty::ReVar(..) | ty::ReBound(..) => bug!("not a universal region"),
})
}
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 448a3029ae97a..4af875e8d79df 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -23,8 +23,8 @@
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(allocator_api)]
#![feature(array_windows)]
#![feature(assert_matches)]
@@ -32,8 +32,7 @@
#![feature(core_intrinsics)]
#![feature(discriminant_kind)]
#![feature(exhaustive_patterns)]
-#![cfg_attr(bootstrap, feature(generators))]
-#![cfg_attr(not(bootstrap), feature(coroutines))]
+#![feature(coroutines)]
#![feature(get_mut_unchecked)]
#![feature(if_let_guard)]
#![feature(inline_const)]
@@ -59,7 +58,6 @@
#![feature(extract_if)]
#![feature(intra_doc_pointers)]
#![feature(yeet_expr)]
-#![feature(result_option_inspect)]
#![feature(const_option)]
#![feature(trait_alias)]
#![feature(ptr_alignment_type)]
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 56fed05c63f74..b76d1d6e141d6 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -77,7 +77,7 @@ use std::ops::Deref;
/// picture, but rather the ending point.
//
// FIXME(pnkfelix): this currently derives `PartialOrd` and `Ord` to
-// placate the same deriving in `ty::FreeRegion`, but we may want to
+// placate the same deriving in `ty::LateParamRegion`, but we may want to
// actually attach a more meaningful ordering to scopes than the one
// generated via deriving here.
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index e360fb3eaaf3c..b87c6885e04c8 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -525,6 +525,13 @@ impl<'tcx> TyCtxt<'tcx> {
self.alloc_map.lock().reserve()
}
+ /// Miri's provenance GC needs to see all live allocations. The interpreter manages most
+ /// allocations but some are managed by [`TyCtxt`] and without this method the interpreter
+ /// doesn't know their [`AllocId`]s are in use.
+ pub fn iter_allocs(self, func: F) {
+ self.alloc_map.lock().alloc_map.keys().copied().for_each(func)
+ }
+
/// Reserves a new ID *if* this allocation has not been dedup-reserved before.
/// Should only be used for "symbolic" allocations (function pointers, vtables, statics), we
/// don't want to dedup IDs for "real" memory!
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 7054cede2d87c..874c997c23be8 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1611,14 +1611,29 @@ impl Location {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DefLocation {
Argument,
- Body(Location),
+ Assignment(Location),
+ CallReturn { call: BasicBlock, target: Option },
}
impl DefLocation {
pub fn dominates(self, location: Location, dominators: &Dominators) -> bool {
match self {
DefLocation::Argument => true,
- DefLocation::Body(def) => def.successor_within_block().dominates(location, dominators),
+ DefLocation::Assignment(def) => {
+ def.successor_within_block().dominates(location, dominators)
+ }
+ DefLocation::CallReturn { target: None, .. } => false,
+ DefLocation::CallReturn { call, target: Some(target) } => {
+ // The definition occurs on the call -> target edge. The definition dominates a use
+ // if and only if the edge is on all paths from the entry to the use.
+ //
+ // Note that a call terminator has only one edge that can reach the target, so when
+ // the call strongly dominates the target, all paths from the entry to the target
+ // go through the call -> target edge.
+ call != target
+ && dominators.dominates(call, target)
+ && dominators.dominates(target, location.block)
+ }
}
}
}
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 0540eb0efd6c9..d609965f36fe6 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -416,7 +416,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
ty::ReVar(vid) => {
let br = ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon };
- ty::Region::new_late_bound(tcx, depth, br)
+ ty::Region::new_bound(tcx, depth, br)
}
_ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
});
@@ -430,7 +430,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
) -> Ty<'tcx> {
tcx.fold_regions(self.inner, |r, depth| match r.kind() {
- ty::ReLateBound(debruijn, br) => {
+ ty::ReBound(debruijn, br) => {
debug_assert_eq!(debruijn, depth);
map(ty::RegionVid::new(br.var.index()))
}
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index a5358687c14c5..38538a0b316a7 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -507,11 +507,7 @@ fn write_span(
where
W: Write,
{
- let maybe_alt_class = if layer > 0 {
- if alt { " odd" } else { " even" }
- } else {
- ""
- };
+ let maybe_alt_class = if layer > 0 { if alt { " odd" } else { " even" } } else { "" };
let maybe_title_attr = if !tooltip.is_empty() {
format!(" title=\"{}\"", escape_attr(tooltip))
} else {
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 9dfbe1733cc51..9a6ac6ff57a4e 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -28,7 +28,9 @@ impl SwitchTargets {
/// Inverse of `SwitchTargets::static_if`.
pub fn as_static_if(&self) -> Option<(u128, BasicBlock, BasicBlock)> {
- if let &[value] = &self.values[..] && let &[then, else_] = &self.targets[..] {
+ if let &[value] = &self.values[..]
+ && let &[then, else_] = &self.targets[..]
+ {
Some((value, then, else_))
} else {
None
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 3086082fe8d57..00c33113692d0 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -655,7 +655,9 @@ impl<'tcx> Pat<'tcx> {
pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
let mut error = None;
self.walk(|pat| {
- if let PatKind::Error(e) = pat.kind && error.is_none() {
+ if let PatKind::Error(e) = pat.kind
+ && error.is_none()
+ {
error = Some(e);
}
error.is_none()
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 551c4a15dd0d9..ee23c9c48978e 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -39,7 +39,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::steal::Steal;
-use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, WorkerLocal};
+use rustc_data_structures::sync::{FreezeReadGuard, Lock, WorkerLocal};
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
@@ -69,7 +69,6 @@ use rustc_type_ir::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
-use std::any::Any;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt;
@@ -113,9 +112,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ExprConst = ty::Expr<'tcx>;
type Region = Region<'tcx>;
- type EarlyBoundRegion = ty::EarlyBoundRegion;
+ type EarlyParamRegion = ty::EarlyParamRegion;
type BoundRegion = ty::BoundRegion;
- type FreeRegion = ty::FreeRegion;
+ type LateParamRegion = ty::LateParamRegion;
type InferRegion = ty::RegionVid;
type PlaceholderRegion = ty::PlaceholderRegion;
@@ -327,7 +326,7 @@ pub struct CommonLifetimes<'tcx> {
pub re_vars: Vec>,
/// Pre-interned values of the form:
- /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })`
+ /// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })`
/// for small values of `i` and `v`.
pub re_late_bounds: Vec>>,
}
@@ -402,7 +401,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
.map(|i| {
(0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
.map(|v| {
- mk(ty::ReLateBound(
+ mk(ty::ReBound(
ty::DebruijnIndex::from(i),
ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon },
))
@@ -445,14 +444,14 @@ impl<'tcx> CommonConsts<'tcx> {
}
}
-/// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
-/// conflict.
+/// This struct contains information regarding a free parameter region,
+/// either a `ReEarlyParam` or `ReLateParam`.
#[derive(Debug)]
pub struct FreeRegionInfo {
- /// `LocalDefId` corresponding to FreeRegion
+ /// `LocalDefId` of the free region.
pub def_id: LocalDefId,
- /// the bound region corresponding to FreeRegion
- pub boundregion: ty::BoundRegionKind,
+ /// the bound region corresponding to free region.
+ pub bound_region: ty::BoundRegionKind,
/// checks if bound region is in Impl Item
pub is_impl_item: bool,
}
@@ -544,12 +543,6 @@ pub struct GlobalCtxt<'tcx> {
/// `rustc_symbol_mangling` crate for more information.
stable_crate_id: StableCrateId,
- /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
- ///
- /// FIXME(Centril): consider `dyn LintStoreMarker` once
- /// we can upcast to `Any` for some additional type safety.
- pub lint_store: Lrc,
-
pub dep_graph: DepGraph,
pub prof: SelfProfilerRef,
@@ -709,7 +702,6 @@ impl<'tcx> TyCtxt<'tcx> {
s: &'tcx Session,
crate_types: Vec,
stable_crate_id: StableCrateId,
- lint_store: Lrc,
arena: &'tcx WorkerLocal>,
hir_arena: &'tcx WorkerLocal>,
untracked: Untracked,
@@ -730,7 +722,6 @@ impl<'tcx> TyCtxt<'tcx> {
sess: s,
crate_types,
stable_crate_id,
- lint_store,
arena,
hir_arena,
interners,
@@ -1080,8 +1071,8 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option {
let (suitable_region_binding_scope, bound_region) = loop {
let def_id = match region.kind() {
- ty::ReFree(fr) => fr.bound_region.get_id()?.as_local()?,
- ty::ReEarlyBound(ebr) => ebr.def_id.expect_local(),
+ ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?,
+ ty::ReEarlyParam(ebr) => ebr.def_id.expect_local(),
_ => return None, // not a free region
};
let scope = self.local_parent(def_id);
@@ -1102,11 +1093,7 @@ impl<'tcx> TyCtxt<'tcx> {
_ => false,
};
- Some(FreeRegionInfo {
- def_id: suitable_region_binding_scope,
- boundregion: bound_region,
- is_impl_item,
- })
+ Some(FreeRegionInfo { def_id: suitable_region_binding_scope, bound_region, is_impl_item })
}
/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
@@ -1743,7 +1730,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
match param.kind {
GenericParamDefKind::Lifetime => {
- ty::Region::new_early_bound(self, param.to_early_bound_region_data()).into()
+ ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
}
GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
GenericParamDefKind::Const { .. } => ty::Const::new_param(
@@ -2040,7 +2027,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Given the def-id of an early-bound lifetime on an RPIT corresponding to
/// a duplicated captured lifetime, map it back to the early- or late-bound
/// lifetime of the function from which it originally as captured. If it is
- /// a late-bound lifetime, this will represent the liberated (`ReFree`) lifetime
+ /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
/// of the signature.
// FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
// re-use the generics of the opaque, this function will need to be tweaked slightly.
@@ -2079,9 +2066,9 @@ impl<'tcx> TyCtxt<'tcx> {
}
let generics = self.generics_of(new_parent);
- return ty::Region::new_early_bound(
+ return ty::Region::new_early_param(
self,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: ebv,
index: generics
.param_def_id_to_index(self, ebv)
@@ -2092,7 +2079,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
Some(resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv)) => {
let new_parent = self.parent(lbv);
- return ty::Region::new_free(
+ return ty::Region::new_late_param(
self,
new_parent,
ty::BoundRegionKind::BrNamed(
diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs
index 3371ea3bec8c5..cfd36fd8c7c35 100644
--- a/compiler/rustc_middle/src/ty/erase_regions.rs
+++ b/compiler/rustc_middle/src/ty/erase_regions.rs
@@ -53,16 +53,11 @@ impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> {
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- // because late-bound regions affect subtyping, we can't
- // erase the bound/free distinction, but we can replace
- // all free regions with 'erased.
- //
- // Note that we *CAN* replace early-bound regions -- the
- // type system never "sees" those, they get substituted
- // away. In codegen, they will always be erased to 'erased
- // whenever a substitution occurs.
+ // We must not erase bound regions. `for<'a> fn(&'a ())` and
+ // `fn(&'free ())` are different types: they may implement different
+ // traits and have a different `TypeId`.
match *r {
- ty::ReLateBound(..) => r,
+ ty::ReBound(..) => r,
_ => self.tcx.lifetimes.re_erased,
}
}
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 738bb5e8b1959..b26f98769c14a 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -7,8 +7,7 @@ use rustc_hir::def_id::DefId;
use rustc_span::symbol::Symbol;
use rustc_target::spec::abi;
use std::borrow::Cow;
-use std::collections::hash_map::DefaultHasher;
-use std::hash::{Hash, Hasher};
+use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::PathBuf;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 75ea53195a3ac..f95ceeff1507a 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -189,14 +189,14 @@ pub struct DeepRejectCtxt {
}
impl DeepRejectCtxt {
- pub fn args_refs_may_unify<'tcx>(
+ pub fn args_may_unify<'tcx>(
self,
obligation_args: GenericArgsRef<'tcx>,
impl_args: GenericArgsRef<'tcx>,
) -> bool {
iter::zip(obligation_args, impl_args).all(|(obl, imp)| {
match (obl.unpack(), imp.unpack()) {
- // We don't fast reject based on regions for now.
+ // We don't fast reject based on regions.
(GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true,
(GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => {
self.types_may_unify(obl, imp)
@@ -231,7 +231,7 @@ impl DeepRejectCtxt {
| ty::Never
| ty::Tuple(..)
| ty::FnPtr(..)
- | ty::Foreign(..) => {}
+ | ty::Foreign(..) => debug_assert!(impl_ty.is_known_rigid()),
ty::FnDef(..)
| ty::Closure(..)
| ty::Coroutine(..)
@@ -260,7 +260,7 @@ impl DeepRejectCtxt {
},
ty::Adt(obl_def, obl_args) => match k {
&ty::Adt(impl_def, impl_args) => {
- obl_def == impl_def && self.args_refs_may_unify(obl_args, impl_args)
+ obl_def == impl_def && self.args_may_unify(obl_args, impl_args)
}
_ => false,
},
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index ec36bdc5a518b..4d7b12662c663 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -137,7 +137,7 @@ impl FlagComputation {
&ty::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
- self.add_flags(TypeFlags::HAS_TY_LATE_BOUND);
+ self.add_flags(TypeFlags::HAS_TY_BOUND);
}
&ty::Placeholder(..) => {
@@ -294,7 +294,7 @@ impl FlagComputation {
fn add_region(&mut self, r: ty::Region<'_>) {
self.add_flags(r.type_flags());
- if let ty::ReLateBound(debruijn, _) = *r {
+ if let ty::ReBound(debruijn, _) = *r {
self.add_bound_var(debruijn);
}
}
@@ -317,7 +317,7 @@ impl FlagComputation {
}
ty::ConstKind::Bound(debruijn, _) => {
self.add_bound_var(debruijn);
- self.add_flags(TypeFlags::HAS_CT_LATE_BOUND);
+ self.add_flags(TypeFlags::HAS_CT_BOUND);
}
ty::ConstKind::Param(_) => {
self.add_flags(TypeFlags::HAS_CT_PARAM);
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 00529a1e066cc..cff0d4df67356 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -68,12 +68,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// Folds over the substructure of a type, visiting its component
/// types and all regions that occur *free* within it.
///
-/// That is, `Ty` can contain function or method types that bind
-/// regions at the call site (`ReLateBound`), and occurrences of
-/// regions (aka "lifetimes") that are bound within a type are not
-/// visited by this folder; only regions that occur free will be
+/// That is, function pointer types and trait object can introduce
+/// new bound regions which are not visited by this visitors as
+/// they are not free; only regions that occur free will be
/// visited by `fld_r`.
-
pub struct RegionFolder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
@@ -117,7 +115,7 @@ impl<'a, 'tcx> TypeFolder> for RegionFolder<'a, 'tcx> {
#[instrument(skip(self), level = "debug", ret)]
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
+ ty::ReBound(debruijn, _) if debruijn < self.current_index => {
debug!(?self.current_index, "skipped bound region");
r
}
@@ -205,15 +203,15 @@ where
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
+ ty::ReBound(debruijn, br) if debruijn == self.current_index => {
let region = self.delegate.replace_region(br);
- if let ty::ReLateBound(debruijn1, br) = *region {
- // If the callback returns a late-bound region,
+ if let ty::ReBound(debruijn1, br) = *region {
+ // If the callback returns a bound region,
// that region should always use the INNERMOST
// debruijn index. Then we adjust it to the
// correct depth.
assert_eq!(debruijn1, ty::INNERMOST);
- ty::Region::new_late_bound(self.tcx, debruijn, br)
+ ty::Region::new_bound(self.tcx, debruijn, br)
} else {
region
}
@@ -328,7 +326,7 @@ impl<'tcx> TyCtxt<'tcx> {
T: TypeFoldable>,
{
self.replace_late_bound_regions_uncached(value, |br| {
- ty::Region::new_free(self, all_outlive_scope, br.kind)
+ ty::Region::new_late_param(self, all_outlive_scope, br.kind)
})
}
@@ -341,7 +339,7 @@ impl<'tcx> TyCtxt<'tcx> {
value,
FnMutDelegate {
regions: &mut |r: ty::BoundRegion| {
- ty::Region::new_late_bound(
+ ty::Region::new_bound(
self,
ty::INNERMOST,
ty::BoundRegion { var: shift_bv(r.var), kind: r.kind },
@@ -388,7 +386,7 @@ impl<'tcx> TyCtxt<'tcx> {
.or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon))
.expect_region();
let br = ty::BoundRegion { var, kind };
- ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br)
+ ty::Region::new_bound(self.tcx, ty::INNERMOST, br)
}
fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
let entry = self.map.entry(bt.var);
@@ -454,9 +452,9 @@ impl<'tcx> TypeFolder> for Shifter<'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
+ ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
let debruijn = debruijn.shifted_in(self.amount);
- ty::Region::new_late_bound(self.tcx, debruijn, br)
+ ty::Region::new_bound(self.tcx, debruijn, br)
}
_ => r,
}
@@ -496,8 +494,8 @@ pub fn shift_region<'tcx>(
amount: u32,
) -> ty::Region<'tcx> {
match *region {
- ty::ReLateBound(debruijn, br) if amount > 0 => {
- ty::Region::new_late_bound(tcx, debruijn.shifted_in(amount), br)
+ ty::ReBound(debruijn, br) if amount > 0 => {
+ ty::Region::new_bound(tcx, debruijn.shifted_in(amount), br)
}
_ => region,
}
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 41a1bf04e5f3f..8fd08c724d2ba 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -809,7 +809,7 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
#[cold]
#[inline(never)]
- fn region_param_out_of_range(data: ty::EarlyBoundRegion, args: &[GenericArg<'_>]) -> ! {
+ fn region_param_out_of_range(data: ty::EarlyParamRegion, args: &[GenericArg<'_>]) -> ! {
bug!(
"Region parameter out of range when substituting in region {} (index={}, args = {:?})",
data.name,
@@ -820,7 +820,7 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> {
#[cold]
#[inline(never)]
- fn region_param_invalid(data: ty::EarlyBoundRegion, other: GenericArgKind<'_>) -> ! {
+ fn region_param_invalid(data: ty::EarlyParamRegion, other: GenericArgKind<'_>) -> ! {
bug!(
"Unexpected parameter {:?} when substituting in region {} (index={})",
other,
@@ -835,7 +835,7 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> {
// regions that appear in a function signature is done using
// the specialized routine `ty::replace_late_regions()`.
match *r {
- ty::ReEarlyBound(data) => {
+ ty::ReEarlyParam(data) => {
let rk = self.args.get(data.index as usize).map(|k| k.unpack());
match rk {
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
@@ -843,8 +843,8 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> {
None => region_param_out_of_range(data, self.args),
}
}
- ty::ReLateBound(..)
- | ty::ReFree(_)
+ ty::ReBound(..)
+ | ty::ReLateParam(_)
| ty::ReStatic
| ty::RePlaceholder(_)
| ty::ReErased
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 888ee1d237ae7..4a6e3cfacd3d0 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span;
-use super::{Clause, EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
+use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum GenericParamDefKind {
@@ -62,9 +62,9 @@ pub struct GenericParamDef {
}
impl GenericParamDef {
- pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
+ pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion {
if let GenericParamDefKind::Lifetime = self.kind {
- ty::EarlyBoundRegion { def_id: self.def_id, index: self.index, name: self.name }
+ ty::EarlyParamRegion { def_id: self.def_id, index: self.index, name: self.name }
} else {
bug!("cannot convert a non-lifetime parameter def to an early bound region")
}
@@ -260,10 +260,10 @@ impl<'tcx> Generics {
}
}
- /// Returns the `GenericParamDef` associated with this `EarlyBoundRegion`.
+ /// Returns the `GenericParamDef` associated with this `EarlyParamRegion`.
pub fn region_param(
&'tcx self,
- param: &EarlyBoundRegion,
+ param: &ty::EarlyParamRegion,
tcx: TyCtxt<'tcx>,
) -> &'tcx GenericParamDef {
let param = self.param_at(param.index as usize, tcx);
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 4223e503f5e22..aca6acd783b92 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -215,7 +215,7 @@ pub enum LayoutError<'tcx> {
SizeOverflow(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
ReferencesError(ErrorGuaranteed),
- Cycle,
+ Cycle(ErrorGuaranteed),
}
impl<'tcx> LayoutError<'tcx> {
@@ -226,7 +226,7 @@ impl<'tcx> LayoutError<'tcx> {
Unknown(_) => middle_unknown_layout,
SizeOverflow(_) => middle_values_too_big,
NormalizationFailure(_, _) => middle_cannot_be_normalized,
- Cycle => middle_cycle,
+ Cycle(_) => middle_cycle,
ReferencesError(_) => middle_layout_references_error,
}
}
@@ -240,7 +240,7 @@ impl<'tcx> LayoutError<'tcx> {
NormalizationFailure(ty, e) => {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
}
- Cycle => E::Cycle,
+ Cycle(_) => E::Cycle,
ReferencesError(_) => E::ReferencesError,
}
}
@@ -261,7 +261,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
t,
e.get_type_for_failure()
),
- LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"),
+ LayoutError::Cycle(_) => write!(f, "a cycle occurred during layout computation"),
LayoutError::ReferencesError(_) => write!(f, "the type has an unknown layout"),
}
}
@@ -333,7 +333,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
Err(err @ LayoutError::Unknown(_)) => err,
// We can't extract SizeSkeleton info from other layout errors
Err(
- e @ LayoutError::Cycle
+ e @ LayoutError::Cycle(_)
| e @ LayoutError::SizeOverflow(_)
| e @ LayoutError::NormalizationFailure(..)
| e @ LayoutError::ReferencesError(_),
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index e1c616ba0785d..559bf9fb825de 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -98,11 +98,12 @@ pub use self::sty::BoundRegionKind::*;
pub use self::sty::{
AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind,
- ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyBoundRegion, EffectVid, ExistentialPredicate,
- ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, InlineConstArgs,
- InlineConstArgsParts, ParamConst, ParamTy, PolyExistentialPredicate, PolyExistentialProjection,
- PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, PredicateKind, Region,
- RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
+ ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, EffectVid, ExistentialPredicate,
+ ExistentialProjection, ExistentialTraitRef, FnSig, GenSig, InlineConstArgs,
+ InlineConstArgsParts, LateParamRegion, ParamConst, ParamTy, PolyExistentialPredicate,
+ PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef,
+ PredicateKind, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs,
+ VarianceDiagInfo,
};
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
@@ -463,7 +464,7 @@ pub struct CReaderCacheKey {
#[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo>>);
-impl ty::EarlyBoundRegion {
+impl EarlyParamRegion {
/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).
pub fn has_name(&self) -> bool {
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 8d895732dff20..1305f63bdbc2f 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -102,8 +102,9 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> {
// Ignore bound regions and `'static` regions that appear in the
// type, we only need to remap regions that reference lifetimes
// from the function declaration.
- // This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
- ty::ReLateBound(..) | ty::ReStatic => return r,
+ //
+ // E.g. We ignore `'r` in a type like `for<'r> fn(&'r u32)`.
+ ty::ReBound(..) | ty::ReStatic => return r,
// If regions have been erased (by writeback), don't try to unerase
// them.
@@ -112,7 +113,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> {
ty::ReError(_) => return r,
// The regions that we expect from borrow checking.
- ty::ReEarlyBound(_) | ty::ReFree(_) => {}
+ ty::ReEarlyParam(_) | ty::ReLateParam(_) => {}
ty::RePlaceholder(_) | ty::ReVar(_) => {
// All of the regions in the type should either have been
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index baf160bcc99da..ad070dcc9e385 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2158,10 +2158,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
match *region {
- ty::ReEarlyBound(ref data) => data.has_name(),
+ ty::ReEarlyParam(ref data) => data.has_name(),
- ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
- | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
+ ty::ReBound(_, ty::BoundRegion { kind: br, .. })
+ | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. })
| ty::RePlaceholder(ty::Placeholder {
bound: ty::BoundRegion { kind: br, .. }, ..
}) => {
@@ -2228,14 +2228,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
// to fit that into a short string. Hence the recommendation to use
// `explain_region()` or `note_and_explain_region()`.
match *region {
- ty::ReEarlyBound(ref data) => {
+ ty::ReEarlyParam(ref data) => {
if data.name != kw::Empty {
p!(write("{}", data.name));
return Ok(());
}
}
- ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
- | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
+ ty::ReBound(_, ty::BoundRegion { kind: br, .. })
+ | ty::ReLateParam(ty::LateParamRegion { bound_region: br, .. })
| ty::RePlaceholder(ty::Placeholder {
bound: ty::BoundRegion { kind: br, .. }, ..
}) => {
@@ -2315,7 +2315,7 @@ impl<'a, 'tcx> ty::TypeFolder> for RegionFolder<'a, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
let name = &mut self.name;
let region = match *r {
- ty::ReLateBound(db, br) if db >= self.current_index => {
+ ty::ReBound(db, br) if db >= self.current_index => {
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
}
ty::RePlaceholder(ty::PlaceholderRegion {
@@ -2338,9 +2338,9 @@ impl<'a, 'tcx> ty::TypeFolder> for RegionFolder<'a, 'tcx> {
}
_ => return r,
};
- if let ty::ReLateBound(debruijn1, br) = *region {
+ if let ty::ReBound(debruijn1, br) = *region {
assert_eq!(debruijn1, ty::INNERMOST);
- ty::Region::new_late_bound(self.tcx, self.current_index, br)
+ ty::Region::new_bound(self.tcx, self.current_index, br)
} else {
region
}
@@ -2450,7 +2450,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
if let Some(lt_idx) = lifetime_idx {
if lt_idx > binder_level_idx {
let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
- return ty::Region::new_late_bound(
+ return ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
@@ -2466,7 +2466,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
if let Some(lt_idx) = lifetime_idx {
if lt_idx > binder_level_idx {
let kind = ty::BrNamed(def_id, name);
- return ty::Region::new_late_bound(
+ return ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
@@ -2480,7 +2480,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
if let Some(lt_idx) = lifetime_idx {
if lt_idx > binder_level_idx {
let kind = br.kind;
- return ty::Region::new_late_bound(
+ return ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
@@ -2496,11 +2496,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
start_or_continue(self, "for<", ", ");
do_continue(self, name);
}
- ty::Region::new_late_bound(
- tcx,
- ty::INNERMOST,
- ty::BoundRegion { var: br.var, kind },
- )
+ ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { var: br.var, kind })
};
let mut folder = RegionFolder {
tcx,
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 6af68bc5dbabb..e223ffd7c5d54 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -79,9 +79,9 @@ impl fmt::Debug for ty::BoundRegionKind {
}
}
-impl fmt::Debug for ty::FreeRegion {
+impl fmt::Debug for ty::LateParamRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
+ write!(f, "ReLateParam({:?}, {:?})", self.scope, self.bound_region)
}
}
@@ -444,7 +444,7 @@ TrivialTypeTraversalImpls! {
crate::ty::Placeholder,
crate::ty::Placeholder,
crate::ty::Placeholder,
- crate::ty::FreeRegion,
+ crate::ty::LateParamRegion,
crate::ty::InferTy,
crate::ty::IntVarValue,
crate::ty::adjustment::PointerCoercion,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 44592b10d5574..2b1e57f58717b 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -61,9 +61,9 @@ pub struct TypeAndMut<'tcx> {
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
#[derive(HashStable)]
-/// A "free" region `fr` can be interpreted as "some region
+/// The parameter representation of late-bound function parameters, "some region
/// at least as big as the scope `fr.scope`".
-pub struct FreeRegion {
+pub struct LateParamRegion {
pub scope: DefId,
pub bound_region: BoundRegionKind,
}
@@ -1468,15 +1468,15 @@ pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
impl<'tcx> Region<'tcx> {
#[inline]
- pub fn new_early_bound(
+ pub fn new_early_param(
tcx: TyCtxt<'tcx>,
- early_bound_region: ty::EarlyBoundRegion,
+ early_bound_region: ty::EarlyParamRegion,
) -> Region<'tcx> {
- tcx.intern_region(ty::ReEarlyBound(early_bound_region))
+ tcx.intern_region(ty::ReEarlyParam(early_bound_region))
}
#[inline]
- pub fn new_late_bound(
+ pub fn new_bound(
tcx: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
bound_region: ty::BoundRegion,
@@ -1488,17 +1488,17 @@ impl<'tcx> Region<'tcx> {
{
re
} else {
- tcx.intern_region(ty::ReLateBound(debruijn, bound_region))
+ tcx.intern_region(ty::ReBound(debruijn, bound_region))
}
}
#[inline]
- pub fn new_free(
+ pub fn new_late_param(
tcx: TyCtxt<'tcx>,
scope: DefId,
bound_region: ty::BoundRegionKind,
) -> Region<'tcx> {
- tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region }))
+ tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region }))
}
#[inline]
@@ -1549,10 +1549,10 @@ impl<'tcx> Region<'tcx> {
/// to avoid the cost of the `match`.
pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
match kind {
- ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region),
- ty::ReLateBound(debruijn, region) => Region::new_late_bound(tcx, debruijn, region),
- ty::ReFree(ty::FreeRegion { scope, bound_region }) => {
- Region::new_free(tcx, scope, bound_region)
+ ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
+ ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region),
+ ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => {
+ Region::new_late_param(tcx, scope, bound_region)
}
ty::ReStatic => tcx.lifetimes.re_static,
ty::ReVar(vid) => Region::new_var(tcx, vid),
@@ -1574,13 +1574,13 @@ impl<'tcx> Deref for Region<'tcx> {
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
#[derive(HashStable)]
-pub struct EarlyBoundRegion {
+pub struct EarlyParamRegion {
pub def_id: DefId,
pub index: u32,
pub name: Symbol,
}
-impl fmt::Debug for EarlyBoundRegion {
+impl fmt::Debug for EarlyParamRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name)
}
@@ -1722,9 +1722,9 @@ impl<'tcx> Region<'tcx> {
pub fn get_name(self) -> Option {
if self.has_name() {
match *self {
- ty::ReEarlyBound(ebr) => Some(ebr.name),
- ty::ReLateBound(_, br) => br.kind.get_name(),
- ty::ReFree(fr) => fr.bound_region.get_name(),
+ ty::ReEarlyParam(ebr) => Some(ebr.name),
+ ty::ReBound(_, br) => br.kind.get_name(),
+ ty::ReLateParam(fr) => fr.bound_region.get_name(),
ty::ReStatic => Some(kw::StaticLifetime),
ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
_ => None,
@@ -1744,9 +1744,9 @@ impl<'tcx> Region<'tcx> {
/// Is this region named by the user?
pub fn has_name(self) -> bool {
match *self {
- ty::ReEarlyBound(ebr) => ebr.has_name(),
- ty::ReLateBound(_, br) => br.kind.is_named(),
- ty::ReFree(fr) => fr.bound_region.is_named(),
+ ty::ReEarlyParam(ebr) => ebr.has_name(),
+ ty::ReBound(_, br) => br.kind.is_named(),
+ ty::ReLateParam(fr) => fr.bound_region.is_named(),
ty::ReStatic => true,
ty::ReVar(..) => false,
ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
@@ -1771,8 +1771,8 @@ impl<'tcx> Region<'tcx> {
}
#[inline]
- pub fn is_late_bound(self) -> bool {
- matches!(*self, ty::ReLateBound(..))
+ pub fn is_bound(self) -> bool {
+ matches!(*self, ty::ReBound(..))
}
#[inline]
@@ -1783,7 +1783,7 @@ impl<'tcx> Region<'tcx> {
#[inline]
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
match *self {
- ty::ReLateBound(debruijn, _) => debruijn >= index,
+ ty::ReBound(debruijn, _) => debruijn >= index,
_ => false,
}
}
@@ -1802,20 +1802,20 @@ impl<'tcx> Region<'tcx> {
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
}
- ty::ReEarlyBound(..) => {
+ ty::ReEarlyParam(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PARAM;
}
- ty::ReFree { .. } => {
+ ty::ReLateParam { .. } => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
}
ty::ReStatic => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
}
- ty::ReLateBound(..) => {
- flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
+ ty::ReBound(..) => {
+ flags = flags | TypeFlags::HAS_RE_BOUND;
}
ty::ReErased => {
flags = flags | TypeFlags::HAS_RE_ERASED;
@@ -1851,22 +1851,28 @@ impl<'tcx> Region<'tcx> {
/// function might return the `DefId` of a closure.
pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
match *self {
- ty::ReEarlyBound(br) => tcx.parent(br.def_id),
- ty::ReFree(fr) => fr.scope,
+ ty::ReEarlyParam(br) => tcx.parent(br.def_id),
+ ty::ReLateParam(fr) => fr.scope,
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
}
}
/// True for free regions other than `'static`.
- pub fn is_free(self) -> bool {
- matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_))
+ pub fn is_param(self) -> bool {
+ matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
}
- /// True if `self` is a free region or static.
- pub fn is_free_or_static(self) -> bool {
+ /// True for free region in the current context.
+ ///
+ /// This is the case for `'static` and param regions.
+ pub fn is_free(self) -> bool {
match *self {
- ty::ReStatic => true,
- _ => self.is_free(),
+ ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
+ ty::ReVar(..)
+ | ty::RePlaceholder(..)
+ | ty::ReBound(..)
+ | ty::ReErased
+ | ty::ReError(..) => false,
}
}
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index e9240d1b268e6..914ff1fabd1bd 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -126,7 +126,7 @@ pub struct TypeckResults<'tcx> {
/// fn(&'a u32) -> u32
/// ```
///
- /// Note that `'a` is not bound (it would be an `ReFree`) and
+ /// Note that `'a` is not bound (it would be an `ReLateParam`) and
/// that the `Foo` opaque type is replaced by its hidden type.
liberated_fn_sigs: ItemLocalMap>,
@@ -638,7 +638,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
},
GenericArgKind::Lifetime(r) => match *r {
- ty::ReLateBound(debruijn, br) => {
+ ty::ReBound(debruijn, br) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(debruijn, ty::INNERMOST);
cvar == br.var
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index a251518d14575..e9f65d99a2ef1 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -35,12 +35,14 @@ pub struct Discr<'tcx> {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum CheckRegions {
No,
- /// Only permit early bound regions. This is useful for Adts which
- /// can never have late bound regions.
- OnlyEarlyBound,
- /// Permit both late bound and early bound regions. Use this for functions,
- /// which frequently have late bound regions.
- Bound,
+ /// Only permit parameter regions. This should be used
+ /// for everything apart from functions, which may use
+ /// `ReBound` to represent late-bound regions.
+ OnlyParam,
+ /// Check region parameters from a function definition.
+ /// Allows `ReEarlyParam` and `ReBound` to handle early
+ /// and late-bound region parameters.
+ FromFunction,
}
#[derive(Copy, Clone, Debug)]
@@ -431,7 +433,7 @@ impl<'tcx> TyCtxt<'tcx> {
.filter(|&(_, k)| {
match k.unpack() {
GenericArgKind::Lifetime(region) => match region.kind() {
- ty::ReEarlyBound(ref ebr) => {
+ ty::ReEarlyParam(ref ebr) => {
!impl_generics.region_param(ebr, self).pure_wrt_drop
}
// Error: not a region param
@@ -468,17 +470,17 @@ impl<'tcx> TyCtxt<'tcx> {
for arg in args {
match arg.unpack() {
GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) {
- (CheckRegions::Bound, ty::ReLateBound(di, reg)) => {
+ (CheckRegions::FromFunction, ty::ReBound(di, reg)) => {
if !seen_late.insert((di, reg)) {
return Err(NotUniqueParam::DuplicateParam(lt.into()));
}
}
- (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => {
+ (CheckRegions::OnlyParam | CheckRegions::FromFunction, ty::ReEarlyParam(p)) => {
if !seen.insert(p.index) {
return Err(NotUniqueParam::DuplicateParam(lt.into()));
}
}
- (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => {
+ (CheckRegions::OnlyParam | CheckRegions::FromFunction, _) => {
return Err(NotUniqueParam::NotParam(lt.into()));
}
(CheckRegions::No, _) => {}
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 8fc5c03027784..f14232d34352b 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -111,16 +111,16 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable> {
}
/// True if there are any late-bound regions
- fn has_late_bound_regions(&self) -> bool {
- self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
+ fn has_bound_regions(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_RE_BOUND)
}
/// True if there are any late-bound non-region variables
- fn has_non_region_late_bound(&self) -> bool {
- self.has_type_flags(TypeFlags::HAS_LATE_BOUND - TypeFlags::HAS_RE_LATE_BOUND)
+ fn has_non_region_bound_vars(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
}
- /// True if there are any late-bound variables
- fn has_late_bound_vars(&self) -> bool {
- self.has_type_flags(TypeFlags::HAS_LATE_BOUND)
+ /// True if there are any bound variables
+ fn has_bound_vars(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
}
/// Indicates whether this value still has parameters/placeholders/inference variables
@@ -204,7 +204,7 @@ impl<'tcx> TyCtxt<'tcx> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
match *r {
- ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
+ ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
ControlFlow::Continue(())
}
_ => {
@@ -337,7 +337,7 @@ impl<'tcx> TypeVisitor> for ValidateBoundVars<'tcx> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
match *r {
- ty::ReLateBound(index, br) if index == self.binder_index => {
+ ty::ReBound(index, br) if index == self.binder_index => {
if self.bound_vars.len() <= br.var.as_usize() {
bug!("Not enough bound vars: {:?} not found in {:?}", br, self.bound_vars);
}
@@ -613,7 +613,7 @@ impl<'tcx> TypeVisitor> for LateBoundRegionsCollector {
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow {
- if let ty::ReLateBound(debruijn, br) = *r {
+ if let ty::ReBound(debruijn, br) = *r {
if debruijn == self.current_index {
self.regions.insert(br.kind);
}
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index f30993c9a694d..2b4ae37362699 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -114,12 +114,11 @@ impl<'tcx> Value> for ty::EarlyBinder>
}
impl<'tcx, T> Value> for Result> {
- fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo], _guar: ErrorGuaranteed) -> Self {
+ fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo], guar: ErrorGuaranteed) -> Self {
// tcx.arena.alloc cannot be used because we are not allowed to use &'tcx LayoutError under
// min_specialization. Since this is an error path anyways, leaking doesn't matter (and really,
// tcx.arena.alloc is pretty much equal to leaking).
- // FIXME: `Cycle` should carry the ErrorGuaranteed
- Err(Box::leak(Box::new(ty::layout::LayoutError::Cycle)))
+ Err(Box::leak(Box::new(ty::layout::LayoutError::Cycle(guar))))
}
}
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index 3de2f45ad9a83..d302d538ad416 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -162,6 +162,19 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
expected: expected.to_string(),
}
}
+
+ fn stmt_error(&self, stmt: StmtId, expected: &'static str) -> ParseError {
+ let stmt = &self.thir[stmt];
+ let span = match stmt.kind {
+ StmtKind::Expr { expr, .. } => self.thir[expr].span,
+ StmtKind::Let { span, .. } => span,
+ };
+ ParseError {
+ span,
+ item_description: format!("{:?}", stmt.kind),
+ expected: expected.to_string(),
+ }
+ }
}
type PResult = Result;
diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs
index e2ab2cb90c72f..a6f9caada2d19 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse.rs
@@ -27,10 +27,13 @@ macro_rules! parse_by_kind {
$expr_name:pat,
$expected:literal,
$(
- @call($name:literal, $args:ident) => $call_expr:expr,
+ @call($name:ident, $args:ident) => $call_expr:expr,
)*
$(
- $pat:pat => $expr:expr,
+ @variant($adt:ident, $variant:ident) => $variant_expr:expr,
+ )*
+ $(
+ $pat:pat $(if $guard:expr)? => $expr:expr,
)*
) => {{
let expr_id = $self.preparse($expr_id);
@@ -42,14 +45,20 @@ macro_rules! parse_by_kind {
ExprKind::Call { ty, fun: _, args: $args, .. } if {
match ty.kind() {
ty::FnDef(did, _) => {
- $self.tcx.is_diagnostic_item(rustc_span::Symbol::intern($name), *did)
+ $self.tcx.is_diagnostic_item(rustc_span::sym::$name, *did)
}
_ => false,
}
} => $call_expr,
)*
$(
- $pat => $expr,
+ ExprKind::Adt(box AdtExpr { adt_def, variant_index, .. }) if {
+ $self.tcx.is_diagnostic_item(rustc_span::sym::$adt, adt_def.did()) &&
+ adt_def.variants()[*variant_index].name == rustc_span::sym::$variant
+ } => $variant_expr,
+ )*
+ $(
+ $pat $(if $guard)? => $expr,
)*
#[allow(unreachable_patterns)]
_ => return Err($self.expr_error(expr_id, $expected))
@@ -172,7 +181,8 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
ExprKind::Block { block } => &self.thir[*block].stmts,
);
for (i, block_def) in block_defs.iter().enumerate() {
- let block = self.parse_block_def(self.statement_as_expr(*block_def)?)?;
+ let is_cleanup = self.body.basic_blocks_mut()[BasicBlock::from_usize(i)].is_cleanup;
+ let block = self.parse_block_def(self.statement_as_expr(*block_def)?, is_cleanup)?;
self.body.basic_blocks_mut()[BasicBlock::from_usize(i)] = block;
}
@@ -181,15 +191,28 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
fn parse_block_decls(&mut self, stmts: impl Iterator
- ) -> PResult<()> {
for stmt in stmts {
- let (var, _, _) = self.parse_let_statement(stmt)?;
- let data = BasicBlockData::new(None);
- let block = self.body.basic_blocks_mut().push(data);
- self.block_map.insert(var, block);
+ self.parse_basic_block_decl(stmt)?;
}
-
Ok(())
}
+ fn parse_basic_block_decl(&mut self, stmt: StmtId) -> PResult<()> {
+ match &self.thir[stmt].kind {
+ StmtKind::Let { pattern, initializer: Some(initializer), .. } => {
+ let (var, ..) = self.parse_var(pattern)?;
+ let mut data = BasicBlockData::new(None);
+ data.is_cleanup = parse_by_kind!(self, *initializer, _, "basic block declaration",
+ @variant(mir_basic_block, Normal) => false,
+ @variant(mir_basic_block, Cleanup) => true,
+ );
+ let block = self.body.basic_blocks_mut().push(data);
+ self.block_map.insert(var, block);
+ Ok(())
+ }
+ _ => Err(self.stmt_error(stmt, "let statement with an initializer")),
+ }
+ }
+
fn parse_local_decls(&mut self, mut stmts: impl Iterator
- ) -> PResult<()> {
let (ret_var, ..) = self.parse_let_statement(stmts.next().unwrap())?;
self.local_map.insert(ret_var, Local::from_u32(0));
@@ -219,7 +242,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
};
let span = self.thir[expr].span;
let (name, operand) = parse_by_kind!(self, expr, _, "debuginfo",
- @call("mir_debuginfo", args) => {
+ @call(mir_debuginfo, args) => {
(args[0], args[1])
},
);
@@ -281,12 +304,13 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
}
}
- fn parse_block_def(&self, expr_id: ExprId) -> PResult> {
+ fn parse_block_def(&self, expr_id: ExprId, is_cleanup: bool) -> PResult> {
let block = parse_by_kind!(self, expr_id, _, "basic block",
ExprKind::Block { block } => &self.thir[*block],
);
let mut data = BasicBlockData::new(None);
+ data.is_cleanup = is_cleanup;
for stmt_id in &*block.stmts {
let stmt = self.statement_as_expr(*stmt_id)?;
let span = self.thir[stmt].span;
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index fd2c57a0a6f12..4ce7f831c8711 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -13,19 +13,19 @@ use super::{parse_by_kind, PResult, ParseCtxt};
impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
pub fn parse_statement(&self, expr_id: ExprId) -> PResult> {
parse_by_kind!(self, expr_id, _, "statement",
- @call("mir_storage_live", args) => {
+ @call(mir_storage_live, args) => {
Ok(StatementKind::StorageLive(self.parse_local(args[0])?))
},
- @call("mir_storage_dead", args) => {
+ @call(mir_storage_dead, args) => {
Ok(StatementKind::StorageDead(self.parse_local(args[0])?))
},
- @call("mir_deinit", args) => {
+ @call(mir_deinit, args) => {
Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
},
- @call("mir_retag", args) => {
+ @call(mir_retag, args) => {
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
},
- @call("mir_set_discriminant", args) => {
+ @call(mir_set_discriminant, args) => {
let place = self.parse_place(args[0])?;
let var = self.parse_integer_literal(args[1])? as u32;
Ok(StatementKind::SetDiscriminant {
@@ -43,24 +43,30 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
pub fn parse_terminator(&self, expr_id: ExprId) -> PResult> {
parse_by_kind!(self, expr_id, expr, "terminator",
- @call("mir_return", _args) => {
+ @call(mir_return, _args) => {
Ok(TerminatorKind::Return)
},
- @call("mir_goto", args) => {
+ @call(mir_goto, args) => {
Ok(TerminatorKind::Goto { target: self.parse_block(args[0])? } )
},
- @call("mir_unreachable", _args) => {
+ @call(mir_unreachable, _args) => {
Ok(TerminatorKind::Unreachable)
},
- @call("mir_drop", args) => {
+ @call(mir_unwind_resume, _args) => {
+ Ok(TerminatorKind::UnwindResume)
+ },
+ @call(mir_unwind_terminate, args) => {
+ Ok(TerminatorKind::UnwindTerminate(self.parse_unwind_terminate_reason(args[0])?))
+ },
+ @call(mir_drop, args) => {
Ok(TerminatorKind::Drop {
place: self.parse_place(args[0])?,
target: self.parse_block(args[1])?,
- unwind: UnwindAction::Continue,
+ unwind: self.parse_unwind_action(args[2])?,
replace: false,
})
},
- @call("mir_call", args) => {
+ @call(mir_call, args) => {
self.parse_call(args)
},
ExprKind::Match { scrutinee, arms, .. } => {
@@ -70,6 +76,34 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
)
}
+ fn parse_unwind_terminate_reason(&self, expr_id: ExprId) -> PResult {
+ parse_by_kind!(self, expr_id, _, "unwind terminate reason",
+ @variant(mir_unwind_terminate_reason, Abi) => {
+ Ok(UnwindTerminateReason::Abi)
+ },
+ @variant(mir_unwind_terminate_reason, InCleanup) => {
+ Ok(UnwindTerminateReason::InCleanup)
+ },
+ )
+ }
+
+ fn parse_unwind_action(&self, expr_id: ExprId) -> PResult {
+ parse_by_kind!(self, expr_id, _, "unwind action",
+ @call(mir_unwind_continue, _args) => {
+ Ok(UnwindAction::Continue)
+ },
+ @call(mir_unwind_unreachable, _args) => {
+ Ok(UnwindAction::Unreachable)
+ },
+ @call(mir_unwind_terminate, args) => {
+ Ok(UnwindAction::Terminate(self.parse_unwind_terminate_reason(args[0])?))
+ },
+ @call(mir_unwind_cleanup, args) => {
+ Ok(UnwindAction::Cleanup(self.parse_block(args[0])?))
+ },
+ )
+ }
+
fn parse_match(&self, arms: &[ArmId], span: Span) -> PResult {
let Some((otherwise, rest)) = arms.split_last() else {
return Err(ParseError {
@@ -113,6 +147,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
);
let destination = self.parse_place(destination)?;
let target = self.parse_block(args[1])?;
+ let unwind = self.parse_unwind_action(args[2])?;
parse_by_kind!(self, call, _, "function call",
ExprKind::Call { fun, args, from_hir_call, fn_span, .. } => {
@@ -126,7 +161,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
args,
destination,
target: Some(target),
- unwind: UnwindAction::Continue,
+ unwind,
call_source: if *from_hir_call { CallSource::Normal } else {
CallSource::OverloadedOperator
},
@@ -138,25 +173,25 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
fn parse_rvalue(&self, expr_id: ExprId) -> PResult> {
parse_by_kind!(self, expr_id, expr, "rvalue",
- @call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
- @call("mir_cast_transmute", args) => {
+ @call(mir_discriminant, args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
+ @call(mir_cast_transmute, args) => {
let source = self.parse_operand(args[0])?;
Ok(Rvalue::Cast(CastKind::Transmute, source, expr.ty))
},
- @call("mir_checked", args) => {
+ @call(mir_checked, args) => {
parse_by_kind!(self, args[0], _, "binary op",
ExprKind::Binary { op, lhs, rhs } => Ok(Rvalue::CheckedBinaryOp(
*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
)),
)
},
- @call("mir_offset", args) => {
+ @call(mir_offset, args) => {
let ptr = self.parse_operand(args[0])?;
let offset = self.parse_operand(args[1])?;
Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
},
- @call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
- @call("mir_copy_for_deref", args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
+ @call(mir_len, args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
+ @call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
ExprKind::Borrow { borrow_kind, arg } => Ok(
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
),
@@ -206,9 +241,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
pub fn parse_operand(&self, expr_id: ExprId) -> PResult> {
parse_by_kind!(self, expr_id, expr, "operand",
- @call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move),
- @call("mir_static", args) => self.parse_static(args[0]),
- @call("mir_static_mut", args) => self.parse_static(args[0]),
+ @call(mir_move, args) => self.parse_place(args[0]).map(Operand::Move),
+ @call(mir_static, args) => self.parse_static(args[0]),
+ @call(mir_static_mut, args) => self.parse_static(args[0]),
ExprKind::Literal { .. }
| ExprKind::NamedConst { .. }
| ExprKind::NonHirLiteral { .. }
@@ -229,7 +264,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
fn parse_place_inner(&self, expr_id: ExprId) -> PResult<(Place<'tcx>, PlaceTy<'tcx>)> {
let (parent, proj) = parse_by_kind!(self, expr_id, expr, "place",
- @call("mir_field", args) => {
+ @call(mir_field, args) => {
let (parent, ty) = self.parse_place_inner(args[0])?;
let field = FieldIdx::from_u32(self.parse_integer_literal(args[1])? as u32);
let field_ty = ty.field_ty(self.tcx, field);
@@ -237,7 +272,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
let place = parent.project_deeper(&[proj], self.tcx);
return Ok((place, PlaceTy::from_ty(field_ty)));
},
- @call("mir_variant", args) => {
+ @call(mir_variant, args) => {
(args[0], PlaceElem::Downcast(
None,
VariantIdx::from_u32(self.parse_integer_literal(args[1])? as u32)
@@ -245,7 +280,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
},
ExprKind::Deref { arg } => {
parse_by_kind!(self, *arg, _, "does not matter",
- @call("mir_make_place", args) => return self.parse_place_inner(args[0]),
+ @call(mir_make_place, args) => return self.parse_place_inner(args[0]),
_ => (*arg, PlaceElem::Deref),
)
},
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 7c729016521b0..886d805454db4 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -656,17 +656,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
let args = args.as_coroutine();
let yield_ty = args.yield_ty();
let return_ty = args.return_ty();
- let self_ty = Ty::new_adt(
- tcx,
- tcx.adt_def(tcx.lang_items().pin_type().unwrap()),
- tcx.mk_args(&[Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty).into()]),
- );
- let coroutine_state = Ty::new_adt(
- tcx,
- tcx.adt_def(tcx.lang_items().coroutine_state().unwrap()),
- tcx.mk_args(&[yield_ty.into(), return_ty.into()]),
- );
- (vec![self_ty, args.resume_ty()], coroutine_state, Some(yield_ty))
+ (vec![coroutine_ty, args.resume_ty()], return_ty, Some(yield_ty))
}
dk => bug!("{:?} is not a body: {:?}", def_id, dk),
};
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index dfd39b512e241..50f57b28a983a 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -192,10 +192,10 @@ impl<'tcx> Cx<'tcx> {
cast: PointerCoercion::ArrayToPointer,
}
} else if let hir::ExprKind::Path(ref qpath) = source.kind
- && let res = self.typeck_results().qpath_res(qpath, source.hir_id)
- && let ty = self.typeck_results().node_type(source.hir_id)
- && let ty::Adt(adt_def, args) = ty.kind()
- && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
+ && let res = self.typeck_results().qpath_res(qpath, source.hir_id)
+ && let ty = self.typeck_results().node_type(source.hir_id)
+ && let ty::Adt(adt_def, args) = ty.kind()
+ && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
{
// Check whether this is casting an enum variant discriminant.
// To prevent cycles, we refer to the discriminant initializer,
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index b6adb383fa6b2..bcd9140f0e181 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -132,7 +132,7 @@ impl<'tcx> Cx<'tcx> {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind: ty::BrEnv,
};
- let env_region = ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br);
+ let env_region = ty::Region::new_bound(self.tcx, ty::INNERMOST, br);
let closure_env_ty =
self.tcx.closure_env_ty(closure_def_id, closure_args, env_region).unwrap();
let liberated_closure_env_ty = self.tcx.erase_late_bound_regions(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 48a590f5d37f8..440767927d70c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -200,7 +200,9 @@ impl<'tcx> ConstToPat<'tcx> {
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
let kind = PatKind::Error(e);
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
- } else if let ty::Adt(..) = cv.ty().kind() && matches!(cv, mir::Const::Val(..)) {
+ } else if let ty::Adt(..) = cv.ty().kind()
+ && matches!(cv, mir::Const::Val(..))
+ {
// This branch is only entered when the current `cv` is `mir::Const::Val`.
// This is because `mir::Const::ty` has already been handled by `Self::recur`
// and the invalid types may be ignored.
diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs
index 9bb26693cb244..79bed960b950f 100644
--- a/compiler/rustc_mir_transform/src/cost_checker.rs
+++ b/compiler/rustc_mir_transform/src/cost_checker.rs
@@ -69,7 +69,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
}
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
let fn_ty = self.instantiate_ty(f.const_.ty());
- self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
+ self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind()
+ && tcx.is_intrinsic(def_id)
+ {
// Don't give intrinsics the extra penalty for calls
INSTR_COST
} else {
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index b34ec95b4e8d3..1bc3c25c653bf 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -138,7 +138,9 @@ impl CoverageCounters {
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
// have an expression (to be injected into an existing `BasicBlock` represented by this
// `BasicCoverageBlock`).
- if let Some(node_counter) = self.bcb_counter(to_bcb) && !node_counter.is_expression() {
+ if let Some(node_counter) = self.bcb_counter(to_bcb)
+ && !node_counter.is_expression()
+ {
bug!(
"attempt to add an incoming edge counter from {from_bcb:?} \
when the target BCB already has {node_counter:?}"
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 704eea413e118..e0abb5da0479a 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -381,6 +381,12 @@ impl<'a> CoverageSpansGenerator<'a> {
let merged_prefix_len = self.curr_original_span.lo() - curr.span.lo();
let after_macro_bang = merged_prefix_len + BytePos(visible_macro.as_str().len() as u32 + 1);
+ if self.curr().span.lo() + after_macro_bang > self.curr().span.hi() {
+ // Something is wrong with the macro name span;
+ // return now to avoid emitting malformed mappings.
+ // FIXME(#117788): Track down why this happens.
+ return;
+ }
let mut macro_name_cov = curr.clone();
self.curr_mut().span = curr.span.with_lo(curr.span.lo() + after_macro_bang);
macro_name_cov.span =
@@ -469,7 +475,9 @@ impl<'a> CoverageSpansGenerator<'a> {
}
while let Some(curr) = self.sorted_spans_iter.next() {
debug!("FOR curr={:?}", curr);
- if let Some(prev) = &self.some_prev && prev.span.lo() > curr.span.lo() {
+ if let Some(prev) = &self.some_prev
+ && prev.span.lo() > curr.span.lo()
+ {
// Skip curr because prev has already advanced beyond the end of curr.
// This can only happen if a prior iteration updated `prev` to skip past
// a region of code, such as skipping past a closure.
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 81d2bba989a7f..bb2a90a06da96 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -597,7 +597,9 @@ fn propagatable_scalar(
state: &State>,
map: &Map,
) -> Option {
- if let FlatSet::Elem(value) = state.get_idx(place, map) && value.try_to_int().is_ok() {
+ if let FlatSet::Elem(value) = state.get_idx(place, map)
+ && value.try_to_int().is_ok()
+ {
// Do not attempt to propagate pointers, as we may fail to preserve their identity.
Some(value)
} else {
@@ -836,7 +838,8 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
location: Location,
) {
if let PlaceElem::Index(local) = elem
- && let Some(value) = self.visitor.try_make_constant(self.ecx, local.into(), self.state, self.map)
+ && let Some(value) =
+ self.visitor.try_make_constant(self.ecx, local.into(), self.state, self.map)
{
self.visitor.patch.before_effect.insert((location, local.into()), value);
}
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index dce298e92e166..98a036182861e 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -461,7 +461,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
}
NullaryOp(null_op, ty) => {
let layout = self.ecx.layout_of(ty).ok()?;
- if let NullOp::SizeOf | NullOp::AlignOf = null_op && layout.is_unsized() {
+ if let NullOp::SizeOf | NullOp::AlignOf = null_op
+ && layout.is_unsized()
+ {
return None;
}
let val = match null_op {
@@ -865,7 +867,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
.collect();
let fields = fields?;
- if let AggregateTy::Array = ty && fields.len() > 4 {
+ if let AggregateTy::Array = ty
+ && fields.len() > 4
+ {
let first = fields[0];
if fields.iter().all(|&v| v == first) {
let len = ty::Const::from_target_usize(self.tcx, fields.len().try_into().unwrap());
@@ -1008,8 +1012,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
// Do not try to simplify a constant, it's already in canonical shape.
&& !matches!(rvalue, Rvalue::Use(Operand::Constant(_)))
{
- if let Some(value) = self.simplify_rvalue(rvalue, location)
- {
+ if let Some(value) = self.simplify_rvalue(rvalue, location) {
if let Some(const_) = self.try_as_constant(value) {
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
} else if let Some(local) = self.try_as_local(value, location)
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 7b918be447413..22300ad24be7f 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -247,7 +247,9 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
let last_non_rec = self.opportunities.len();
let predecessors = &self.body.basic_blocks.predecessors()[bb];
- if let &[pred] = &predecessors[..] && bb != START_BLOCK {
+ if let &[pred] = &predecessors[..]
+ && bb != START_BLOCK
+ {
let term = self.body.basic_blocks[pred].terminator();
match term.kind {
TerminatorKind::SwitchInt { ref discr, ref targets } => {
@@ -419,8 +421,10 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
// Do not support unions.
AggregateKind::Adt(.., Some(_)) => return None,
AggregateKind::Adt(_, variant_index, ..) if agg_ty.is_enum() => {
- if let Some(discr_target) = self.map.apply(lhs, TrackElem::Discriminant)
- && let Some(discr_value) = discriminant_for_variant(agg_ty, *variant_index)
+ if let Some(discr_target) =
+ self.map.apply(lhs, TrackElem::Discriminant)
+ && let Some(discr_value) =
+ discriminant_for_variant(agg_ty, *variant_index)
{
self.process_operand(bb, discr_target, &discr_value, state);
}
diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs
index 5aa3c3cfe4dde..9f59f9d124520 100644
--- a/compiler/rustc_mir_transform/src/remove_zsts.rs
+++ b/compiler/rustc_mir_transform/src/remove_zsts.rs
@@ -17,6 +17,11 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
if tcx.type_of(body.source.def_id()).instantiate_identity().is_coroutine() {
return;
}
+
+ if !tcx.consider_optimizing(|| format!("RemoveZsts - {:?}", body.source.def_id())) {
+ return;
+ }
+
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
let local_decls = &body.local_decls;
let mut replacer = Replacer { tcx, param_env, local_decls };
@@ -125,12 +130,6 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
if let Some(place_for_ty) = place_for_ty
&& let ty = place_for_ty.ty(self.local_decls, self.tcx).ty
&& self.known_to_be_zst(ty)
- && self.tcx.consider_optimizing(|| {
- format!(
- "RemoveZsts - Place: {:?} SourceInfo: {:?}",
- place_for_ty, statement.source_info
- )
- })
{
statement.make_nop();
} else {
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index 1f59c790b4ebe..3a6e1ef348831 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -40,7 +40,8 @@ impl SsaLocals {
let dominators = body.basic_blocks.dominators();
let direct_uses = IndexVec::from_elem(0, &body.local_decls);
- let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses };
+ let mut visitor =
+ SsaVisitor { body, assignments, assignment_order, dominators, direct_uses };
for local in body.args_iter() {
visitor.assignments[local] = Set1::One(DefLocation::Argument);
@@ -110,7 +111,7 @@ impl SsaLocals {
body: &'a Body<'tcx>,
) -> impl Iterator
- , Location)> + 'a {
self.assignment_order.iter().filter_map(|&local| {
- if let Set1::One(DefLocation::Body(loc)) = self.assignments[local] {
+ if let Set1::One(DefLocation::Assignment(loc)) = self.assignments[local] {
let stmt = body.stmt_at(loc).left()?;
// `loc` must point to a direct assignment to `local`.
let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() };
@@ -134,21 +135,21 @@ impl SsaLocals {
AssignedValue::Arg,
Location { block: START_BLOCK, statement_index: 0 },
),
- Set1::One(DefLocation::Body(loc)) => {
+ Set1::One(DefLocation::Assignment(loc)) => {
let bb = &mut basic_blocks[loc.block];
- let value = if loc.statement_index < bb.statements.len() {
- // `loc` must point to a direct assignment to `local`.
- let stmt = &mut bb.statements[loc.statement_index];
- let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else {
- bug!()
- };
- assert_eq!(target.as_local(), Some(local));
- AssignedValue::Rvalue(rvalue)
- } else {
- let term = bb.terminator_mut();
- AssignedValue::Terminator(&mut term.kind)
+ // `loc` must point to a direct assignment to `local`.
+ let stmt = &mut bb.statements[loc.statement_index];
+ let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else {
+ bug!()
};
- f(local, value, loc)
+ assert_eq!(target.as_local(), Some(local));
+ f(local, AssignedValue::Rvalue(rvalue), loc)
+ }
+ Set1::One(DefLocation::CallReturn { call, .. }) => {
+ let bb = &mut basic_blocks[call];
+ let loc = Location { block: call, statement_index: bb.statements.len() };
+ let term = bb.terminator_mut();
+ f(local, AssignedValue::Terminator(&mut term.kind), loc)
}
_ => {}
}
@@ -201,14 +202,15 @@ impl SsaLocals {
}
}
-struct SsaVisitor<'a> {
+struct SsaVisitor<'tcx, 'a> {
+ body: &'a Body<'tcx>,
dominators: &'a Dominators,
assignments: IndexVec>,
assignment_order: Vec,
direct_uses: IndexVec,
}
-impl SsaVisitor<'_> {
+impl SsaVisitor<'_, '_> {
fn check_dominates(&mut self, local: Local, loc: Location) {
let set = &mut self.assignments[local];
let assign_dominates = match *set {
@@ -224,7 +226,7 @@ impl SsaVisitor<'_> {
}
}
-impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
+impl<'tcx> Visitor<'tcx> for SsaVisitor<'tcx, '_> {
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
match ctxt {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
@@ -250,9 +252,18 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) {
let location = match ctxt {
- PlaceContext::MutatingUse(
- MutatingUseContext::Store | MutatingUseContext::Call | MutatingUseContext::Yield,
- ) => Some(DefLocation::Body(loc)),
+ PlaceContext::MutatingUse(MutatingUseContext::Store) => {
+ Some(DefLocation::Assignment(loc))
+ }
+ PlaceContext::MutatingUse(MutatingUseContext::Call) => {
+ let call = loc.block;
+ let TerminatorKind::Call { target, .. } =
+ self.body.basic_blocks[call].terminator().kind
+ else {
+ bug!()
+ };
+ Some(DefLocation::CallReturn { call, target })
+ }
_ => None,
};
if let Some(location) = location
@@ -359,7 +370,7 @@ impl StorageLiveLocals {
for (statement_index, statement) in bbdata.statements.iter().enumerate() {
if let StatementKind::StorageLive(local) = statement.kind {
storage_live[local]
- .insert(DefLocation::Body(Location { block, statement_index }));
+ .insert(DefLocation::Assignment(Location { block, statement_index }));
}
}
}
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 8ab1ec298a1c7..99e66fddc705b 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2278,9 +2278,8 @@ pub(crate) enum InvalidMutInPattern {
#[note(parse_note_mut_pattern_usage)]
NonIdent {
#[primary_span]
- #[suggestion(code = "{pat}", applicability = "machine-applicable")]
+ #[suggestion(code = "", applicability = "machine-applicable")]
span: Span,
- pat: String,
},
}
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index 31d91fe80bd61..db795ce9f7236 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -5,7 +5,8 @@ use super::{StringReader, UnmatchedDelim};
use rustc_ast::token::{self, Delimiter, Token};
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast_pretty::pprust::token_to_string;
-use rustc_errors::PErr;
+use rustc_errors::{Applicability, PErr};
+use rustc_span::symbol::kw;
pub(super) struct TokenTreesReader<'a> {
string_reader: StringReader<'a>,
@@ -116,24 +117,8 @@ impl<'a> TokenTreesReader<'a> {
// We stop at any delimiter so we can try to recover if the user
// uses an incorrect delimiter.
let (tts, res) = self.parse_token_trees(/* is_delimited */ true);
- if let Err(mut errs) = res {
- // If there are unclosed delims, see if there are diff markers and if so, point them
- // out instead of complaining about the unclosed delims.
- let mut parser = crate::stream_to_parser(self.string_reader.sess, tts, None);
- let mut diff_errs = vec![];
- while parser.token != token::Eof {
- if let Err(diff_err) = parser.err_diff_marker() {
- diff_errs.push(diff_err);
- }
- parser.bump();
- }
- if !diff_errs.is_empty() {
- errs.iter_mut().for_each(|err| {
- err.delay_as_bug();
- });
- return Err(diff_errs);
- }
- return Err(errs);
+ if let Err(errs) = res {
+ return Err(self.unclosed_delim_err(tts, errs));
}
// Expand to cover the entire delimited token tree
@@ -220,6 +205,62 @@ impl<'a> TokenTreesReader<'a> {
Ok(TokenTree::Delimited(delim_span, open_delim, tts))
}
+ fn unclosed_delim_err(&mut self, tts: TokenStream, mut errs: Vec>) -> Vec> {
+ // If there are unclosed delims, see if there are diff markers and if so, point them
+ // out instead of complaining about the unclosed delims.
+ let mut parser = crate::stream_to_parser(self.string_reader.sess, tts, None);
+ let mut diff_errs = vec![];
+ // Suggest removing a `{` we think appears in an `if`/`while` condition
+ // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition, but
+ // we have no way of tracking this in the lexer itself, so we piggyback on the parser
+ let mut in_cond = false;
+ while parser.token != token::Eof {
+ if let Err(diff_err) = parser.err_diff_marker() {
+ diff_errs.push(diff_err);
+ } else if parser.is_keyword_ahead(0, &[kw::If, kw::While]) {
+ in_cond = true;
+ } else if matches!(
+ parser.token.kind,
+ token::CloseDelim(Delimiter::Brace) | token::FatArrow
+ ) {
+ // end of the `if`/`while` body, or the end of a `match` guard
+ in_cond = false;
+ } else if in_cond && parser.token == token::OpenDelim(Delimiter::Brace) {
+ // Store the `&&` and `let` to use their spans later when creating the diagnostic
+ let maybe_andand = parser.look_ahead(1, |t| t.clone());
+ let maybe_let = parser.look_ahead(2, |t| t.clone());
+ if maybe_andand == token::OpenDelim(Delimiter::Brace) {
+ // This might be the beginning of the `if`/`while` body (i.e., the end of the condition)
+ in_cond = false;
+ } else if maybe_andand == token::AndAnd && maybe_let.is_keyword(kw::Let) {
+ let mut err = parser.struct_span_err(
+ parser.token.span,
+ "found a `{` in the middle of a let-chain",
+ );
+ err.span_suggestion(
+ parser.token.span,
+ "consider removing this brace to parse the `let` as part of the same chain",
+ "",
+ Applicability::MachineApplicable,
+ );
+ err.span_label(
+ maybe_andand.span.to(maybe_let.span),
+ "you might have meant to continue the let-chain here",
+ );
+ errs.push(err);
+ }
+ }
+ parser.bump();
+ }
+ if !diff_errs.is_empty() {
+ errs.iter_mut().for_each(|err| {
+ err.delay_as_bug();
+ });
+ return diff_errs;
+ }
+ return errs;
+ }
+
fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'a> {
// An unexpected closing delimiter (i.e., there is no
// matching opening delimiter).
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 2a8eb6edd23fd..f2acb70ac45ba 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -506,7 +506,9 @@ impl<'a> Parser<'a> {
if expected.contains(&TokenType::Token(token::Semi)) {
// If the user is trying to write a ternary expression, recover it and
// return an Err to prevent a cascade of irrelevant diagnostics
- if self.prev_token == token::Question && let Err(e) = self.maybe_recover_from_ternary_operator() {
+ if self.prev_token == token::Question
+ && let Err(e) = self.maybe_recover_from_ternary_operator()
+ {
return Err(e);
}
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 235b28b6e26e2..bfd7e8ef4d0ab 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2904,15 +2904,16 @@ impl<'a> Parser<'a> {
"=>",
Applicability::MachineApplicable,
);
- err.emit();
- this.bump();
- } else if matches!(
- (&this.prev_token.kind, &this.token.kind),
- (token::DotDotEq, token::Gt)
- ) {
- // `error_inclusive_range_match_arrow` handles cases like `0..=> {}`,
- // so we suppress the error here
- err.delay_as_bug();
+ if matches!(
+ (&this.prev_token.kind, &this.token.kind),
+ (token::DotDotEq, token::Gt)
+ ) {
+ // `error_inclusive_range_match_arrow` handles cases like `0..=> {}`,
+ // so we suppress the error here
+ err.delay_as_bug();
+ } else {
+ err.emit();
+ }
this.bump();
} else {
return Err(err);
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 1a7ae40691145..833381a650344 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -107,15 +107,15 @@ macro_rules! maybe_whole {
macro_rules! maybe_recover_from_interpolated_ty_qpath {
($self: expr, $allow_qpath_recovery: expr) => {
if $allow_qpath_recovery
- && $self.may_recover()
- && $self.look_ahead(1, |t| t == &token::ModSep)
- && let token::Interpolated(nt) = &$self.token.kind
- && let token::NtTy(ty) = &**nt
- {
- let ty = ty.clone();
- $self.bump();
- return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty);
- }
+ && $self.may_recover()
+ && $self.look_ahead(1, |t| t == &token::ModSep)
+ && let token::Interpolated(nt) = &$self.token.kind
+ && let token::NtTy(ty) = &**nt
+ {
+ let ty = ty.clone();
+ $self.bump();
+ return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty);
+ }
};
}
@@ -830,8 +830,8 @@ impl<'a> Parser<'a> {
// https://github.com/rust-lang/rust/issues/72373
if self.prev_token.is_ident() && self.token.kind == token::DotDot {
let msg = format!(
- "if you meant to bind the contents of \
- the rest of the array pattern into `{}`, use `@`",
+ "if you meant to bind the contents of the rest of the array \
+ pattern into `{}`, use `@`",
pprust::token_to_string(&self.prev_token)
);
expect_err
@@ -1115,7 +1115,7 @@ impl<'a> Parser<'a> {
}
/// Returns whether any of the given keywords are `dist` tokens ahead of the current one.
- fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
+ pub(crate) fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
self.look_ahead(dist, |t| kws.iter().any(|&kw| t.is_keyword(kw)))
}
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 0a4c7c17d06a0..f6e1a21bd2607 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -638,13 +638,13 @@ impl<'a> Parser<'a> {
/// Error on `mut $pat` where `$pat` is not an ident.
fn ban_mut_general_pat(&self, lo: Span, pat: &Pat, changed_any_binding: bool) {
- let span = lo.to(pat.span);
- let pat = pprust::pat_to_string(&pat);
-
self.sess.emit_err(if changed_any_binding {
- InvalidMutInPattern::NestedIdent { span, pat }
+ InvalidMutInPattern::NestedIdent {
+ span: lo.to(pat.span),
+ pat: pprust::pat_to_string(&pat),
+ }
} else {
- InvalidMutInPattern::NonIdent { span, pat }
+ InvalidMutInPattern::NonIdent { span: lo.until(pat.span) }
});
}
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index be2cbaf3020e6..dc0f139652307 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -135,7 +135,7 @@ impl<'a> Parser<'a> {
)
}
- /// Parse a type suitable for a field defintion.
+ /// Parse a type suitable for a field definition.
/// The difference from `parse_ty` is that this version
/// allows anonymous structs and unions.
pub fn parse_ty_for_field_def(&mut self) -> PResult<'a, P> {
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 7b6153eea09b4..e886db3da2965 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -9,13 +9,10 @@
html_playground_url = "https://play.rust-lang.org/",
test(attr(deny(warnings)))
)]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
-// We want to be able to build this crate with a stable compiler, so no
-// `#![feature]` attributes should be added.
+// WARNING: We want to be able to build this crate with a stable compiler,
+// so no `#![feature]` attributes should be added!
use rustc_lexer::unescape;
pub use Alignment::*;
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 2e8c58b0241f9..6b2b842543a8c 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -314,7 +314,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
// for the `#[expect]` case.
//
// Note that an item can and will be duplicated on the worklist with different
- // `ComesFromAllowExpect`, particulary if it was added from the
+ // `ComesFromAllowExpect`, particularly if it was added from the
// `effective_visibilities` query or from the `#[allow]`/`#[expect]` checks,
// this "duplication" is essential as otherwise a function with `#[expect]`
// called from a `pub fn` may be falsely reported as not live, falsely
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 946a9e68da6e0..9eb1df0b2e284 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -6,9 +6,9 @@
#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(map_try_insert)]
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 6a2498f3f99e9..018d42793b2bd 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -196,7 +196,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
}
}
- if let Some((depr, span)) = &depr && depr.is_since_rustc_version() && stab.is_none() {
+ if let Some((depr, span)) = &depr
+ && depr.is_since_rustc_version()
+ && stab.is_none()
+ {
self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
}
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 4bb7e65747f70..a14c2916392de 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1,7 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(associated_type_defaults)]
#![feature(rustc_private)]
#![feature(try_blocks)]
@@ -1756,7 +1756,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
// fn from(_: Priv) -> Pub {...}
// }
//
- // lints shouldn't be emmited even if `from` effective visibility
+ // lints shouldn't be emitted even if `from` effective visibility
// is larger than `Priv` nominal visibility and if `Priv` can leak
// in some scenarios due to type inference.
let impl_ev = EffectiveVisibility::of_impl::(
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index a1465dabed697..59812efc32465 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -1,8 +1,8 @@
//! Support for serializing the dep-graph and reloading it.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
// this shouldn't be necessary, but the check for `&mut _` is too naive and denies returning a function pointer that takes a mut ref
#![feature(const_mut_refs)]
#![feature(const_refs_to_cell)]
diff --git a/compiler/rustc_query_system/src/dep_graph/edges.rs b/compiler/rustc_query_system/src/dep_graph/edges.rs
index 6ba3924f65eb0..400f128d5833b 100644
--- a/compiler/rustc_query_system/src/dep_graph/edges.rs
+++ b/compiler/rustc_query_system/src/dep_graph/edges.rs
@@ -5,7 +5,7 @@ use std::iter::Extend;
use std::ops::Deref;
#[derive(Default, Debug)]
-pub struct EdgesVec {
+pub(crate) struct EdgesVec {
max: u32,
edges: SmallVec<[DepNodeIndex; EdgesVec::INLINE_CAPACITY]>,
}
@@ -18,21 +18,21 @@ impl Hash for EdgesVec {
}
impl EdgesVec {
- pub const INLINE_CAPACITY: usize = 8;
+ pub(crate) const INLINE_CAPACITY: usize = 8;
#[inline]
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self::default()
}
#[inline]
- pub fn push(&mut self, edge: DepNodeIndex) {
+ pub(crate) fn push(&mut self, edge: DepNodeIndex) {
self.max = self.max.max(edge.as_u32());
self.edges.push(edge);
}
#[inline]
- pub fn max_index(&self) -> u32 {
+ pub(crate) fn max_index(&self) -> u32 {
self.max
}
}
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 6cace01955e75..831062b1678f4 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -18,7 +18,7 @@ use std::sync::atomic::Ordering::Relaxed;
use super::query::DepGraphQuery;
use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
use super::{DepContext, DepKind, DepNode, Deps, HasDepContext, WorkProductId};
-use crate::dep_graph::EdgesVec;
+use crate::dep_graph::edges::EdgesVec;
use crate::ich::StableHashingContext;
use crate::query::{QueryContext, QuerySideEffects};
@@ -41,8 +41,7 @@ rustc_index::newtype_index! {
}
impl DepNodeIndex {
- pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
- pub const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::from_u32(0);
+ const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::from_u32(0);
pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1);
}
@@ -53,20 +52,20 @@ impl From for QueryInvocationId {
}
}
-pub struct MarkFrame<'a> {
+pub(crate) struct MarkFrame<'a> {
index: SerializedDepNodeIndex,
parent: Option<&'a MarkFrame<'a>>,
}
#[derive(PartialEq)]
-pub enum DepNodeColor {
+enum DepNodeColor {
Red,
Green(DepNodeIndex),
}
impl DepNodeColor {
#[inline]
- pub fn is_green(self) -> bool {
+ fn is_green(self) -> bool {
match self {
DepNodeColor::Red => false,
DepNodeColor::Green(_) => true,
@@ -74,7 +73,7 @@ impl DepNodeColor {
}
}
-pub struct DepGraphData {
+pub(crate) struct DepGraphData {
/// The new encoding of the dependency graph, optimized for red/green
/// tracking. The `current` field is the dependency graph of only the
/// current compilation session: We don't merge the previous dep-graph into
@@ -185,7 +184,7 @@ impl DepGraph {
}
#[inline]
- pub fn data(&self) -> Option<&DepGraphData> {
+ pub(crate) fn data(&self) -> Option<&DepGraphData> {
self.data.as_deref()
}
@@ -333,7 +332,7 @@ impl DepGraphData {
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation.html
#[inline(always)]
- pub fn with_task, A: Debug, R>(
+ pub(crate) fn with_task, A: Debug, R>(
&self,
key: DepNode,
cx: Ctxt,
@@ -398,7 +397,7 @@ impl DepGraphData {
/// Executes something within an "anonymous" task, that is, a task the
/// `DepNode` of which is determined by the list of inputs it read from.
- pub fn with_anon_task, OP, R>(
+ pub(crate) fn with_anon_task, OP, R>(
&self,
cx: Tcx,
dep_kind: DepKind,
@@ -618,7 +617,7 @@ impl DepGraph {
impl DepGraphData {
#[inline]
- pub fn dep_node_index_of_opt(&self, dep_node: &DepNode) -> Option {
+ fn dep_node_index_of_opt(&self, dep_node: &DepNode) -> Option {
if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) {
self.current.prev_index_to_index.lock()[prev_index]
} else {
@@ -627,7 +626,7 @@ impl DepGraphData {
}
#[inline]
- pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
+ fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
self.dep_node_index_of_opt(dep_node).is_some()
}
@@ -643,21 +642,21 @@ impl