Merge from rustc

This commit is contained in:
Jieyou Xu 2025-04-02 23:26:35 +08:00
commit cae5d8a81c
No known key found for this signature in database
GPG Key ID: 045B995028EA6AFC
1891 changed files with 30456 additions and 19949 deletions

1
.gitattributes vendored
View File

@ -5,6 +5,7 @@
*.h rust
*.rs rust diff=rust
*.fixed linguist-language=Rust
*.pp linguist-language=Rust
*.mir linguist-language=Rust
src/etc/installer/gfx/* binary
src/vendor/** -text

View File

@ -69,6 +69,8 @@ jobs:
env:
CI_JOB_NAME: ${{ matrix.name }}
CI_JOB_DOC_URL: ${{ matrix.doc_url }}
GITHUB_WORKFLOW_RUN_ID: ${{ github.run_id }}
GITHUB_REPOSITORY: ${{ github.repository }}
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
# commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
@ -239,16 +241,31 @@ jobs:
if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1'
- name: postprocess metrics into the summary
# This step is not critical, and if some I/O problem happens, we don't want
# to cancel the build.
continue-on-error: true
run: |
if [ -f build/metrics.json ]; then
./build/citool/debug/citool postprocess-metrics build/metrics.json ${GITHUB_STEP_SUMMARY}
METRICS=build/metrics.json
elif [ -f obj/build/metrics.json ]; then
./build/citool/debug/citool postprocess-metrics obj/build/metrics.json ${GITHUB_STEP_SUMMARY}
METRICS=obj/build/metrics.json
else
echo "No metrics.json found"
exit 0
fi
# Get closest bors merge commit
PARENT_COMMIT=`git rev-list --author='bors <bors@rust-lang.org>' -n1 --first-parent HEAD^1`
./build/citool/debug/citool postprocess-metrics \
--job-name ${CI_JOB_NAME} \
--parent ${PARENT_COMMIT} \
${METRICS} >> ${GITHUB_STEP_SUMMARY}
- name: upload job metrics to DataDog
# This step is not critical, and if some I/O problem happens, we don't want
# to cancel the build.
continue-on-error: true
if: needs.calculate_matrix.outputs.run_type != 'pr'
env:
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}

View File

@ -5,6 +5,9 @@
# Docker Hub has a rate limit, while ghcr.io doesn't.
# Those images are pushed to ghcr.io by this job.
#
# While Docker Hub rate limit *shouldn't* be an issue on GitHub Actions,
# it certainly is for AWS codebuild.
#
# Note that authenticating to DockerHub or other registries isn't possible
# for PR jobs, because forks can't access secrets.
# That's why we use ghcr.io: it has no rate limit and it doesn't require authentication.
@ -54,6 +57,10 @@ jobs:
"ubuntu:22.04"
# Mirrored because used by all linux CI jobs, including mingw-check-tidy
"moby/buildkit:buildx-stable-1"
# Mirrored because used when CI is running inside a Docker container
"alpine:3.4"
# Mirrored because used by dist-x86_64-linux
"centos:7"
)
# Mirror each image from DockerHub to ghcr.io

View File

@ -35,13 +35,12 @@ jobs:
cd src/ci/citool
printf "*This is an experimental post-merge analysis report. You can ignore it.*\n\n" > output.log
printf "<details>\n<summary>Post-merge report</summary>\n\n" >> output.log
printf "<details>\n<summary>What is this?</summary>\n" >> output.log
printf "This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.\n" >> output.log
printf "</details>\n\n" >> output.log
cargo run --release post-merge-report ${PARENT_COMMIT} ${{ github.sha }} >> output.log
printf "</details>\n" >> output.log
cat output.log
gh pr comment ${HEAD_PR} -F output.log

2
.gitmodules vendored
View File

@ -45,7 +45,7 @@
shallow = true
[submodule "src/tools/enzyme"]
path = src/tools/enzyme
url = https://github.com/EnzymeAD/Enzyme.git
url = https://github.com/rust-lang/Enzyme.git
shallow = true
[submodule "src/gcc"]
path = src/gcc

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,137 @@
Version 1.86.0 (2025-04-03)
==========================
<a id="1.86.0-Language"></a>
Language
--------
- [Stabilize upcasting trait objects to supertraits.](https://github.com/rust-lang/rust/pull/134367)
- [Allow safe functions to be marked with the `#[target_feature]` attribute.](https://github.com/rust-lang/rust/pull/134090)
- [The `missing_abi` lint now warns-by-default.](https://github.com/rust-lang/rust/pull/132397)
- Rust now lints about double negations, to catch cases that might have intended to be a prefix decrement operator (`--x`) as written in other languages. This was previously a clippy lint, `clippy::double_neg`, and is [now available directly in Rust as `double_negations`.](https://github.com/rust-lang/rust/pull/126604)
- [More pointers are now detected as definitely not-null based on their alignment in const eval.](https://github.com/rust-lang/rust/pull/133700)
- [Empty `repr()` attribute applied to invalid items are now correctly rejected.](https://github.com/rust-lang/rust/pull/133925)
- [Inner attributes `#![test]` and `#![rustfmt::skip]` are no longer accepted in more places than intended.](https://github.com/rust-lang/rust/pull/134276)
<a id="1.86.0-Compiler"></a>
Compiler
--------
- [Debug-assert that raw pointers are non-null on access.](https://github.com/rust-lang/rust/pull/134424)
- [Change `-O` to mean `-C opt-level=3` instead of `-C opt-level=2` to match Cargo's defaults.](https://github.com/rust-lang/rust/pull/135439)
- [Fix emission of `overflowing_literals` under certain macro environments.](https://github.com/rust-lang/rust/pull/136393)
<a id="1.86.0-Platform-Support"></a>
Platform Support
----------------
- [Replace `i686-unknown-redox` target with `i586-unknown-redox`.](https://github.com/rust-lang/rust/pull/136698)
- [Increase baseline CPU of `i686-unknown-hurd-gnu` to Pentium 4.](https://github.com/rust-lang/rust/pull/136700)
- New tier 3 targets:
- [`{aarch64-unknown,x86_64-pc}-nto-qnx710_iosock`](https://github.com/rust-lang/rust/pull/133631).
For supporting Neutrino QNX 7.1 with `io-socket` network stack.
- [`{aarch64-unknown,x86_64-pc}-nto-qnx800`](https://github.com/rust-lang/rust/pull/133631).
For supporting Neutrino QNX 8.0 (`no_std`-only).
- [`{x86_64,i686}-win7-windows-gnu`](https://github.com/rust-lang/rust/pull/134609).
Intended for backwards compatibility with Windows 7. `{x86_64,i686}-win7-windows-msvc` are the Windows MSVC counterparts that already exist as Tier 3 targets.
- [`amdgcn-amd-amdhsa`](https://github.com/rust-lang/rust/pull/134740).
- [`x86_64-pc-cygwin`](https://github.com/rust-lang/rust/pull/134999).
- [`{mips,mipsel}-mti-none-elf`](https://github.com/rust-lang/rust/pull/135074).
Initial bare-metal support.
- [`m68k-unknown-none-elf`](https://github.com/rust-lang/rust/pull/135085).
- [`armv7a-nuttx-{eabi,eabihf}`, `aarch64-unknown-nuttx`, and `thumbv7a-nuttx-{eabi,eabihf}`](https://github.com/rust-lang/rust/pull/135757).
Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.
<a id="1.86.0-Libraries"></a>
Libraries
---------
- The type of `FromBytesWithNulError` in `CStr::from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError>` was [changed from an opaque struct to an enum](https://github.com/rust-lang/rust/pull/134143), allowing users to examine why the conversion failed.
- [Remove `RustcDecodable` and `RustcEncodable`.](https://github.com/rust-lang/rust/pull/134272)
- [Deprecate libtest's `--logfile` option.](https://github.com/rust-lang/rust/pull/134283)
- [On recent versions of Windows, `std::fs::remove_file` will now remove read-only files.](https://github.com/rust-lang/rust/pull/134679)
<a id="1.86.0-Stabilized-APIs"></a>
Stabilized APIs
---------------
- [`{float}::next_down`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_down)
- [`{float}::next_up`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_up)
- [`<[_]>::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut)
- [`<[_]>::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_unchecked_mut)
- [`slice::GetDisjointMutError`](https://doc.rust-lang.org/stable/std/slice/enum.GetDisjointMutError.html)
- [`HashMap::get_disjoint_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_mut)
- [`HashMap::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_unchecked_mut)
- [`NonZero::count_ones`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.count_ones)
- [`Vec::pop_if`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop_if)
- [`sync::Once::wait`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait)
- [`sync::Once::wait_force`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait_force)
- [`sync::OnceLock::wait`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.wait)
These APIs are now stable in const contexts:
- [`hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
- [`io::Cursor::get_mut`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_mut)
- [`io::Cursor::set_position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.set_position)
- [`str::is_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.is_char_boundary)
- [`str::split_at`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at)
- [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked)
- [`str::split_at_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut)
- [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked)
<a id="1.86.0-Cargo"></a>
Cargo
-----
- [When merging, replace rather than combine configuration keys that refer to a program path and its arguments.](https://github.com/rust-lang/cargo/pull/15066/)
- [Error if both `--package` and `--workspace` are passed but the requested package is missing.](https://github.com/rust-lang/cargo/pull/15071/) This was previously silently ignored, which was considered a bug since missing packages should be reported.
- [Deprecate the token argument in `cargo login` to avoid shell history leaks.](https://github.com/rust-lang/cargo/pull/15057/)
- [Simplify the implementation of `SourceID` comparisons.](https://github.com/rust-lang/cargo/pull/14980/) This may potentially change behavior if the canonicalized URL compares differently in alternative registries.
<a id="1.86.0-Rustdoc"></a>
Rustdoc
-----
- [Add a sans-serif font setting.](https://github.com/rust-lang/rust/pull/133636)
<a id="1.86.0-Compatibility-Notes"></a>
Compatibility Notes
-------------------
- [The `wasm_c_abi` future compatibility warning is now a hard error.](https://github.com/rust-lang/rust/pull/133951)
Users of `wasm-bindgen` should upgrade to at least version 0.2.89, otherwise compilation will fail.
- [Remove long-deprecated no-op attributes `#![no_start]` and `#![crate_id]`.](https://github.com/rust-lang/rust/pull/134300)
- [The future incompatibility lint `cenum_impl_drop_cast` has been made into a hard error.](https://github.com/rust-lang/rust/pull/135964) This means it is now an error to cast a field-less enum to an integer if the enum implements `Drop`.
- [SSE2 is now required for "i686" 32-bit x86 hard-float targets; disabling it causes a warning that will become a hard error eventually.](https://github.com/rust-lang/rust/pull/137037)
To compile for pre-SSE2 32-bit x86, use a "i586" target instead.
<a id="1.86.0-Internal-Changes"></a>
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.
- [Build the rustc on AArch64 Linux with ThinLTO + PGO.](https://github.com/rust-lang/rust/pull/133807)
The ARM 64-bit compiler (AArch64) on Linux is now optimized with ThinLTO and PGO, similar to the optimizations we have already performed for the x86-64 compiler on Linux. This should make it up to 30% faster.
Version 1.85.1 (2025-03-18)
==========================
<a id="1.85.1"></a>
- [Fix the doctest-merging feature of the 2024 Edition.](https://github.com/rust-lang/rust/pull/137899/)
- [Relax some `target_feature` checks when generating docs.](https://github.com/rust-lang/rust/pull/137632/)
- [Fix errors in `std::fs::rename` on Windows 10, version 1607.](https://github.com/rust-lang/rust/pull/137528/)
- [Downgrade bootstrap `cc` to fix custom targets.](https://github.com/rust-lang/rust/pull/137460/)
- [Skip submodule updates when building Rust from a source tarball.](https://github.com/rust-lang/rust/pull/137338/)
Version 1.85.0 (2025-02-20)
==========================

View File

@ -1,7 +1,7 @@
# Sample TOML configuration file for building Rust.
#
# To configure bootstrap, run `./configure` or `./x.py setup`.
# See https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#create-a-configtoml for more information.
# See https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#create-a-bootstraptoml for more information.
#
# All options are commented out by default in this file, and they're commented
# out with their default values. The build system by default looks for
@ -28,8 +28,9 @@
# - A new option
# - A change in the default values
#
# If `change-id` does not match the version that is currently running,
# `x.py` will inform you about the changes made on bootstrap.
# If the change-id does not match the version currently in use, x.py will
# display the changes made to the bootstrap.
# To suppress these warnings, you can set change-id = "ignore".
#change-id = <latest change id in src/bootstrap/src/utils/change_tracker.rs>
# =============================================================================
@ -446,7 +447,7 @@
# a specific version.
#ccache = false
# List of paths to exclude from the build and test processes.
# List of paths to exclude from the build and test processes.
# For example, exclude = ["tests/ui", "src/tools/tidy"].
#exclude = []

View File

@ -1462,7 +1462,8 @@ impl BackendRepr {
!self.is_unsized()
}
/// Returns `true` if this is a single signed integer scalar
/// Returns `true` if this is a single signed integer scalar.
/// Sanity check: panics if this is not a scalar type (see PR #70189).
#[inline]
pub fn is_signed(&self) -> bool {
match self {

View File

@ -6,7 +6,6 @@ edition = "2024"
[dependencies]
# tidy-alphabetical-start
bitflags = "2.4.1"
literal-escaper = { path = "../../library/literal-escaper" }
memchr = "2.7.4"
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_data_structures = { path = "../rustc_data_structures" }

View File

@ -545,14 +545,6 @@ pub struct Block {
pub rules: BlockCheckMode,
pub span: Span,
pub tokens: Option<LazyAttrTokenStream>,
/// The following *isn't* a parse error, but will cause multiple errors in following stages.
/// ```compile_fail
/// let x = {
/// foo: var
/// };
/// ```
/// #34255
pub could_be_bare_literal: bool,
}
/// A match pattern.
@ -1657,7 +1649,7 @@ pub enum ExprKind {
Try(P<Expr>),
/// A `yield`, with an optional value to be yielded.
Yield(Option<P<Expr>>),
Yield(YieldKind),
/// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
/// with an optional value to be returned.
@ -1903,6 +1895,44 @@ pub enum MatchKind {
Postfix,
}
/// The kind of yield expression
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum YieldKind {
/// yield expr { ... }
Prefix(Option<P<Expr>>),
/// expr.yield { ... }
Postfix(P<Expr>),
}
impl YieldKind {
/// Returns the expression inside the yield expression, if any.
///
/// For postfix yields, this is guaranteed to be `Some`.
pub const fn expr(&self) -> Option<&P<Expr>> {
match self {
YieldKind::Prefix(expr) => expr.as_ref(),
YieldKind::Postfix(expr) => Some(expr),
}
}
/// Returns a mutable reference to the expression being yielded, if any.
pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
match self {
YieldKind::Prefix(expr) => expr.as_mut(),
YieldKind::Postfix(expr) => Some(expr),
}
}
/// Returns true if both yields are prefix or both are postfix.
pub const fn same_kind(&self, other: &Self) -> bool {
match (self, other) {
(YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
(YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
_ => false,
}
}
}
/// A literal in a meta item.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MetaItemLit {
@ -3273,9 +3303,6 @@ pub struct Item<K = ItemKind> {
pub id: NodeId,
pub span: Span,
pub vis: Visibility,
/// The name of the item.
/// It might be a dummy name in case of anonymous items.
pub ident: Ident,
pub kind: K,
@ -3297,23 +3324,23 @@ impl Item {
pub fn opt_generics(&self) -> Option<&Generics> {
match &self.kind {
ItemKind::ExternCrate(_)
ItemKind::ExternCrate(..)
| ItemKind::Use(_)
| ItemKind::Mod(_, _)
| ItemKind::Mod(..)
| ItemKind::ForeignMod(_)
| ItemKind::GlobalAsm(_)
| ItemKind::MacCall(_)
| ItemKind::Delegation(_)
| ItemKind::DelegationMac(_)
| ItemKind::MacroDef(_) => None,
| ItemKind::MacroDef(..) => None,
ItemKind::Static(_) => None,
ItemKind::Const(i) => Some(&i.generics),
ItemKind::Fn(i) => Some(&i.generics),
ItemKind::TyAlias(i) => Some(&i.generics),
ItemKind::TraitAlias(generics, _)
| ItemKind::Enum(_, generics)
| ItemKind::Struct(_, generics)
| ItemKind::Union(_, generics) => Some(&generics),
ItemKind::TraitAlias(_, generics, _)
| ItemKind::Enum(_, _, generics)
| ItemKind::Struct(_, _, generics)
| ItemKind::Union(_, _, generics) => Some(&generics),
ItemKind::Trait(i) => Some(&i.generics),
ItemKind::Impl(i) => Some(&i.generics),
}
@ -3390,6 +3417,7 @@ impl Default for FnHeader {
pub struct Trait {
pub safety: Safety,
pub is_auto: IsAuto,
pub ident: Ident,
pub generics: Generics,
pub bounds: GenericBounds,
pub items: ThinVec<P<AssocItem>>,
@ -3435,6 +3463,7 @@ pub struct TyAliasWhereClauses {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TyAlias {
pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics,
pub where_clauses: TyAliasWhereClauses,
pub bounds: GenericBounds,
@ -3463,6 +3492,7 @@ pub struct FnContract {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Fn {
pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics,
pub sig: FnSig,
pub contract: Option<P<FnContract>>,
@ -3476,6 +3506,7 @@ pub struct Delegation {
pub id: NodeId,
pub qself: Option<P<QSelf>>,
pub path: Path,
pub ident: Ident,
pub rename: Option<Ident>,
pub body: Option<P<Block>>,
/// The item was expanded from a glob delegation item.
@ -3493,18 +3524,22 @@ pub struct DelegationMac {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StaticItem {
pub ident: Ident,
pub ty: P<Ty>,
pub safety: Safety,
pub mutability: Mutability,
pub expr: Option<P<Expr>>,
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ConstItem {
pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics,
pub ty: P<Ty>,
pub expr: Option<P<Expr>>,
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
}
// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
@ -3513,7 +3548,7 @@ pub enum ItemKind {
/// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
///
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
ExternCrate(Option<Symbol>),
ExternCrate(Option<Symbol>, Ident),
/// A use declaration item (`use`).
///
/// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
@ -3535,7 +3570,7 @@ pub enum ItemKind {
/// E.g., `mod foo;` or `mod foo { .. }`.
/// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
/// semantically by Rust.
Mod(Safety, ModKind),
Mod(Safety, Ident, ModKind),
/// An external module (`extern`).
///
/// E.g., `extern {}` or `extern "C" {}`.
@ -3549,15 +3584,15 @@ pub enum ItemKind {
/// An enum definition (`enum`).
///
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
Enum(EnumDef, Generics),
Enum(Ident, EnumDef, Generics),
/// A struct definition (`struct`).
///
/// E.g., `struct Foo<A> { x: A }`.
Struct(VariantData, Generics),
Struct(Ident, VariantData, Generics),
/// A union definition (`union`).
///
/// E.g., `union Foo<A, B> { x: A, y: B }`.
Union(VariantData, Generics),
Union(Ident, VariantData, Generics),
/// A trait declaration (`trait`).
///
/// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
@ -3565,7 +3600,7 @@ pub enum ItemKind {
/// Trait alias.
///
/// E.g., `trait Foo = Bar + Quux;`.
TraitAlias(Generics, GenericBounds),
TraitAlias(Ident, Generics, GenericBounds),
/// An implementation.
///
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
@ -3576,7 +3611,7 @@ pub enum ItemKind {
MacCall(P<MacCall>),
/// A macro definition.
MacroDef(MacroDef),
MacroDef(Ident, MacroDef),
/// A single delegation item (`reuse`).
///
@ -3588,6 +3623,31 @@ pub enum ItemKind {
}
impl ItemKind {
pub fn ident(&self) -> Option<Ident> {
match *self {
ItemKind::ExternCrate(_, ident)
| ItemKind::Static(box StaticItem { ident, .. })
| ItemKind::Const(box ConstItem { ident, .. })
| ItemKind::Fn(box Fn { ident, .. })
| ItemKind::Mod(_, ident, _)
| ItemKind::TyAlias(box TyAlias { ident, .. })
| ItemKind::Enum(ident, ..)
| ItemKind::Struct(ident, ..)
| ItemKind::Union(ident, ..)
| ItemKind::Trait(box Trait { ident, .. })
| ItemKind::TraitAlias(ident, ..)
| ItemKind::MacroDef(ident, _)
| ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
ItemKind::Use(_)
| ItemKind::ForeignMod(_)
| ItemKind::GlobalAsm(_)
| ItemKind::Impl(_)
| ItemKind::MacCall(_)
| ItemKind::DelegationMac(_) => None,
}
}
/// "a" or "an"
pub fn article(&self) -> &'static str {
use ItemKind::*;
@ -3628,11 +3688,11 @@ impl ItemKind {
Self::Fn(box Fn { generics, .. })
| Self::TyAlias(box TyAlias { generics, .. })
| Self::Const(box ConstItem { generics, .. })
| Self::Enum(_, generics)
| Self::Struct(_, generics)
| Self::Union(_, generics)
| Self::Enum(_, _, generics)
| Self::Struct(_, _, generics)
| Self::Union(_, _, generics)
| Self::Trait(box Trait { generics, .. })
| Self::TraitAlias(generics, _)
| Self::TraitAlias(_, generics, _)
| Self::Impl(box Impl { generics, .. }) => Some(generics),
_ => None,
}
@ -3668,6 +3728,17 @@ pub enum AssocItemKind {
}
impl AssocItemKind {
pub fn ident(&self) -> Option<Ident> {
match *self {
AssocItemKind::Const(box ConstItem { ident, .. })
| AssocItemKind::Fn(box Fn { ident, .. })
| AssocItemKind::Type(box TyAlias { ident, .. })
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
}
}
pub fn defaultness(&self) -> Defaultness {
match *self {
Self::Const(box ConstItem { defaultness, .. })
@ -3714,14 +3785,26 @@ impl TryFrom<ItemKind> for AssocItemKind {
pub enum ForeignItemKind {
/// A foreign static item (`static FOO: u8`).
Static(Box<StaticItem>),
/// An foreign function.
/// A foreign function.
Fn(Box<Fn>),
/// An foreign type.
/// A foreign type.
TyAlias(Box<TyAlias>),
/// A macro expanding to foreign items.
MacCall(P<MacCall>),
}
impl ForeignItemKind {
pub fn ident(&self) -> Option<Ident> {
match *self {
ForeignItemKind::Static(box StaticItem { ident, .. })
| ForeignItemKind::Fn(box Fn { ident, .. })
| ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
ForeignItemKind::MacCall(_) => None,
}
}
}
impl From<ForeignItemKind> for ItemKind {
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
match foreign_item_kind {
@ -3758,21 +3841,21 @@ mod size_asserts {
use super::*;
// tidy-alphabetical-start
static_assert_size!(AssocItem, 88);
static_assert_size!(AssocItem, 80);
static_assert_size!(AssocItemKind, 16);
static_assert_size!(Attribute, 32);
static_assert_size!(Block, 32);
static_assert_size!(Expr, 72);
static_assert_size!(ExprKind, 40);
static_assert_size!(Fn, 176);
static_assert_size!(ForeignItem, 88);
static_assert_size!(Fn, 184);
static_assert_size!(ForeignItem, 80);
static_assert_size!(ForeignItemKind, 16);
static_assert_size!(GenericArg, 24);
static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 40);
static_assert_size!(Impl, 136);
static_assert_size!(Item, 136);
static_assert_size!(ItemKind, 64);
static_assert_size!(Item, 144);
static_assert_size!(ItemKind, 80);
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 80);
static_assert_size!(MetaItemLit, 40);

View File

@ -209,13 +209,11 @@ impl HasTokens for Attribute {
impl HasTokens for Nonterminal {
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
match self {
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
Nonterminal::NtBlock(block) => block.tokens(),
}
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
match self {
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
Nonterminal::NtBlock(block) => block.tokens_mut(),
}
}

View File

@ -41,7 +41,6 @@ pub trait WalkItemKind {
&mut self,
span: Span,
id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility,
ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor,
@ -238,6 +237,10 @@ pub trait MutVisitor: Sized {
walk_ident(self, i);
}
fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) {
walk_modifiers(self, m);
}
fn visit_path(&mut self, p: &mut Path) {
walk_path(self, p);
}
@ -896,8 +899,6 @@ pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
match nt {
token::NtBlock(block) => vis.visit_block(block),
token::NtExpr(expr) => vis.visit_expr(expr),
token::NtLiteral(expr) => vis.visit_expr(expr),
}
}
@ -959,10 +960,10 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
match kind {
FnKind::Fn(
_ctxt,
_ident,
_vis,
Fn {
defaultness,
ident,
generics,
contract,
body,
@ -970,8 +971,9 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
define_opaque,
},
) => {
// Identifier and visibility are visited as a part of the item.
// Visibility is visited as a part of the item.
visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_fn_header(header);
vis.visit_generics(generics);
vis.visit_fn_decl(decl);
@ -983,10 +985,7 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
}
vis.visit_span(span);
for (id, path) in define_opaque.iter_mut().flatten() {
vis.visit_id(id);
vis.visit_path(path)
}
walk_define_opaques(vis, define_opaque);
}
FnKind::Closure(binder, coroutine_kind, decl, body) => {
vis.visit_closure_binder(binder);
@ -1156,12 +1155,29 @@ fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut Tr
}
fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p;
let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
vis.visit_modifiers(modifiers);
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
vis.visit_trait_ref(trait_ref);
vis.visit_span(span);
}
fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) {
let TraitBoundModifiers { constness, asyncness, polarity } = m;
match constness {
BoundConstness::Never => {}
BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span),
}
match asyncness {
BoundAsyncness::Normal => {}
BoundAsyncness::Async(span) => vis.visit_span(span),
}
match polarity {
BoundPolarity::Positive => {}
BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span),
}
}
pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd;
visitor.visit_id(id);
@ -1204,7 +1220,7 @@ fn walk_mt<T: MutVisitor>(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) {
}
pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) {
let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut();
let Block { id, stmts, rules: _, span, tokens } = block.deref_mut();
vis.visit_id(id);
stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
visit_lazy_tts(vis, tokens);
@ -1215,12 +1231,11 @@ pub fn walk_item_kind<K: WalkItemKind>(
kind: &mut K,
span: Span,
id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility,
ctxt: K::Ctxt,
vis: &mut impl MutVisitor,
) {
kind.walk(span, id, ident, visibility, ctxt, vis)
kind.walk(span, id, visibility, ctxt, vis)
}
impl WalkItemKind for ItemKind {
@ -1229,26 +1244,35 @@ impl WalkItemKind for ItemKind {
&mut self,
span: Span,
id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility,
_ctxt: Self::Ctxt,
vis: &mut impl MutVisitor,
) {
match self {
ItemKind::ExternCrate(_orig_name) => {}
ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
ItemKind::Static(box StaticItem {
ident,
ty,
safety: _,
mutability: _,
expr,
define_opaque,
}) => {
vis.visit_ident(ident);
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
walk_define_opaques(vis, define_opaque);
}
ItemKind::Const(item) => {
visit_const_item(item, vis);
walk_const_item(vis, item);
}
ItemKind::Fn(func) => {
vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id);
vis.visit_fn(FnKind::Fn(FnCtxt::Free, visibility, &mut *func), span, id);
}
ItemKind::Mod(safety, mod_kind) => {
ItemKind::Mod(safety, ident, mod_kind) => {
visit_safety(vis, safety);
vis.visit_ident(ident);
match mod_kind {
ModKind::Loaded(
items,
@ -1265,18 +1289,29 @@ impl WalkItemKind for ItemKind {
}
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias { defaultness, generics, where_clauses, bounds, ty }) => {
ItemKind::TyAlias(box TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound);
visit_opt(ty, |ty| vis.visit_ty(ty));
walk_ty_alias_where_clauses(vis, where_clauses);
}
ItemKind::Enum(EnumDef { variants }, generics) => {
ItemKind::Enum(ident, EnumDef { variants }, generics) => {
vis.visit_ident(ident);
vis.visit_generics(generics);
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
}
ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
ItemKind::Struct(ident, variant_data, generics)
| ItemKind::Union(ident, variant_data, generics) => {
vis.visit_ident(ident);
vis.visit_generics(generics);
vis.visit_variant_data(variant_data);
}
@ -1297,24 +1332,32 @@ impl WalkItemKind for ItemKind {
visit_polarity(vis, polarity);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Impl));
items.flat_map_in_place(|item| {
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
});
}
ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
visit_safety(vis, safety);
vis.visit_ident(ident);
vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound);
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait));
}
ItemKind::TraitAlias(generics, bounds) => {
ItemKind::TraitAlias(ident, generics, bounds) => {
vis.visit_ident(ident);
vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound);
}
ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
ItemKind::MacroDef(ident, def) => {
vis.visit_ident(ident);
vis.visit_macro_def(def)
}
ItemKind::Delegation(box Delegation {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
@ -1322,6 +1365,7 @@ impl WalkItemKind for ItemKind {
vis.visit_id(id);
vis.visit_qself(qself);
vis.visit_path(path);
vis.visit_ident(ident);
if let Some(rename) = rename {
vis.visit_ident(rename);
}
@ -1354,30 +1398,27 @@ impl WalkItemKind for AssocItemKind {
&mut self,
span: Span,
id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility,
ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor,
) {
match self {
AssocItemKind::Const(item) => {
visit_const_item(item, visitor);
walk_const_item(visitor, item);
}
AssocItemKind::Fn(func) => {
visitor.visit_fn(
FnKind::Fn(FnCtxt::Assoc(ctxt), ident, visibility, &mut *func),
span,
id,
);
visitor.visit_fn(FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &mut *func), span, id);
}
AssocItemKind::Type(box TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
visit_defaultness(visitor, defaultness);
visitor.visit_ident(ident);
visitor.visit_generics(generics);
visit_bounds(visitor, bounds, BoundKind::Bound);
visit_opt(ty, |ty| visitor.visit_ty(ty));
@ -1388,6 +1429,7 @@ impl WalkItemKind for AssocItemKind {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
@ -1395,6 +1437,7 @@ impl WalkItemKind for AssocItemKind {
visitor.visit_id(id);
visitor.visit_qself(qself);
visitor.visit_path(path);
visitor.visit_ident(ident);
if let Some(rename) = rename {
visitor.visit_ident(rename);
}
@ -1421,14 +1464,14 @@ impl WalkItemKind for AssocItemKind {
}
}
fn visit_const_item<T: MutVisitor>(
ConstItem { defaultness, generics, ty, expr }: &mut ConstItem,
visitor: &mut T,
) {
visit_defaultness(visitor, defaultness);
visitor.visit_generics(generics);
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_generics(generics);
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
walk_define_opaques(vis, define_opaque);
}
fn walk_fn_header<T: MutVisitor>(vis: &mut T, header: &mut FnHeader) {
@ -1461,12 +1504,11 @@ fn walk_item_ctxt<K: WalkItemKind>(
item: &mut P<Item<K>>,
ctxt: K::Ctxt,
) {
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
let Item { attrs, id, kind, vis, span, tokens } = item.deref_mut();
visitor.visit_id(id);
visit_attrs(visitor, attrs);
visitor.visit_vis(vis);
visitor.visit_ident(ident);
kind.walk(*span, *id, ident, vis, ctxt, visitor);
kind.walk(*span, *id, vis, ctxt, visitor);
visit_lazy_tts(visitor, tokens);
visitor.visit_span(span);
}
@ -1499,31 +1541,37 @@ impl WalkItemKind for ForeignItemKind {
&mut self,
span: Span,
id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility,
_ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor,
) {
match self {
ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
ForeignItemKind::Static(box StaticItem {
ident,
ty,
mutability: _,
expr,
safety: _,
define_opaque,
}) => {
visitor.visit_ident(ident);
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
walk_define_opaques(visitor, define_opaque);
}
ForeignItemKind::Fn(func) => {
visitor.visit_fn(
FnKind::Fn(FnCtxt::Foreign, ident, visibility, &mut *func),
span,
id,
);
visitor.visit_fn(FnKind::Fn(FnCtxt::Foreign, visibility, &mut *func), span, id);
}
ForeignItemKind::TyAlias(box TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
visit_defaultness(visitor, defaultness);
visitor.visit_ident(ident);
visitor.visit_generics(generics);
visit_bounds(visitor, bounds, BoundKind::Bound);
visit_opt(ty, |ty| visitor.visit_ty(ty));
@ -1813,8 +1861,11 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
ExprKind::Paren(expr) => {
vis.visit_expr(expr);
}
ExprKind::Yield(expr) => {
visit_opt(expr, |expr| vis.visit_expr(expr));
ExprKind::Yield(kind) => {
let expr = kind.expr_mut();
if let Some(expr) = expr {
vis.visit_expr(expr);
}
}
ExprKind::Try(expr) => vis.visit_expr(expr),
ExprKind::TryBlock(body) => vis.visit_block(body),
@ -1905,6 +1956,18 @@ fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
}
}
fn walk_define_opaques<T: MutVisitor>(
vis: &mut T,
define_opaque: &mut Option<ThinVec<(NodeId, Path)>>,
) {
if let Some(define_opaque) = define_opaque {
for (id, path) in define_opaque {
vis.visit_id(id);
vis.visit_path(path)
}
}
}
/// Some value for the AST node that is valid but possibly meaningless. Similar
/// to `Default` but not intended for wide use. The value will never be used
/// meaningfully, it exists just to support unwinding in `visit_clobber` in the
@ -1936,8 +1999,7 @@ impl DummyAstNode for Item {
span: Default::default(),
tokens: Default::default(),
},
ident: Ident::dummy(),
kind: ItemKind::ExternCrate(None),
kind: ItemKind::ExternCrate(None, Ident::dummy()),
tokens: Default::default(),
}
}
@ -2004,7 +2066,7 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo
#[derive(Debug)]
pub enum FnKind<'a> {
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
Fn(FnCtxt, &'a mut Ident, &'a mut Visibility, &'a mut Fn),
Fn(FnCtxt, &'a mut Visibility, &'a mut Fn),
/// E.g., `|x, y| body`.
Closure(

View File

@ -198,16 +198,17 @@ impl Lit {
}
}
/// Keep this in sync with `Token::can_begin_literal_maybe_minus` excluding unary negation.
/// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
/// `Parser::eat_token_lit` (excluding unary negation).
pub fn from_token(token: &Token) -> Option<Lit> {
match token.uninterpolate().kind {
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
Literal(token_lit) => Some(token_lit),
Interpolated(ref nt)
if let NtExpr(expr) | NtLiteral(expr) = &**nt
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
{
Some(token_lit)
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Literal | MetaVarKind::Expr { .. },
))) => {
// Unreachable with the current test suite.
panic!("from_token metavar");
}
_ => None,
}
@ -447,8 +448,9 @@ pub enum TokenKind {
/// Identifier token.
/// Do not forget about `NtIdent` when you want to match on identifiers.
/// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
/// treat regular and interpolated identifiers in the same way.
/// It's recommended to use `Token::{ident,uninterpolate}` and
/// `Parser::token_uninterpolated_span` to treat regular and interpolated
/// identifiers in the same way.
Ident(Symbol, IdentIsRaw),
/// This identifier (and its span) is the identifier passed to the
/// declarative macro. The span in the surrounding `Token` is the span of
@ -457,8 +459,9 @@ pub enum TokenKind {
/// Lifetime identifier token.
/// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
/// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
/// treat regular and interpolated lifetime identifiers in the same way.
/// It's recommended to use `Token::{ident,uninterpolate}` and
/// `Parser::token_uninterpolated_span` to treat regular and interpolated
/// identifiers in the same way.
Lifetime(Symbol, IdentIsRaw),
/// This identifier (and its span) is the lifetime passed to the
/// declarative macro. The span in the surrounding `Token` is the span of
@ -584,20 +587,6 @@ impl Token {
Token::new(Ident(ident.name, ident.is_raw_guess().into()), ident.span)
}
/// For interpolated tokens, returns a span of the fragment to which the interpolated
/// token refers. For all other tokens this is just a regular span.
/// It is particularly important to use this for identifiers and lifetimes
/// for which spans affect name resolution and edition checks.
/// Note that keywords are also identifiers, so they should use this
/// if they keep spans or perform edition checks.
pub fn uninterpolated_span(&self) -> Span {
match self.kind {
NtIdent(ident, _) | NtLifetime(ident, _) => ident.span,
Interpolated(ref nt) => nt.use_span(),
_ => self.span,
}
}
pub fn is_range_separator(&self) -> bool {
[DotDot, DotDotDot, DotDotEq].contains(&self.kind)
}
@ -642,12 +631,7 @@ impl Token {
PathSep | // global path
Lifetime(..) | // labeled loop
Pound => true, // expression attributes
Interpolated(ref nt) =>
matches!(&**nt,
NtBlock(..) |
NtExpr(..) |
NtLiteral(..)
),
Interpolated(ref nt) => matches!(&**nt, NtBlock(..)),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Block |
MetaVarKind::Expr { .. } |
@ -677,11 +661,6 @@ impl Token {
Lt | // path (UFCS constant)
Shl => true, // path (double UFCS)
Or => matches!(pat_kind, PatWithOr), // leading vert `|` or-pattern
Interpolated(nt) =>
matches!(&**nt,
| NtExpr(..)
| NtLiteral(..)
),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } |
MetaVarKind::Literal |
@ -724,7 +703,7 @@ impl Token {
match self.kind {
OpenDelim(Delimiter::Brace) | Literal(..) | Minus => true,
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
Interpolated(ref nt) => matches!(&**nt, NtBlock(..)),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } | MetaVarKind::Block | MetaVarKind::Literal,
))) => true,
@ -768,22 +747,12 @@ impl Token {
///
/// In other words, would this token be a valid start of `parse_literal_maybe_minus`?
///
/// Keep this in sync with and `Lit::from_token`, excluding unary negation.
/// Keep this in sync with `Lit::from_token` and `Parser::eat_token_lit`
/// (excluding unary negation).
pub fn can_begin_literal_maybe_minus(&self) -> bool {
match self.uninterpolate().kind {
Literal(..) | Minus => true,
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
Interpolated(ref nt) => match &**nt {
NtLiteral(_) => true,
NtExpr(e) => match &e.kind {
ast::ExprKind::Lit(_) => true,
ast::ExprKind::Unary(ast::UnOp::Neg, e) => {
matches!(&e.kind, ast::ExprKind::Lit(_))
}
_ => false,
},
_ => false,
},
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
MetaVarKind::Literal => true,
MetaVarKind::Expr { can_begin_literal_maybe_minus, .. } => {
@ -798,14 +767,6 @@ impl Token {
pub fn can_begin_string_literal(&self) -> bool {
match self.uninterpolate().kind {
Literal(..) => true,
Interpolated(ref nt) => match &**nt {
NtLiteral(_) => true,
NtExpr(e) => match &e.kind {
ast::ExprKind::Lit(_) => true,
_ => false,
},
_ => false,
},
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
MetaVarKind::Literal => true,
MetaVarKind::Expr { can_begin_string_literal, .. } => can_begin_string_literal,
@ -869,12 +830,17 @@ impl Token {
/// Is this a pre-parsed expression dropped into the token stream
/// (which happens while parsing the result of macro expansion)?
pub fn is_whole_expr(&self) -> bool {
pub fn is_metavar_expr(&self) -> bool {
#[allow(irrefutable_let_patterns)] // FIXME: temporary
if let Interpolated(nt) = &self.kind
&& let NtExpr(_) | NtLiteral(_) | NtBlock(_) = &**nt
&& let NtBlock(_) = &**nt
{
true
} else if matches!(
self.is_metavar_seq(),
Some(MetaVarKind::Expr { .. } | MetaVarKind::Literal | MetaVarKind::Path)
) {
true
} else {
matches!(self.is_metavar_seq(), Some(MetaVarKind::Path))
}
@ -882,6 +848,7 @@ impl Token {
/// Is the token an interpolated block (`$b:block`)?
pub fn is_whole_block(&self) -> bool {
#[allow(irrefutable_let_patterns)] // FIXME: temporary
if let Interpolated(nt) = &self.kind
&& let NtBlock(..) = &**nt
{
@ -928,11 +895,6 @@ impl Token {
self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
}
/// Don't use this unless you're doing something very loose and heuristic-y.
pub fn is_any_keyword(&self) -> bool {
self.is_non_raw_ident_where(Ident::is_any_keyword)
}
/// Returns true for reserved identifiers used internally for elided lifetimes,
/// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special_ident(&self) -> bool {
@ -1105,8 +1067,6 @@ pub enum NtExprKind {
/// For interpolation during macro expansion.
pub enum Nonterminal {
NtBlock(P<ast::Block>),
NtExpr(P<ast::Expr>),
NtLiteral(P<ast::Expr>),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
@ -1196,15 +1156,12 @@ impl Nonterminal {
pub fn use_span(&self) -> Span {
match self {
NtBlock(block) => block.span,
NtExpr(expr) | NtLiteral(expr) => expr.span,
}
}
pub fn descr(&self) -> &'static str {
match self {
NtBlock(..) => "block",
NtExpr(..) => "expression",
NtLiteral(..) => "literal",
}
}
}
@ -1223,8 +1180,6 @@ impl fmt::Debug for Nonterminal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
NtBlock(..) => f.pad("NtBlock(..)"),
NtExpr(..) => f.pad("NtExpr(..)"),
NtLiteral(..) => f.pad("NtLiteral(..)"),
}
}
}
@ -1247,7 +1202,7 @@ mod size_asserts {
// tidy-alphabetical-start
static_assert_size!(Lit, 12);
static_assert_size!(LitKind, 2);
static_assert_size!(Nonterminal, 16);
static_assert_size!(Nonterminal, 8);
static_assert_size!(Token, 24);
static_assert_size!(TokenKind, 16);
// tidy-alphabetical-end

View File

@ -233,35 +233,52 @@ fn attrs_and_tokens_to_token_trees(
// Insert inner attribute tokens.
if !inner_attrs.is_empty() {
let mut found = false;
// Check the last two trees (to account for a trailing semi)
for tree in res.iter_mut().rev().take(2) {
if let TokenTree::Delimited(span, spacing, delim, delim_tokens) = tree {
// Inner attributes are only supported on extern blocks, functions,
// impls, and modules. All of these have their inner attributes
// placed at the beginning of the rightmost outermost braced group:
// e.g. fn foo() { #![my_attr] }
//
// Therefore, we can insert them back into the right location
// without needing to do any extra position tracking.
//
// Note: Outline modules are an exception - they can
// have attributes like `#![my_attr]` at the start of a file.
// Support for custom attributes in this position is not
// properly implemented - we always synthesize fake tokens,
// so we never reach this code.
let found = insert_inner_attrs(inner_attrs, res);
assert!(found, "Failed to find trailing delimited group in: {res:?}");
}
// Inner attributes are only supported on blocks, functions, impls, and
// modules. All of these have their inner attributes placed at the
// beginning of the rightmost outermost braced group:
// e.g. `fn foo() { #![my_attr] }`. (Note: the braces may be within
// invisible delimiters.)
//
// Therefore, we can insert them back into the right location without
// needing to do any extra position tracking.
//
// Note: Outline modules are an exception - they can have attributes like
// `#![my_attr]` at the start of a file. Support for custom attributes in
// this position is not properly implemented - we always synthesize fake
// tokens, so we never reach this code.
fn insert_inner_attrs(inner_attrs: &[Attribute], tts: &mut Vec<TokenTree>) -> bool {
for tree in tts.iter_mut().rev() {
if let TokenTree::Delimited(span, spacing, Delimiter::Brace, stream) = tree {
// Found it: the rightmost, outermost braced group.
let mut tts = vec![];
for inner_attr in inner_attrs {
tts.extend(inner_attr.token_trees());
}
tts.extend(delim_tokens.0.iter().cloned());
tts.extend(stream.0.iter().cloned());
let stream = TokenStream::new(tts);
*tree = TokenTree::Delimited(*span, *spacing, *delim, stream);
found = true;
break;
*tree = TokenTree::Delimited(*span, *spacing, Delimiter::Brace, stream);
return true;
} else if let TokenTree::Delimited(span, spacing, Delimiter::Invisible(src), stream) =
tree
{
// Recurse inside invisible delimiters.
let mut vec: Vec<_> = stream.iter().cloned().collect();
if insert_inner_attrs(inner_attrs, &mut vec) {
*tree = TokenTree::Delimited(
*span,
*spacing,
Delimiter::Invisible(*src),
TokenStream::new(vec),
);
return true;
}
}
}
assert!(found, "Failed to find trailing delimited group in: {res:?}");
false
}
}
@ -462,7 +479,6 @@ impl TokenStream {
pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
match nt {
Nonterminal::NtBlock(block) => TokenStream::from_ast(block),
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
}
}

View File

@ -182,11 +182,14 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
| Range(_, Some(e), _)
| Ret(Some(e))
| Unary(_, e)
| Yield(Some(e))
| Yeet(Some(e))
| Become(e) => {
expr = e;
}
Yield(kind) => match kind.expr() {
Some(e) => expr = e,
None => break None,
},
Closure(closure) => {
expr = &closure.body;
}
@ -217,7 +220,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
Break(_, None)
| Range(_, None, _)
| Ret(None)
| Yield(None)
| Array(_)
| Call(_, _)
| MethodCall(_)
@ -237,7 +239,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
| Yeet(None)
| UnsafeBinderCast(..)
| Err(_)
| Dummy => break None,
| Dummy => {
break None;
}
}
}
}

View File

@ -2,7 +2,7 @@
use std::{ascii, fmt, str};
use literal_escaper::{
use rustc_lexer::unescape::{
MixedUnit, Mode, byte_from_char, unescape_byte, unescape_char, unescape_mixed, unescape_unicode,
};
use rustc_span::{Span, Symbol, kw, sym};

View File

@ -16,6 +16,7 @@
pub use rustc_ast_ir::visit::VisitorResult;
pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
use rustc_span::{Ident, Span};
use thin_vec::ThinVec;
use crate::ast::*;
use crate::ptr::P;
@ -23,7 +24,7 @@ use crate::ptr::P;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AssocCtxt {
Trait,
Impl,
Impl { of_trait: bool },
}
#[derive(Copy, Clone, Debug, PartialEq)]
@ -65,7 +66,7 @@ impl BoundKind {
#[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> {
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
Fn(FnCtxt, &'a Ident, &'a Visibility, &'a Fn),
Fn(FnCtxt, &'a Visibility, &'a Fn),
/// E.g., `|x, y| body`.
Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr),
@ -74,21 +75,21 @@ pub enum FnKind<'a> {
impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&'a FnHeader> {
match *self {
FnKind::Fn(_, _, _, Fn { sig, .. }) => Some(&sig.header),
FnKind::Fn(_, _, Fn { sig, .. }) => Some(&sig.header),
FnKind::Closure(..) => None,
}
}
pub fn ident(&self) -> Option<&Ident> {
match self {
FnKind::Fn(_, ident, ..) => Some(ident),
FnKind::Fn(_, _, Fn { ident, .. }) => Some(ident),
_ => None,
}
}
pub fn decl(&self) -> &'a FnDecl {
match self {
FnKind::Fn(_, _, _, Fn { sig, .. }) => &sig.decl,
FnKind::Fn(_, _, Fn { sig, .. }) => &sig.decl,
FnKind::Closure(_, _, decl, _) => decl,
}
}
@ -117,7 +118,6 @@ pub trait WalkItemKind {
&'a self,
span: Span,
id: NodeId,
ident: &'a Ident,
visibility: &'a Visibility,
ctxt: Self::Ctxt,
visitor: &mut V,
@ -363,49 +363,72 @@ impl WalkItemKind for ItemKind {
&'a self,
span: Span,
id: NodeId,
ident: &'a Ident,
vis: &'a Visibility,
_ctxt: Self::Ctxt,
visitor: &mut V,
) -> V::Result {
match self {
ItemKind::ExternCrate(_rename) => {}
ItemKind::ExternCrate(_rename, ident) => try_visit!(visitor.visit_ident(ident)),
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
ItemKind::Static(box StaticItem {
ident,
ty,
safety: _,
mutability: _,
expr,
define_opaque,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque));
}
ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
ItemKind::Const(box ConstItem {
defaultness: _,
ident,
generics,
ty,
expr,
define_opaque,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque));
}
ItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func);
let kind = FnKind::Fn(FnCtxt::Free, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
ModKind::Loaded(items, _inline, _inner_span, _) => {
walk_list!(visitor, visit_item, items);
ItemKind::Mod(_unsafety, ident, mod_kind) => {
try_visit!(visitor.visit_ident(ident));
match mod_kind {
ModKind::Loaded(items, _inline, _inner_span, _) => {
walk_list!(visitor, visit_item, items);
}
ModKind::Unloaded => {}
}
ModKind::Unloaded => {}
},
}
ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
walk_list!(visitor, visit_foreign_item, items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
ItemKind::TyAlias(box TyAlias {
generics,
ident,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
ItemKind::Enum(enum_definition, generics) => {
ItemKind::Enum(ident, enum_definition, generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_enum_def(enum_definition));
}
@ -422,34 +445,54 @@ impl WalkItemKind for ItemKind {
try_visit!(visitor.visit_generics(generics));
visit_opt!(visitor, visit_trait_ref, of_trait);
try_visit!(visitor.visit_ty(self_ty));
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
walk_list!(
visitor,
visit_assoc_item,
items,
AssocCtxt::Impl { of_trait: of_trait.is_some() }
);
}
ItemKind::Struct(struct_definition, generics)
| ItemKind::Union(struct_definition, generics) => {
ItemKind::Struct(ident, struct_definition, generics)
| ItemKind::Union(ident, struct_definition, generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_variant_data(struct_definition));
}
ItemKind::Trait(box Trait { safety: _, is_auto: _, generics, bounds, items }) => {
ItemKind::Trait(box Trait {
safety: _,
is_auto: _,
ident,
generics,
bounds,
items,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
}
ItemKind::TraitAlias(generics, bounds) => {
ItemKind::TraitAlias(ident, generics, bounds) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, id)),
ItemKind::MacroDef(ident, ts) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_mac_def(ts, id))
}
ItemKind::Delegation(box Delegation {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
}) => {
try_visit!(visitor.visit_qself(qself));
try_visit!(visitor.visit_path(path, *id));
try_visit!(visitor.visit_ident(ident));
visit_opt!(visitor, visit_ident, rename);
visit_opt!(visitor, visit_block, body);
}
@ -723,27 +766,37 @@ impl WalkItemKind for ForeignItemKind {
&'a self,
span: Span,
id: NodeId,
ident: &'a Ident,
vis: &'a Visibility,
_ctxt: Self::Ctxt,
visitor: &mut V,
) -> V::Result {
match self {
ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
ForeignItemKind::Static(box StaticItem {
ident,
ty,
mutability: _,
expr,
safety: _,
define_opaque,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque));
}
ForeignItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func);
let kind = FnKind::Fn(FnCtxt::Foreign, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
ForeignItemKind::TyAlias(box TyAlias {
generics,
ident,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
@ -890,10 +943,10 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
match kind {
FnKind::Fn(
_ctxt,
_ident,
_vis,
Fn {
defaultness: _,
ident,
sig: FnSig { header, decl, span: _ },
generics,
contract,
@ -901,15 +954,14 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
define_opaque,
},
) => {
// Identifier and visibility are visited as a part of the item.
// Visibility is visited as a part of the item.
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_fn_header(header));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_fn_decl(decl));
visit_opt!(visitor, visit_contract, contract);
visit_opt!(visitor, visit_block, body);
for (id, path) in define_opaque.iter().flatten() {
try_visit!(visitor.visit_path(path, *id))
}
try_visit!(walk_define_opaques(visitor, define_opaque));
}
FnKind::Closure(binder, coroutine_kind, decl, body) => {
try_visit!(visitor.visit_closure_binder(binder));
@ -927,29 +979,39 @@ impl WalkItemKind for AssocItemKind {
&'a self,
span: Span,
id: NodeId,
ident: &'a Ident,
vis: &'a Visibility,
ctxt: Self::Ctxt,
visitor: &mut V,
) -> V::Result {
match self {
AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
AssocItemKind::Const(box ConstItem {
defaultness: _,
ident,
generics,
ty,
expr,
define_opaque,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque));
}
AssocItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
AssocItemKind::Type(box TyAlias {
generics,
ident,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ident(ident));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
@ -960,12 +1022,14 @@ impl WalkItemKind for AssocItemKind {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
}) => {
try_visit!(visitor.visit_qself(qself));
try_visit!(visitor.visit_path(path, *id));
try_visit!(visitor.visit_ident(ident));
visit_opt!(visitor, visit_ident, rename);
visit_opt!(visitor, visit_block, body);
}
@ -1007,11 +1071,10 @@ fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
item: &'a Item<K>,
ctxt: K::Ctxt,
) -> V::Result {
let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item;
let Item { id, span, vis, attrs, kind, tokens: _ } = item;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(ident));
try_visit!(kind.walk(*span, *id, ident, vis, ctxt, visitor));
try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
V::Result::output()
}
@ -1035,7 +1098,7 @@ pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef)
}
pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) -> V::Result {
let Block { stmts, id: _, rules: _, span: _, tokens: _, could_be_bare_literal: _ } = block;
let Block { stmts, id: _, rules: _, span: _, tokens: _ } = block;
walk_list!(visitor, visit_stmt, stmts);
V::Result::output()
}
@ -1269,8 +1332,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
try_visit!(visitor.visit_ty(container));
walk_list!(visitor, visit_ident, fields.iter());
}
ExprKind::Yield(optional_expression) => {
visit_opt!(visitor, visit_expr, optional_expression);
ExprKind::Yield(kind) => {
visit_opt!(visitor, visit_expr, kind.expr());
}
ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
@ -1337,3 +1400,15 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
}
V::Result::output()
}
fn walk_define_opaques<'a, V: Visitor<'a>>(
visitor: &mut V,
define_opaque: &'a Option<ThinVec<(NodeId, Path)>>,
) -> V::Result {
if let Some(define_opaque) = define_opaque {
for (id, path) in define_opaque {
try_visit!(visitor.visit_path(path, *id));
}
}
V::Result::output()
}

View File

@ -8,7 +8,6 @@ edition = "2024"
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_span = { path = "../rustc_span", optional = true }
# tidy-alphabetical-end
[features]
@ -17,5 +16,4 @@ nightly = [
"dep:rustc_serialize",
"dep:rustc_data_structures",
"dep:rustc_macros",
"dep:rustc_span",
]

View File

@ -20,7 +20,6 @@ rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }

View File

@ -141,9 +141,6 @@ ast_lowering_never_pattern_with_guard =
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
ast_lowering_no_precise_captures_on_rpitit = `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
.note = currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
ast_lowering_previously_used_here = previously used here
ast_lowering_register1 = register `{$reg1_name}`

View File

@ -56,13 +56,20 @@ use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
pub(crate) struct DelegationResults<'hir> {
pub body_id: hir::BodyId,
pub sig: hir::FnSig<'hir>,
pub ident: Ident,
pub generics: &'hir hir::Generics<'hir>,
}
impl<'hir> LoweringContext<'_, 'hir> {
/// Defines whether the delegatee is an associated function whose first parameter is `self`.
pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool {
let sig_id = self.get_delegation_sig_id(item_id, path_id, span);
pub(crate) fn delegatee_is_method(
&self,
item_id: NodeId,
path_id: NodeId,
span: Span,
is_in_trait_impl: bool,
) -> bool {
let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl);
let Ok(sig_id) = sig_id else {
return false;
};
@ -88,18 +95,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
delegation: &Delegation,
item_id: NodeId,
is_in_trait_impl: bool,
) -> DelegationResults<'hir> {
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
match sig_id {
Ok(sig_id) => {
let (param_count, c_variadic) = self.param_count(sig_id);
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
let sig = self.lower_delegation_sig(sig_id, decl, span);
let body_id = self.lower_delegation_body(delegation, param_count, span);
let ident = self.lower_ident(delegation.ident);
let generics = self.lower_delegation_generics(span);
DelegationResults { body_id, sig, generics }
DelegationResults { body_id, sig, ident, generics }
}
Err(err) => self.generate_delegation_error(err, span),
}
@ -110,8 +118,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
item_id: NodeId,
path_id: NodeId,
span: Span,
is_in_trait_impl: bool,
) -> Result<DefId, ErrorGuaranteed> {
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
let sig_id = if is_in_trait_impl { item_id } else { path_id };
self.get_resolution_id(sig_id, span)
}
@ -397,8 +406,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let header = self.generate_header_error();
let sig = hir::FnSig { decl, header, span };
let ident = Ident::dummy();
let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span)));
DelegationResults { generics, body_id, sig }
DelegationResults { ident, generics, body_id, sig }
}
fn generate_header_error(&self) -> hir::FnHeader {

View File

@ -444,14 +444,6 @@ pub(crate) struct NoPreciseCapturesOnApit {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_no_precise_captures_on_rpitit)]
#[note]
pub(crate) struct NoPreciseCapturesOnRpitit {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_yield_in_closure)]
pub(crate) struct YieldInClosure {

View File

@ -351,7 +351,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
rest,
)
}
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
ExprKind::Yield(kind) => self.lower_expr_yield(e.span, kind.expr().map(|x| &**x)),
ExprKind::Err(guar) => hir::ExprKind::Err(*guar),
ExprKind::UnsafeBinderCast(kind, expr, ty) => hir::ExprKind::UnsafeBinderCast(
@ -2150,11 +2150,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr_uint(sp, ast::UintTy::U16, value as u128)
}
pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> {
let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) });
self.expr(sp, hir::ExprKind::Lit(lit))
}
pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> {
let lit = self
.arena

View File

@ -323,14 +323,12 @@ fn make_count<'hir>(
/// Generates
///
/// ```text
/// <core::fmt::rt::Placeholder::new(
/// …usize, // position
/// '…', // fill
/// <core::fmt::rt::Alignment>::…, // alignment
/// …u32, // flags
/// <core::fmt::rt::Count::…>, // width
/// <core::fmt::rt::Count::…>, // precision
/// )
/// <core::fmt::rt::Placeholder {
/// position: …usize,
/// flags: …u32,
/// precision: <core::fmt::rt::Count::…>,
/// width: <core::fmt::rt::Count::…>,
/// }
/// ```
fn make_format_spec<'hir>(
ctx: &mut LoweringContext<'_, 'hir>,
@ -361,34 +359,36 @@ fn make_format_spec<'hir>(
zero_pad,
debug_hex,
} = &placeholder.format_options;
let fill = ctx.expr_char(sp, fill.unwrap_or(' '));
let align = ctx.expr_lang_item_type_relative(
sp,
hir::LangItem::FormatAlignment,
match alignment {
Some(FormatAlignment::Left) => sym::Left,
Some(FormatAlignment::Right) => sym::Right,
Some(FormatAlignment::Center) => sym::Center,
None => sym::Unknown,
},
);
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
| ((sign == Some(FormatSign::Minus)) as u32) << 1
| (alternate as u32) << 2
| (zero_pad as u32) << 3
| ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4
| ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5;
let fill = fill.unwrap_or(' ');
// These need to match the constants in library/core/src/fmt/rt.rs.
let align = match alignment {
Some(FormatAlignment::Left) => 0,
Some(FormatAlignment::Right) => 1,
Some(FormatAlignment::Center) => 2,
None => 3,
};
// This needs to match the constants in library/core/src/fmt/rt.rs.
let flags: u32 = fill as u32
| ((sign == Some(FormatSign::Plus)) as u32) << 21
| ((sign == Some(FormatSign::Minus)) as u32) << 22
| (alternate as u32) << 23
| (zero_pad as u32) << 24
| ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25
| ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26
| (width.is_some() as u32) << 27
| (precision.is_some() as u32) << 28
| align << 29
| 1 << 31; // Highest bit always set.
let flags = ctx.expr_u32(sp, flags);
let precision = make_count(ctx, sp, precision, argmap);
let width = make_count(ctx, sp, width, argmap);
let format_placeholder_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
sp,
hir::LangItem::FormatPlaceholder,
sym::new,
));
let args = ctx.arena.alloc_from_iter([position, fill, align, flags, precision, width]);
ctx.expr_call_mut(sp, format_placeholder_new, args)
let position = ctx.expr_field(Ident::new(sym::position, sp), ctx.arena.alloc(position), sp);
let flags = ctx.expr_field(Ident::new(sym::flags, sp), ctx.arena.alloc(flags), sp);
let precision = ctx.expr_field(Ident::new(sym::precision, sp), ctx.arena.alloc(precision), sp);
let width = ctx.expr_field(Ident::new(sym::width, sp), ctx.arena.alloc(width), sp);
let placeholder = ctx.arena.alloc(hir::QPath::LangItem(hir::LangItem::FormatPlaceholder, sp));
let fields = ctx.arena.alloc_from_iter([position, flags, precision, width]);
ctx.expr(sp, hir::ExprKind::Struct(placeholder, fields, hir::StructTailExpr::None))
}
fn expand_format_args<'hir>(

View File

@ -164,7 +164,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_item(&mut self, i: &'hir Item<'hir>) {
debug_assert_eq!(i.owner_id, self.owner);
self.with_parent(i.hir_id(), |this| {
if let ItemKind::Struct(struct_def, _) = &i.kind {
if let ItemKind::Struct(_, struct_def, _) = &i.kind {
// If this is a tuple or unit-like struct, register the constructor.
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));

View File

@ -5,9 +5,8 @@ use rustc_ast::*;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::{self as hir, HirId, PredicateOrigin};
use rustc_hir::{self as hir, HirId, IsAnonInPath, PredicateOrigin};
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
@ -104,10 +103,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
}
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
let def_id = self.resolver.node_id_to_def_id[&item.id];
let parent_id = self.tcx.local_parent(def_id);
let parent_hir = self.lower_node(parent_id).unwrap();
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt, parent_hir))
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
}
fn lower_foreign_item(&mut self, item: &ForeignItem) {
@ -131,8 +127,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
let mut node_ids =
smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }];
if let ItemKind::Use(use_tree) = &i.kind {
self.lower_item_id_use_tree(use_tree, &mut node_ids);
}
@ -143,9 +138,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
match &tree.kind {
UseTreeKind::Nested { items, .. } => {
for &(ref nested, id) in items {
vec.push(hir::ItemId {
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
});
vec.push(hir::ItemId { owner_id: self.owner_id(id) });
self.lower_item_id_use_tree(nested, vec);
}
}
@ -154,14 +147,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
let mut ident = i.ident;
let vis_span = self.lower_span(i.vis.span);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
let item = hir::Item {
owner_id: hir_id.expect_owner(),
ident: self.lower_ident(ident),
kind,
vis_span,
span: self.lower_span(i.span),
@ -174,25 +165,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
id: NodeId,
hir_id: hir::HirId,
ident: &mut Ident,
attrs: &'hir [hir::Attribute],
vis_span: Span,
i: &ItemKind,
) -> hir::ItemKind<'hir> {
match i {
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name),
ItemKind::ExternCrate(orig_name, ident) => {
let ident = self.lower_ident(*ident);
hir::ItemKind::ExternCrate(*orig_name, ident)
}
ItemKind::Use(use_tree) => {
// Start with an empty prefix.
let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
}
ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
ItemKind::Static(box ast::StaticItem {
ident,
ty: t,
safety: _,
mutability: m,
expr: e,
define_opaque,
}) => {
let ident = self.lower_ident(*ident);
let (ty, body_id) =
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
hir::ItemKind::Static(ty, *m, body_id)
self.lower_define_opaque(hir_id, define_opaque);
hir::ItemKind::Static(ident, ty, *m, body_id)
}
ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
ItemKind::Const(box ast::ConstItem {
ident,
generics,
ty,
expr,
define_opaque,
..
}) => {
let ident = self.lower_ident(*ident);
let (generics, (ty, body_id)) = self.lower_generics(
generics,
id,
@ -201,10 +211,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
},
);
hir::ItemKind::Const(ty, generics, body_id)
self.lower_define_opaque(hir_id, &define_opaque);
hir::ItemKind::Const(ident, ty, generics, body_id)
}
ItemKind::Fn(box Fn {
sig: FnSig { decl, header, span: fn_sig_span },
ident,
generics,
body,
contract,
@ -237,16 +249,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
span: this.lower_span(*fn_sig_span),
};
this.lower_define_opaque(hir_id, &define_opaque);
hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
this.lower_define_opaque(hir_id, define_opaque);
let ident = this.lower_ident(*ident);
hir::ItemKind::Fn {
ident,
sig,
generics,
body: body_id,
has_body: body.is_some(),
}
})
}
ItemKind::Mod(_, mod_kind) => match mod_kind {
ModKind::Loaded(items, _, spans, _) => {
hir::ItemKind::Mod(self.lower_mod(items, spans))
ItemKind::Mod(_, ident, mod_kind) => {
let ident = self.lower_ident(*ident);
match mod_kind {
ModKind::Loaded(items, _, spans, _) => {
hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
},
}
ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
items: self
@ -259,7 +281,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
hir::ItemKind::GlobalAsm { asm, fake_body }
}
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
// We lower
//
// type Foo = impl Trait
@ -268,6 +290,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
//
// type Foo = Foo1
// opaque type Foo1: Trait
let ident = self.lower_ident(*ident);
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
let (generics, ty) = self.lower_generics(
@ -293,9 +316,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
),
},
);
hir::ItemKind::TyAlias(ty, generics)
hir::ItemKind::TyAlias(ident, ty, generics)
}
ItemKind::Enum(enum_definition, generics) => {
ItemKind::Enum(ident, enum_definition, generics) => {
let ident = self.lower_ident(*ident);
let (generics, variants) = self.lower_generics(
generics,
id,
@ -306,25 +330,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
},
);
hir::ItemKind::Enum(hir::EnumDef { variants }, generics)
hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics)
}
ItemKind::Struct(struct_def, generics) => {
ItemKind::Struct(ident, struct_def, generics) => {
let ident = self.lower_ident(*ident);
let (generics, struct_def) = self.lower_generics(
generics,
id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, struct_def),
);
hir::ItemKind::Struct(struct_def, generics)
hir::ItemKind::Struct(ident, struct_def, generics)
}
ItemKind::Union(vdata, generics) => {
ItemKind::Union(ident, vdata, generics) => {
let ident = self.lower_ident(*ident);
let (generics, vdata) = self.lower_generics(
generics,
id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, vdata),
);
hir::ItemKind::Union(vdata, generics)
hir::ItemKind::Union(ident, vdata, generics)
}
ItemKind::Impl(box Impl {
safety,
@ -375,10 +401,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
(trait_ref, lowered_ty)
});
self.is_in_trait_impl = trait_ref.is_some();
let new_impl_items = self
.arena
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
let new_impl_items = self.arena.alloc_from_iter(
impl_items
.iter()
.map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
);
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function.
@ -400,7 +427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
items: new_impl_items,
}))
}
ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => {
ItemKind::Trait(box Trait { is_auto, safety, ident, generics, bounds, items }) => {
let ident = self.lower_ident(*ident);
let (generics, (safety, items, bounds)) = self.lower_generics(
generics,
id,
@ -417,9 +445,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
(safety, items, bounds)
},
);
hir::ItemKind::Trait(*is_auto, safety, generics, bounds, items)
hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
}
ItemKind::TraitAlias(generics, bounds) => {
ItemKind::TraitAlias(ident, generics, bounds) => {
let ident = self.lower_ident(*ident);
let (generics, bounds) = self.lower_generics(
generics,
id,
@ -431,9 +460,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
},
);
hir::ItemKind::TraitAlias(generics, bounds)
hir::ItemKind::TraitAlias(ident, generics, bounds)
}
ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
let ident = self.lower_ident(*ident);
let body = P(self.lower_delim_args(body));
let def_id = self.local_def_id(id);
let def_kind = self.tcx.def_kind(def_id);
@ -444,11 +474,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
};
let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
hir::ItemKind::Macro(macro_def, macro_kind)
hir::ItemKind::Macro(ident, macro_def, macro_kind)
}
ItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, id);
let delegation_results = self.lower_delegation(delegation, id, false);
hir::ItemKind::Fn {
ident: delegation_results.ident,
sig: delegation_results.sig,
generics: delegation_results.generics,
body: delegation_results.body_id,
@ -479,7 +510,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
prefix: &Path,
id: NodeId,
vis_span: Span,
ident: &mut Ident,
attrs: &'hir [hir::Attribute],
) -> hir::ItemKind<'hir> {
let path = &tree.prefix;
@ -487,7 +517,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
match tree.kind {
UseTreeKind::Simple(rename) => {
*ident = tree.ident();
let mut ident = tree.ident();
// First, apply the prefix to the path.
let mut path = Path { segments, span: path.span, tokens: None };
@ -498,13 +528,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
{
let _ = path.segments.pop();
if rename.is_none() {
*ident = path.segments.last().unwrap().ident;
ident = path.segments.last().unwrap().ident;
}
}
let res = self.lower_import_res(id, path.span);
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
hir::ItemKind::Use(path, hir::UseKind::Single)
let ident = self.lower_ident(ident);
hir::ItemKind::Use(path, hir::UseKind::Single(ident))
}
UseTreeKind::Glob => {
let res = self.expect_full_res(id);
@ -543,7 +574,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Add all the nested `PathListItem`s to the HIR.
for &(ref use_tree, id) in trees {
let new_hir_id = self.local_def_id(id);
let owner_id = self.owner_id(id);
// Each `use` import is an item and thus are owners of the
// names in the path. Up to this point the nested import is
@ -551,20 +582,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
// own its own names, we have to adjust the owner before
// lowering the rest of the import.
self.with_hir_id_owner(id, |this| {
let mut ident = *ident;
// `prefix` is lowered multiple times, but in different HIR owners.
// So each segment gets renewed `HirId` with the same
// `ItemLocalId` and the new owner. (See `lower_node_id`)
let kind =
this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
if !attrs.is_empty() {
this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
}
let item = hir::Item {
owner_id: hir::OwnerId { def_id: new_hir_id },
ident: this.lower_ident(ident),
owner_id,
kind,
vis_span,
span: this.lower_span(use_tree.span),
@ -593,29 +620,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
fn lower_assoc_item(
&mut self,
item: &AssocItem,
ctxt: AssocCtxt,
parent_hir: &'hir hir::OwnerInfo<'hir>,
) -> hir::OwnerNode<'hir> {
let parent_item = parent_hir.node().expect_item();
match parent_item.kind {
hir::ItemKind::Impl(impl_) => {
self.is_in_trait_impl = impl_.of_trait.is_some();
}
hir::ItemKind::Trait(_, _, _, _, _) => {}
kind => {
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
}
}
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
// Evaluate with the lifetimes in `params` in-scope.
// This is used to track which lifetimes have already been defined,
// and which need to be replicated when lowering an async fn.
match ctxt {
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
AssocCtxt::Impl { of_trait } => {
hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
}
}
}
@ -623,47 +636,64 @@ impl<'hir> LoweringContext<'_, 'hir> {
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let owner_id = hir_id.expect_owner();
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let item = hir::ForeignItem {
owner_id,
ident: self.lower_ident(i.ident),
kind: match &i.kind {
ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
let fdec = &sig.decl;
let itctx = ImplTraitContext::Universal;
let (generics, (decl, fn_args)) =
self.lower_generics(generics, i.id, itctx, |this| {
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(
fdec,
i.id,
sig.span,
FnDeclKind::ExternFn,
None,
),
this.lower_fn_params_to_names(fdec),
)
});
let (ident, kind) = match &i.kind {
ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
let fdec = &sig.decl;
let itctx = ImplTraitContext::Universal;
let (generics, (decl, fn_args)) =
self.lower_generics(generics, i.id, itctx, |this| {
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
this.lower_fn_params_to_names(fdec),
)
});
// Unmarked safety in unsafe block defaults to unsafe.
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
// Unmarked safety in unsafe block defaults to unsafe.
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
if define_opaque.is_some() {
self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
}
(
ident,
hir::ForeignItemKind::Fn(
hir::FnSig { header, decl, span: self.lower_span(sig.span) },
fn_args,
generics,
)
}
ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => {
let ty = self
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
),
)
}
ForeignItemKind::Static(box StaticItem {
ident,
ty,
mutability,
expr: _,
safety,
define_opaque,
}) => {
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
hir::ForeignItemKind::Static(ty, *mutability, safety)
// njn: where for this?
if define_opaque.is_some() {
self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
},
(ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
}
ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
(ident, hir::ForeignItemKind::Type)
}
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
};
let item = hir::ForeignItem {
owner_id,
ident: self.lower_ident(*ident),
kind,
vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span),
};
@ -672,8 +702,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
hir::ForeignItemRef {
id: hir::ForeignItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
ident: self.lower_ident(i.ident),
id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
// `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind
// without an identifier and it cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span),
}
}
@ -764,8 +796,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let trait_item_def_id = hir_id.expect_owner();
let (generics, kind, has_default) = match &i.kind {
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => {
let (ident, generics, kind, has_default) = match &i.kind {
AssocItemKind::Const(box ConstItem {
ident,
generics,
ty,
expr,
define_opaque,
..
}) => {
let (generics, kind) = self.lower_generics(
generics,
i.id,
@ -778,9 +817,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::TraitItemKind::Const(ty, body)
},
);
(generics, kind, expr.is_some())
if define_opaque.is_some() {
if expr.is_some() {
self.lower_define_opaque(hir_id, &define_opaque);
} else {
self.dcx().span_err(
i.span,
"only trait consts with default bodies can define opaque types",
);
}
}
(*ident, generics, kind, expr.is_some())
}
AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => {
AssocItemKind::Fn(box Fn {
sig, ident, generics, body: None, define_opaque, ..
}) => {
// FIXME(contracts): Deny contract here since it won't apply to
// any impl method or callees.
let names = self.lower_fn_params_to_names(&sig.decl);
@ -798,10 +851,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
"only trait methods with default bodies can define opaque types",
);
}
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
(
*ident,
generics,
hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)),
false,
)
}
AssocItemKind::Fn(box Fn {
sig,
ident,
generics,
body: Some(body),
contract,
@ -827,9 +886,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
attrs,
);
self.lower_define_opaque(hir_id, &define_opaque);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
(
*ident,
generics,
hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
true,
)
}
AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
AssocItemKind::Type(box TyAlias {
ident, generics, where_clauses, bounds, ty, ..
}) => {
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
let (generics, kind) = self.lower_generics(
@ -852,15 +918,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
},
);
(generics, kind, ty.is_some())
(*ident, generics, kind, ty.is_some())
}
AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id);
let delegation_results = self.lower_delegation(delegation, i.id, false);
let item_kind = hir::TraitItemKind::Fn(
delegation_results.sig,
hir::TraitFn::Provided(delegation_results.body_id),
);
(delegation_results.generics, item_kind, true)
(delegation.ident, delegation_results.generics, item_kind, true)
}
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
@ -869,7 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let item = hir::TraitItem {
owner_id: trait_item_def_id,
ident: self.lower_ident(i.ident),
ident: self.lower_ident(ident),
generics,
kind,
span: self.lower_span(i.span),
@ -879,23 +945,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
let kind = match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::Type(..) => hir::AssocItemKind::Type,
AssocItemKind::Fn(box Fn { sig, .. }) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
let (ident, kind) = match &i.kind {
AssocItemKind::Const(box ConstItem { ident, .. }) => {
(*ident, hir::AssocItemKind::Const)
}
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
},
AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
(*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
}
AssocItemKind::Delegation(box delegation) => (
delegation.ident,
hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
},
),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
};
let id = hir::TraitItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } };
let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
hir::TraitItemRef {
id,
ident: self.lower_ident(i.ident),
ident: self.lower_ident(ident),
span: self.lower_span(i.span),
kind,
}
@ -906,27 +977,49 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr(span, hir::ExprKind::Err(guar))
}
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
fn lower_impl_item(
&mut self,
i: &AssocItem,
is_in_trait_impl: bool,
) -> &'hir hir::ImplItem<'hir> {
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let (generics, kind) = match &i.kind {
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
let (ident, (generics, kind)) = match &i.kind {
AssocItemKind::Const(box ConstItem {
ident,
generics,
i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty =
this.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let body = this.lower_const_body(i.span, expr.as_deref());
hir::ImplItemKind::Const(ty, body)
},
ty,
expr,
define_opaque,
..
}) => (
*ident,
self.lower_generics(
generics,
i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let body = this.lower_const_body(i.span, expr.as_deref());
this.lower_define_opaque(hir_id, &define_opaque);
hir::ImplItemKind::Const(ty, body)
},
),
),
AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => {
AssocItemKind::Fn(box Fn {
sig,
ident,
generics,
body,
contract,
define_opaque,
..
}) => {
let body_id = self.lower_maybe_coroutine_body(
sig.span,
i.span,
@ -941,50 +1034,56 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
sig,
i.id,
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
sig.header.coroutine_kind,
attrs,
);
self.lower_define_opaque(hir_id, &define_opaque);
(generics, hir::ImplItemKind::Fn(sig, body_id))
(*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
}
AssocItemKind::Type(box TyAlias { generics, where_clauses, ty, .. }) => {
AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
self.lower_generics(
&generics,
i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| match ty {
None => {
let guar = this.dcx().span_delayed_bug(
i.span,
"expected to lower associated type, but it was missing",
);
let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
hir::ImplItemKind::Type(ty)
}
Some(ty) => {
let ty = this.lower_ty(
ty,
ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias {
parent: this.local_def_id(i.id),
in_assoc_ty: true,
(
*ident,
self.lower_generics(
&generics,
i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| match ty {
None => {
let guar = this.dcx().span_delayed_bug(
i.span,
"expected to lower associated type, but it was missing",
);
let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
hir::ImplItemKind::Type(ty)
}
Some(ty) => {
let ty = this.lower_ty(
ty,
ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias {
parent: this.local_def_id(i.id),
in_assoc_ty: true,
},
},
},
);
hir::ImplItemKind::Type(ty)
}
},
);
hir::ImplItemKind::Type(ty)
}
},
),
)
}
AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id);
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
(
delegation_results.generics,
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
delegation.ident,
(
delegation_results.generics,
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
),
)
}
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
@ -994,7 +1093,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let item = hir::ImplItem {
owner_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident),
ident: self.lower_ident(ident),
generics,
kind,
vis_span: self.lower_span(i.vis.span),
@ -1004,10 +1103,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(item)
}
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
hir::ImplItemRef {
id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
ident: self.lower_ident(i.ident),
id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
// `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
// assoc item kinds without an identifier and they cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span),
kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const,
@ -1016,7 +1117,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
has_self: self.delegatee_is_method(
i.id,
delegation.id,
i.span,
is_in_trait_impl,
),
},
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
@ -1684,8 +1790,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
return;
};
let define_opaque = define_opaque.iter().filter_map(|(id, path)| {
let res = self.resolver.get_partial_res(*id).unwrap();
let Some(did) = res.expect_full_res().opt_def_id() else {
let res = self.resolver.get_partial_res(*id);
let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else {
self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
return None;
};
@ -1758,7 +1864,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
GenericParamKind::Lifetime => {
let lt_id = self.next_node_id();
let lifetime = self.new_named_lifetime(id, lt_id, ident);
let lifetime = self.new_named_lifetime(id, lt_id, ident, IsAnonInPath::No);
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime,
bounds,

View File

@ -55,7 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
use rustc_hir::{
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, ParamName, TraitCandidate,
self as hir, ConstArg, GenericArg, HirId, IsAnonInPath, ItemLocalMap, LangItem, ParamName,
TraitCandidate,
};
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_macros::extension;
@ -121,7 +122,6 @@ struct LoweringContext<'a, 'hir> {
catch_scope: Option<HirId>,
loop_scope: Option<HirId>,
is_in_loop_condition: bool,
is_in_trait_impl: bool,
is_in_dyn_type: bool,
current_hir_id_owner: hir::OwnerId,
@ -173,7 +173,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
catch_scope: None,
loop_scope: None,
is_in_loop_condition: false,
is_in_trait_impl: false,
is_in_dyn_type: false,
coroutine_kind: None,
task_context: None,
@ -536,6 +535,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
}
/// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.
fn owner_id(&self, node: NodeId) -> hir::OwnerId {
hir::OwnerId { def_id: self.local_def_id(node) }
}
/// Freshen the `LoweringContext` and ready it to lower a nested item.
/// The lowered item is registered into `self.children`.
///
@ -547,7 +551,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
owner: NodeId,
f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
) {
let def_id = self.local_def_id(owner);
let owner_id = self.owner_id(owner);
let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies);
@ -558,8 +562,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
#[cfg(debug_assertions)]
let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
let current_trait_map = std::mem::take(&mut self.trait_map);
let current_owner =
std::mem::replace(&mut self.current_hir_id_owner, hir::OwnerId { def_id });
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);
let current_local_counter =
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
@ -577,7 +580,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
let item = f(self);
debug_assert_eq!(def_id, item.def_id().def_id);
debug_assert_eq!(owner_id, item.def_id());
// `f` should have consumed all the elements in these vectors when constructing `item`.
debug_assert!(self.impl_trait_defs.is_empty());
debug_assert!(self.impl_trait_bounds.is_empty());
@ -598,8 +601,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.impl_trait_defs = current_impl_trait_defs;
self.impl_trait_bounds = current_impl_trait_bounds;
debug_assert!(!self.children.iter().any(|(id, _)| id == &def_id));
self.children.push((def_id, hir::MaybeOwner::Owner(info)));
debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
}
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
@ -621,7 +624,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Don't hash unless necessary, because it's expensive.
let (opt_hash_including_bodies, attrs_hash) =
self.tcx.hash_owner_nodes(node, &bodies, &attrs);
self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);
let num_nodes = self.item_local_id_counter.as_usize();
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
@ -1438,28 +1441,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
// Feature gate for RPITIT + use<..>
match origin {
rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => {
if !self.tcx.features().precise_capturing_in_traits()
&& let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span),
_ => None,
})
{
let mut diag =
self.tcx.dcx().create_err(errors::NoPreciseCapturesOnRpitit { span });
add_feature_diagnostics(
&mut diag,
self.tcx.sess,
sym::precise_capturing_in_traits,
);
diag.emit();
}
}
_ => {}
}
self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
this.lower_param_bounds(bounds, itctx)
})
@ -1513,16 +1494,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}))
}
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
PatKind::Ident(_, ident, _) => self.lower_ident(ident),
PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
PatKind::Ident(_, ident, _) => {
if ident.name != kw::Empty {
Some(self.lower_ident(ident))
} else {
None
}
}
PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
_ => {
self.dcx().span_delayed_bug(
param.pat.span,
"non-ident/wild param pat must trigger an error",
);
Ident::new(kw::Empty, self.lower_span(param.pat.span))
None
}
}))
}
@ -1769,7 +1756,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
self.new_named_lifetime(l.id, l.id, l.ident)
self.new_named_lifetime(l.id, l.id, l.ident, IsAnonInPath::No)
}
fn lower_lifetime_anon_in_path(&mut self, id: NodeId, span: Span) -> &'hir hir::Lifetime {
self.new_named_lifetime(id, id, Ident::new(kw::UnderscoreLifetime, span), IsAnonInPath::Yes)
}
#[instrument(level = "debug", skip(self))]
@ -1778,28 +1769,43 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
id: NodeId,
new_id: NodeId,
ident: Ident,
is_anon_in_path: IsAnonInPath,
) -> &'hir hir::Lifetime {
debug_assert_ne!(ident.name, kw::Empty);
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
let res = match res {
LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param),
LifetimeRes::Fresh { param, .. } => {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
let param = self.local_def_id(param);
hir::LifetimeName::Param(param)
}
LifetimeRes::Infer => hir::LifetimeName::Infer,
LifetimeRes::Static { .. } => hir::LifetimeName::Static,
LifetimeRes::Infer => {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
hir::LifetimeName::Infer
}
LifetimeRes::Static { .. } => {
debug_assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
hir::LifetimeName::Static
}
LifetimeRes::Error => hir::LifetimeName::Error,
LifetimeRes::ElidedAnchor { .. } => {
panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
}
};
#[cfg(debug_assertions)]
if is_anon_in_path == IsAnonInPath::Yes {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
}
debug!(?res);
self.arena.alloc(hir::Lifetime {
hir_id: self.lower_node_id(new_id),
ident: self.lower_ident(ident),
self.arena.alloc(hir::Lifetime::new(
self.lower_node_id(new_id),
self.lower_ident(ident),
res,
})
is_anon_in_path,
))
}
fn lower_generic_params_mut(
@ -2383,11 +2389,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// when the bound is written, even if it is written with `'_` like in
/// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
let r = hir::Lifetime {
hir_id: self.next_id(),
ident: Ident::new(kw::Empty, self.lower_span(span)),
res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
};
let r = hir::Lifetime::new(
self.next_id(),
Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
hir::LifetimeName::ImplicitObjectLifetimeDefault,
IsAnonInPath::No,
);
debug!("elided_dyn_bound: r={:?}", r);
self.arena.alloc(r)
}

View File

@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res};
use rustc_hir::def_id::DefId;
use rustc_middle::span_bug;
use rustc_session::parse::add_feature_diagnostics;
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
use smallvec::{SmallVec, smallvec};
use tracing::{debug, instrument};
@ -450,10 +450,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
0,
(start.as_u32()..end.as_u32()).map(|i| {
let id = NodeId::from_u32(i);
let l = self.lower_lifetime(&Lifetime {
id,
ident: Ident::new(kw::Empty, elided_lifetime_span),
});
let l = self.lower_lifetime_anon_in_path(id, elided_lifetime_span);
GenericArg::Lifetime(l)
}),
);

View File

@ -334,8 +334,8 @@ impl<'a> AstValidator<'a> {
.filter(|attr| {
let arr = [
sym::allow,
sym::cfg,
sym::cfg_attr,
sym::cfg_trace,
sym::cfg_attr_trace,
sym::deny,
sym::expect,
sym::forbid,
@ -607,7 +607,7 @@ impl<'a> AstValidator<'a> {
fn deny_items(&self, trait_items: &[P<AssocItem>], ident: Span) {
if !trait_items.is_empty() {
let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect();
let spans: Vec<_> = trait_items.iter().map(|i| i.kind.ident().unwrap().span).collect();
let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
self.dcx().emit_err(errors::AutoTraitItems { spans, total, ident });
}
@ -817,8 +817,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.has_proc_macro_decls = true;
}
if attr::contains_name(&item.attrs, sym::no_mangle) {
self.check_nomangle_item_asciionly(item.ident, item.span);
if let Some(ident) = item.kind.ident()
&& attr::contains_name(&item.attrs, sym::no_mangle)
{
self.check_nomangle_item_asciionly(ident, item.span);
}
match &item.kind {
@ -852,14 +854,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
this.visit_vis(&item.vis);
this.visit_ident(&item.ident);
let disallowed = matches!(constness, Const::No)
.then(|| TildeConstReason::TraitImpl { span: item.span });
this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
this.visit_trait_ref(t);
this.visit_ty(self_ty);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: true });
});
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
@ -906,20 +907,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
this.visit_vis(&item.vis);
this.visit_ident(&item.ident);
this.with_tilde_const(
Some(TildeConstReason::Impl { span: item.span }),
|this| this.visit_generics(generics),
);
this.visit_ty(self_ty);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: false });
});
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
}
ItemKind::Fn(
func
@ box Fn { defaultness, generics: _, sig, contract: _, body, define_opaque: _ },
func @ box Fn {
defaultness,
ident,
generics: _,
sig,
contract: _,
body,
define_opaque: _,
},
) => {
self.check_defaultness(item.span, *defaultness);
@ -949,8 +956,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
self.visit_vis(&item.vis);
self.visit_ident(&item.ident);
let kind = FnKind::Fn(FnCtxt::Free, &item.ident, &item.vis, &*func);
self.visit_ident(ident);
let kind = FnKind::Fn(FnCtxt::Free, &item.vis, &*func);
self.visit_fn(kind, item.span, item.id);
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
@ -986,7 +993,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
return; // Avoid visiting again.
}
ItemKind::Enum(def, _) => {
ItemKind::Enum(_, def, _) => {
for variant in &def.variants {
self.visibility_not_permitted(
&variant.vis,
@ -1000,22 +1007,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
}
ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
ItemKind::Trait(box Trait { is_auto, generics, ident, bounds, items, .. }) => {
let is_const_trait =
attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span);
self.with_in_trait(item.span, is_const_trait, |this| {
if *is_auto == IsAuto::Yes {
// Auto traits cannot have generics, super traits nor contain items.
this.deny_generic_params(generics, item.ident.span);
this.deny_super_traits(bounds, item.ident.span);
this.deny_where_clause(&generics.where_clause, item.ident.span);
this.deny_items(items, item.ident.span);
this.deny_generic_params(generics, ident.span);
this.deny_super_traits(bounds, ident.span);
this.deny_where_clause(&generics.where_clause, ident.span);
this.deny_items(items, ident.span);
}
// Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
// context for the supertraits.
this.visit_vis(&item.vis);
this.visit_ident(&item.ident);
this.visit_ident(ident);
let disallowed = is_const_trait
.is_none()
.then(|| TildeConstReason::Trait { span: item.span });
@ -1028,7 +1035,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again
}
ItemKind::Mod(safety, mod_kind) => {
ItemKind::Mod(safety, ident, mod_kind) => {
if let &Safety::Unsafe(span) = safety {
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
}
@ -1036,13 +1043,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _))
&& !attr::contains_name(&item.attrs, sym::path)
{
self.check_mod_file_item_asciionly(item.ident);
self.check_mod_file_item_asciionly(*ident);
}
}
ItemKind::Struct(vdata, generics) => match vdata {
ItemKind::Struct(ident, vdata, generics) => match vdata {
VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis);
self.visit_ident(&item.ident);
self.visit_ident(ident);
self.visit_generics(generics);
// Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields);
@ -1051,14 +1058,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
_ => {}
},
ItemKind::Union(vdata, generics) => {
ItemKind::Union(ident, vdata, generics) => {
if vdata.fields().is_empty() {
self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
}
match vdata {
VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis);
self.visit_ident(&item.ident);
self.visit_ident(ident);
self.visit_generics(generics);
// Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields);
@ -1121,14 +1128,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
match &fi.kind {
ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
ForeignItemKind::Fn(box Fn { defaultness, ident, sig, body, .. }) => {
self.check_defaultness(fi.span, *defaultness);
self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
self.check_foreign_fn_bodyless(*ident, body.as_deref());
self.check_foreign_fn_headerless(sig.header);
self.check_foreign_item_ascii_only(fi.ident);
self.check_foreign_item_ascii_only(*ident);
}
ForeignItemKind::TyAlias(box TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
@ -1136,15 +1144,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
..
}) => {
self.check_defaultness(fi.span, *defaultness);
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
self.check_foreign_kind_bodyless(*ident, "type", ty.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
self.check_foreign_ty_genericless(generics, where_clauses);
self.check_foreign_item_ascii_only(fi.ident);
self.check_foreign_item_ascii_only(*ident);
}
ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => {
ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => {
self.check_item_safety(fi.span, *safety);
self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
self.check_foreign_item_ascii_only(fi.ident);
self.check_foreign_kind_bodyless(*ident, "static", expr.as_ref().map(|b| b.span));
self.check_foreign_item_ascii_only(*ident);
}
ForeignItemKind::MacCall(..) => {}
}
@ -1351,7 +1359,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
if let FnKind::Fn(
_,
_,
_,
Fn {
@ -1364,7 +1371,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
// Functions without bodies cannot have patterns.
if let FnKind::Fn(ctxt, _, _, Fn { body: None, sig, .. }) = fk {
if let FnKind::Fn(ctxt, _, Fn { body: None, sig, .. }) = fk {
Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
if let Some(ident) = ident {
@ -1398,22 +1405,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.is_some();
let disallowed = (!tilde_const_allowed).then(|| match fk {
FnKind::Fn(_, ident, _, _) => TildeConstReason::Function { ident: ident.span },
FnKind::Fn(_, _, f) => TildeConstReason::Function { ident: f.ident.span },
FnKind::Closure(..) => TildeConstReason::Closure,
});
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
}
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
if attr::contains_name(&item.attrs, sym::no_mangle) {
self.check_nomangle_item_asciionly(item.ident, item.span);
if let Some(ident) = item.kind.ident()
&& attr::contains_name(&item.attrs, sym::no_mangle)
{
self.check_nomangle_item_asciionly(ident, item.span);
}
if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
self.check_defaultness(item.span, item.kind.defaultness());
}
if ctxt == AssocCtxt::Impl {
if let AssocCtxt::Impl { .. } = ctxt {
match &item.kind {
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
self.dcx().emit_err(errors::AssocConstWithoutBody {
@ -1466,8 +1475,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
if let AssocItemKind::Const(..) = item.kind {
self.check_item_named(item.ident, "const");
if let AssocItemKind::Const(ci) = &item.kind {
self.check_item_named(ci.ident, "const");
}
let parent_is_const =
@ -1480,8 +1489,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|| matches!(func.sig.header.constness, Const::Yes(_)) =>
{
self.visit_vis(&item.vis);
self.visit_ident(&item.ident);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, &item.vis, &*func);
self.visit_ident(&func.ident);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func);
walk_list!(self, visit_attribute, &item.attrs);
self.visit_fn(kind, item.span, item.id);
}

View File

@ -99,6 +99,13 @@ impl<'a> PostExpansionVisitor<'a> {
}
visit::walk_ty(self, ty);
}
fn visit_anon_const(&mut self, _: &ast::AnonConst) -> Self::Result {
// We don't walk the anon const because it crosses a conceptual boundary: We're no
// longer "inside" the original type.
// Brittle: We assume that the callers of `check_impl_trait` will later recurse into
// the items found in the AnonConst to look for nested TyAliases.
}
}
ImplTraitVisitor { vis: self, in_associated_ty }.visit_ty(ty);
}
@ -229,7 +236,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate!(&self, trait_alias, i.span, "trait aliases are experimental");
}
ast::ItemKind::MacroDef(ast::MacroDef { macro_rules: false, .. }) => {
ast::ItemKind::MacroDef(_, ast::MacroDef { macro_rules: false, .. }) => {
let msg = "`macro` is experimental";
gate!(&self, decl_macro, i.span, msg);
}
@ -483,7 +490,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
half_open_range_patterns_in_slices,
"half-open range patterns in slices are unstable"
);
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
gate_all!(associated_const_equality, "associated const equality is incomplete");
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(dyn_star, "`dyn*` trait objects are experimental");

View File

@ -7,8 +7,11 @@ edition = "2024"
# tidy-alphabetical-start
itertools = "0.12"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_span = { path = "../rustc_span" }
# tidy-alphabetical-end
[dev-dependencies]
# tidy-alphabetical-start
thin-vec = "0.2.12"
# tidy-alphabetical-end

View File

@ -578,11 +578,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
let mut printed = false;
for attr in attrs {
if attr.style == kind {
self.print_attribute_inline(attr, is_inline);
if is_inline {
self.nbsp();
if self.print_attribute_inline(attr, is_inline) {
if is_inline {
self.nbsp();
}
printed = true;
}
printed = true;
}
}
if printed && trailing_hardbreak && !is_inline {
@ -591,7 +592,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
printed
}
fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) {
fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool {
if attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace) {
// It's not a valid identifier, so avoid printing it
// to keep the printed code reasonably parse-able.
return false;
}
if !is_inline {
self.hardbreak_if_not_bol();
}
@ -610,6 +616,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
self.hardbreak()
}
}
true
}
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
@ -2047,7 +2054,7 @@ impl<'a> State<'a> {
}
fn print_attribute(&mut self, attr: &ast::Attribute) {
self.print_attribute_inline(attr, false)
self.print_attribute_inline(attr, false);
}
fn print_meta_list_item(&mut self, item: &ast::MetaItemInner) {

View File

@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
use rustc_ast::{
self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount,
FormatDebugHex, FormatSign, FormatTrait, token,
FormatDebugHex, FormatSign, FormatTrait, YieldKind, token,
};
use crate::pp::Breaks::Inconsistent;
@ -761,7 +761,7 @@ impl<'a> State<'a> {
self.print_expr(e, FixupContext::default());
self.pclose();
}
ast::ExprKind::Yield(e) => {
ast::ExprKind::Yield(YieldKind::Prefix(e)) => {
self.word("yield");
if let Some(expr) = e {
@ -773,6 +773,14 @@ impl<'a> State<'a> {
);
}
}
ast::ExprKind::Yield(YieldKind::Postfix(e)) => {
self.print_expr_cond_paren(
e,
e.precedence() < ExprPrecedence::Unambiguous,
fixup.leftmost_subexpression_with_dot(),
);
self.word(".yield");
}
ast::ExprKind::Try(e) => {
self.print_expr_cond_paren(
e,

View File

@ -28,36 +28,43 @@ impl<'a> State<'a> {
}
fn print_foreign_item(&mut self, item: &ast::ForeignItem) {
let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item;
let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
self.ann.pre(self, AnnNode::SubItem(id));
self.hardbreak_if_not_bol();
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
ast::ForeignItemKind::Fn(func) => {
self.print_fn_full(ident, vis, attrs, &*func);
}
ast::ForeignItemKind::Static(box ast::StaticItem { ty, mutability, expr, safety }) => {
self.print_item_const(
ident,
Some(*mutability),
&ast::Generics::default(),
ty,
expr.as_deref(),
vis,
*safety,
ast::Defaultness::Final,
)
self.print_fn_full(vis, attrs, &*func);
}
ast::ForeignItemKind::Static(box ast::StaticItem {
ident,
ty,
mutability,
expr,
safety,
define_opaque,
}) => self.print_item_const(
*ident,
Some(*mutability),
&ast::Generics::default(),
ty,
expr.as_deref(),
vis,
*safety,
ast::Defaultness::Final,
define_opaque.as_deref(),
),
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
self.print_associated_type(
ident,
*ident,
generics,
*where_clauses,
bounds,
@ -86,7 +93,9 @@ impl<'a> State<'a> {
vis: &ast::Visibility,
safety: ast::Safety,
defaultness: ast::Defaultness,
define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
) {
self.print_define_opaques(define_opaque);
self.head("");
self.print_visibility(vis);
self.print_safety(safety);
@ -155,7 +164,7 @@ impl<'a> State<'a> {
self.print_outer_attributes(&item.attrs);
self.ann.pre(self, AnnNode::Item(item));
match &item.kind {
ast::ItemKind::ExternCrate(orig_name) => {
ast::ItemKind::ExternCrate(orig_name, ident) => {
self.head(visibility_qualified(&item.vis, "extern crate"));
if let &Some(orig_name) = orig_name {
self.print_name(orig_name);
@ -163,7 +172,7 @@ impl<'a> State<'a> {
self.word("as");
self.space();
}
self.print_ident(item.ident);
self.print_ident(*ident);
self.word(";");
self.end(); // end inner head-block
self.end(); // end outer head-block
@ -174,10 +183,17 @@ impl<'a> State<'a> {
self.print_use_tree(tree);
self.word(";");
}
ast::ItemKind::Static(box StaticItem { ty, safety, mutability: mutbl, expr: body }) => {
ast::ItemKind::Static(box StaticItem {
ident,
ty,
safety,
mutability: mutbl,
expr: body,
define_opaque,
}) => {
self.print_safety(*safety);
self.print_item_const(
item.ident,
*ident,
Some(*mutbl),
&ast::Generics::default(),
ty,
@ -185,11 +201,19 @@ impl<'a> State<'a> {
&item.vis,
ast::Safety::Default,
ast::Defaultness::Final,
define_opaque.as_deref(),
);
}
ast::ItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
ast::ItemKind::Const(box ast::ConstItem {
defaultness,
ident,
generics,
ty,
expr,
define_opaque,
}) => {
self.print_item_const(
item.ident,
*ident,
None,
generics,
ty,
@ -197,18 +221,19 @@ impl<'a> State<'a> {
&item.vis,
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
);
}
ast::ItemKind::Fn(func) => {
self.print_fn_full(item.ident, &item.vis, &item.attrs, &*func);
self.print_fn_full(&item.vis, &item.attrs, &*func);
}
ast::ItemKind::Mod(safety, mod_kind) => {
ast::ItemKind::Mod(safety, ident, mod_kind) => {
self.head(Self::to_string(|s| {
s.print_visibility(&item.vis);
s.print_safety(*safety);
s.word("mod");
}));
self.print_ident(item.ident);
self.print_ident(*ident);
match mod_kind {
ModKind::Loaded(items, ..) => {
@ -252,13 +277,14 @@ impl<'a> State<'a> {
}
ast::ItemKind::TyAlias(box ast::TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
self.print_associated_type(
item.ident,
*ident,
generics,
*where_clauses,
bounds,
@ -267,16 +293,16 @@ impl<'a> State<'a> {
*defaultness,
);
}
ast::ItemKind::Enum(enum_definition, params) => {
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
ast::ItemKind::Enum(ident, enum_definition, params) => {
self.print_enum_def(enum_definition, params, *ident, item.span, &item.vis);
}
ast::ItemKind::Struct(struct_def, generics) => {
ast::ItemKind::Struct(ident, struct_def, generics) => {
self.head(visibility_qualified(&item.vis, "struct"));
self.print_struct(struct_def, generics, item.ident, item.span, true);
self.print_struct(struct_def, generics, *ident, item.span, true);
}
ast::ItemKind::Union(struct_def, generics) => {
ast::ItemKind::Union(ident, struct_def, generics) => {
self.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident, item.span, true);
self.print_struct(struct_def, generics, *ident, item.span, true);
}
ast::ItemKind::Impl(box ast::Impl {
safety,
@ -326,19 +352,19 @@ impl<'a> State<'a> {
self.bclose(item.span, empty);
}
ast::ItemKind::Trait(box ast::Trait {
is_auto,
safety,
is_auto,
ident,
generics,
bounds,
items,
..
}) => {
self.head("");
self.print_visibility(&item.vis);
self.print_safety(*safety);
self.print_is_auto(*is_auto);
self.word_nbsp("trait");
self.print_ident(item.ident);
self.print_ident(*ident);
self.print_generic_params(&generics.params);
if !bounds.is_empty() {
self.word_nbsp(":");
@ -354,9 +380,9 @@ impl<'a> State<'a> {
let empty = item.attrs.is_empty() && items.is_empty();
self.bclose(item.span, empty);
}
ast::ItemKind::TraitAlias(generics, bounds) => {
ast::ItemKind::TraitAlias(ident, generics, bounds) => {
self.head(visibility_qualified(&item.vis, "trait"));
self.print_ident(item.ident);
self.print_ident(*ident);
self.print_generic_params(&generics.params);
self.nbsp();
if !bounds.is_empty() {
@ -374,8 +400,8 @@ impl<'a> State<'a> {
self.word(";");
}
}
ast::ItemKind::MacroDef(macro_def) => {
self.print_mac_def(macro_def, &item.ident, item.span, |state| {
ast::ItemKind::MacroDef(ident, macro_def) => {
self.print_mac_def(macro_def, &ident, item.span, |state| {
state.print_visibility(&item.vis)
});
}
@ -528,18 +554,25 @@ impl<'a> State<'a> {
}
fn print_assoc_item(&mut self, item: &ast::AssocItem) {
let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item;
let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
self.ann.pre(self, AnnNode::SubItem(id));
self.hardbreak_if_not_bol();
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
ast::AssocItemKind::Fn(func) => {
self.print_fn_full(ident, vis, attrs, &*func);
self.print_fn_full(vis, attrs, &*func);
}
ast::AssocItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
ast::AssocItemKind::Const(box ast::ConstItem {
defaultness,
ident,
generics,
ty,
expr,
define_opaque,
}) => {
self.print_item_const(
ident,
*ident,
None,
generics,
ty,
@ -547,17 +580,19 @@ impl<'a> State<'a> {
vis,
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
);
}
ast::AssocItemKind::Type(box ast::TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
self.print_associated_type(
ident,
*ident,
generics,
*where_clauses,
bounds,
@ -643,29 +678,17 @@ impl<'a> State<'a> {
}
}
fn print_fn_full(
&mut self,
name: Ident,
vis: &ast::Visibility,
attrs: &[ast::Attribute],
func: &ast::Fn,
) {
let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func;
fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque } = func;
if let Some(define_opaque) = define_opaque {
for (_, path) in define_opaque {
self.word("define opaques from ");
self.print_path(path, false, 0);
self.word(",");
}
}
self.print_define_opaques(define_opaque.as_deref());
if body.is_some() {
self.head("");
}
self.print_visibility(vis);
self.print_defaultness(*defaultness);
self.print_fn(&sig.decl, sig.header, Some(name), generics);
self.print_fn(&sig.decl, sig.header, Some(*ident), generics);
if let Some(contract) = &contract {
self.nbsp();
self.print_contract(contract);
@ -678,6 +701,21 @@ impl<'a> State<'a> {
}
}
fn print_define_opaques(&mut self, define_opaque: Option<&[(ast::NodeId, ast::Path)]>) {
if let Some(define_opaque) = define_opaque {
self.word("#[define_opaque(");
for (i, (_, path)) in define_opaque.iter().enumerate() {
if i != 0 {
self.word_space(",");
}
self.print_path(path, false, 0);
}
self.word(")]");
}
self.hardbreak_if_not_bol();
}
fn print_contract(&mut self, contract: &ast::FnContract) {
if let Some(pred) = &contract.requires {
self.word("rustc_requires");
@ -697,13 +735,13 @@ impl<'a> State<'a> {
&mut self,
decl: &ast::FnDecl,
header: ast::FnHeader,
name: Option<Ident>,
ident: Option<Ident>,
generics: &ast::Generics,
) {
self.print_fn_header_info(header);
if let Some(name) = name {
if let Some(ident) = ident {
self.nbsp();
self.print_ident(name);
self.print_ident(ident);
}
self.print_generic_params(&generics.params);
self.print_fn_params_and_ret(decl, false);

View File

@ -191,6 +191,7 @@ pub enum AttributeKind {
},
MacroTransparency(Transparency),
Repr(ThinVec<(ReprAttr, Span)>),
RustcMacroEdition2021,
Stability {
stability: Stability,
/// Span of the `#[stable(...)]` or `#[unstable(...)]` attribute

View File

@ -182,21 +182,18 @@ macro_rules! find_attr {
}};
($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator<Item = &'a rustc_hir::Attribute>) {}
check_attribute_iterator(&$attributes_list);
let find_attribute = |iter| {
'done: {
for i in $attributes_list {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
return Some($e);
break 'done Some($e);
}
_ => {}
}
}
None
};
find_attribute($attributes_list)
}
}};
}

View File

@ -9,15 +9,12 @@ rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
thin-vec = "0.2.12"

View File

@ -28,6 +28,7 @@ pub(crate) mod cfg;
pub(crate) mod confusables;
pub(crate) mod deprecation;
pub(crate) mod repr;
pub(crate) mod rustc;
pub(crate) mod stability;
pub(crate) mod transparency;
pub(crate) mod util;

View File

@ -0,0 +1,19 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_span::sym;
use super::{AcceptContext, SingleAttributeParser};
use crate::parser::ArgParser;
pub(crate) struct RustcMacroEdition2021Parser;
// FIXME(jdonszelmann): make these proper diagnostics
impl SingleAttributeParser for RustcMacroEdition2021Parser {
const PATH: &'static [rustc_span::Symbol] = &[sym::rustc_macro_edition_2021];
fn on_duplicate(_cx: &crate::context::AcceptContext<'_>, _first_span: rustc_span::Span) {}
fn convert(_cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
assert!(args.no_args());
Some(AttributeKind::RustcMacroEdition2021)
}
}

View File

@ -5,7 +5,7 @@ use rustc_attr_data_structures::{
StableSince, UnstableReason, VERSION_PLACEHOLDER,
};
use rustc_errors::ErrorGuaranteed;
use rustc_span::{Span, Symbol, kw, sym};
use rustc_span::{Span, Symbol, sym};
use super::util::parse_version;
use super::{AcceptMapping, AttributeParser, SingleAttributeParser};
@ -61,11 +61,7 @@ impl AttributeParser for StabilityParser {
}),
(&[sym::rustc_allowed_through_unstable_modules], |this, cx, args| {
reject_outside_std!(cx);
this.allowed_through_unstable_modules =
Some(match args.name_value().and_then(|i| i.value_as_str()) {
Some(msg) => msg,
None => kw::Empty,
});
this.allowed_through_unstable_modules = args.name_value().and_then(|i| i.value_as_str())
}),
];

View File

@ -15,6 +15,7 @@ use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInterna
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::repr::ReprParser;
use crate::attributes::rustc::RustcMacroEdition2021Parser;
use crate::attributes::stability::{
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
@ -76,6 +77,7 @@ attribute_groups!(
// tidy-alphabetical-start
Single<ConstStabilityIndirectParser>,
Single<DeprecationParser>,
Single<RustcMacroEdition2021Parser>,
Single<TransparencyParser>,
// tidy-alphabetical-end
];

View File

@ -1,7 +1,7 @@
//! This file provides API for compiler consumers.
use rustc_hir::def_id::LocalDefId;
use rustc_index::{IndexSlice, IndexVec};
use rustc_index::IndexVec;
use rustc_middle::mir::{Body, Promoted};
use rustc_middle::ty::TyCtxt;
@ -100,8 +100,5 @@ pub fn get_body_with_borrowck_facts(
def: LocalDefId,
options: ConsumerOptions,
) -> BodyWithBorrowckFacts<'_> {
let (input_body, promoted) = tcx.mir_promoted(def);
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexSlice<_, _> = &promoted.borrow();
*super::do_mir_borrowck(tcx, input_body, promoted, Some(options)).1.unwrap()
*super::do_mir_borrowck(tcx, def, Some(options)).1.unwrap()
}

View File

@ -2514,12 +2514,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let ty::Tuple(params) = tupled_params.kind() else { return };
// Find the first argument with a matching type, get its name
let Some((_, this_name)) =
params.iter().zip(tcx.hir_body_param_names(closure.body)).find(|(param_ty, name)| {
let Some(this_name) = params.iter().zip(tcx.hir_body_param_names(closure.body)).find_map(
|(param_ty, name)| {
// FIXME: also support deref for stuff like `Rc` arguments
param_ty.peel_refs() == local_ty && name != &Ident::empty()
})
else {
if param_ty.peel_refs() == local_ty { name } else { None }
},
) else {
return;
};
@ -3787,7 +3787,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
method_args,
*fn_span,
call_source.from_hir_call(),
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
self.infcx.tcx.fn_arg_names(method_did)[0],
)
{
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));

View File

@ -1029,7 +1029,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
method_args,
*fn_span,
call_source.from_hir_call(),
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
self.infcx.tcx.fn_arg_names(method_did)[0],
);
return FnSelfUse {

View File

@ -691,7 +691,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
true,
td.is_local(),
td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) {
Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. }) => {
Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, _, _, items), ..
}) => {
let mut f_in_trait_opt = None;
for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
let hi = fi.hir_id();
@ -980,7 +982,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let arg = match tcx.hir_get_if_local(callee_def_id) {
Some(
hir::Node::Item(hir::Item {
ident, kind: hir::ItemKind::Fn { sig, .. }, ..
kind: hir::ItemKind::Fn { ident, sig, .. }, ..
})
| hir::Node::TraitItem(hir::TraitItem {
ident,
@ -1021,7 +1023,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// return type.
match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) {
hir::Node::Item(hir::Item {
ident, kind: hir::ItemKind::Fn { sig, .. }, ..
kind: hir::ItemKind::Fn { ident, sig, .. }, ..
})
| hir::Node::TraitItem(hir::TraitItem {
ident,

View File

@ -513,14 +513,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
ty::VarianceDiagInfo::Invariant { ty, param_index } => {
let (desc, note) = match ty.kind() {
ty::RawPtr(ty, mutbl) => {
assert_eq!(*mutbl, rustc_hir::Mutability::Mut);
assert_eq!(*mutbl, hir::Mutability::Mut);
(
format!("a mutable pointer to `{}`", ty),
"mutable pointers are invariant over their type parameter".to_string(),
)
}
ty::Ref(_, inner_ty, mutbl) => {
assert_eq!(*mutbl, rustc_hir::Mutability::Mut);
assert_eq!(*mutbl, hir::Mutability::Mut);
(
format!("a mutable reference to `{inner_ty}`"),
"mutable references are invariant over their type parameter"
@ -887,7 +887,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Skip `async` desugaring `impl Future`.
}
if let TyKind::TraitObject(_, lt) = alias_ty.kind {
if lt.ident.name == kw::Empty {
if lt.res == hir::LifetimeName::ImplicitObjectLifetimeDefault {
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
} else {
spans_suggs.push((lt.ident.span, "'a".to_string()));

View File

@ -73,6 +73,7 @@ mod def_use;
mod diagnostics;
mod member_constraints;
mod nll;
mod opaque_types;
mod path_utils;
mod place_ext;
mod places_conflict;
@ -102,11 +103,8 @@ pub fn provide(providers: &mut Providers) {
}
fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
let (input_body, _) = tcx.mir_promoted(def);
let input_body: &Body<'_> = &input_body.borrow();
if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
debug!("Skipping borrowck because of injected body or tainted body");
// Let's make up a borrowck result! Fun times!
@ -119,7 +117,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
return tcx.arena.alloc(result);
}
let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0;
let borrowck_result = do_mir_borrowck(tcx, def, None).0;
debug!("mir_borrowck done");
tcx.arena.alloc(borrowck_result)
@ -130,15 +128,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
/// Use `consumer_options: None` for the default behavior of returning
/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
/// to the given [`ConsumerOptions`].
#[instrument(skip(tcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
#[instrument(skip(tcx), level = "debug")]
fn do_mir_borrowck<'tcx>(
tcx: TyCtxt<'tcx>,
input_body: &Body<'tcx>,
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
def: LocalDefId,
consumer_options: Option<ConsumerOptions>,
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
let def = input_body.source.def_id().expect_local();
let infcx = BorrowckInferCtxt::new(tcx, def);
let (input_body, promoted) = tcx.mir_promoted(def);
let input_body: &Body<'_> = &input_body.borrow();
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
if let Some(e) = input_body.tainted_by_errors {
infcx.set_tainted_by_errors(e);
}
@ -192,7 +191,7 @@ fn do_mir_borrowck<'tcx>(
// Compute non-lexical lifetimes.
let nll::NllOutput {
regioncx,
opaque_type_values,
concrete_opaque_types,
polonius_input,
polonius_output,
opt_closure_req,
@ -222,7 +221,7 @@ fn do_mir_borrowck<'tcx>(
body,
&regioncx,
&opt_closure_req,
&opaque_type_values,
&concrete_opaque_types,
diags_buffer,
);
@ -357,7 +356,7 @@ fn do_mir_borrowck<'tcx>(
let tainted_by_errors = mbcx.emit_errors();
let result = BorrowCheckResult {
concrete_opaque_types: opaque_type_values,
concrete_opaque_types: concrete_opaque_types.into_inner(),
closure_requirements: opt_closure_req,
used_mut_upvars: mbcx.used_mut_upvars,
tainted_by_errors,
@ -498,7 +497,8 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
)
});
self.inject_new_hidden_type_unchecked(key, hidden_ty);
let prev = self.register_hidden_type_in_storage(key, hidden_ty);
assert_eq!(prev, None);
}
}
}

View File

@ -1,13 +1,11 @@
//! The entry point of the NLL borrow checker.
use std::io;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use std::{env, io};
use polonius_engine::{Algorithm, Output};
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::LocalDefId;
use rustc_index::IndexSlice;
use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options};
use rustc_middle::mir::{
@ -15,7 +13,7 @@ use rustc_middle::mir::{
dump_enabled, dump_mir,
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_mir_dataflow::ResultsCursor;
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::MoveData;
@ -27,6 +25,7 @@ use tracing::{debug, instrument};
use crate::borrow_set::BorrowSet;
use crate::consumers::ConsumerOptions;
use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors};
use crate::opaque_types::ConcreteOpaqueTypes;
use crate::polonius::PoloniusDiagnosticsContext;
use crate::polonius::legacy::{
PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
@ -40,7 +39,7 @@ use crate::{BorrowckInferCtxt, polonius, renumber};
/// closure requirements to propagate, and any generated errors.
pub(crate) struct NllOutput<'tcx> {
pub regioncx: RegionInferenceContext<'tcx>,
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
pub polonius_input: Option<Box<PoloniusFacts>>,
pub polonius_output: Option<Box<PoloniusOutput>>,
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@ -99,6 +98,8 @@ pub(crate) fn compute_regions<'a, 'tcx>(
let location_map = Rc::new(DenseLocationMap::new(body));
let mut concrete_opaque_types = ConcreteOpaqueTypes::default();
// Run the MIR type-checker.
let MirTypeckResults {
constraints,
@ -116,6 +117,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
flow_inits,
move_data,
Rc::clone(&location_map),
&mut concrete_opaque_types,
);
// Create the region inference context, taking ownership of the
@ -160,9 +162,8 @@ pub(crate) fn compute_regions<'a, 'tcx>(
}
if polonius_output {
let algorithm =
env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Hybrid"));
let algorithm = Algorithm::from_str(&algorithm).unwrap();
let algorithm = infcx.tcx.env_var("POLONIUS_ALGORITHM").unwrap_or("Hybrid");
let algorithm = Algorithm::from_str(algorithm).unwrap();
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis");
Some(Box::new(Output::compute(polonius_facts, algorithm, false)))
@ -180,11 +181,11 @@ pub(crate) fn compute_regions<'a, 'tcx>(
infcx.set_tainted_by_errors(guar);
}
let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values);
regioncx.infer_opaque_types(infcx, opaque_type_values, &mut concrete_opaque_types);
NllOutput {
regioncx,
opaque_type_values: remapped_opaque_tys,
concrete_opaque_types,
polonius_input: polonius_facts.map(Box::new),
polonius_output,
opt_closure_req: closure_region_requirements,
@ -300,7 +301,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>,
diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
) {
let tcx = infcx.tcx;
@ -343,8 +344,8 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
err
};
if !opaque_type_values.is_empty() {
err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}"));
if !concrete_opaque_types.is_empty() {
err.note(format!("Inferred opaque type values:\n{concrete_opaque_types:#?}"));
}
diagnostics_buffer.buffer_non_error(err);

View File

@ -0,0 +1,55 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{OpaqueHiddenType, Ty, TyCtxt};
#[derive(Debug, Default)]
pub(super) struct ConcreteOpaqueTypes<'tcx> {
concrete_opaque_types: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
}
impl<'tcx> ConcreteOpaqueTypes<'tcx> {
pub(super) fn is_empty(&self) -> bool {
self.concrete_opaque_types.is_empty()
}
pub(super) fn into_inner(self) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
self.concrete_opaque_types
}
/// Insert an opaque type into the list of opaque types defined by this function
/// after mapping the hidden type to the generic parameters of the opaque type
/// definition.
pub(super) fn insert(
&mut self,
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
hidden_ty: OpaqueHiddenType<'tcx>,
) {
// Sometimes two opaque types are the same only after we remap the generic parameters
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
// `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
// only know that once we convert the generic parameters to those of the opaque type.
if let Some(prev) = self.concrete_opaque_types.get_mut(&def_id) {
if prev.ty != hidden_ty.ty {
let (Ok(guar) | Err(guar)) =
prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
prev.ty = Ty::new_error(tcx, guar);
}
// Pick a better span if there is one.
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
prev.span = prev.span.substitute_dummy(hidden_ty.span);
} else {
self.concrete_opaque_types.insert(def_id, hidden_ty);
}
}
pub(super) fn extend_from_nested_body(
&mut self,
tcx: TyCtxt<'tcx>,
nested_body: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
) {
for (&def_id, &hidden_ty) in nested_body {
self.insert(tcx, def_id, hidden_ty);
}
}
}

View File

@ -15,6 +15,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
use tracing::{debug, instrument};
use super::RegionInferenceContext;
use crate::opaque_types::ConcreteOpaqueTypes;
use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam};
use crate::universal_regions::RegionClassification;
@ -67,8 +68,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&self,
infcx: &InferCtxt<'tcx>,
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
) {
let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
FxIndexMap::default();
@ -143,33 +144,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
continue;
}
}
// Sometimes two opaque types are the same only after we remap the generic parameters
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
// `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
// only know that once we convert the generic parameters to those of the opaque type.
if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
if prev.ty != ty {
let guar = ty.error_reported().err().unwrap_or_else(|| {
let (Ok(e) | Err(e)) = prev
.build_mismatch_error(
&OpaqueHiddenType { ty, span: concrete_type.span },
infcx.tcx,
)
.map(|d| d.emit());
e
});
prev.ty = Ty::new_error(infcx.tcx, guar);
}
// Pick a better span if there is one.
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
prev.span = prev.span.substitute_dummy(concrete_type.span);
} else {
result.insert(
opaque_type_key.def_id,
OpaqueHiddenType { ty, span: concrete_type.span },
);
}
concrete_opaque_types.insert(
infcx.tcx,
opaque_type_key.def_id,
OpaqueHiddenType { ty, span: concrete_type.span },
);
// Check that all opaque types have the same region parameters if they have the same
// non-region parameters. This is necessary because within the new solver we perform
// various query operations modulo regions, and thus could unsoundly select some impls
@ -193,7 +173,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
});
}
}
result
}
/// Map the regions in the type to named regions. This is similar to what

View File

@ -45,6 +45,7 @@ use crate::borrow_set::BorrowSet;
use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet};
use crate::diagnostics::UniverseInfo;
use crate::member_constraints::MemberConstraintSet;
use crate::opaque_types::ConcreteOpaqueTypes;
use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable};
use crate::polonius::{PoloniusContext, PoloniusLivenessContext};
use crate::region_infer::TypeTest;
@ -111,6 +112,7 @@ pub(crate) fn type_check<'a, 'tcx>(
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>,
location_map: Rc<DenseLocationMap>,
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
) -> MirTypeckResults<'tcx> {
let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
let mut constraints = MirTypeckRegionConstraints {
@ -165,6 +167,7 @@ pub(crate) fn type_check<'a, 'tcx>(
polonius_facts,
borrow_set,
constraints: &mut constraints,
concrete_opaque_types,
polonius_liveness,
};
@ -230,6 +233,7 @@ struct TypeChecker<'a, 'tcx> {
polonius_facts: &'a mut Option<PoloniusFacts>,
borrow_set: &'a BorrowSet<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
concrete_opaque_types: &'a mut ConcreteOpaqueTypes<'tcx>,
/// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints.
polonius_liveness: Option<PoloniusLivenessContext>,
}
@ -2499,7 +2503,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
args: GenericArgsRef<'tcx>,
locations: Locations,
) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
let closure_borrowck_results = tcx.mir_borrowck(def_id);
self.concrete_opaque_types
.extend_from_nested_body(tcx, &closure_borrowck_results.concrete_opaque_types);
if let Some(closure_requirements) = &closure_borrowck_results.closure_requirements {
constraint_conversion::ConstraintConversion::new(
self.infcx,
self.universal_regions,

View File

@ -21,15 +21,15 @@ pub(crate) fn expand(
// Allow using `#[alloc_error_handler]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, sig_span) = if let Annotatable::Item(item) = &item
let (item, ident, is_stmt, sig_span) = if let Annotatable::Item(item) = &item
&& let ItemKind::Fn(fn_kind) = &item.kind
{
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
(item, fn_kind.ident, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else if let Annotatable::Stmt(stmt) = &item
&& let StmtKind::Item(item) = &stmt.kind
&& let ItemKind::Fn(fn_kind) = &item.kind
{
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
(item, fn_kind.ident, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else {
ecx.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
return vec![orig_item];
@ -39,7 +39,7 @@ pub(crate) fn expand(
let span = ecx.with_def_site_ctxt(item.span);
// Generate item statements for the allocator methods.
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
let stmts = thin_vec![generate_handler(ecx, ident, span, sig_span)];
// Generate anonymous constant serving as container for the allocator methods.
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
@ -85,6 +85,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
let kind = ItemKind::Fn(Box::new(Fn {
defaultness: ast::Defaultness::Final,
sig,
ident: Ident::from_str_and_span("__rg_oom", span),
generics: Generics::default(),
contract: None,
body,
@ -93,6 +94,6 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind);
let item = cx.item(span, attrs, kind);
cx.stmt_item(sig_span, item)
}

View File

@ -10,7 +10,7 @@ use rustc_index::bit_set::GrowableBitSet;
use rustc_parse::exp;
use rustc_parse::parser::{ExpKeywordPair, Parser};
use rustc_session::lint;
use rustc_span::{ErrorGuaranteed, Ident, InnerSpan, Span, Symbol, kw};
use rustc_span::{ErrorGuaranteed, InnerSpan, Span, Symbol, kw};
use rustc_target::asm::InlineAsmArch;
use smallvec::smallvec;
use {rustc_ast as ast, rustc_parse_format as parse};
@ -888,7 +888,6 @@ pub(super) fn expand_global_asm<'cx>(
};
match mac {
Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
ident: Ident::empty(),
attrs: ast::AttrVec::new(),
id: ast::DUMMY_NODE_ID,
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),

View File

@ -112,7 +112,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
self.span,
self.cx.item(
self.span,
Ident::empty(),
thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)],
ItemKind::Use(UseTree {
prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),

View File

@ -26,6 +26,16 @@ mod llvm_enzyme {
use crate::errors;
pub(crate) fn outer_normal_attr(
kind: &P<rustc_ast::NormalAttr>,
id: rustc_ast::AttrId,
span: Span,
) -> rustc_ast::Attribute {
let style = rustc_ast::AttrStyle::Outer;
let kind = rustc_ast::AttrKind::Normal(kind.clone());
rustc_ast::Attribute { kind, id, style, span }
}
// If we have a default `()` return type or explicitley `()` return type,
// then we often can skip doing some work.
fn has_ret(ty: &FnRetTy) -> bool {
@ -136,26 +146,26 @@ mod llvm_enzyme {
}
let dcx = ecx.sess.dcx();
// first get the annotable item:
let (sig, is_impl): (FnSig, bool) = match &item {
let (primal, sig, is_impl): (Ident, FnSig, bool) = match &item {
Annotatable::Item(iitem) => {
let sig = match &iitem.kind {
ItemKind::Fn(box ast::Fn { sig, .. }) => sig,
let (ident, sig) = match &iitem.kind {
ItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
_ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item];
}
};
(sig.clone(), false)
(*ident, sig.clone(), false)
}
Annotatable::AssocItem(assoc_item, _) => {
let sig = match &assoc_item.kind {
ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
let (ident, sig) = match &assoc_item.kind {
ast::AssocItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
_ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item];
}
};
(sig.clone(), true)
(*ident, sig.clone(), true)
}
_ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
@ -174,11 +184,9 @@ mod llvm_enzyme {
let has_ret = has_ret(&sig.decl.output);
let sig_span = ecx.with_call_site_ctxt(sig.span);
let (vis, primal) = match &item {
Annotatable::Item(iitem) => (iitem.vis.clone(), iitem.ident.clone()),
Annotatable::AssocItem(assoc_item, _) => {
(assoc_item.vis.clone(), assoc_item.ident.clone())
}
let vis = match &item {
Annotatable::Item(iitem) => iitem.vis.clone(),
Annotatable::AssocItem(assoc_item, _) => assoc_item.vis.clone(),
_ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item];
@ -224,27 +232,15 @@ mod llvm_enzyme {
.filter(|a| **a == DiffActivity::Active || **a == DiffActivity::ActiveOnly)
.count() as u32;
let (d_sig, new_args, idents, errored) = gen_enzyme_decl(ecx, &sig, &x, span);
let new_decl_span = d_sig.span;
let d_body = gen_enzyme_body(
ecx,
&x,
n_active,
&sig,
&d_sig,
primal,
&new_args,
span,
sig_span,
new_decl_span,
idents,
errored,
ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored,
);
let d_ident = first_ident(&meta_item_vec[0]);
// The first element of it is the name of the function to be generated
let asdf = Box::new(ast::Fn {
defaultness: ast::Defaultness::Final,
sig: d_sig,
ident: first_ident(&meta_item_vec[0]),
generics: Generics::default(),
contract: None,
body: Some(d_body),
@ -270,36 +266,39 @@ mod llvm_enzyme {
};
let inline_never_attr = P(ast::NormalAttr { item: inline_item, tokens: None });
let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
let attr: ast::Attribute = ast::Attribute {
kind: ast::AttrKind::Normal(rustc_ad_attr.clone()),
id: new_id,
style: ast::AttrStyle::Outer,
span,
};
let attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
let inline_never: ast::Attribute = ast::Attribute {
kind: ast::AttrKind::Normal(inline_never_attr),
id: new_id,
style: ast::AttrStyle::Outer,
span,
};
let inline_never = outer_normal_attr(&inline_never_attr, new_id, span);
// We're avoid duplicating the attributes `#[rustc_autodiff]` and `#[inline(never)]`.
fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool {
match (attr, item) {
(ast::AttrKind::Normal(a), ast::AttrKind::Normal(b)) => {
let a = &a.item.path;
let b = &b.item.path;
a.segments.len() == b.segments.len()
&& a.segments.iter().zip(b.segments.iter()).all(|(a, b)| a.ident == b.ident)
}
_ => false,
}
}
// Don't add it multiple times:
let orig_annotatable: Annotatable = match item {
Annotatable::Item(ref mut iitem) => {
if !iitem.attrs.iter().any(|a| a.id == attr.id) {
if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
iitem.attrs.push(attr);
}
if !iitem.attrs.iter().any(|a| a.id == inline_never.id) {
if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) {
iitem.attrs.push(inline_never.clone());
}
Annotatable::Item(iitem.clone())
}
Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => {
if !assoc_item.attrs.iter().any(|a| a.id == attr.id) {
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => {
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
assoc_item.attrs.push(attr);
}
if !assoc_item.attrs.iter().any(|a| a.id == inline_never.id) {
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) {
assoc_item.attrs.push(inline_never.clone());
}
Annotatable::AssocItem(assoc_item.clone(), i)
@ -314,13 +313,7 @@ mod llvm_enzyme {
delim: rustc_ast::token::Delimiter::Parenthesis,
tokens: ts,
});
let d_attr: ast::Attribute = ast::Attribute {
kind: ast::AttrKind::Normal(rustc_ad_attr.clone()),
id: new_id,
style: ast::AttrStyle::Outer,
span,
};
let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
let d_annotatable = if is_impl {
let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf);
let d_fn = P(ast::AssocItem {
@ -328,14 +321,12 @@ mod llvm_enzyme {
id: ast::DUMMY_NODE_ID,
span,
vis,
ident: d_ident,
kind: assoc_item,
tokens: None,
});
Annotatable::AssocItem(d_fn, Impl)
Annotatable::AssocItem(d_fn, Impl { of_trait: false })
} else {
let mut d_fn =
ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
d_fn.vis = vis;
Annotatable::Item(d_fn)
};
@ -361,30 +352,27 @@ mod llvm_enzyme {
ty
}
/// We only want this function to type-check, since we will replace the body
/// later on llvm level. Using `loop {}` does not cover all return types anymore,
/// so instead we build something that should pass. We also add a inline_asm
/// line, as one more barrier for rustc to prevent inlining of this function.
/// FIXME(ZuseZ4): We still have cases of incorrect inlining across modules, see
/// <https://github.com/EnzymeAD/rust/issues/173>, so this isn't sufficient.
/// It also triggers an Enzyme crash if we due to a bug ever try to differentiate
/// this function (which should never happen, since it is only a placeholder).
/// Finally, we also add back_box usages of all input arguments, to prevent rustc
/// from optimizing any arguments away.
fn gen_enzyme_body(
// Will generate a body of the type:
// ```
// {
// unsafe {
// asm!("NOP");
// }
// ::core::hint::black_box(primal(args));
// ::core::hint::black_box((args, ret));
// <This part remains to be done by following function>
// }
// ```
fn init_body_helper(
ecx: &ExtCtxt<'_>,
x: &AutoDiffAttrs,
n_active: u32,
sig: &ast::FnSig,
d_sig: &ast::FnSig,
span: Span,
primal: Ident,
new_names: &[String],
span: Span,
sig_span: Span,
new_decl_span: Span,
idents: Vec<Ident>,
idents: &[Ident],
errored: bool,
) -> P<ast::Block> {
) -> (P<ast::Block>, P<ast::Expr>, P<ast::Expr>, P<ast::Expr>) {
let blackbox_path = ecx.std_path(&[sym::hint, sym::black_box]);
let noop = ast::InlineAsm {
asm_macro: ast::AsmMacro::Asm,
@ -403,7 +391,6 @@ mod llvm_enzyme {
tokens: None,
rules: unsf,
span,
could_be_bare_literal: false,
};
let unsf_expr = ecx.expr_block(P(unsf_block));
let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path));
@ -433,6 +420,51 @@ mod llvm_enzyme {
}
body.stmts.push(ecx.stmt_semi(black_box_remaining_args));
(body, primal_call, black_box_primal_call, blackbox_call_expr)
}
/// We only want this function to type-check, since we will replace the body
/// later on llvm level. Using `loop {}` does not cover all return types anymore,
/// so instead we manually build something that should pass the type checker.
/// We also add a inline_asm line, as one more barrier for rustc to prevent inlining
/// or const propagation. inline_asm will also triggers an Enzyme crash if due to another
/// bug would ever try to accidentially differentiate this placeholder function body.
/// Finally, we also add back_box usages of all input arguments, to prevent rustc
/// from optimizing any arguments away.
fn gen_enzyme_body(
ecx: &ExtCtxt<'_>,
x: &AutoDiffAttrs,
n_active: u32,
sig: &ast::FnSig,
d_sig: &ast::FnSig,
primal: Ident,
new_names: &[String],
span: Span,
sig_span: Span,
idents: Vec<Ident>,
errored: bool,
) -> P<ast::Block> {
let new_decl_span = d_sig.span;
// Just adding some default inline-asm and black_box usages to prevent early inlining
// and optimizations which alter the function signature.
//
// The bb_primal_call is the black_box call of the primal function. We keep it around,
// since it has the convenient property of returning the type of the primal function,
// Remember, we only care to match types here.
// No matter which return we pick, we always wrap it into a std::hint::black_box call,
// to prevent rustc from propagating it into the caller.
let (mut body, primal_call, bb_primal_call, bb_call_expr) = init_body_helper(
ecx,
span,
primal,
new_names,
sig_span,
new_decl_span,
&idents,
errored,
);
if !has_ret(&d_sig.decl.output) {
// there is no return type that we have to match, () works fine.
return body;
@ -444,7 +476,7 @@ mod llvm_enzyme {
if primal_ret && n_active == 0 && x.mode.is_rev() {
// We only have the primal ret.
body.stmts.push(ecx.stmt_expr(black_box_primal_call));
body.stmts.push(ecx.stmt_expr(bb_primal_call));
return body;
}
@ -536,11 +568,11 @@ mod llvm_enzyme {
return body;
}
[arg] => {
ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![arg.clone()]);
ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![arg.clone()]);
}
args => {
let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into());
ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![ret_tuple]);
ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![ret_tuple]);
}
}
assert!(has_ret(&d_sig.decl.output));
@ -553,7 +585,7 @@ mod llvm_enzyme {
ecx: &ExtCtxt<'_>,
span: Span,
primal: Ident,
idents: Vec<Ident>,
idents: &[Ident],
) -> P<ast::Expr> {
let has_self = idents.len() > 0 && idents[0].name == kw::SelfLower;
if has_self {

View File

@ -121,18 +121,11 @@ impl CfgEval<'_> {
let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
Annotatable::Item(self.flat_map_item(item).pop().unwrap())
}
Annotatable::AssocItem(_, AssocCtxt::Trait) => {
Annotatable::AssocItem(_, ctxt) => {
let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
Annotatable::AssocItem(
self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(),
AssocCtxt::Trait,
)
}
Annotatable::AssocItem(_, AssocCtxt::Impl) => {
let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap();
Annotatable::AssocItem(
self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(),
AssocCtxt::Impl,
self.flat_map_assoc_item(item, ctxt).pop().unwrap(),
ctxt,
)
}
Annotatable::ForeignItem(_) => {

View File

@ -11,15 +11,20 @@ pub(crate) fn expand(
let define_opaque = match &mut item {
Annotatable::Item(p) => match &mut p.kind {
ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
_ => None,
},
Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
ast::AssocItemKind::Const(ct) => Some(&mut ct.define_opaque),
_ => None,
},
Annotatable::Stmt(s) => match &mut s.kind {
ast::StmtKind::Item(p) => match &mut p.kind {
ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
_ => None,
},
_ => None,
@ -47,7 +52,10 @@ pub(crate) fn expand(
.collect(),
);
} else {
ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types");
ecx.dcx().span_err(
meta_item.span,
"only functions, statics, and consts can define opaque types",
);
}
vec![item]

View File

@ -103,7 +103,7 @@ impl MultiItemModifier for Expander {
fn dummy_annotatable() -> Annotatable {
Annotatable::GenericParam(ast::GenericParam {
id: ast::DUMMY_NODE_ID,
ident: Ident::empty(),
ident: Ident::dummy(),
attrs: Default::default(),
bounds: Default::default(),
is_placeholder: false,

View File

@ -34,8 +34,8 @@ pub(crate) fn expand_deriving_clone(
let is_simple;
match item {
Annotatable::Item(annitem) => match &annitem.kind {
ItemKind::Struct(_, Generics { params, .. })
| ItemKind::Enum(_, Generics { params, .. }) => {
ItemKind::Struct(_, _, Generics { params, .. })
| ItemKind::Enum(_, _, Generics { params, .. }) => {
let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
let has_derive_copy = cx.resolver.has_derive_copy(container_id);
if has_derive_copy

View File

@ -21,7 +21,7 @@ pub(crate) fn expand_deriving_partial_ord(
// Order in which to perform matching
let discr_then_data = if let Annotatable::Item(item) = item
&& let ItemKind::Enum(def, _) = &item.kind
&& let ItemKind::Enum(_, def, _) = &item.kind
{
let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect();
match dataful.iter().filter(|&&b| b).count() {

View File

@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
let (name_ident, generics) = if let Annotatable::Item(aitem) = item
&& let ItemKind::Struct(struct_data, g) = &aitem.kind
&& let ItemKind::Struct(ident, struct_data, g) = &aitem.kind
{
if !matches!(
struct_data,
@ -40,7 +40,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
cx.dcx().emit_err(RequireOneField { span });
return;
}
(aitem.ident, g)
(*ident, g)
} else {
cx.dcx().emit_err(RequireTransparent { span });
return;
@ -108,7 +108,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
push(Annotatable::Item(
cx.item(
span,
Ident::empty(),
attrs.clone(),
ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default,
@ -153,7 +152,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
let trait_ref = cx.trait_ref(trait_path);
let item = cx.item(
span,
Ident::empty(),
attrs.clone(),
ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default,

View File

@ -487,28 +487,28 @@ impl<'a> TraitDef<'a> {
);
let newitem = match &item.kind {
ast::ItemKind::Struct(struct_def, generics) => self.expand_struct_def(
ast::ItemKind::Struct(ident, struct_def, generics) => self.expand_struct_def(
cx,
struct_def,
item.ident,
*ident,
generics,
from_scratch,
is_packed,
),
ast::ItemKind::Enum(enum_def, generics) => {
ast::ItemKind::Enum(ident, enum_def, generics) => {
// We ignore `is_packed` here, because `repr(packed)`
// enums cause an error later on.
//
// This can only cause further compilation errors
// downstream in blatantly illegal code, so it is fine.
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
self.expand_enum_def(cx, enum_def, *ident, generics, from_scratch)
}
ast::ItemKind::Union(struct_def, generics) => {
ast::ItemKind::Union(ident, struct_def, generics) => {
if self.supports_unions {
self.expand_struct_def(
cx,
struct_def,
item.ident,
*ident,
generics,
from_scratch,
is_packed,
@ -596,7 +596,6 @@ impl<'a> TraitDef<'a> {
P(ast::AssocItem {
id: ast::DUMMY_NODE_ID,
span: self.span,
ident,
vis: ast::Visibility {
span: self.span.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,
@ -605,6 +604,7 @@ impl<'a> TraitDef<'a> {
attrs: ast::AttrVec::new(),
kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias {
defaultness: ast::Defaultness::Final,
ident,
generics: Generics::default(),
where_clauses: ast::TyAliasWhereClauses::default(),
bounds: Vec::new(),
@ -789,7 +789,6 @@ impl<'a> TraitDef<'a> {
cx.item(
self.span,
Ident::empty(),
attrs,
ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default,
@ -1033,10 +1032,10 @@ impl<'a> MethodDef<'a> {
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
ident: method_ident,
kind: ast::AssocItemKind::Fn(Box::new(ast::Fn {
defaultness,
sig,
ident: method_ident,
generics: fn_generics,
contract: None,
body: Some(body_block),

View File

@ -110,7 +110,6 @@ fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
span,
tokens: None,
could_be_bare_literal: false,
}))
}

View File

@ -74,11 +74,11 @@ pub(crate) fn use_panic_2021(mut span: Span) -> bool {
// (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
loop {
let expn = span.ctxt().outer_expn_data();
if let Some(features) = expn.allow_internal_unstable {
if features.iter().any(|&f| f == sym::edition_panic) {
span = expn.call_site;
continue;
}
if let Some(features) = expn.allow_internal_unstable
&& features.contains(&sym::edition_panic)
{
span = expn.call_site;
continue;
}
break expn.edition >= Edition::Edition2021;
}

View File

@ -25,15 +25,15 @@ pub(crate) fn expand(
// Allow using `#[global_allocator]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, ty_span) = if let Annotatable::Item(item) = &item
&& let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind
let (item, ident, is_stmt, ty_span) = if let Annotatable::Item(item) = &item
&& let ItemKind::Static(box ast::StaticItem { ident, ty, .. }) = &item.kind
{
(item, false, ecx.with_def_site_ctxt(ty.span))
(item, *ident, false, ecx.with_def_site_ctxt(ty.span))
} else if let Annotatable::Stmt(stmt) = &item
&& let StmtKind::Item(item) = &stmt.kind
&& let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind
&& let ItemKind::Static(box ast::StaticItem { ident, ty, .. }) = &item.kind
{
(item, true, ecx.with_def_site_ctxt(ty.span))
(item, *ident, true, ecx.with_def_site_ctxt(ty.span))
} else {
ecx.dcx().emit_err(errors::AllocMustStatics { span: item.span() });
return vec![orig_item];
@ -41,7 +41,7 @@ pub(crate) fn expand(
// Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span);
let f = AllocFnFactory { span, ty_span, global: item.ident, cx: ecx };
let f = AllocFnFactory { span, ty_span, global: ident, cx: ecx };
// Generate item statements for the allocator methods.
let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect();
@ -80,17 +80,13 @@ impl AllocFnFactory<'_, '_> {
let kind = ItemKind::Fn(Box::new(Fn {
defaultness: ast::Defaultness::Final,
sig,
ident: Ident::from_str_and_span(&global_fn_name(method.name), self.span),
generics: Generics::default(),
contract: None,
body,
define_opaque: None,
}));
let item = self.cx.item(
self.span,
Ident::from_str_and_span(&global_fn_name(method.name), self.span),
self.attrs(),
kind,
);
let item = self.cx.item(self.span, self.attrs(), kind);
self.cx.stmt_item(self.ty_span, item)
}

View File

@ -23,6 +23,8 @@
extern crate proc_macro;
use std::sync::Arc;
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
use rustc_expand::proc_macro::BangProcMacro;
use rustc_span::sym;
@ -67,13 +69,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
macro register_bang($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
$(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)*
}
macro register_attr($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)*
}
macro register_derive($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)*
}
register_bang! {
@ -139,9 +141,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
}
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires));
register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })));
let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires));
register(sym::contracts_requires, requires);
let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures));
let ensures = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandEnsures));
register(sym::contracts_ensures, ensures);
}

View File

@ -92,7 +92,12 @@ impl<'a> CollectProcMacros<'a> {
}
}
fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
fn collect_custom_derive(
&mut self,
item: &'a ast::Item,
function_name: Ident,
attr: &'a ast::Attribute,
) {
let Some((trait_name, proc_attrs)) =
parse_macro_name_and_helper_attrs(self.dcx, attr, "derive")
else {
@ -104,7 +109,7 @@ impl<'a> CollectProcMacros<'a> {
id: item.id,
span: item.span,
trait_name,
function_name: item.ident,
function_name,
attrs: proc_attrs,
}));
} else {
@ -118,12 +123,12 @@ impl<'a> CollectProcMacros<'a> {
}
}
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Attr(ProcMacroDef {
id: item.id,
span: item.span,
function_name: item.ident,
function_name,
}));
} else {
let msg = if !self.in_root {
@ -136,12 +141,12 @@ impl<'a> CollectProcMacros<'a> {
}
}
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Bang(ProcMacroDef {
id: item.id,
span: item.span,
function_name: item.ident,
function_name,
}));
} else {
let msg = if !self.in_root {
@ -165,12 +170,6 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
}
}
// First up, make sure we're checking a bare function. If we're not then
// we're just not interested in this item.
//
// If we find one, try to locate a `#[proc_macro_derive]` attribute on it.
let is_fn = matches!(item.kind, ast::ItemKind::Fn(..));
let mut found_attr: Option<&'a ast::Attribute> = None;
for attr in &item.attrs {
@ -214,7 +213,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
return;
};
if !is_fn {
// Make sure we're checking a bare function. If we're not then we're
// just not interested any further in this item.
let fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
fn_.ident
} else {
self.dcx
.create_err(errors::AttributeOnlyBeUsedOnBareFunctions {
span: attr.span,
@ -222,7 +225,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
})
.emit();
return;
}
};
if self.is_test_crate {
return;
@ -238,12 +241,13 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
return;
}
// Try to locate a `#[proc_macro_derive]` attribute.
if attr.has_name(sym::proc_macro_derive) {
self.collect_custom_derive(item, attr);
self.collect_custom_derive(item, fn_ident, attr);
} else if attr.has_name(sym::proc_macro_attribute) {
self.collect_attr_proc_macro(item);
self.collect_attr_proc_macro(item, fn_ident);
} else if attr.has_name(sym::proc_macro) {
self.collect_bang_proc_macro(item);
self.collect_bang_proc_macro(item, fn_ident);
};
let prev_in_root = mem::replace(&mut self.in_root, false);
@ -278,7 +282,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
let proc_macro = Ident::new(sym::proc_macro, span);
let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
let krate = cx.item(span, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, proc_macro));
let bridge = Ident::new(sym::bridge, span);
let client = Ident::new(sym::client, span);

View File

@ -43,9 +43,8 @@ pub fn inject(
let item = cx.item(
span,
Ident::new(name, ident_span),
thin_vec![cx.attr_word(sym::macro_use, span)],
ast::ItemKind::ExternCrate(None),
ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
);
krate.items.insert(0, item);
@ -68,7 +67,6 @@ pub fn inject(
// Inject the relevant crate's prelude.
let use_item = cx.item(
span,
Ident::empty(),
thin_vec![cx.attr_word(sym::prelude_import, span)],
ast::ItemKind::Use(ast::UseTree {
prefix: cx.path(span, import_path),

View File

@ -51,21 +51,28 @@ pub(crate) fn expand_test_case(
return vec![];
}
};
item = item.map(|mut item| {
let test_path_symbol = Symbol::intern(&item_path(
// skip the name of the root module
&ecx.current_expansion.module.mod_path[1..],
&item.ident,
));
item.vis = ast::Visibility {
span: item.vis.span,
kind: ast::VisibilityKind::Public,
tokens: None,
};
item.ident.span = item.ident.span.with_ctxt(sp.ctxt());
item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp));
item
});
// `#[test_case]` is valid on functions, consts, and statics. Only modify
// the item in those cases.
match &mut item.kind {
ast::ItemKind::Fn(box ast::Fn { ident, .. })
| ast::ItemKind::Const(box ast::ConstItem { ident, .. })
| ast::ItemKind::Static(box ast::StaticItem { ident, .. }) => {
ident.span = ident.span.with_ctxt(sp.ctxt());
let test_path_symbol = Symbol::intern(&item_path(
// skip the name of the root module
&ecx.current_expansion.module.mod_path[1..],
ident,
));
item.vis = ast::Visibility {
span: item.vis.span,
kind: ast::VisibilityKind::Public,
tokens: None,
};
item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp));
}
_ => {}
}
let ret = if is_stmt {
Annotatable::Stmt(P(ecx.stmt_item(item.span, item)))
@ -162,17 +169,17 @@ pub(crate) fn expand_test_or_bench(
let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span());
let attr_sp = cx.with_def_site_ctxt(attr_sp);
let test_id = Ident::new(sym::test, attr_sp);
let test_ident = Ident::new(sym::test, attr_sp);
// creates test::$name
let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
let test_path = |name| cx.path(ret_ty_sp, vec![test_ident, Ident::from_str_and_span(name, sp)]);
// creates test::ShouldPanic::$name
let should_panic_path = |name| {
cx.path(
sp,
vec![
test_id,
test_ident,
Ident::from_str_and_span("ShouldPanic", sp),
Ident::from_str_and_span(name, sp),
],
@ -184,7 +191,7 @@ pub(crate) fn expand_test_or_bench(
cx.path(
sp,
vec![
test_id,
test_ident,
Ident::from_str_and_span("TestType", sp),
Ident::from_str_and_span(name, sp),
],
@ -223,7 +230,7 @@ pub(crate) fn expand_test_or_bench(
// super::$test_fn(b)
cx.expr_call(
ret_ty_sp,
cx.expr_path(cx.path(sp, vec![item.ident])),
cx.expr_path(cx.path(sp, vec![fn_.ident])),
thin_vec![cx.expr_ident(sp, b)],
),
],
@ -249,7 +256,7 @@ pub(crate) fn expand_test_or_bench(
// $test_fn()
cx.expr_call(
ret_ty_sp,
cx.expr_path(cx.path(sp, vec![item.ident])),
cx.expr_path(cx.path(sp, vec![fn_.ident])),
ThinVec::new(),
), // )
],
@ -262,15 +269,14 @@ pub(crate) fn expand_test_or_bench(
let test_path_symbol = Symbol::intern(&item_path(
// skip the name of the root module
&cx.current_expansion.module.mod_path[1..],
&item.ident,
&fn_.ident,
));
let location_info = get_location_info(cx, &item);
let location_info = get_location_info(cx, &fn_);
let mut test_const =
cx.item(
sp,
Ident::new(item.ident.name, sp),
thin_vec![
// #[cfg(test)]
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
@ -283,8 +289,10 @@ pub(crate) fn expand_test_or_bench(
ast::ItemKind::Const(
ast::ConstItem {
defaultness: ast::Defaultness::Final,
ident: Ident::new(fn_.ident.name, sp),
generics: ast::Generics::default(),
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
define_opaque: None,
// test::TestDescAndFn {
expr: Some(
cx.expr_struct(
@ -379,7 +387,8 @@ pub(crate) fn expand_test_or_bench(
});
// extern crate test
let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
let test_extern =
cx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident));
debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
@ -433,8 +442,8 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
.emit();
}
fn get_location_info(cx: &ExtCtxt<'_>, item: &ast::Item) -> (Symbol, usize, usize, usize, usize) {
let span = item.ident.span;
fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
let span = fn_.ident.span;
let (source_file, lo_line, lo_col, hi_line, hi_col) =
cx.sess.source_map().span_to_location_info(span);

View File

@ -134,27 +134,21 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
if let Some(name) = get_test_name(&item) {
debug!("this is a test item");
let test = Test { span: item.span, ident: item.ident, name };
// `unwrap` is ok because only functions, consts, and static should reach here.
let test = Test { span: item.span, ident: item.kind.ident().unwrap(), name };
self.tests.push(test);
}
// We don't want to recurse into anything other than mods, since
// mods or tests inside of functions will break things
if let ast::ItemKind::Mod(
_,
_,
ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
) = item.kind
{
let prev_tests = mem::take(&mut self.tests);
walk_item_kind(
&mut item.kind,
item.span,
item.id,
&mut item.ident,
&mut item.vis,
(),
self,
);
walk_item_kind(&mut item.kind, item.span, item.id, &mut item.vis, (), self);
self.add_test_cases(item.id, span, prev_tests);
} else {
// But in those cases, we emit a lint to warn the user of these missing tests.
@ -181,9 +175,9 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> {
}
fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType {
match item.kind {
ast::ItemKind::Fn(..) => {
rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(item.ident.name))
match &item.kind {
ast::ItemKind::Fn(fn_) => {
rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(fn_.ident.name))
}
_ => EntryPointType::None,
}
@ -295,7 +289,7 @@ fn generate_test_harness(
fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let sp = cx.def_site;
let ecx = &cx.ext_cx;
let test_id = Ident::new(sym::test, sp);
let test_ident = Ident::new(sym::test, sp);
let runner_name = match cx.panic_strategy {
PanicStrategy::Unwind => "test_main_static",
@ -303,10 +297,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
};
// test::test_main_static(...)
let mut test_runner = cx
.test_runner
.clone()
.unwrap_or_else(|| ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)]));
let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
ecx.path(sp, vec![test_ident, Ident::from_str_and_span(runner_name, sp)])
});
test_runner.span = sp;
@ -317,7 +310,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
// extern crate test
let test_extern_stmt = ecx.stmt_item(
sp,
ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)),
ecx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident)),
);
// #[rustc_main]
@ -340,23 +333,24 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty));
let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
let defaultness = ast::Defaultness::Final;
// Honor the reexport_test_harness_main attribute
let main_ident = match cx.reexport_test_harness_main {
Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
None => Ident::new(sym::main, sp),
};
let main = ast::ItemKind::Fn(Box::new(ast::Fn {
defaultness,
sig,
ident: main_ident,
generics: ast::Generics::default(),
contract: None,
body: Some(main_body),
define_opaque: None,
}));
// Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main {
Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
None => Ident::new(sym::main, sp),
};
let main = P(ast::Item {
ident: main_id,
attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr],
id: ast::DUMMY_NODE_ID,
kind: main,

View File

@ -1,20 +1,21 @@
task:
name: freebsd
freebsd_instance:
image: freebsd-13-2-release-amd64
setup_rust_script:
- pkg install -y git-tiny binutils
- curl https://sh.rustup.rs -sSf --output rustup.sh
- sh rustup.sh --default-toolchain none -y --profile=minimal
target_cache:
folder: build/cg_clif
prepare_script:
- . $HOME/.cargo/env
- ./y.sh prepare
test_script:
- . $HOME/.cargo/env
# Disabling incr comp reduces cache size and incr comp doesn't save as much
# on CI anyway.
- export CARGO_BUILD_INCREMENTAL=false
# Skip rand as it fails on FreeBSD due to rust-random/rand#1355
- ./y.sh test --skip-test test.rust-random/rand
# FIXME re-enable once https://github.com/rust-lang/rust/issues/134863 is fixed.
# task:
# name: freebsd
# freebsd_instance:
# image: freebsd-13-2-release-amd64
# setup_rust_script:
# - pkg install -y git-tiny binutils
# - curl https://sh.rustup.rs -sSf --output rustup.sh
# - sh rustup.sh --default-toolchain none -y --profile=minimal
# target_cache:
# folder: build/cg_clif
# prepare_script:
# - . $HOME/.cargo/env
# - ./y.sh prepare
# test_script:
# - . $HOME/.cargo/env
# # Disabling incr comp reduces cache size and incr comp doesn't save as much
# # on CI anyway.
# - export CARGO_BUILD_INCREMENTAL=false
# # Skip rand as it fails on FreeBSD due to rust-random/rand#1355
# - ./y.sh test --skip-test test.rust-random/rand

View File

@ -1,18 +0,0 @@
# github-release
An action used to publish GitHub releases for `wasmtime`.
As of the time of this writing there's a few actions floating around which
perform github releases but they all tend to have their set of drawbacks.
Additionally nothing handles deleting releases which we need for our rolling
`dev` release.
To handle all this this action rolls-its-own implementation using the
actions/toolkit repository and packages published there. These run in a Docker
container and take various inputs to orchestrate the release from the build.
More comments can be found in `main.js`.
Testing this is really hard. If you want to try though run `npm install` and
then `node main.js`. You'll have to configure a bunch of env vars though to get
anything reasonably working.

View File

@ -1,13 +0,0 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
name: 'rustc_codegen_cranelift github releases'
description: 'rustc_codegen_cranelift github releases'
inputs:
token:
description: ''
required: true
files:
description: ''
required: true
runs:
using: 'node16'
main: 'main.js'

View File

@ -1,162 +0,0 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
const core = require('@actions/core');
const path = require("path");
const fs = require("fs");
const github = require('@actions/github');
const glob = require('glob');
function sleep(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}
async function runOnce() {
// Load all our inputs and env vars. Note that `getInput` reads from `INPUT_*`
const files = core.getInput('files');
const token = core.getInput('token');
const slug = process.env.GITHUB_REPOSITORY;
const owner = slug.split('/')[0];
const repo = slug.split('/')[1];
const sha = process.env.GITHUB_SHA;
let name = 'dev';
if (process.env.GITHUB_REF.startsWith('refs/tags/v')) {
name = process.env.GITHUB_REF.substring(10);
}
core.info(`files: ${files}`);
core.info(`name: ${name}`);
core.info(`token: ${token}`);
const octokit = github.getOctokit(token);
// For the `dev` release we may need to update the tag to point to the new
// commit on this branch. All other names should already have tags associated
// with them.
if (name == 'dev') {
let tag = null;
try {
tag = await octokit.request("GET /repos/:owner/:repo/git/refs/tags/:name", { owner, repo, name });
core.info(`found existing tag`);
console.log("tag: ", JSON.stringify(tag.data, null, 2));
} catch (e) {
// ignore if this tag doesn't exist
core.info(`no existing tag found`);
}
if (tag === null || tag.data.object.sha !== sha) {
core.info(`updating existing tag or creating new one`);
try {
core.info(`updating dev tag`);
await octokit.rest.git.updateRef({
owner,
repo,
ref: 'tags/dev',
sha,
force: true,
});
} catch (e) {
console.log("ERROR: ", JSON.stringify(e.response, null, 2));
core.info(`creating dev tag`);
try {
await octokit.rest.git.createRef({
owner,
repo,
ref: 'refs/tags/dev',
sha,
});
} catch (e) {
// we might race with others, so assume someone else has created the
// tag by this point.
console.log("failed to create tag: ", JSON.stringify(e.response, null, 2));
}
}
console.log("double-checking tag is correct");
tag = await octokit.request("GET /repos/:owner/:repo/git/refs/tags/:name", { owner, repo, name });
if (tag.data.object.sha !== sha) {
console.log("tag: ", JSON.stringify(tag.data, null, 2));
throw new Error("tag didn't work");
}
} else {
core.info(`existing tag works`);
}
}
// Delete a previous release
try {
core.info(`fetching release`);
let release = await octokit.rest.repos.getReleaseByTag({ owner, repo, tag: name });
console.log("found release: ", JSON.stringify(release.data, null, 2));
await octokit.rest.repos.deleteRelease({
owner,
repo,
release_id: release.data.id,
});
console.log("deleted release");
} catch (e) {
console.log("ERROR: ", JSON.stringify(e, null, 2));
}
console.log("creating a release");
let release = await octokit.rest.repos.createRelease({
owner,
repo,
tag_name: name,
prerelease: name === 'dev',
});
// Delete all assets from a previous run
for (const asset of release.data.assets) {
console.log(`deleting prior asset ${asset.id}`);
await octokit.rest.repos.deleteReleaseAsset({
owner,
repo,
asset_id: asset.id,
});
}
// Upload all the relevant assets for this release as just general blobs.
for (const file of glob.sync(files)) {
const size = fs.statSync(file).size;
const name = path.basename(file);
core.info(`upload ${file}`);
await octokit.rest.repos.uploadReleaseAsset({
data: fs.createReadStream(file),
headers: { 'content-length': size, 'content-type': 'application/octet-stream' },
name,
url: release.data.upload_url,
});
}
}
async function run() {
const retries = 10;
for (let i = 0; i < retries; i++) {
try {
await runOnce();
break;
} catch (e) {
if (i === retries - 1)
throw e;
logError(e);
console.log("RETRYING after 10s");
await sleep(10000)
}
}
}
function logError(e) {
console.log("ERROR: ", e.message);
try {
console.log(JSON.stringify(e, null, 2));
} catch (e) {
// ignore json errors for now
}
console.log(e.stack);
}
run().catch(err => {
logError(err);
core.setFailed(err.message);
});

View File

@ -1,571 +0,0 @@
{
"name": "rustc_codegen_cranelift-github-release",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "rustc_codegen_cranelift-github-release",
"version": "0.0.0",
"dependencies": {
"@actions/core": "^1.9.1",
"@actions/github": "^5.1.0",
"glob": "^7.1.5"
}
},
"node_modules/@actions/core": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/github": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.0.tgz",
"integrity": "sha512-tuI80F7JQIhg77ZTTgUAPpVD7ZnP9oHSPN8xw7LOwtA4vEMbAjWJNbmLBfV7xua7r016GyjzWLuec5cs8f/a8A==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"@octokit/core": "^3.6.0",
"@octokit/plugin-paginate-rest": "^2.17.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
}
},
"node_modules/@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"node_modules/@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.21.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
"dependencies": {
"@octokit/types": "^6.40.0"
},
"peerDependencies": {
"@octokit/core": ">=2"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.16.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
"dependencies": {
"@octokit/types": "^6.39.0",
"deprecation": "^2.3.1"
},
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"node_modules/@octokit/types": {
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
"dependencies": {
"@octokit/openapi-types": "^12.11.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
},
"dependencies": {
"@actions/core": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"requires": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"@actions/github": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.0.tgz",
"integrity": "sha512-tuI80F7JQIhg77ZTTgUAPpVD7ZnP9oHSPN8xw7LOwtA4vEMbAjWJNbmLBfV7xua7r016GyjzWLuec5cs8f/a8A==",
"requires": {
"@actions/http-client": "^2.0.1",
"@octokit/core": "^3.6.0",
"@octokit/plugin-paginate-rest": "^2.17.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
}
},
"@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.21.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
"requires": {
"@octokit/types": "^6.40.0"
}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.16.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
"requires": {
"@octokit/types": "^6.39.0",
"deprecation": "^2.3.1"
}
},
"@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/types": {
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
"requires": {
"@octokit/openapi-types": "^12.11.0"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
}
}

View File

@ -1,11 +0,0 @@
{
"name": "rustc_codegen_cranelift-github-release",
"version": "0.0.0",
"license": "Apache-2.0 WITH LLVM-exception",
"main": "main.js",
"dependencies": {
"@actions/core": "^1.9.1",
"@actions/github": "^5.1.0",
"glob": "^7.1.5"
}
}

View File

@ -25,7 +25,10 @@ jobs:
- os: ubuntu-latest
env:
TARGET_TRIPLE: x86_64-unknown-linux-gnu
- os: macos-latest
- os: ubuntu-24.04-arm
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
- os: macos-13
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: macos-latest
@ -56,13 +59,6 @@ jobs:
if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
run: rustup set default-host x86_64-pc-windows-gnu
- name: Use x86_64 compiler on macOS
if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin'
run: rustup set default-host x86_64-apple-darwin
- name: Prepare dependencies
run: ./y.sh prepare
- name: Build
run: ./y.sh build --sysroot none

View File

@ -53,13 +53,12 @@ jobs:
- os: ubuntu-latest
env:
TARGET_TRIPLE: x86_64-unknown-linux-gnu
- os: macos-latest
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: ubuntu-latest
- os: ubuntu-24.04-arm
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
apt_deps: gcc-aarch64-linux-gnu qemu-user
- os: macos-13
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: macos-latest
env:
TARGET_TRIPLE: aarch64-apple-darwin
@ -95,10 +94,6 @@ jobs:
if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
run: rustup set default-host x86_64-pc-windows-gnu
- name: Use x86_64 compiler on macOS
if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin'
run: rustup set default-host x86_64-apple-darwin
- name: Install toolchain and emulator
if: matrix.apt_deps != null
run: |
@ -170,9 +165,6 @@ jobs:
sudo apt update
sudo apt install -y hyperfine
- name: Prepare dependencies
run: ./y.sh prepare
- name: Build
run: ./y.sh build --sysroot none
@ -192,7 +184,10 @@ jobs:
- os: ubuntu-22.04
env:
TARGET_TRIPLE: x86_64-unknown-linux-gnu
- os: macos-latest
- os: ubuntu-24.04-arm
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
- os: macos-13
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: macos-latest
@ -218,13 +213,6 @@ jobs:
if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
run: rustup set default-host x86_64-pc-windows-gnu
- name: Use x86_64 compiler on macOS
if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin'
run: rustup set default-host x86_64-apple-darwin
- name: Prepare dependencies
run: ./y.sh prepare
- name: Build backend
run: ./y.sh build --sysroot none
@ -273,12 +261,9 @@ jobs:
rmdir artifacts/ # verify all artifacts are represented in release/
ls -R release/
- run: npm install --production
working-directory: .github/actions/github-release
- name: Publish Release
uses: ./.github/actions/github-release
with:
files: "release/*"
token: ${{ github.token }}
continue-on-error: true
- name: Publish release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release delete --cleanup-tag -y dev || true
gh release create --target $GITHUB_SHA --prerelease dev release/*

View File

@ -22,9 +22,6 @@ jobs:
path: build/cg_clif
key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }}
- name: Prepare dependencies
run: ./y.sh prepare
- name: Test
run: ./scripts/test_bootstrap.sh
@ -50,8 +47,5 @@ jobs:
sudo apt update
sudo apt install -y ripgrep
- name: Prepare dependencies
run: ./y.sh prepare
- name: Test
run: ./scripts/test_rustc_tests.sh

View File

@ -1,41 +1,40 @@
{
"editor.formatOnSave": true,
// in case rustc.source is disabled for performance reasons; disable the errors about this
"rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
"rust-analyzer.diagnostics.disabled": [
"unresolved-extern-crate",
"unresolved-macro-call"
],
"rust-analyzer.rustc.source": "discover",
"rust-analyzer.imports.granularity.enforce": true,
"rust-analyzer.imports.granularity.group": "module",
"rust-analyzer.imports.prefix": "crate",
"rust-analyzer.cargo.features": ["unstable-features"],
"rust-analyzer.cargo.features": [
"unstable-features"
],
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
"./build_system/Cargo.toml",
{
"sysroot_src": "./build/stdlib/library",
"crates": [
{
"root_module": "./example/mini_core.rs",
"edition": "2018",
"edition": "2015",
"deps": [],
"cfg": [],
},
{
"root_module": "./example/mini_core_hello_world.rs",
"edition": "2018",
"deps": [{ "crate": 0, "name": "mini_core" }],
"edition": "2015",
"deps": [
{
"crate": 0,
"name": "mini_core"
}
],
"cfg": [],
},
{
"root_module": "./example/mod_bench.rs",
"edition": "2018",
"deps": [],
"cfg": [],
},
]
},
{
"sysroot_src": "./build/stdlib/library",
"crates": [
{
"root_module": "./example/std_example.rs",
"edition": "2015",

View File

@ -5,7 +5,10 @@
"initialization_options": {
"diagnostics": {
// in case rustc.source is disabled for performance reasons; disable the errors about this
"disabled": ["unresolved-extern-crate", "unresolved-macro-call"]
"disabled": [
"unresolved-extern-crate",
"unresolved-macro-call"
]
},
"rustc": {
"source": "discover"
@ -18,22 +21,25 @@
"prefix": "crate"
},
"cargo": {
"features": ["unstable-features"]
"features": [
"unstable-features"
]
},
"linkedProjects": [
"./Cargo.toml",
"./build_system/Cargo.toml",
{
"sysroot_src": "./build/stdlib/library",
"crates": [
{
"root_module": "./example/mini_core.rs",
"edition": "2018",
"edition": "2015",
"deps": [],
"cfg": []
},
{
"root_module": "./example/mini_core_hello_world.rs",
"edition": "2018",
"edition": "2015",
"deps": [
{
"crate": 0,
@ -42,17 +48,6 @@
],
"cfg": []
},
{
"root_module": "./example/mod_bench.rs",
"edition": "2018",
"deps": [],
"cfg": []
}
]
},
{
"sysroot_src": "./build/stdlib/library",
"crates": [
{
"root_module": "./example/std_example.rs",
"edition": "2015",

View File

@ -42,27 +42,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
version = "0.116.1"
name = "cranelift-assembler-x64"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e15d04a0ce86cb36ead88ad68cf693ffd6cda47052b9e0ac114bc47fd9cd23c4"
checksum = "3e4b56ebe316895d3fa37775d0a87b0c889cc933f5c8b253dbcc7c7bcb7fe7e4"
dependencies = [
"cranelift-assembler-x64-meta",
]
[[package]]
name = "cranelift-assembler-x64-meta"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95cabbc01dfbd7dcd6c329ca44f0212910309c221797ac736a67a5bc8857fe1b"
[[package]]
name = "cranelift-bforest"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76ffe46df300a45f1dc6f609dc808ce963f0e3a2e971682c479a2d13e3b9b8ef"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c6e3969a7ce267259ce244b7867c5d3bc9e65b0a87e81039588dfdeaede9f34"
checksum = "b265bed7c51e1921fdae6419791d31af77d33662ee56d7b0fa0704dc8d231cab"
[[package]]
name = "cranelift-codegen"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c22032c4cb42558371cf516bb47f26cdad1819d3475c133e93c49f50ebf304e"
checksum = "e606230a7e3a6897d603761baee0d19f88d077f17b996bb5089488a29ae96e41"
dependencies = [
"bumpalo",
"cranelift-assembler-x64",
"cranelift-bforest",
"cranelift-bitset",
"cranelift-codegen-meta",
@ -71,7 +87,7 @@ dependencies = [
"cranelift-entity",
"cranelift-isle",
"gimli",
"hashbrown 0.14.5",
"hashbrown",
"log",
"regalloc2",
"rustc-hash",
@ -82,42 +98,43 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c904bc71c61b27fc57827f4a1379f29de64fe95653b620a3db77d59655eee0b8"
checksum = "8a63bffafc23bc60969ad528e138788495999d935f0adcfd6543cb151ca8637d"
dependencies = [
"cranelift-assembler-x64",
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40180f5497572f644ce88c255480981ae2ec1d7bb4d8e0c0136a13b87a2f2ceb"
checksum = "af50281b67324b58e843170a6a5943cf6d387c06f7eeacc9f5696e4ab7ae7d7e"
[[package]]
name = "cranelift-control"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d132c6d0bd8a489563472afc171759da0707804a65ece7ceb15a8c6d7dd5ef"
checksum = "8c20c1b38d1abfbcebb0032e497e71156c0e3b8dcb3f0a92b9863b7bcaec290c"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b2d0d9618275474fbf679dd018ac6e009acbd6ae6850f6a67be33fb3b00b323"
checksum = "0c2c67d95507c51b4a1ff3f3555fe4bfec36b9e13c1b684ccc602736f5d5f4a2"
dependencies = [
"cranelift-bitset",
]
[[package]]
name = "cranelift-frontend"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fac41e16729107393174b0c9e3730fb072866100e1e64e80a1a963b2e484d57"
checksum = "4e002691cc69c38b54fc7ec93e5be5b744f627d027031d991cc845d1d512d0ce"
dependencies = [
"cranelift-codegen",
"log",
@ -127,15 +144,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ca20d576e5070044d0a72a9effc2deacf4d6aa650403189d8ea50126483944d"
checksum = "e93588ed1796cbcb0e2ad160403509e2c5d330d80dd6e0014ac6774c7ebac496"
[[package]]
name = "cranelift-jit"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e65c42755a719b09662b00c700daaf76cc35d5ace1f5c002ad404b591ff1978"
checksum = "17f6682f0b193d6b7873cc8e7ed67e8776a8a26f50eeabf88534e9be618b9a03"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -153,9 +170,9 @@ dependencies = [
[[package]]
name = "cranelift-module"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d55612bebcf16ff7306c8a6f5bdb6d45662b8aa1ee058ecce8807ad87db719b"
checksum = "ff19784c6de05116e63e6a34791012bd927b2a4eac56233039c46f1b6a4edac8"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -164,9 +181,9 @@ dependencies = [
[[package]]
name = "cranelift-native"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8dee82f3f1f2c4cba9177f1cc5e350fe98764379bcd29340caa7b01f85076c7"
checksum = "e5b09bdd6407bf5d89661b80cf926ce731c9e8cc184bf49102267a2369a8358e"
dependencies = [
"cranelift-codegen",
"libc",
@ -175,9 +192,9 @@ dependencies = [
[[package]]
name = "cranelift-object"
version = "0.116.1"
version = "0.118.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aad5a6d3e379493c3f8b35dc61c93d0bf5f27003bbe20614e0200b0ec372ef52"
checksum = "685e8661a30d1cb69509f589ac643adeee79c5f63c0da316431b9fad29e6d3b4"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -226,12 +243,6 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.2"
@ -248,7 +259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
"hashbrown",
]
[[package]]
@ -295,7 +306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"crc32fast",
"hashbrown 0.15.2",
"hashbrown",
"indexmap",
"memchr",
]
@ -326,7 +337,7 @@ checksum = "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3"
dependencies = [
"allocator-api2",
"bumpalo",
"hashbrown 0.15.2",
"hashbrown",
"log",
"rustc-hash",
"smallvec",
@ -425,9 +436,9 @@ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "29.0.1"
version = "31.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec5e8552e01692e6c2e5293171704fed8abdec79d1a6995a0870ab190e5747d1"
checksum = "a54f6c6c7e9d7eeee32dfcc10db7f29d505ee7dd28d00593ea241d5f70698e64"
dependencies = [
"anyhow",
"cfg-if",

View File

@ -8,12 +8,12 @@ crate-type = ["dylib"]
[dependencies]
# These have to be in sync with each other
cranelift-codegen = { version = "0.116.0", default-features = false, features = ["std", "unwind", "all-native-arch"] }
cranelift-frontend = { version = "0.116.0" }
cranelift-module = { version = "0.116.0" }
cranelift-native = { version = "0.116.0" }
cranelift-jit = { version = "0.116.0", optional = true }
cranelift-object = { version = "0.116.0" }
cranelift-codegen = { version = "0.118.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
cranelift-frontend = { version = "0.118.0" }
cranelift-module = { version = "0.118.0" }
cranelift-native = { version = "0.118.0" }
cranelift-jit = { version = "0.118.0", optional = true }
cranelift-object = { version = "0.118.0" }
target-lexicon = "0.13"
gimli = { version = "0.31", default-features = false, features = ["write"] }
object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@ -24,12 +24,12 @@ smallvec = "1.8.1"
[patch.crates-io]
# Uncomment to use an unreleased version of cranelift
#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-29.0.0", version = "0.116.0" }
#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-31.0.0", version = "0.118.0" }
# Uncomment to use local checkout of cranelift
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }

View File

@ -49,13 +49,13 @@ If you want to build the backend manually, you can download it from GitHub and b
```bash
$ git clone https://github.com/rust-lang/rustc_codegen_cranelift
$ cd rustc_codegen_cranelift
$ ./y.sh prepare
$ ./y.sh build
```
To run the test suite replace the last command with:
```bash
$ ./y.sh prepare # only needs to be run the first time
$ ./test.sh
```

View File

@ -91,6 +91,13 @@ impl GitRepo {
fn verify_checksum(&self, dirs: &Dirs) {
let download_dir = self.download_dir(dirs);
if !download_dir.exists() {
eprintln!(
"Missing directory {download_dir}: Please run ./y.sh prepare to download.",
download_dir = download_dir.display(),
);
std::process::exit(1);
}
let actual_hash = format!("{:016x}", hash_dir(&download_dir));
if actual_hash != self.content_hash {
eprintln!(

View File

@ -1,5 +1,4 @@
use std::ffi::OsStr;
use std::fs;
use std::path::PathBuf;
use std::process::Command;
@ -126,9 +125,9 @@ static PORTABLE_SIMD_SRC: RelPath = RelPath::build("portable-simd");
static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target");
static LIBCORE_TESTS_SRC: RelPath = RelPath::build("coretests");
static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests");
static LIBCORE_TESTS: CargoProject = CargoProject::new(&LIBCORE_TESTS_SRC, "coretests_target");
static SYSROOT_TESTS: CargoProject = CargoProject::new(&SYSROOT_TESTS_SRC, "sysroot_tests_target");
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
TestCase::custom("test.rust-random/rand", &|runner| {
@ -147,28 +146,24 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
spawn_and_wait(build_cmd);
}
}),
TestCase::custom("test.libcore", &|runner| {
TestCase::custom("test.sysroot", &|runner| {
apply_patches(
&runner.dirs,
"coretests",
&runner.stdlib_source.join("library/coretests"),
&LIBCORE_TESTS_SRC.to_path(&runner.dirs),
"sysroot_tests",
&runner.stdlib_source.join("library"),
&SYSROOT_TESTS_SRC.to_path(&runner.dirs),
);
let source_lockfile = runner.dirs.source_dir.join("patches/coretests-lock.toml");
let target_lockfile = LIBCORE_TESTS_SRC.to_path(&runner.dirs).join("Cargo.lock");
fs::copy(source_lockfile, target_lockfile).unwrap();
LIBCORE_TESTS.clean(&runner.dirs);
SYSROOT_TESTS.clean(&runner.dirs);
if runner.is_native {
let mut test_cmd = LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs);
test_cmd.arg("--").arg("-q");
let mut test_cmd = SYSROOT_TESTS.test(&runner.target_compiler, &runner.dirs);
test_cmd.args(["-p", "coretests", "-p", "alloctests", "--", "-q"]);
spawn_and_wait(test_cmd);
} else {
eprintln!("Cross-Compiling: Not running tests");
let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs);
build_cmd.arg("--tests");
let mut build_cmd = SYSROOT_TESTS.build(&runner.target_compiler, &runner.dirs);
build_cmd.args(["-p", "coretests", "-p", "alloctests", "--tests"]);
spawn_and_wait(build_cmd);
}
}),
@ -330,10 +325,8 @@ impl<'a> TestRunner<'a> {
target_compiler.rustflags.extend(rustflags_from_env("RUSTFLAGS"));
target_compiler.rustdocflags.extend(rustflags_from_env("RUSTDOCFLAGS"));
let jit_supported = use_unstable_features
&& is_native
&& target_compiler.triple.contains("x86_64")
&& !target_compiler.triple.contains("windows");
let jit_supported =
use_unstable_features && is_native && !target_compiler.triple.contains("windows");
Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source }
}
@ -374,21 +367,7 @@ impl<'a> TestRunner<'a> {
TestCaseCmd::JitBin { source, args } => {
let mut jit_cmd = self.rustc_command([
"-Zunstable-options",
"-Cllvm-args=mode=jit",
"-Cprefer-dynamic",
source,
"--cfg",
"jit",
]);
if !args.is_empty() {
jit_cmd.env("CG_CLIF_JIT_ARGS", args);
}
spawn_and_wait(jit_cmd);
eprintln!("[JIT-lazy] {testname}");
let mut jit_cmd = self.rustc_command([
"-Zunstable-options",
"-Cllvm-args=mode=jit-lazy",
"-Cllvm-args=jit-mode",
"-Cprefer-dynamic",
source,
"--cfg",

View File

@ -35,6 +35,6 @@ aot.raw-dylib
testsuite.extended_sysroot
test.rust-random/rand
test.libcore
test.sysroot
test.regex
test.portable-simd

View File

@ -38,14 +38,7 @@ $ $cg_clif_dir/dist/cargo-clif jit
or
```bash
$ $cg_clif_dir/dist/rustc-clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
```
There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
first called.
```bash
$ $cg_clif_dir/dist/cargo-clif lazy-jit
$ $cg_clif_dir/dist/rustc-clif -Cllvm-args=jit-mode -Cprefer-dynamic my_crate.rs
```
## Shell
@ -54,7 +47,7 @@ These are a few functions that allow you to easily run rust code from the shell
```bash
function jit_naked() {
echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-options -Cllvm-args=mode=jit-lazy -Cprefer-dynamic
echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-options -Cllvm-args=jit-mode-Cprefer-dynamic
}
function jit() {

View File

@ -6,16 +6,25 @@
#![feature(gen_blocks)]
fn foo() -> impl Iterator<Item = u32> {
gen { yield 42; for x in 3..6 { yield x } }
gen {
yield 42;
for x in 3..6 {
yield x
}
}
}
fn moved() -> impl Iterator<Item = u32> {
let mut x = "foo".to_string();
gen move {
yield 42;
if x == "foo" { return }
if x == "foo" {
return;
}
x.clear();
for x in 3..6 { yield x }
for x in 3..6 {
yield x
}
}
}
@ -32,5 +41,4 @@ fn main() {
let mut iter = moved();
assert_eq!(iter.next(), Some(42));
assert_eq!(iter.next(), None);
}

View File

@ -10,20 +10,20 @@ Cranelift doesn't support them yet
library/core/tests/atomic.rs | 4 ---
4 files changed, 4 insertions(+), 50 deletions(-)
diff --git a/tests/lib.rs b/tests/lib.rs
diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs
index 1e336bf..35e6f54 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
--- a/coretests/tests/lib.rs
+++ b/coretests/tests/lib.rs
@@ -2,5 +2,4 @@
// tidy-alphabetical-start
-#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![cfg_attr(test, feature(cfg_match))]
#![feature(alloc_layout_extra)]
#![feature(array_chunks)]
diff --git a/tests/atomic.rs b/tests/atomic.rs
diff --git a/coretests/tests/atomic.rs b/coretests/tests/atomic.rs
index b735957..ea728b6 100644
--- a/tests/atomic.rs
+++ b/tests/atomic.rs
--- a/coretests/tests/atomic.rs
+++ b/coretests/tests/atomic.rs
@@ -185,10 +185,6 @@ fn atomic_alignment() {
assert_eq!(align_of::<AtomicU64>(), size_of::<AtomicU64>());
#[cfg(target_has_atomic = "64")]

View File

@ -1,48 +0,0 @@
From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 3 Dec 2021 12:16:30 +0100
Subject: [PATCH] Disable long running tests
---
library/core/tests/slice.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/slice.rs b/tests/slice.rs
index 8402833..84592e0 100644
--- a/tests/slice.rs
+++ b/tests/slice.rs
@@ -1809,6 +1809,7 @@ fn sort_unstable() {
}
}
+/*
#[test]
#[cfg(not(target_arch = "wasm32"))]
#[cfg_attr(miri, ignore)] // Miri is too slow
@@ -1914,6 +1915,7 @@ fn select_nth_unstable() {
v.select_nth_unstable(0);
assert!(v == [0xDEADBEEF]);
}
+*/
#[test]
#[should_panic(expected = "index 0 greater than length of slice")]
@@ -2462,6 +2462,7 @@ take_tests! {
#[cfg(not(miri))] // unused in Miri
const EMPTY_MAX: &'static [()] = &[(); usize::MAX];
+/*
// can't be a constant due to const mutability rules
#[cfg(not(miri))] // unused in Miri
macro_rules! empty_max_mut {
@@ -2485,6 +2486,7 @@ take_tests! {
(split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
(split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
}
+*/
#[test]
fn test_slice_from_ptr_range() {
--
2.26.2.7.g19db9cfb68

View File

@ -0,0 +1,105 @@
From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 3 Dec 2021 12:16:30 +0100
Subject: [PATCH] Disable long running tests
---
library/coretests/tests/slice.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/coretests/tests/slice.rs b/coretests/tests/slice.rs
index 8402833..84592e0 100644
--- a/coretests/tests/slice.rs
+++ b/coretests/tests/slice.rs
@@ -1809,6 +1809,7 @@ fn sort_unstable() {
}
}
+/*
#[test]
#[cfg(not(target_arch = "wasm32"))]
#[cfg_attr(miri, ignore)] // Miri is too slow
@@ -1914,6 +1915,7 @@ fn select_nth_unstable() {
v.select_nth_unstable(0);
assert!(v == [0xDEADBEEF]);
}
+*/
#[test]
#[should_panic(expected = "index 0 greater than length of slice")]
@@ -2462,6 +2462,7 @@ take_tests! {
#[cfg(not(miri))] // unused in Miri
const EMPTY_MAX: &'static [()] = &[(); usize::MAX];
+/*
// can't be a constant due to const mutability rules
#[cfg(not(miri))] // unused in Miri
macro_rules! empty_max_mut {
@@ -2485,6 +2486,7 @@ take_tests! {
(split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
(split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
}
+*/
#[test]
fn test_slice_from_ptr_range() {
diff --git a/alloctests/tests/sort/tests.rs b/alloctests/tests/sort/tests.rs
index d321f8d..8b2040a 100644
--- a/alloctests/tests/sort/tests.rs
+++ b/alloctests/tests/sort/tests.rs
@@ -1,3 +1,5 @@
+#![cfg(any())]
+
use std::cell::Cell;
use std::cmp::Ordering;
use std::fmt::Debug;
diff --git a/alloctests/tests/str.rs b/alloctests/tests/str.rs
index 906fa2d..b82fa99 100644
--- a/alloctests/tests/str.rs
+++ b/alloctests/tests/str.rs
@@ -2234,7 +2234,7 @@ fn const_str_ptr() {
const C: *const u8 = B as *const u8;
// Miri does not deduplicate consts (https://github.com/rust-lang/miri/issues/131)
- #[cfg(not(miri))]
+ #[cfg(any())]
{
let foo = &A as *const u8;
assert_eq!(foo, C);
diff --git a/alloctests/tests/task.rs b/alloctests/tests/task.rs
index 390dec1..87df6e6 100644
--- a/alloctests/tests/task.rs
+++ b/alloctests/tests/task.rs
@@ -4,7 +4,7 @@ use alloc::task::{LocalWake, Wake};
use core::task::{LocalWaker, Waker};
#[test]
-#[cfg_attr(miri, ignore)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
+#[ignore] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
fn test_waker_will_wake_clone() {
struct NoopWaker;
@@ -20,7 +20,7 @@ fn test_waker_will_wake_clone() {
}
#[test]
-#[cfg_attr(miri, ignore)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
+#[ignore] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
fn test_local_waker_will_wake_clone() {
struct NoopWaker;
diff --git a/alloctests/tests/vec.rs b/alloctests/tests/vec.rs
index f430d97..cfbd3cb 100644
--- a/alloctests/tests/vec.rs
+++ b/alloctests/tests/vec.rs
@@ -762,6 +762,7 @@ fn test_drain_inclusive_range() {
}
#[test]
+#[ignore]
fn test_drain_max_vec_size() {
let mut v = Vec::<()>::with_capacity(usize::MAX);
unsafe {
--
2.26.2.7.g19db9cfb68

View File

@ -1,26 +0,0 @@
From 175d52c5e1779764b66777db1e6f172c2dc365ff Mon Sep 17 00:00:00 2001
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
Date: Fri, 9 Aug 2024 15:44:51 +0000
Subject: [PATCH] Disable f16 and f128 in compiler-builtins
---
library/liballoc/Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/liballoc/Cargo.toml b/library/liballoc/Cargo.toml
index 7165c3e48af..968552ad435 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -11,7 +11,7 @@ test = { path = "../test" }
bench = false
[dependencies]
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] }
[features]
compiler-builtins-mem = ['compiler_builtins/mem']
--
2.34.1

View File

@ -1,35 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "coretests"
version = "0.0.0"
dependencies = [
"rand",
"rand_xorshift",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rand_xorshift"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
dependencies = [
"rand_core",
]

View File

@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2025-02-15"
channel = "nightly-2025-03-30"
components = ["rust-src", "rustc-dev", "llvm-tools"]
profile = "minimal"

View File

@ -1,7 +1,3 @@
ignore = [
"example/gen_block_iterate.rs", # uses edition 2024
]
# Matches rustfmt.toml of rustc
style_edition = "2024"
use_small_heuristics = "Max"

View File

@ -50,19 +50,7 @@ fn main() {
.chain([
"--".to_string(),
"-Zunstable-options".to_string(),
"-Cllvm-args=mode=jit".to_string(),
])
.collect()
}
Some("lazy-jit") => {
rustflags.push("-Cprefer-dynamic".to_owned());
args.remove(0);
IntoIterator::into_iter(["rustc".to_string()])
.chain(args)
.chain([
"--".to_string(),
"-Zunstable-options".to_string(),
"-Cllvm-args=mode=jit-lazy".to_string(),
"-Cllvm-args=jit-mode".to_string(),
])
.collect()
}

View File

@ -4,7 +4,7 @@
pushd $(dirname "$0")/../
RUSTC="$(pwd)/dist/rustc-clif"
popd
PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic $0
PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=jit-mode -Cprefer-dynamic $0
#*/
//! This program filters away uninteresting samples and trims uninteresting frames for stackcollapse

View File

@ -64,7 +64,7 @@ case $1 in
cg_clif=$(pwd)
pushd ../rust
git fetch origin master
git checkout "$RUST_VERS"
git -c advice.detachedHead=false checkout "$RUST_VERS"
"$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust
popd
git merge sync_from_rust -m "Sync from rust $RUST_VERS"

Some files were not shown because too many files have changed in this diff Show More