commit
e69303f372
1328 changed files with 15988 additions and 12999 deletions
23
.github/workflows/spellcheck.yml
vendored
23
.github/workflows/spellcheck.yml
vendored
|
|
@ -1,23 +0,0 @@
|
|||
# This workflow runs spellcheck job
|
||||
|
||||
name: Spellcheck
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
jobs:
|
||||
spellcheck:
|
||||
name: run spellchecker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: check typos
|
||||
# sync version with src/tools/tidy/src/ext_tool_checks.rs in spellcheck_runner
|
||||
uses: crate-ci/typos@v1.34.0
|
||||
with:
|
||||
# sync target files with src/tools/tidy/src/ext_tool_checks.rs in check_impl
|
||||
files: ./compiler ./library ./src/bootstrap ./src/librustdoc
|
||||
config: ./typos.toml
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -85,8 +85,6 @@ __pycache__/
|
|||
|
||||
## Node
|
||||
node_modules
|
||||
package-lock.json
|
||||
package.json
|
||||
/src/doc/rustc-dev-guide/mermaid.min.js
|
||||
|
||||
## Rustdoc GUI tests
|
||||
|
|
|
|||
159
Cargo.lock
159
Cargo.lock
|
|
@ -384,7 +384,7 @@ dependencies = [
|
|||
name = "cargo-miri"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.19.2",
|
||||
"cargo_metadata 0.21.0",
|
||||
"directories",
|
||||
"rustc-build-sysroot",
|
||||
"rustc_tools_util 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -402,6 +402,31 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-util-schemas"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830"
|
||||
dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
"serde-untagged",
|
||||
"serde-value",
|
||||
"thiserror 2.0.12",
|
||||
"toml 0.8.23",
|
||||
"unicode-xid",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.18.1"
|
||||
|
|
@ -409,7 +434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"cargo-platform 0.1.9",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -423,7 +448,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"cargo-platform 0.1.9",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform 0.2.0",
|
||||
"cargo-util-schemas",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -561,7 +601,7 @@ dependencies = [
|
|||
"tempfile",
|
||||
"termize",
|
||||
"toml 0.7.8",
|
||||
"ui_test 0.30.2",
|
||||
"ui_test",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
|
|
@ -703,6 +743,15 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "comma"
|
||||
version = "1.0.0"
|
||||
|
|
@ -716,7 +765,7 @@ dependencies = [
|
|||
"anstyle-svg",
|
||||
"build_helper",
|
||||
"camino",
|
||||
"colored",
|
||||
"colored 2.2.0",
|
||||
"diff",
|
||||
"getopts",
|
||||
"glob",
|
||||
|
|
@ -1143,6 +1192,16 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"typeid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.13"
|
||||
|
|
@ -1831,17 +1890,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ipc-channel"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb8251fb7bcd9ccd3725ed8deae9fe7db8e586495c9eb5b0c52e6233e5e75ea"
|
||||
checksum = "5b1c98b70019c830a1fc39cecfe1f60ff99c4122f0a189697c810c90ec545c14"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"crossbeam-channel",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"mio",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.1",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"uuid",
|
||||
|
|
@ -2240,7 +2298,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
|
@ -2263,7 +2320,7 @@ dependencies = [
|
|||
"capstone",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"colored",
|
||||
"colored 3.0.0",
|
||||
"directories",
|
||||
"getrandom 0.3.3",
|
||||
"ipc-channel",
|
||||
|
|
@ -2280,7 +2337,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"tempfile",
|
||||
"tikv-jemalloc-sys",
|
||||
"ui_test 0.29.2",
|
||||
"ui_test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2560,6 +2617,15 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "2.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
|
@ -4845,6 +4911,27 @@ dependencies = [
|
|||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-untagged"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e"
|
||||
dependencies = [
|
||||
"erased-serde",
|
||||
"serde",
|
||||
"typeid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-value"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
||||
dependencies = [
|
||||
"ordered-float",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
|
|
@ -4942,16 +5029,6 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spanned"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86af297923fbcfd107c20a189a6e9c872160df71a7190ae4a7a6c5dce4b2feb6"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"color-eyre",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spanned"
|
||||
version = "0.4.1"
|
||||
|
|
@ -5529,6 +5606,12 @@ dependencies = [
|
|||
"rustc-hash 2.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typeid"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
|
|
@ -5550,32 +5633,6 @@ version = "0.1.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||
|
||||
[[package]]
|
||||
name = "ui_test"
|
||||
version = "0.29.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1211b1111c752c73b33073d2958072be08825fd97c9ab4d83444da361a06634b"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.11.5",
|
||||
"anyhow",
|
||||
"bstr",
|
||||
"cargo-platform",
|
||||
"cargo_metadata 0.18.1",
|
||||
"color-eyre",
|
||||
"colored",
|
||||
"comma",
|
||||
"crossbeam-channel",
|
||||
"indicatif",
|
||||
"levenshtein",
|
||||
"prettydiff",
|
||||
"regex",
|
||||
"rustc_version",
|
||||
"rustfix",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"spanned 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ui_test"
|
||||
version = "0.30.2"
|
||||
|
|
@ -5585,10 +5642,10 @@ dependencies = [
|
|||
"annotate-snippets 0.11.5",
|
||||
"anyhow",
|
||||
"bstr",
|
||||
"cargo-platform",
|
||||
"cargo-platform 0.1.9",
|
||||
"cargo_metadata 0.18.1",
|
||||
"color-eyre",
|
||||
"colored",
|
||||
"colored 2.2.0",
|
||||
"comma",
|
||||
"crossbeam-channel",
|
||||
"indicatif",
|
||||
|
|
@ -5599,7 +5656,7 @@ dependencies = [
|
|||
"rustfix",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"spanned 0.4.1",
|
||||
"spanned",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ path = [
|
|||
"rust-bors.toml",
|
||||
"triagebot.toml",
|
||||
"typos.toml",
|
||||
"package.json",
|
||||
"package-lock.json",
|
||||
"x",
|
||||
"x.ps1",
|
||||
"x.py",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_macros::{Decodable, Encodable, Walkable};
|
||||
use rustc_span::{Ident, Span, Symbol};
|
||||
|
||||
use crate::Expr;
|
||||
|
|
@ -41,7 +41,7 @@ use crate::token::LitKind;
|
|||
/// Basically the "AST" for a complete `format_args!()`.
|
||||
///
|
||||
/// E.g., `format_args!("hello {name}");`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub struct FormatArgs {
|
||||
pub span: Span,
|
||||
pub template: Vec<FormatArgsPiece>,
|
||||
|
|
@ -63,7 +63,7 @@ pub struct FormatArgs {
|
|||
/// A piece of a format template string.
|
||||
///
|
||||
/// E.g. "hello" or "{name}".
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub enum FormatArgsPiece {
|
||||
Literal(Symbol),
|
||||
Placeholder(FormatPlaceholder),
|
||||
|
|
@ -73,7 +73,7 @@ pub enum FormatArgsPiece {
|
|||
///
|
||||
/// E.g. `1, 2, name="ferris", n=3`,
|
||||
/// but also implicit captured arguments like `x` in `format_args!("{x}")`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub struct FormatArguments {
|
||||
arguments: Vec<FormatArgument>,
|
||||
num_unnamed_args: usize,
|
||||
|
|
@ -144,13 +144,13 @@ impl FormatArguments {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub struct FormatArgument {
|
||||
pub kind: FormatArgumentKind,
|
||||
pub expr: P<Expr>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub enum FormatArgumentKind {
|
||||
/// `format_args(…, arg)`
|
||||
Normal,
|
||||
|
|
@ -170,24 +170,28 @@ impl FormatArgumentKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
|
||||
pub struct FormatPlaceholder {
|
||||
/// Index into [`FormatArgs::arguments`].
|
||||
pub argument: FormatArgPosition,
|
||||
/// The span inside the format string for the full `{…}` placeholder.
|
||||
pub span: Option<Span>,
|
||||
/// `{}`, `{:?}`, or `{:x}`, etc.
|
||||
#[visitable(ignore)]
|
||||
pub format_trait: FormatTrait,
|
||||
/// `{}` or `{:.5}` or `{:-^20}`, etc.
|
||||
#[visitable(ignore)]
|
||||
pub format_options: FormatOptions,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
|
||||
pub struct FormatArgPosition {
|
||||
/// Which argument this position refers to (Ok),
|
||||
/// or would've referred to if it existed (Err).
|
||||
#[visitable(ignore)]
|
||||
pub index: Result<usize, usize>,
|
||||
/// What kind of position this is. See [`FormatArgPositionKind`].
|
||||
#[visitable(ignore)]
|
||||
pub kind: FormatArgPositionKind,
|
||||
/// The span of the name or number.
|
||||
pub span: Option<Span>,
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ use std::panic;
|
|||
|
||||
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{Ident, Span};
|
||||
use rustc_span::{Ident, Span, Symbol};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::ptr::P;
|
||||
use crate::tokenstream::*;
|
||||
use crate::visit::{AssocCtxt, BoundKind, FnCtxt, VisitorResult, try_visit, visit_opt, walk_list};
|
||||
use crate::visit::{AssocCtxt, BoundKind, FnCtxt, LifetimeCtxt, VisitorResult, try_visit};
|
||||
|
||||
mod sealed {
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
|
|
@ -36,11 +36,249 @@ mod sealed {
|
|||
|
||||
use sealed::MutVisitorResult;
|
||||
|
||||
pub(crate) trait MutVisitable<V: MutVisitor> {
|
||||
type Extra: Copy;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra);
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T: ?Sized> MutVisitable<V> for P<T>
|
||||
where
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = T::Extra;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
(**self).visit_mut(visitor, extra)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T> MutVisitable<V> for Option<T>
|
||||
where
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = T::Extra;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
if let Some(this) = self {
|
||||
this.visit_mut(visitor, extra)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T> MutVisitable<V> for Spanned<T>
|
||||
where
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = T::Extra;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
let Spanned { span, node } = self;
|
||||
span.visit_mut(visitor, ());
|
||||
node.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T> MutVisitable<V> for [T]
|
||||
where
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = T::Extra;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
for item in self {
|
||||
item.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T> MutVisitable<V> for Vec<T>
|
||||
where
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = T::Extra;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
for item in self {
|
||||
item.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T> MutVisitable<V> for (T,)
|
||||
where
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = T::Extra;
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
self.0.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T1, T2> MutVisitable<V> for (T1, T2)
|
||||
where
|
||||
T1: MutVisitable<V, Extra = ()>,
|
||||
T2: MutVisitable<V, Extra = ()>,
|
||||
{
|
||||
type Extra = ();
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
self.0.visit_mut(visitor, extra);
|
||||
self.1.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T1, T2, T3> MutVisitable<V> for (T1, T2, T3)
|
||||
where
|
||||
T1: MutVisitable<V, Extra = ()>,
|
||||
T2: MutVisitable<V, Extra = ()>,
|
||||
T3: MutVisitable<V, Extra = ()>,
|
||||
{
|
||||
type Extra = ();
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
self.0.visit_mut(visitor, extra);
|
||||
self.1.visit_mut(visitor, extra);
|
||||
self.2.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: MutVisitor, T1, T2, T3, T4> MutVisitable<V> for (T1, T2, T3, T4)
|
||||
where
|
||||
T1: MutVisitable<V, Extra = ()>,
|
||||
T2: MutVisitable<V, Extra = ()>,
|
||||
T3: MutVisitable<V, Extra = ()>,
|
||||
T4: MutVisitable<V, Extra = ()>,
|
||||
{
|
||||
type Extra = ();
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
self.0.visit_mut(visitor, extra);
|
||||
self.1.visit_mut(visitor, extra);
|
||||
self.2.visit_mut(visitor, extra);
|
||||
self.3.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MutWalkable<V: MutVisitor> {
|
||||
fn walk_mut(&mut self, visitor: &mut V);
|
||||
}
|
||||
|
||||
macro_rules! visit_visitable {
|
||||
(mut $visitor:expr, $($expr:expr),* $(,)?) => {{
|
||||
$(MutVisitable::visit_mut($expr, $visitor, ());)*
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! visit_visitable_with {
|
||||
(mut $visitor:expr, $expr:expr, $extra:expr $(,)?) => {
|
||||
MutVisitable::visit_mut($expr, $visitor, $extra)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! walk_walkable {
|
||||
($visitor:expr, $expr:expr, mut) => {
|
||||
MutWalkable::walk_mut($expr, $visitor)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_visitable {
|
||||
(|&mut $self:ident: $self_ty:ty,
|
||||
$vis:ident: &mut $vis_ty:ident,
|
||||
$extra:ident: $extra_ty:ty| $block:block) => {
|
||||
#[allow(unused_parens, non_local_definitions)]
|
||||
impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty {
|
||||
type Extra = $extra_ty;
|
||||
fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result {
|
||||
$block
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_walkable {
|
||||
($(<$K:ident: $Kb:ident>)? |&mut $self:ident: $self_ty:ty,
|
||||
$vis:ident: &mut $vis_ty:ident| $block:block) => {
|
||||
#[allow(unused_parens, non_local_definitions)]
|
||||
impl<$($K: $Kb,)? $vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty {
|
||||
fn walk_mut(&mut $self, $vis: &mut $vis_ty) -> V::Result {
|
||||
$block
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_visitable_noop {
|
||||
(<mut> $($ty:ty,)*) => {
|
||||
$(
|
||||
impl_visitable!(|&mut self: $ty, _vis: &mut V, _extra: ()| {});
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_visitable_list {
|
||||
(<mut> $($ty:ty,)*) => {
|
||||
$(impl<V: MutVisitor, T> MutVisitable<V> for $ty
|
||||
where
|
||||
for<'a> &'a mut $ty: IntoIterator<Item = &'a mut T>,
|
||||
T: MutVisitable<V>,
|
||||
{
|
||||
type Extra = <T as MutVisitable<V>>::Extra;
|
||||
|
||||
#[inline]
|
||||
fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
|
||||
for i in self {
|
||||
i.visit_mut(visitor, extra);
|
||||
}
|
||||
}
|
||||
})*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_visitable_direct {
|
||||
(<mut> $($ty:ty,)*) => {
|
||||
$(impl_visitable!(
|
||||
|&mut self: $ty, visitor: &mut V, _extra: ()| {
|
||||
MutWalkable::walk_mut(self, visitor)
|
||||
}
|
||||
);)*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_visitable_calling_walkable {
|
||||
(<mut>
|
||||
$( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )*
|
||||
) => {
|
||||
$(fn $method(&mut self, node: &mut $ty $(, $extra_name:$extra_ty)?) {
|
||||
impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| {
|
||||
let ($($extra_name)?) = extra;
|
||||
visitor.$method(self $(, $extra_name)?);
|
||||
});
|
||||
walk_walkable!(self, node, mut)
|
||||
})*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_named_walk {
|
||||
((mut) $Visitor:ident
|
||||
$( pub fn $method:ident($ty:ty); )*
|
||||
) => {
|
||||
$(pub fn $method<V: $Visitor>(visitor: &mut V, node: &mut $ty) {
|
||||
walk_walkable!(visitor, node, mut)
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
super::common_visitor_and_walkers!((mut) MutVisitor);
|
||||
|
||||
macro_rules! generate_flat_map_visitor_fns {
|
||||
($($name:ident, $Ty:ty, $flat_map_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
|
||||
$(
|
||||
#[allow(unused_parens)]
|
||||
impl<V: MutVisitor> MutVisitable<V> for ThinVec<$Ty> {
|
||||
type Extra = ($($ParamTy),*);
|
||||
|
||||
#[inline]
|
||||
fn visit_mut(
|
||||
&mut self,
|
||||
visitor: &mut V,
|
||||
($($param),*): Self::Extra,
|
||||
) -> V::Result {
|
||||
$name(visitor, self $(, $param)*)
|
||||
}
|
||||
}
|
||||
|
||||
fn $name<V: MutVisitor>(
|
||||
vis: &mut V,
|
||||
values: &mut ThinVec<$Ty>,
|
||||
|
|
@ -78,15 +316,6 @@ pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
|||
smallvec![fp]
|
||||
}
|
||||
|
||||
fn visit_nested_use_tree<V: MutVisitor>(
|
||||
vis: &mut V,
|
||||
nested_tree: &mut UseTree,
|
||||
nested_id: &mut NodeId,
|
||||
) {
|
||||
vis.visit_id(nested_id);
|
||||
vis.visit_use_tree(nested_tree);
|
||||
}
|
||||
|
||||
macro_rules! generate_walk_flat_map_fns {
|
||||
($($fn_name:ident($Ty:ty$(,$extra_name:ident: $ExtraTy:ty)*) => $visit_fn_name:ident;)+) => {$(
|
||||
pub fn $fn_name<V: MutVisitor>(vis: &mut V, mut value: $Ty$(,$extra_name: $ExtraTy)*) -> SmallVec<[$Ty; 1]> {
|
||||
|
|
@ -109,14 +338,6 @@ generate_walk_flat_map_fns! {
|
|||
walk_flat_map_assoc_item(P<AssocItem>, ctxt: AssocCtxt) => visit_assoc_item;
|
||||
}
|
||||
|
||||
fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWhereClauses) {
|
||||
let TyAliasWhereClauses { before, after, split: _ } = tawcs;
|
||||
let TyAliasWhereClause { has_where_token: _, span: span_before } = before;
|
||||
let TyAliasWhereClause { has_where_token: _, span: span_after } = after;
|
||||
vis.visit_span(span_before);
|
||||
vis.visit_span(span_after);
|
||||
}
|
||||
|
||||
pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> {
|
||||
vis.visit_expr(&mut e);
|
||||
Some(e)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use std::{cmp, fmt, iter, mem};
|
|||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym};
|
||||
use thin_vec::ThinVec;
|
||||
|
|
@ -977,7 +977,7 @@ impl TokenCursor {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
|
||||
pub struct DelimSpan {
|
||||
pub open: Span,
|
||||
pub close: Span,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -874,25 +874,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
/// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
|
||||
/// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
|
||||
/// parameters will be successful.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
#[inline]
|
||||
fn lower_lifetime_binder(
|
||||
&mut self,
|
||||
binder: NodeId,
|
||||
generic_params: &[GenericParam],
|
||||
) -> &'hir [hir::GenericParam<'hir>] {
|
||||
let mut generic_params: Vec<_> = self
|
||||
.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
|
||||
.collect();
|
||||
// Start by creating params for extra lifetimes params, as this creates the definitions
|
||||
// that may be referred to by the AST inside `generic_params`.
|
||||
let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
|
||||
debug!(?extra_lifetimes);
|
||||
generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
|
||||
self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
|
||||
}));
|
||||
let generic_params = self.arena.alloc_from_iter(generic_params);
|
||||
debug!(?generic_params);
|
||||
|
||||
generic_params
|
||||
let extra_lifetimes: Vec<_> = extra_lifetimes
|
||||
.into_iter()
|
||||
.filter_map(|(ident, node_id, res)| {
|
||||
self.lifetime_res_to_generic_param(
|
||||
ident,
|
||||
node_id,
|
||||
res,
|
||||
hir::GenericParamSource::Binder,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let arena = self.arena;
|
||||
let explicit_generic_params =
|
||||
self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);
|
||||
arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))
|
||||
}
|
||||
|
||||
fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
|
|
|
|||
|
|
@ -157,6 +157,19 @@ pub enum UsedBy {
|
|||
Linker,
|
||||
}
|
||||
|
||||
#[derive(Encodable, Decodable, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
pub enum MacroUseArgs {
|
||||
UseAll,
|
||||
UseSpecific(ThinVec<Ident>),
|
||||
}
|
||||
|
||||
impl Default for MacroUseArgs {
|
||||
fn default() -> Self {
|
||||
Self::UseSpecific(ThinVec::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Encodable, Decodable, HashStable_Generic)]
|
||||
pub struct StrippedCfgItem<ModId = DefId> {
|
||||
pub parent_module: ModId,
|
||||
|
|
@ -234,6 +247,7 @@ pub enum CfgEntry {
|
|||
pub enum AttributeKind {
|
||||
// tidy-alphabetical-start
|
||||
/// Represents `#[align(N)]`.
|
||||
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
|
||||
Align { align: Align, span: Span },
|
||||
|
||||
/// Represents `#[rustc_allow_const_fn_unstable]`.
|
||||
|
|
@ -350,9 +364,15 @@ pub enum AttributeKind {
|
|||
/// Represents `#[loop_match]`.
|
||||
LoopMatch(Span),
|
||||
|
||||
/// Represents `#[macro_escape]`.
|
||||
MacroEscape(Span),
|
||||
|
||||
/// Represents `#[rustc_macro_transparency]`.
|
||||
MacroTransparency(Transparency),
|
||||
|
||||
/// Represents `#[macro_use]`.
|
||||
MacroUse { span: Span, arguments: MacroUseArgs },
|
||||
|
||||
/// Represents `#[marker]`.
|
||||
Marker(Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ impl AttributeKind {
|
|||
LinkOrdinal { .. } => No,
|
||||
LinkSection { .. } => Yes, // Needed for rustdoc
|
||||
LoopMatch(..) => No,
|
||||
MacroEscape(..) => No,
|
||||
MacroTransparency(..) => Yes,
|
||||
MacroUse { .. } => No,
|
||||
Marker(..) => No,
|
||||
MayDangle(..) => No,
|
||||
MustUse { .. } => Yes,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use rustc_ast::token::CommentKind;
|
|||
use rustc_ast::{AttrStyle, IntTy, UintTy};
|
||||
use rustc_ast_pretty::pp::Printer;
|
||||
use rustc_span::hygiene::Transparency;
|
||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
|
||||
pub use stability::*;
|
||||
use thin_vec::ThinVec;
|
||||
pub use version::*;
|
||||
|
|
@ -172,7 +172,7 @@ macro_rules! print_tup {
|
|||
print_tup!(A B C D E F G H);
|
||||
print_skip!(Span, (), ErrorGuaranteed);
|
||||
print_disp!(u16, bool, NonZero<u32>);
|
||||
print_debug!(Symbol, UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
|
||||
print_debug!(Symbol, Ident, UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
|
||||
|
||||
/// Finds attributes in sequences of attributes by pattern matching.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
|
|||
sym::instruction_set,
|
||||
sym::repr,
|
||||
sym::rustc_std_internal_symbol,
|
||||
sym::align,
|
||||
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
|
||||
sym::rustc_align,
|
||||
// obviously compatible with self
|
||||
sym::naked,
|
||||
// documentation
|
||||
|
|
|
|||
115
compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
Normal file
115
compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
use rustc_attr_data_structures::{AttributeKind, MacroUseArgs};
|
||||
use rustc_errors::DiagArgValue;
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::attributes::{AcceptMapping, AttributeParser, NoArgsAttributeParser, OnDuplicate};
|
||||
use crate::context::{AcceptContext, FinalizeContext, Stage};
|
||||
use crate::parser::ArgParser;
|
||||
use crate::session_diagnostics;
|
||||
|
||||
pub(crate) struct MacroEscapeParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for MacroEscapeParser {
|
||||
const PATH: &[Symbol] = &[sym::macro_escape];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::MacroEscape;
|
||||
}
|
||||
|
||||
/// `#[macro_use]` attributes can either:
|
||||
/// - Use all macros from a crate, if provided without arguments
|
||||
/// - Use specific macros from a crate, if provided with arguments `#[macro_use(macro1, macro2)]`
|
||||
/// A warning should be provided if an use all is combined with specific uses, or if multiple use-alls are used.
|
||||
#[derive(Default)]
|
||||
pub(crate) struct MacroUseParser {
|
||||
state: MacroUseArgs,
|
||||
|
||||
/// Spans of all `#[macro_use]` arguments with arguments, used for linting
|
||||
uses_attr_spans: ThinVec<Span>,
|
||||
/// If `state` is `UseSpecific`, stores the span of the first `#[macro_use]` argument, used as the span for this attribute
|
||||
/// If `state` is `UseAll`, stores the span of the first `#[macro_use]` arguments without arguments
|
||||
first_span: Option<Span>,
|
||||
}
|
||||
|
||||
const MACRO_USE_TEMPLATE: AttributeTemplate = template!(Word, List: "name1, name2, ...");
|
||||
|
||||
impl<S: Stage> AttributeParser<S> for MacroUseParser {
|
||||
const ATTRIBUTES: AcceptMapping<Self, S> = &[(
|
||||
&[sym::macro_use],
|
||||
MACRO_USE_TEMPLATE,
|
||||
|group: &mut Self, cx: &mut AcceptContext<'_, '_, S>, args| {
|
||||
let span = cx.attr_span;
|
||||
group.first_span.get_or_insert(span);
|
||||
match args {
|
||||
ArgParser::NoArgs => {
|
||||
match group.state {
|
||||
MacroUseArgs::UseAll => {
|
||||
let first_span = group.first_span.expect(
|
||||
"State is UseAll is some so this is not the first attribute",
|
||||
);
|
||||
// Since there is a `#[macro_use]` import already, give a warning
|
||||
cx.warn_unused_duplicate(first_span, span);
|
||||
}
|
||||
MacroUseArgs::UseSpecific(_) => {
|
||||
group.state = MacroUseArgs::UseAll;
|
||||
group.first_span = Some(span);
|
||||
// If there is a `#[macro_use]` attribute, warn on all `#[macro_use(...)]` attributes since everything is already imported
|
||||
for specific_use in group.uses_attr_spans.drain(..) {
|
||||
cx.warn_unused_duplicate(span, specific_use);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ArgParser::List(list) => {
|
||||
if list.is_empty() {
|
||||
cx.warn_empty_attribute(list.span);
|
||||
return;
|
||||
}
|
||||
|
||||
match &mut group.state {
|
||||
MacroUseArgs::UseAll => {
|
||||
let first_span = group.first_span.expect(
|
||||
"State is UseAll is some so this is not the first attribute",
|
||||
);
|
||||
cx.warn_unused_duplicate(first_span, span);
|
||||
}
|
||||
MacroUseArgs::UseSpecific(arguments) => {
|
||||
// Store here so if we encounter a `UseAll` later we can still lint this attribute
|
||||
group.uses_attr_spans.push(cx.attr_span);
|
||||
|
||||
for item in list.mixed() {
|
||||
let Some(item) = item.meta_item() else {
|
||||
cx.expected_identifier(item.span());
|
||||
continue;
|
||||
};
|
||||
if let Err(err_span) = item.args().no_args() {
|
||||
cx.expected_no_args(err_span);
|
||||
continue;
|
||||
}
|
||||
let Some(item) = item.path().word() else {
|
||||
cx.expected_identifier(item.span());
|
||||
continue;
|
||||
};
|
||||
arguments.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ArgParser::NameValue(_) => {
|
||||
let suggestions = MACRO_USE_TEMPLATE.suggestions(false, sym::macro_use);
|
||||
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
|
||||
),
|
||||
span,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
)];
|
||||
|
||||
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state })
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ pub(crate) mod inline;
|
|||
pub(crate) mod link_attrs;
|
||||
pub(crate) mod lint_helpers;
|
||||
pub(crate) mod loop_match;
|
||||
pub(crate) mod macro_attrs;
|
||||
pub(crate) mod must_use;
|
||||
pub(crate) mod no_implicit_prelude;
|
||||
pub(crate) mod non_exhaustive;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
|
|||
ArgParser::List(_) => {
|
||||
let suggestions =
|
||||
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use");
|
||||
cx.emit_err(session_diagnostics::MustUseIllFormedAttributeInput {
|
||||
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
|
||||
num_suggestions: suggestions.len(),
|
||||
suggestions: DiagArgValue::StrListSepByAnd(
|
||||
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
|
|||
pub(crate) struct AlignParser(Option<(Align, Span)>);
|
||||
|
||||
impl AlignParser {
|
||||
const PATH: &'static [Symbol] = &[sym::align];
|
||||
const PATH: &'static [Symbol] = &[sym::rustc_align];
|
||||
const TEMPLATE: AttributeTemplate = template!(List: "<alignment in bytes>");
|
||||
|
||||
fn parse<'c, S: Stage>(
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use crate::attributes::lint_helpers::{
|
|||
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
|
||||
};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::macro_attrs::{MacroEscapeParser, MacroUseParser};
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
||||
use crate::attributes::non_exhaustive::NonExhaustiveParser;
|
||||
|
|
@ -126,6 +127,7 @@ attribute_parsers!(
|
|||
BodyStabilityParser,
|
||||
ConfusablesParser,
|
||||
ConstStabilityParser,
|
||||
MacroUseParser,
|
||||
NakedParser,
|
||||
StabilityParser,
|
||||
UsedParser,
|
||||
|
|
@ -174,6 +176,7 @@ attribute_parsers!(
|
|||
Single<WithoutArgs<FfiPureParser>>,
|
||||
Single<WithoutArgs<FundamentalParser>>,
|
||||
Single<WithoutArgs<LoopMatchParser>>,
|
||||
Single<WithoutArgs<MacroEscapeParser>>,
|
||||
Single<WithoutArgs<MarkerParser>>,
|
||||
Single<WithoutArgs<MayDangleParser>>,
|
||||
Single<WithoutArgs<NoImplicitPreludeParser>>,
|
||||
|
|
@ -386,6 +389,17 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
|
|||
})
|
||||
}
|
||||
|
||||
/// emit an error that a `name` was expected here
|
||||
pub(crate) fn expected_identifier(&self, span: Span) -> ErrorGuaranteed {
|
||||
self.emit_err(AttributeParseError {
|
||||
span,
|
||||
attr_span: self.attr_span,
|
||||
template: self.template.clone(),
|
||||
attribute: self.attr_path.clone(),
|
||||
reason: AttributeParseErrorReason::ExpectedIdentifier,
|
||||
})
|
||||
}
|
||||
|
||||
/// emit an error that a `name = value` pair was expected at this span. The symbol can be given for
|
||||
/// a nicer error message talking about the specific name that was found lacking a value.
|
||||
pub(crate) fn expected_name_value(&self, span: Span, name: Option<Symbol>) -> ErrorGuaranteed {
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ pub(crate) struct IllFormedAttributeInput {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_ill_formed_attribute_input)]
|
||||
pub(crate) struct MustUseIllFormedAttributeInput {
|
||||
pub(crate) struct IllFormedAttributeInputLint {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub num_suggestions: usize,
|
||||
|
|
@ -549,6 +549,7 @@ pub(crate) enum AttributeParseErrorReason {
|
|||
/// Should we tell the user to write a list when they didn't?
|
||||
list: bool,
|
||||
},
|
||||
ExpectedIdentifier,
|
||||
}
|
||||
|
||||
pub(crate) struct AttributeParseError {
|
||||
|
|
@ -600,11 +601,11 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError {
|
|||
diag.code(E0538);
|
||||
}
|
||||
AttributeParseErrorReason::UnexpectedLiteral => {
|
||||
diag.span_label(self.span, format!("didn't expect a literal here"));
|
||||
diag.span_label(self.span, "didn't expect a literal here");
|
||||
diag.code(E0565);
|
||||
}
|
||||
AttributeParseErrorReason::ExpectedNoArgs => {
|
||||
diag.span_label(self.span, format!("didn't expect any arguments here"));
|
||||
diag.span_label(self.span, "didn't expect any arguments here");
|
||||
diag.code(E0565);
|
||||
}
|
||||
AttributeParseErrorReason::ExpectedNameValue(None) => {
|
||||
|
|
@ -684,6 +685,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError {
|
|||
}
|
||||
}
|
||||
}
|
||||
AttributeParseErrorReason::ExpectedIdentifier => {
|
||||
diag.span_label(self.span, "expected a valid identifier here");
|
||||
}
|
||||
}
|
||||
|
||||
let suggestions = self.template.suggestions(false, &name);
|
||||
|
|
|
|||
|
|
@ -303,10 +303,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
}
|
||||
|
||||
fn has_ambiguous_copy(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
let Some(copy_trait_def) = self.infcx.tcx.lang_items().copy_trait() else { return false };
|
||||
// This is only going to be ambiguous if there are incoherent impls, because otherwise
|
||||
// ambiguity should never happen in MIR.
|
||||
self.infcx.type_implements_trait(copy_trait_def, [ty], self.infcx.param_env).may_apply()
|
||||
let Some(copy_def_id) = self.infcx.tcx.lang_items().copy_trait() else { return false };
|
||||
|
||||
// Avoid bogus move errors because of an incoherent `Copy` impl.
|
||||
self.infcx.type_implements_trait(copy_def_id, [ty], self.infcx.param_env).may_apply()
|
||||
&& self.infcx.tcx.coherent_trait(copy_def_id).is_err()
|
||||
}
|
||||
|
||||
fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@
|
|||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
struct f32x4(pub [f32; 4]);
|
||||
|
||||
impl f32x4 {
|
||||
fn into_array(self) -> [f32; 4] {
|
||||
unsafe { std::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
use std::intrinsics::simd::*;
|
||||
|
||||
fn main() {
|
||||
|
|
@ -29,22 +35,22 @@ fn main() {
|
|||
unsafe {
|
||||
let min0 = simd_fmin(x, y);
|
||||
let min1 = simd_fmin(y, x);
|
||||
assert_eq!(min0, min1);
|
||||
assert_eq!(min0.into_array(), min1.into_array());
|
||||
let e = f32x4([1.0, 1.0, 3.0, 3.0]);
|
||||
assert_eq!(min0, e);
|
||||
assert_eq!(min0.into_array(), e.into_array());
|
||||
let minn = simd_fmin(x, n);
|
||||
assert_eq!(minn, x);
|
||||
assert_eq!(minn.into_array(), x.into_array());
|
||||
let minn = simd_fmin(y, n);
|
||||
assert_eq!(minn, y);
|
||||
assert_eq!(minn.into_array(), y.into_array());
|
||||
|
||||
let max0 = simd_fmax(x, y);
|
||||
let max1 = simd_fmax(y, x);
|
||||
assert_eq!(max0, max1);
|
||||
assert_eq!(max0.into_array(), max1.into_array());
|
||||
let e = f32x4([2.0, 2.0, 4.0, 4.0]);
|
||||
assert_eq!(max0, e);
|
||||
assert_eq!(max0.into_array(), e.into_array());
|
||||
let maxn = simd_fmax(x, n);
|
||||
assert_eq!(maxn, x);
|
||||
assert_eq!(maxn.into_array(), x.into_array());
|
||||
let maxn = simd_fmax(y, n);
|
||||
assert_eq!(maxn, y);
|
||||
assert_eq!(maxn.into_array(), y.into_array());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,7 +348,8 @@ fn main() {
|
|||
struct V([f64; 2]);
|
||||
|
||||
let f = V([0.0, 1.0]);
|
||||
let _a = f.0[0];
|
||||
let fp = (&raw const f) as *const [f64; 2];
|
||||
let _a = (unsafe { &*fp })[0];
|
||||
|
||||
stack_val_align();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||
&"always",
|
||||
&"--stage",
|
||||
&"0",
|
||||
&"tests/assembly/asm",
|
||||
&"tests/assembly-llvm/asm",
|
||||
&"--compiletest-rustc-args",
|
||||
&rustc_args,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -654,6 +654,7 @@ pub(crate) fn run_pass_manager(
|
|||
// We then run the llvm_optimize function a second time, to optimize the code which we generated
|
||||
// in the enzyme differentiation pass.
|
||||
let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable);
|
||||
let enable_gpu = config.offload.contains(&config::Offload::Enable);
|
||||
let stage = if thin {
|
||||
write::AutodiffStage::PreAD
|
||||
} else {
|
||||
|
|
@ -668,6 +669,12 @@ pub(crate) fn run_pass_manager(
|
|||
write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?;
|
||||
}
|
||||
|
||||
if enable_gpu && !thin {
|
||||
let cx =
|
||||
SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size);
|
||||
crate::builder::gpu_offload::handle_gpu_code(cgcx, &cx);
|
||||
}
|
||||
|
||||
if cfg!(llvm_enzyme) && enable_ad && !thin {
|
||||
let cx =
|
||||
SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::ops::Deref;
|
|||
use std::{iter, ptr};
|
||||
|
||||
pub(crate) mod autodiff;
|
||||
pub(crate) mod gpu_offload;
|
||||
|
||||
use libc::{c_char, c_uint, size_t};
|
||||
use rustc_abi as abi;
|
||||
|
|
@ -117,6 +118,74 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
|
|||
}
|
||||
bx
|
||||
}
|
||||
|
||||
// The generic builder has less functionality and thus (unlike the other alloca) we can not
|
||||
// easily jump to the beginning of the function to place our allocas there. We trust the user
|
||||
// to manually do that. FIXME(offload): improve the genericCx and add more llvm wrappers to
|
||||
// handle this.
|
||||
pub(crate) fn direct_alloca(&mut self, ty: &'ll Type, align: Align, name: &str) -> &'ll Value {
|
||||
let val = unsafe {
|
||||
let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED);
|
||||
llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
|
||||
// Cast to default addrspace if necessary
|
||||
llvm::LLVMBuildPointerCast(self.llbuilder, alloca, self.cx.type_ptr(), UNNAMED)
|
||||
};
|
||||
if name != "" {
|
||||
let name = std::ffi::CString::new(name).unwrap();
|
||||
llvm::set_value_name(val, &name.as_bytes());
|
||||
}
|
||||
val
|
||||
}
|
||||
|
||||
pub(crate) fn inbounds_gep(
|
||||
&mut self,
|
||||
ty: &'ll Type,
|
||||
ptr: &'ll Value,
|
||||
indices: &[&'ll Value],
|
||||
) -> &'ll Value {
|
||||
unsafe {
|
||||
llvm::LLVMBuildGEPWithNoWrapFlags(
|
||||
self.llbuilder,
|
||||
ty,
|
||||
ptr,
|
||||
indices.as_ptr(),
|
||||
indices.len() as c_uint,
|
||||
UNNAMED,
|
||||
GEPNoWrapFlags::InBounds,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
|
||||
debug!("Store {:?} -> {:?}", val, ptr);
|
||||
assert_eq!(self.cx.type_kind(self.cx.val_ty(ptr)), TypeKind::Pointer);
|
||||
unsafe {
|
||||
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
|
||||
llvm::LLVMSetAlignment(store, align.bytes() as c_uint);
|
||||
store
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value {
|
||||
unsafe {
|
||||
let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED);
|
||||
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
|
||||
load
|
||||
}
|
||||
}
|
||||
|
||||
fn memset(&mut self, ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, align: Align) {
|
||||
unsafe {
|
||||
llvm::LLVMRustBuildMemSet(
|
||||
self.llbuilder,
|
||||
ptr,
|
||||
align.bytes() as c_uint,
|
||||
fill_byte,
|
||||
size,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Empty string, to be used where LLVM expects an instruction name, indicating
|
||||
|
|
|
|||
439
compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs
Normal file
439
compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
use std::ffi::CString;
|
||||
|
||||
use llvm::Linkage::*;
|
||||
use rustc_abi::Align;
|
||||
use rustc_codegen_ssa::back::write::CodegenContext;
|
||||
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods;
|
||||
|
||||
use crate::builder::SBuilder;
|
||||
use crate::common::AsCCharPtr;
|
||||
use crate::llvm::AttributePlace::Function;
|
||||
use crate::llvm::{self, Linkage, Type, Value};
|
||||
use crate::{LlvmCodegenBackend, SimpleCx, attributes};
|
||||
|
||||
pub(crate) fn handle_gpu_code<'ll>(
|
||||
_cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cx: &'ll SimpleCx<'_>,
|
||||
) {
|
||||
// The offload memory transfer type for each kernel
|
||||
let mut o_types = vec![];
|
||||
let mut kernels = vec![];
|
||||
let offload_entry_ty = add_tgt_offload_entry(&cx);
|
||||
for num in 0..9 {
|
||||
let kernel = cx.get_function(&format!("kernel_{num}"));
|
||||
if let Some(kernel) = kernel {
|
||||
o_types.push(gen_define_handling(&cx, kernel, offload_entry_ty, num));
|
||||
kernels.push(kernel);
|
||||
}
|
||||
}
|
||||
|
||||
gen_call_handling(&cx, &kernels, &o_types);
|
||||
}
|
||||
|
||||
// What is our @1 here? A magic global, used in our data_{begin/update/end}_mapper:
|
||||
// @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
|
||||
// @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8
|
||||
fn generate_at_one<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Value {
|
||||
// @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
|
||||
let unknown_txt = ";unknown;unknown;0;0;;";
|
||||
let c_entry_name = CString::new(unknown_txt).unwrap();
|
||||
let c_val = c_entry_name.as_bytes_with_nul();
|
||||
let initializer = crate::common::bytes_in_context(cx.llcx, c_val);
|
||||
let at_zero = add_unnamed_global(&cx, &"", initializer, PrivateLinkage);
|
||||
llvm::set_alignment(at_zero, Align::ONE);
|
||||
|
||||
// @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8
|
||||
let struct_ident_ty = cx.type_named_struct("struct.ident_t");
|
||||
let struct_elems = vec![
|
||||
cx.get_const_i32(0),
|
||||
cx.get_const_i32(2),
|
||||
cx.get_const_i32(0),
|
||||
cx.get_const_i32(22),
|
||||
at_zero,
|
||||
];
|
||||
let struct_elems_ty: Vec<_> = struct_elems.iter().map(|&x| cx.val_ty(x)).collect();
|
||||
let initializer = crate::common::named_struct(struct_ident_ty, &struct_elems);
|
||||
cx.set_struct_body(struct_ident_ty, &struct_elems_ty, false);
|
||||
let at_one = add_unnamed_global(&cx, &"", initializer, PrivateLinkage);
|
||||
llvm::set_alignment(at_one, Align::EIGHT);
|
||||
at_one
|
||||
}
|
||||
|
||||
pub(crate) fn add_tgt_offload_entry<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Type {
|
||||
let offload_entry_ty = cx.type_named_struct("struct.__tgt_offload_entry");
|
||||
let tptr = cx.type_ptr();
|
||||
let ti64 = cx.type_i64();
|
||||
let ti32 = cx.type_i32();
|
||||
let ti16 = cx.type_i16();
|
||||
// For each kernel to run on the gpu, we will later generate one entry of this type.
|
||||
// copied from LLVM
|
||||
// typedef struct {
|
||||
// uint64_t Reserved;
|
||||
// uint16_t Version;
|
||||
// uint16_t Kind;
|
||||
// uint32_t Flags; Flags associated with the entry (see Target Region Entry Flags)
|
||||
// void *Address; Address of global symbol within device image (function or global)
|
||||
// char *SymbolName;
|
||||
// uint64_t Size; Size of the entry info (0 if it is a function)
|
||||
// uint64_t Data;
|
||||
// void *AuxAddr;
|
||||
// } __tgt_offload_entry;
|
||||
let entry_elements = vec![ti64, ti16, ti16, ti32, tptr, tptr, ti64, ti64, tptr];
|
||||
cx.set_struct_body(offload_entry_ty, &entry_elements, false);
|
||||
offload_entry_ty
|
||||
}
|
||||
|
||||
fn gen_tgt_kernel_global<'ll>(cx: &'ll SimpleCx<'_>) {
|
||||
let kernel_arguments_ty = cx.type_named_struct("struct.__tgt_kernel_arguments");
|
||||
let tptr = cx.type_ptr();
|
||||
let ti64 = cx.type_i64();
|
||||
let ti32 = cx.type_i32();
|
||||
let tarr = cx.type_array(ti32, 3);
|
||||
|
||||
// Taken from the LLVM APITypes.h declaration:
|
||||
//struct KernelArgsTy {
|
||||
// uint32_t Version = 0; // Version of this struct for ABI compatibility.
|
||||
// uint32_t NumArgs = 0; // Number of arguments in each input pointer.
|
||||
// void **ArgBasePtrs =
|
||||
// nullptr; // Base pointer of each argument (e.g. a struct).
|
||||
// void **ArgPtrs = nullptr; // Pointer to the argument data.
|
||||
// int64_t *ArgSizes = nullptr; // Size of the argument data in bytes.
|
||||
// int64_t *ArgTypes = nullptr; // Type of the data (e.g. to / from).
|
||||
// void **ArgNames = nullptr; // Name of the data for debugging, possibly null.
|
||||
// void **ArgMappers = nullptr; // User-defined mappers, possibly null.
|
||||
// uint64_t Tripcount =
|
||||
// 0; // Tripcount for the teams / distribute loop, 0 otherwise.
|
||||
// struct {
|
||||
// uint64_t NoWait : 1; // Was this kernel spawned with a `nowait` clause.
|
||||
// uint64_t IsCUDA : 1; // Was this kernel spawned via CUDA.
|
||||
// uint64_t Unused : 62;
|
||||
// } Flags = {0, 0, 0};
|
||||
// // The number of teams (for x,y,z dimension).
|
||||
// uint32_t NumTeams[3] = {0, 0, 0};
|
||||
// // The number of threads (for x,y,z dimension).
|
||||
// uint32_t ThreadLimit[3] = {0, 0, 0};
|
||||
// uint32_t DynCGroupMem = 0; // Amount of dynamic cgroup memory requested.
|
||||
//};
|
||||
let kernel_elements =
|
||||
vec![ti32, ti32, tptr, tptr, tptr, tptr, tptr, tptr, ti64, ti64, tarr, tarr, ti32];
|
||||
|
||||
cx.set_struct_body(kernel_arguments_ty, &kernel_elements, false);
|
||||
// For now we don't handle kernels, so for now we just add a global dummy
|
||||
// to make sure that the __tgt_offload_entry is defined and handled correctly.
|
||||
cx.declare_global("my_struct_global2", kernel_arguments_ty);
|
||||
}
|
||||
|
||||
fn gen_tgt_data_mappers<'ll>(
|
||||
cx: &'ll SimpleCx<'_>,
|
||||
) -> (&'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Type) {
|
||||
let tptr = cx.type_ptr();
|
||||
let ti64 = cx.type_i64();
|
||||
let ti32 = cx.type_i32();
|
||||
|
||||
let args = vec![tptr, ti64, ti32, tptr, tptr, tptr, tptr, tptr, tptr];
|
||||
let mapper_fn_ty = cx.type_func(&args, cx.type_void());
|
||||
let mapper_begin = "__tgt_target_data_begin_mapper";
|
||||
let mapper_update = "__tgt_target_data_update_mapper";
|
||||
let mapper_end = "__tgt_target_data_end_mapper";
|
||||
let begin_mapper_decl = declare_offload_fn(&cx, mapper_begin, mapper_fn_ty);
|
||||
let update_mapper_decl = declare_offload_fn(&cx, mapper_update, mapper_fn_ty);
|
||||
let end_mapper_decl = declare_offload_fn(&cx, mapper_end, mapper_fn_ty);
|
||||
|
||||
let nounwind = llvm::AttributeKind::NoUnwind.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(begin_mapper_decl, Function, &[nounwind]);
|
||||
attributes::apply_to_llfn(update_mapper_decl, Function, &[nounwind]);
|
||||
attributes::apply_to_llfn(end_mapper_decl, Function, &[nounwind]);
|
||||
|
||||
(begin_mapper_decl, update_mapper_decl, end_mapper_decl, mapper_fn_ty)
|
||||
}
|
||||
|
||||
fn add_priv_unnamed_arr<'ll>(cx: &SimpleCx<'ll>, name: &str, vals: &[u64]) -> &'ll llvm::Value {
|
||||
let ti64 = cx.type_i64();
|
||||
let mut size_val = Vec::with_capacity(vals.len());
|
||||
for &val in vals {
|
||||
size_val.push(cx.get_const_i64(val));
|
||||
}
|
||||
let initializer = cx.const_array(ti64, &size_val);
|
||||
add_unnamed_global(cx, name, initializer, PrivateLinkage)
|
||||
}
|
||||
|
||||
pub(crate) fn add_unnamed_global<'ll>(
|
||||
cx: &SimpleCx<'ll>,
|
||||
name: &str,
|
||||
initializer: &'ll llvm::Value,
|
||||
l: Linkage,
|
||||
) -> &'ll llvm::Value {
|
||||
let llglobal = add_global(cx, name, initializer, l);
|
||||
llvm::LLVMSetUnnamedAddress(llglobal, llvm::UnnamedAddr::Global);
|
||||
llglobal
|
||||
}
|
||||
|
||||
pub(crate) fn add_global<'ll>(
|
||||
cx: &SimpleCx<'ll>,
|
||||
name: &str,
|
||||
initializer: &'ll llvm::Value,
|
||||
l: Linkage,
|
||||
) -> &'ll llvm::Value {
|
||||
let c_name = CString::new(name).unwrap();
|
||||
let llglobal: &'ll llvm::Value = llvm::add_global(cx.llmod, cx.val_ty(initializer), &c_name);
|
||||
llvm::set_global_constant(llglobal, true);
|
||||
llvm::set_linkage(llglobal, l);
|
||||
llvm::set_initializer(llglobal, initializer);
|
||||
llglobal
|
||||
}
|
||||
|
||||
fn gen_define_handling<'ll>(
|
||||
cx: &'ll SimpleCx<'_>,
|
||||
kernel: &'ll llvm::Value,
|
||||
offload_entry_ty: &'ll llvm::Type,
|
||||
num: i64,
|
||||
) -> &'ll llvm::Value {
|
||||
let types = cx.func_params_types(cx.get_type_of_global(kernel));
|
||||
// It seems like non-pointer values are automatically mapped. So here, we focus on pointer (or
|
||||
// reference) types.
|
||||
let num_ptr_types = types
|
||||
.iter()
|
||||
.map(|&x| matches!(cx.type_kind(x), rustc_codegen_ssa::common::TypeKind::Pointer))
|
||||
.count();
|
||||
|
||||
// We do not know their size anymore at this level, so hardcode a placeholder.
|
||||
// A follow-up pr will track these from the frontend, where we still have Rust types.
|
||||
// Then, we will be able to figure out that e.g. `&[f32;256]` will result in 4*256 bytes.
|
||||
// I decided that 1024 bytes is a great placeholder value for now.
|
||||
add_priv_unnamed_arr(&cx, &format!(".offload_sizes.{num}"), &vec![1024; num_ptr_types]);
|
||||
// Here we figure out whether something needs to be copied to the gpu (=1), from the gpu (=2),
|
||||
// or both to and from the gpu (=3). Other values shouldn't affect us for now.
|
||||
// A non-mutable reference or pointer will be 1, an array that's not read, but fully overwritten
|
||||
// will be 2. For now, everything is 3, until we have our frontend set up.
|
||||
let o_types =
|
||||
add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{num}"), &vec![3; num_ptr_types]);
|
||||
// Next: For each function, generate these three entries. A weak constant,
|
||||
// the llvm.rodata entry name, and the omp_offloading_entries value
|
||||
|
||||
let name = format!(".kernel_{num}.region_id");
|
||||
let initializer = cx.get_const_i8(0);
|
||||
let region_id = add_unnamed_global(&cx, &name, initializer, WeakAnyLinkage);
|
||||
|
||||
let c_entry_name = CString::new(format!("kernel_{num}")).unwrap();
|
||||
let c_val = c_entry_name.as_bytes_with_nul();
|
||||
let offload_entry_name = format!(".offloading.entry_name.{num}");
|
||||
|
||||
let initializer = crate::common::bytes_in_context(cx.llcx, c_val);
|
||||
let llglobal = add_unnamed_global(&cx, &offload_entry_name, initializer, InternalLinkage);
|
||||
llvm::set_alignment(llglobal, Align::ONE);
|
||||
llvm::set_section(llglobal, c".llvm.rodata.offloading");
|
||||
|
||||
// Not actively used yet, for calling real kernels
|
||||
let name = format!(".offloading.entry.kernel_{num}");
|
||||
|
||||
// See the __tgt_offload_entry documentation above.
|
||||
let reserved = cx.get_const_i64(0);
|
||||
let version = cx.get_const_i16(1);
|
||||
let kind = cx.get_const_i16(1);
|
||||
let flags = cx.get_const_i32(0);
|
||||
let size = cx.get_const_i64(0);
|
||||
let data = cx.get_const_i64(0);
|
||||
let aux_addr = cx.const_null(cx.type_ptr());
|
||||
let elems = vec![reserved, version, kind, flags, region_id, llglobal, size, data, aux_addr];
|
||||
|
||||
let initializer = crate::common::named_struct(offload_entry_ty, &elems);
|
||||
let c_name = CString::new(name).unwrap();
|
||||
let llglobal = llvm::add_global(cx.llmod, offload_entry_ty, &c_name);
|
||||
llvm::set_global_constant(llglobal, true);
|
||||
llvm::set_linkage(llglobal, WeakAnyLinkage);
|
||||
llvm::set_initializer(llglobal, initializer);
|
||||
llvm::set_alignment(llglobal, Align::ONE);
|
||||
let c_section_name = CString::new(".omp_offloading_entries").unwrap();
|
||||
llvm::set_section(llglobal, &c_section_name);
|
||||
o_types
|
||||
}
|
||||
|
||||
fn declare_offload_fn<'ll>(
|
||||
cx: &'ll SimpleCx<'_>,
|
||||
name: &str,
|
||||
ty: &'ll llvm::Type,
|
||||
) -> &'ll llvm::Value {
|
||||
crate::declare::declare_simple_fn(
|
||||
cx,
|
||||
name,
|
||||
llvm::CallConv::CCallConv,
|
||||
llvm::UnnamedAddr::No,
|
||||
llvm::Visibility::Default,
|
||||
ty,
|
||||
)
|
||||
}
|
||||
|
||||
// For each kernel *call*, we now use some of our previous declared globals to move data to and from
|
||||
// the gpu. We don't have a proper frontend yet, so we assume that every call to a kernel function
|
||||
// from main is intended to run on the GPU. For now, we only handle the data transfer part of it.
|
||||
// If two consecutive kernels use the same memory, we still move it to the host and back to the gpu.
|
||||
// Since in our frontend users (by default) don't have to specify data transfer, this is something
|
||||
// we should optimize in the future! We also assume that everything should be copied back and forth,
|
||||
// but sometimes we can directly zero-allocate on the device and only move back, or if something is
|
||||
// immutable, we might only copy it to the device, but not back.
|
||||
//
|
||||
// Current steps:
|
||||
// 0. Alloca some variables for the following steps
|
||||
// 1. set insert point before kernel call.
|
||||
// 2. generate all the GEPS and stores, to be used in 3)
|
||||
// 3. generate __tgt_target_data_begin calls to move data to the GPU
|
||||
//
|
||||
// unchanged: keep kernel call. Later move the kernel to the GPU
|
||||
//
|
||||
// 4. set insert point after kernel call.
|
||||
// 5. generate all the GEPS and stores, to be used in 6)
|
||||
// 6. generate __tgt_target_data_end calls to move data from the GPU
|
||||
fn gen_call_handling<'ll>(
|
||||
cx: &'ll SimpleCx<'_>,
|
||||
_kernels: &[&'ll llvm::Value],
|
||||
o_types: &[&'ll llvm::Value],
|
||||
) {
|
||||
// %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr }
|
||||
let tptr = cx.type_ptr();
|
||||
let ti32 = cx.type_i32();
|
||||
let tgt_bin_desc_ty = vec![ti32, tptr, tptr, tptr];
|
||||
let tgt_bin_desc = cx.type_named_struct("struct.__tgt_bin_desc");
|
||||
cx.set_struct_body(tgt_bin_desc, &tgt_bin_desc_ty, false);
|
||||
|
||||
gen_tgt_kernel_global(&cx);
|
||||
let (begin_mapper_decl, _, end_mapper_decl, fn_ty) = gen_tgt_data_mappers(&cx);
|
||||
|
||||
let main_fn = cx.get_function("main");
|
||||
let Some(main_fn) = main_fn else { return };
|
||||
let kernel_name = "kernel_1";
|
||||
let call = unsafe {
|
||||
llvm::LLVMRustGetFunctionCall(main_fn, kernel_name.as_c_char_ptr(), kernel_name.len())
|
||||
};
|
||||
let Some(kernel_call) = call else {
|
||||
return;
|
||||
};
|
||||
let kernel_call_bb = unsafe { llvm::LLVMGetInstructionParent(kernel_call) };
|
||||
let called = unsafe { llvm::LLVMGetCalledValue(kernel_call).unwrap() };
|
||||
let mut builder = SBuilder::build(cx, kernel_call_bb);
|
||||
|
||||
let types = cx.func_params_types(cx.get_type_of_global(called));
|
||||
let num_args = types.len() as u64;
|
||||
|
||||
// Step 0)
|
||||
// %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr }
|
||||
// %6 = alloca %struct.__tgt_bin_desc, align 8
|
||||
unsafe { llvm::LLVMRustPositionBuilderPastAllocas(builder.llbuilder, main_fn) };
|
||||
|
||||
let tgt_bin_desc_alloca = builder.direct_alloca(tgt_bin_desc, Align::EIGHT, "EmptyDesc");
|
||||
|
||||
let ty = cx.type_array(cx.type_ptr(), num_args);
|
||||
// Baseptr are just the input pointer to the kernel, stored in a local alloca
|
||||
let a1 = builder.direct_alloca(ty, Align::EIGHT, ".offload_baseptrs");
|
||||
// Ptrs are the result of a gep into the baseptr, at least for our trivial types.
|
||||
let a2 = builder.direct_alloca(ty, Align::EIGHT, ".offload_ptrs");
|
||||
// These represent the sizes in bytes, e.g. the entry for `&[f64; 16]` will be 8*16.
|
||||
let ty2 = cx.type_array(cx.type_i64(), num_args);
|
||||
let a4 = builder.direct_alloca(ty2, Align::EIGHT, ".offload_sizes");
|
||||
// Now we allocate once per function param, a copy to be passed to one of our maps.
|
||||
let mut vals = vec![];
|
||||
let mut geps = vec![];
|
||||
let i32_0 = cx.get_const_i32(0);
|
||||
for (index, in_ty) in types.iter().enumerate() {
|
||||
// get function arg, store it into the alloca, and read it.
|
||||
let p = llvm::get_param(called, index as u32);
|
||||
let name = llvm::get_value_name(p);
|
||||
let name = str::from_utf8(&name).unwrap();
|
||||
let arg_name = format!("{name}.addr");
|
||||
let alloca = builder.direct_alloca(in_ty, Align::EIGHT, &arg_name);
|
||||
|
||||
builder.store(p, alloca, Align::EIGHT);
|
||||
let val = builder.load(in_ty, alloca, Align::EIGHT);
|
||||
let gep = builder.inbounds_gep(cx.type_f32(), val, &[i32_0]);
|
||||
vals.push(val);
|
||||
geps.push(gep);
|
||||
}
|
||||
|
||||
// Step 1)
|
||||
unsafe { llvm::LLVMRustPositionBefore(builder.llbuilder, kernel_call) };
|
||||
builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT);
|
||||
|
||||
let mapper_fn_ty = cx.type_func(&[cx.type_ptr()], cx.type_void());
|
||||
let register_lib_decl = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty);
|
||||
let unregister_lib_decl = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty);
|
||||
let init_ty = cx.type_func(&[], cx.type_void());
|
||||
let init_rtls_decl = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty);
|
||||
|
||||
// call void @__tgt_register_lib(ptr noundef %6)
|
||||
builder.call(mapper_fn_ty, register_lib_decl, &[tgt_bin_desc_alloca], None);
|
||||
// call void @__tgt_init_all_rtls()
|
||||
builder.call(init_ty, init_rtls_decl, &[], None);
|
||||
|
||||
for i in 0..num_args {
|
||||
let idx = cx.get_const_i32(i);
|
||||
let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, idx]);
|
||||
builder.store(vals[i as usize], gep1, Align::EIGHT);
|
||||
let gep2 = builder.inbounds_gep(ty, a2, &[i32_0, idx]);
|
||||
builder.store(geps[i as usize], gep2, Align::EIGHT);
|
||||
let gep3 = builder.inbounds_gep(ty2, a4, &[i32_0, idx]);
|
||||
// As mentioned above, we don't use Rust type information yet. So for now we will just
|
||||
// assume that we have 1024 bytes, 256 f32 values.
|
||||
// FIXME(offload): write an offload frontend and handle arbitrary types.
|
||||
builder.store(cx.get_const_i64(1024), gep3, Align::EIGHT);
|
||||
}
|
||||
|
||||
// For now we have a very simplistic indexing scheme into our
|
||||
// offload_{baseptrs,ptrs,sizes}. We will probably improve this along with our gpu frontend pr.
|
||||
fn get_geps<'a, 'll>(
|
||||
builder: &mut SBuilder<'a, 'll>,
|
||||
cx: &'ll SimpleCx<'ll>,
|
||||
ty: &'ll Type,
|
||||
ty2: &'ll Type,
|
||||
a1: &'ll Value,
|
||||
a2: &'ll Value,
|
||||
a4: &'ll Value,
|
||||
) -> (&'ll Value, &'ll Value, &'ll Value) {
|
||||
let i32_0 = cx.get_const_i32(0);
|
||||
|
||||
let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, i32_0]);
|
||||
let gep2 = builder.inbounds_gep(ty, a2, &[i32_0, i32_0]);
|
||||
let gep3 = builder.inbounds_gep(ty2, a4, &[i32_0, i32_0]);
|
||||
(gep1, gep2, gep3)
|
||||
}
|
||||
|
||||
fn generate_mapper_call<'a, 'll>(
|
||||
builder: &mut SBuilder<'a, 'll>,
|
||||
cx: &'ll SimpleCx<'ll>,
|
||||
geps: (&'ll Value, &'ll Value, &'ll Value),
|
||||
o_type: &'ll Value,
|
||||
fn_to_call: &'ll Value,
|
||||
fn_ty: &'ll Type,
|
||||
num_args: u64,
|
||||
s_ident_t: &'ll Value,
|
||||
) {
|
||||
let nullptr = cx.const_null(cx.type_ptr());
|
||||
let i64_max = cx.get_const_i64(u64::MAX);
|
||||
let num_args = cx.get_const_i32(num_args);
|
||||
let args =
|
||||
vec![s_ident_t, i64_max, num_args, geps.0, geps.1, geps.2, o_type, nullptr, nullptr];
|
||||
builder.call(fn_ty, fn_to_call, &args, None);
|
||||
}
|
||||
|
||||
// Step 2)
|
||||
let s_ident_t = generate_at_one(&cx);
|
||||
let o = o_types[0];
|
||||
let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4);
|
||||
generate_mapper_call(&mut builder, &cx, geps, o, begin_mapper_decl, fn_ty, num_args, s_ident_t);
|
||||
|
||||
// Step 3)
|
||||
// Here we will add code for the actual kernel launches in a follow-up PR.
|
||||
// FIXME(offload): launch kernels
|
||||
|
||||
// Step 4)
|
||||
unsafe { llvm::LLVMRustPositionAfter(builder.llbuilder, kernel_call) };
|
||||
|
||||
let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4);
|
||||
generate_mapper_call(&mut builder, &cx, geps, o, end_mapper_decl, fn_ty, num_args, s_ident_t);
|
||||
|
||||
builder.call(mapper_fn_ty, unregister_lib_decl, &[tgt_bin_desc_alloca], None);
|
||||
|
||||
// With this we generated the following begin and end mappers. We could easily generate the
|
||||
// update mapper in an update.
|
||||
// call void @__tgt_target_data_begin_mapper(ptr @1, i64 -1, i32 3, ptr %27, ptr %28, ptr %29, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
// call void @__tgt_target_data_update_mapper(ptr @1, i64 -1, i32 2, ptr %46, ptr %47, ptr %48, ptr @.offload_maptypes.1, ptr null, ptr null)
|
||||
// call void @__tgt_target_data_end_mapper(ptr @1, i64 -1, i32 3, ptr %49, ptr %50, ptr %51, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
}
|
||||
|
|
@ -118,6 +118,10 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
|
|||
r
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn const_null(&self, t: &'ll Type) -> &'ll Value {
|
||||
unsafe { llvm::LLVMConstNull(t) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
|
||||
|
|
@ -377,6 +381,11 @@ pub(crate) fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn named_struct<'ll>(ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
|
||||
let len = c_uint::try_from(elts.len()).expect("LLVMConstStructInContext elements len overflow");
|
||||
unsafe { llvm::LLVMConstNamedStruct(ty, elts.as_ptr(), len) }
|
||||
}
|
||||
|
||||
fn struct_in_context<'ll>(
|
||||
llcx: &'ll llvm::Context,
|
||||
elts: &[&'ll Value],
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ pub(crate) unsafe fn create_module<'ll>(
|
|||
|
||||
// Ensure the data-layout values hardcoded remain the defaults.
|
||||
{
|
||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
|
||||
let tm = crate::back::write::create_informational_target_machine(sess, false);
|
||||
unsafe {
|
||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw());
|
||||
}
|
||||
|
|
@ -685,6 +685,22 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
|
|||
unsafe { llvm::LLVMConstInt(ty, val, llvm::False) }
|
||||
}
|
||||
|
||||
pub(crate) fn get_const_i64(&self, n: u64) -> &'ll Value {
|
||||
self.get_const_int(self.type_i64(), n)
|
||||
}
|
||||
|
||||
pub(crate) fn get_const_i32(&self, n: u64) -> &'ll Value {
|
||||
self.get_const_int(self.type_i32(), n)
|
||||
}
|
||||
|
||||
pub(crate) fn get_const_i16(&self, n: u64) -> &'ll Value {
|
||||
self.get_const_int(self.type_i16(), n)
|
||||
}
|
||||
|
||||
pub(crate) fn get_const_i8(&self, n: u64) -> &'ll Value {
|
||||
self.get_const_int(self.type_i8(), n)
|
||||
}
|
||||
|
||||
pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> {
|
||||
let name = SmallCStr::new(name);
|
||||
unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,10 @@ impl Coords {
|
|||
/// or other expansions), and if it does happen then skipping a span or function is
|
||||
/// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
|
||||
pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span) -> Option<Coords> {
|
||||
let span = ensure_non_empty_span(source_map, span)?;
|
||||
if span.is_empty() {
|
||||
debug_assert!(false, "can't make coords from empty span: {span:?}");
|
||||
return None;
|
||||
}
|
||||
|
||||
let lo = span.lo();
|
||||
let hi = span.hi();
|
||||
|
|
@ -70,29 +73,6 @@ pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span)
|
|||
})
|
||||
}
|
||||
|
||||
fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> {
|
||||
if !span.is_empty() {
|
||||
return Some(span);
|
||||
}
|
||||
|
||||
// The span is empty, so try to enlarge it to cover an adjacent '{' or '}'.
|
||||
source_map
|
||||
.span_to_source(span, |src, start, end| try {
|
||||
// Adjusting span endpoints by `BytePos(1)` is normally a bug,
|
||||
// but in this case we have specifically checked that the character
|
||||
// we're skipping over is one of two specific ASCII characters, so
|
||||
// adjusting by exactly 1 byte is correct.
|
||||
if src.as_bytes().get(end).copied() == Some(b'{') {
|
||||
Some(span.with_hi(span.hi() + BytePos(1)))
|
||||
} else if start > 0 && src.as_bytes()[start - 1] == b'}' {
|
||||
Some(span.with_lo(span.lo() - BytePos(1)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok()?
|
||||
}
|
||||
|
||||
/// If `llvm-cov` sees a source region that is improperly ordered (end < start),
|
||||
/// it will immediately exit with a fatal error. To prevent that from happening,
|
||||
/// discard regions that are improperly ordered, or might be interpreted in a
|
||||
|
|
|
|||
|
|
@ -215,7 +215,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
|
||||
llfn
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
|
||||
/// Declare a global with an intention to define it.
|
||||
///
|
||||
/// Use this function when you intend to define a global. This function will
|
||||
|
|
@ -234,13 +236,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
///
|
||||
/// Use this function when you intend to define a global without a name.
|
||||
pub(crate) fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
|
||||
unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) }
|
||||
unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod(), ty) }
|
||||
}
|
||||
|
||||
/// Gets declared value by name.
|
||||
pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
|
||||
debug!("get_declared_value(name={:?})", name);
|
||||
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_c_char_ptr(), name.len()) }
|
||||
unsafe { llvm::LLVMRustGetNamedValue(self.llmod(), name.as_c_char_ptr(), name.len()) }
|
||||
}
|
||||
|
||||
/// Gets defined or externally defined (AvailableExternally linkage) value by
|
||||
|
|
|
|||
|
|
@ -412,6 +412,20 @@ impl ModuleLlvm {
|
|||
}
|
||||
}
|
||||
|
||||
fn tm_from_cgcx(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
name: &str,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
) -> Result<OwnedTargetMachine, FatalError> {
|
||||
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, name);
|
||||
match (cgcx.tm_factory)(tm_factory_config) {
|
||||
Ok(m) => Ok(m),
|
||||
Err(e) => {
|
||||
return Err(dcx.emit_almost_fatal(ParseTargetMachineConfig(e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
name: &CStr,
|
||||
|
|
@ -421,13 +435,7 @@ impl ModuleLlvm {
|
|||
unsafe {
|
||||
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
|
||||
let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx)?;
|
||||
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, name.to_str().unwrap());
|
||||
let tm = match (cgcx.tm_factory)(tm_factory_config) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
return Err(dcx.emit_almost_fatal(ParseTargetMachineConfig(e)));
|
||||
}
|
||||
};
|
||||
let tm = ModuleLlvm::tm_from_cgcx(cgcx, name.to_str().unwrap(), dcx)?;
|
||||
|
||||
Ok(ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use libc::{c_char, c_uint};
|
|||
|
||||
use super::MetadataKindId;
|
||||
use super::ffi::{AttributeKind, BasicBlock, Metadata, Module, Type, Value};
|
||||
use crate::llvm::Bool;
|
||||
use crate::llvm::{Bool, Builder};
|
||||
|
||||
#[link(name = "llvm-wrapper", kind = "static")]
|
||||
unsafe extern "C" {
|
||||
|
|
@ -31,6 +31,14 @@ unsafe extern "C" {
|
|||
index: c_uint,
|
||||
kind: AttributeKind,
|
||||
);
|
||||
pub(crate) fn LLVMRustPositionBefore<'a>(B: &'a Builder<'_>, I: &'a Value);
|
||||
pub(crate) fn LLVMRustPositionAfter<'a>(B: &'a Builder<'_>, I: &'a Value);
|
||||
pub(crate) fn LLVMRustGetFunctionCall(
|
||||
F: &Value,
|
||||
name: *const c_char,
|
||||
NameLen: libc::size_t,
|
||||
) -> Option<&Value>;
|
||||
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
|
|
|
|||
|
|
@ -1138,6 +1138,11 @@ unsafe extern "C" {
|
|||
Count: c_uint,
|
||||
Packed: Bool,
|
||||
) -> &'a Value;
|
||||
pub(crate) fn LLVMConstNamedStruct<'a>(
|
||||
StructTy: &'a Type,
|
||||
ConstantVals: *const &'a Value,
|
||||
Count: c_uint,
|
||||
) -> &'a Value;
|
||||
pub(crate) fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value;
|
||||
|
||||
// Constant expressions
|
||||
|
|
@ -1217,6 +1222,8 @@ unsafe extern "C" {
|
|||
) -> &'a BasicBlock;
|
||||
|
||||
// Operations on instructions
|
||||
pub(crate) fn LLVMGetInstructionParent(Inst: &Value) -> &BasicBlock;
|
||||
pub(crate) fn LLVMGetCalledValue(CallInst: &Value) -> Option<&Value>;
|
||||
pub(crate) fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>;
|
||||
pub(crate) fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock;
|
||||
pub(crate) fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>;
|
||||
|
|
@ -2557,6 +2564,7 @@ unsafe extern "C" {
|
|||
|
||||
pub(crate) fn LLVMRustSetDataLayoutFromTargetMachine<'a>(M: &'a Module, TM: &'a TargetMachine);
|
||||
|
||||
pub(crate) fn LLVMRustPositionBuilderPastAllocas<'a>(B: &Builder<'a>, Fn: &'a Value);
|
||||
pub(crate) fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock);
|
||||
|
||||
pub(crate) fn LLVMRustSetModulePICLevel(M: &Module);
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ pub struct ModuleConfig {
|
|||
pub emit_lifetime_markers: bool,
|
||||
pub llvm_plugins: Vec<String>,
|
||||
pub autodiff: Vec<config::AutoDiff>,
|
||||
pub offload: Vec<config::Offload>,
|
||||
}
|
||||
|
||||
impl ModuleConfig {
|
||||
|
|
@ -268,6 +269,7 @@ impl ModuleConfig {
|
|||
emit_lifetime_markers: sess.emit_lifetime_markers(),
|
||||
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
|
||||
autodiff: if_regular!(sess.opts.unstable_opts.autodiff.clone(), vec![]),
|
||||
offload: if_regular!(sess.opts.unstable_opts.offload.clone(), vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -329,20 +329,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
|||
let offset = self.layout.fields.offset(i);
|
||||
|
||||
if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) {
|
||||
if let BackendRepr::SimdVector { count, .. } = self.layout.backend_repr
|
||||
&& let BackendRepr::Memory { sized: true } = field.backend_repr
|
||||
&& count.is_power_of_two()
|
||||
{
|
||||
assert_eq!(field.size, self.layout.size);
|
||||
// This is being deprecated, but for now stdarch still needs it for
|
||||
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
|
||||
let place = PlaceRef::alloca(bx, field);
|
||||
self.val.store(bx, place.val.with_type(self.layout));
|
||||
return bx.load_operand(place);
|
||||
} else {
|
||||
// Part of https://github.com/rust-lang/compiler-team/issues/838
|
||||
bug!("Non-ref type {self:?} cannot project to ref field type {field:?}");
|
||||
}
|
||||
// Part of https://github.com/rust-lang/compiler-team/issues/838
|
||||
span_bug!(
|
||||
fx.mir.span,
|
||||
"Non-ref type {self:?} cannot project to ref field type {field:?}",
|
||||
);
|
||||
}
|
||||
|
||||
let val = if field.is_zst() {
|
||||
|
|
|
|||
|
|
@ -869,7 +869,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let ltext = bx.zext(is_lt, bx.type_i8());
|
||||
bx.unchecked_ssub(gtext, ltext)
|
||||
} else {
|
||||
// These operations are those expected by `tests/codegen/integer-cmp.rs`,
|
||||
// These operations are those expected by `tests/codegen-llvm/integer-cmp.rs`,
|
||||
// from <https://github.com/rust-lang/rust/pull/63767>.
|
||||
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
|
||||
let is_ne = bx.icmp(pred(mir::BinOp::Ne), lhs, rhs);
|
||||
|
|
|
|||
|
|
@ -279,23 +279,15 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
|
|||
fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
|
||||
interp_ok(match (a, b) {
|
||||
// Comparisons between integers are always known.
|
||||
(Scalar::Int { .. }, Scalar::Int { .. }) => {
|
||||
if a == b {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
// Comparisons of abstract pointers with null pointers are known if the pointer
|
||||
// is in bounds, because if they are in bounds, the pointer can't be null.
|
||||
// Inequality with integers other than null can never be known for sure.
|
||||
(Scalar::Int(int), ptr @ Scalar::Ptr(..))
|
||||
| (ptr @ Scalar::Ptr(..), Scalar::Int(int))
|
||||
(Scalar::Int(a), Scalar::Int(b)) => (a == b) as u8,
|
||||
// Comparisons of null with an arbitrary scalar can be known if `scalar_may_be_null`
|
||||
// indicates that the scalar can definitely *not* be null.
|
||||
(Scalar::Int(int), ptr) | (ptr, Scalar::Int(int))
|
||||
if int.is_null() && !self.scalar_may_be_null(ptr)? =>
|
||||
{
|
||||
0
|
||||
}
|
||||
// Equality with integers can never be known for sure.
|
||||
// Other ways of comparing integers and pointers can never be known for sure.
|
||||
(Scalar::Int { .. }, Scalar::Ptr(..)) | (Scalar::Ptr(..), Scalar::Int { .. }) => 2,
|
||||
// FIXME: return a `1` for when both sides are the same pointer, *except* that
|
||||
// some things (like functions and vtables) do not have stable addresses
|
||||
|
|
|
|||
|
|
@ -67,8 +67,10 @@ pub enum AllocKind {
|
|||
LiveData,
|
||||
/// A function allocation (that fn ptrs point to).
|
||||
Function,
|
||||
/// A "virtual" allocation, used for vtables and TypeId.
|
||||
Virtual,
|
||||
/// A vtable allocation.
|
||||
VTable,
|
||||
/// A TypeId allocation.
|
||||
TypeId,
|
||||
/// A dead allocation.
|
||||
Dead,
|
||||
}
|
||||
|
|
@ -952,7 +954,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let kind = match global_alloc {
|
||||
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
|
||||
GlobalAlloc::Function { .. } => bug!("We already checked function pointers above"),
|
||||
GlobalAlloc::VTable { .. } | GlobalAlloc::TypeId { .. } => AllocKind::Virtual,
|
||||
GlobalAlloc::VTable { .. } => AllocKind::VTable,
|
||||
GlobalAlloc::TypeId { .. } => AllocKind::TypeId,
|
||||
};
|
||||
return AllocInfo::new(size, align, kind, mutbl);
|
||||
}
|
||||
|
|
@ -997,7 +1000,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
ptr: Pointer<Option<M::Provenance>>,
|
||||
) -> InterpResult<'tcx, (Ty<'tcx>, u64)> {
|
||||
let (alloc_id, offset, _meta) = self.ptr_get_alloc_id(ptr, 0)?;
|
||||
let GlobalAlloc::TypeId { ty } = self.tcx.global_alloc(alloc_id) else {
|
||||
let Some(GlobalAlloc::TypeId { ty }) = self.tcx.try_get_global_alloc(alloc_id) else {
|
||||
throw_ub_format!("invalid `TypeId` value: not all bytes carry type id metadata")
|
||||
};
|
||||
interp_ok((ty, offset.bytes()))
|
||||
|
|
@ -1617,6 +1620,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
match self.ptr_try_get_alloc_id(ptr, 0) {
|
||||
Ok((alloc_id, offset, _)) => {
|
||||
let info = self.get_alloc_info(alloc_id);
|
||||
if matches!(info.kind, AllocKind::TypeId) {
|
||||
// We *could* actually precisely answer this question since here,
|
||||
// the offset *is* the integer value. But the entire point of making
|
||||
// this a pointer is not to leak the integer value, so we say everything
|
||||
// might be null.
|
||||
return interp_ok(true);
|
||||
}
|
||||
// If the pointer is in-bounds (including "at the end"), it is definitely not null.
|
||||
if offset <= info.size {
|
||||
return interp_ok(false);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Macro import declaration was malformed.
|
||||
|
||||
Erroneous code examples:
|
||||
|
||||
```compile_fail,E0466
|
||||
```compile_fail
|
||||
#[macro_use(a_macro(another_macro))] // error: invalid import declaration
|
||||
extern crate core as some_crate;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::any::Any;
|
||||
use std::default::Default;
|
||||
use std::iter;
|
||||
use std::path::Component::Prefix;
|
||||
|
|
@ -361,17 +362,13 @@ where
|
|||
}
|
||||
|
||||
/// Represents a thing that maps token trees to Macro Results
|
||||
pub trait TTMacroExpander {
|
||||
pub trait TTMacroExpander: Any {
|
||||
fn expand<'cx>(
|
||||
&self,
|
||||
ecx: &'cx mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
input: TokenStream,
|
||||
) -> MacroExpanderResult<'cx>;
|
||||
|
||||
fn get_unused_rule(&self, _rule_i: usize) -> Option<(&Ident, Span)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
|
||||
|
|
@ -379,7 +376,7 @@ pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
|
|||
pub type MacroExpanderFn =
|
||||
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;
|
||||
|
||||
impl<F> TTMacroExpander for F
|
||||
impl<F: 'static> TTMacroExpander for F
|
||||
where
|
||||
F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ mod placeholders;
|
|||
mod proc_macro_server;
|
||||
mod stats;
|
||||
|
||||
pub use mbe::macro_rules::compile_declarative_macro;
|
||||
pub use mbe::macro_rules::{MacroRulesMacroExpander, compile_declarative_macro};
|
||||
pub mod base;
|
||||
pub mod config;
|
||||
pub mod expand;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ pub(super) struct MacroRule {
|
|||
rhs: mbe::TokenTree,
|
||||
}
|
||||
|
||||
struct MacroRulesMacroExpander {
|
||||
pub struct MacroRulesMacroExpander {
|
||||
node_id: NodeId,
|
||||
name: Ident,
|
||||
span: Span,
|
||||
|
|
@ -136,6 +136,14 @@ struct MacroRulesMacroExpander {
|
|||
rules: Vec<MacroRule>,
|
||||
}
|
||||
|
||||
impl MacroRulesMacroExpander {
|
||||
pub fn get_unused_rule(&self, rule_i: usize) -> Option<(&Ident, Span)> {
|
||||
// If the rhs contains an invocation like `compile_error!`, don't report it as unused.
|
||||
let rule = &self.rules[rule_i];
|
||||
if has_compile_error_macro(&rule.rhs) { None } else { Some((&self.name, rule.lhs_span)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl TTMacroExpander for MacroRulesMacroExpander {
|
||||
fn expand<'cx>(
|
||||
&self,
|
||||
|
|
@ -154,12 +162,6 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
|||
&self.rules,
|
||||
))
|
||||
}
|
||||
|
||||
fn get_unused_rule(&self, rule_i: usize) -> Option<(&Ident, Span)> {
|
||||
// If the rhs contains an invocation like `compile_error!`, don't report it as unused.
|
||||
let rule = &self.rules[rule_i];
|
||||
if has_compile_error_macro(&rule.rhs) { None } else { Some((&self.name, rule.lhs_span)) }
|
||||
}
|
||||
}
|
||||
|
||||
struct DummyExpander(ErrorGuaranteed);
|
||||
|
|
|
|||
|
|
@ -490,7 +490,8 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
||||
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
|
||||
gated!(align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(align)),
|
||||
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
|
||||
gated!(rustc_align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
|
||||
ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
|
||||
ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
|
||||
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
||||
|
|
|
|||
|
|
@ -1302,6 +1302,7 @@ impl AttributeExt for Attribute {
|
|||
// FIXME: should not be needed anymore when all attrs are parsed
|
||||
Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
|
||||
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
|
||||
Attribute::Parsed(AttributeKind::MacroUse { span, .. }) => *span,
|
||||
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
|
||||
Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
|
||||
Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span,
|
||||
|
|
|
|||
|
|
@ -345,9 +345,6 @@ language_item_table! {
|
|||
OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);
|
||||
GlobalAlloc, sym::global_alloc_ty, global_alloc_ty, Target::Struct, GenericRequirement::None;
|
||||
|
||||
// Experimental lang item for Miri
|
||||
PtrUnique, sym::ptr_unique, ptr_unique, Target::Struct, GenericRequirement::Exact(1);
|
||||
|
||||
PhantomData, sym::phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1);
|
||||
|
||||
ManuallyDrop, sym::manually_drop, manually_drop, Target::Struct, GenericRequirement::None;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub(super) fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
|
|||
used_trait_imports.extend_unord(imports.items().copied());
|
||||
}
|
||||
|
||||
for &id in tcx.maybe_unused_trait_imports(()) {
|
||||
for &id in tcx.resolutions(()).maybe_unused_trait_imports.iter() {
|
||||
debug_assert_eq!(tcx.def_kind(id), DefKind::Use);
|
||||
if tcx.visibility(id).is_public() {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ use rustc_session::config::{
|
|||
CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation,
|
||||
Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage,
|
||||
InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans,
|
||||
NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
|
||||
Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
|
||||
SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options,
|
||||
rustc_optgroups,
|
||||
NextSolverConfig, Offload, OomStrategy, Options, OutFileName, OutputType, OutputTypes,
|
||||
PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
|
||||
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration,
|
||||
build_session_options, rustc_optgroups,
|
||||
};
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_session::search_paths::SearchPath;
|
||||
|
|
@ -833,6 +833,7 @@ fn test_unstable_options_tracking_hash() {
|
|||
tracked!(no_profiler_runtime, true);
|
||||
tracked!(no_trait_vptr, true);
|
||||
tracked!(no_unique_section_names, true);
|
||||
tracked!(offload, vec![Offload::Enable]);
|
||||
tracked!(on_broken_pipe, OnBrokenPipe::Kill);
|
||||
tracked!(oom, OomStrategy::Panic);
|
||||
tracked!(osx_rpath_install_name, true);
|
||||
|
|
|
|||
|
|
@ -1591,12 +1591,49 @@ extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst,
|
|||
MaybeAlign(DstAlign), IsVolatile));
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustPositionBuilderPastAllocas(LLVMBuilderRef B,
|
||||
LLVMValueRef Fn) {
|
||||
Function *F = unwrap<Function>(Fn);
|
||||
unwrap(B)->SetInsertPointPastAllocas(F);
|
||||
}
|
||||
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
|
||||
LLVMBasicBlockRef BB) {
|
||||
auto Point = unwrap(BB)->getFirstInsertionPt();
|
||||
unwrap(B)->SetInsertPoint(unwrap(BB), Point);
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustPositionBefore(LLVMBuilderRef B, LLVMValueRef Instr) {
|
||||
if (auto I = dyn_cast<Instruction>(unwrap<Value>(Instr))) {
|
||||
unwrap(B)->SetInsertPoint(I);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustPositionAfter(LLVMBuilderRef B, LLVMValueRef Instr) {
|
||||
if (auto I = dyn_cast<Instruction>(unwrap<Value>(Instr))) {
|
||||
auto J = I->getNextNonDebugInstruction();
|
||||
unwrap(B)->SetInsertPoint(J);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" LLVMValueRef
|
||||
LLVMRustGetFunctionCall(LLVMValueRef Fn, const char *Name, size_t NameLen) {
|
||||
auto targetName = StringRef(Name, NameLen);
|
||||
Function *F = unwrap<Function>(Fn);
|
||||
for (auto &BB : *F) {
|
||||
for (auto &I : BB) {
|
||||
if (auto *callInst = llvm::dyn_cast<llvm::CallBase>(&I)) {
|
||||
const llvm::Function *calledFunc = callInst->getCalledFunction();
|
||||
if (calledFunc && calledFunc->getName() == targetName) {
|
||||
// Found a call to the target function
|
||||
return wrap(callInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" bool LLVMRustConstIntGetZExtValue(LLVMValueRef CV, uint64_t *value) {
|
||||
auto C = unwrap<llvm::ConstantInt>(CV);
|
||||
if (C->getBitWidth() > 64)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ mod symbols;
|
|||
mod try_from;
|
||||
mod type_foldable;
|
||||
mod type_visitable;
|
||||
mod visitable;
|
||||
|
||||
// Reads the rust version (e.g. "1.75.0") from the CFG_RELEASE env var and
|
||||
// produces a `RustcVersion` literal containing that version (e.g.
|
||||
|
|
@ -101,6 +102,16 @@ decl_derive!(
|
|||
/// visited (and its type is not required to implement `TypeVisitable`).
|
||||
type_visitable::type_visitable_derive
|
||||
);
|
||||
decl_derive!(
|
||||
[Walkable, attributes(visitable)] =>
|
||||
/// Derives `Walkable` for the annotated `struct` or `enum` (`union` is not supported).
|
||||
///
|
||||
/// Each field of the struct or enum variant will be visited in definition order, using the
|
||||
/// `Walkable` implementation for its type. However, if a field of a struct or an enum
|
||||
/// variant is annotated with `#[visitable(ignore)]` then that field will not be
|
||||
/// visited (and its type is not required to implement `Walkable`).
|
||||
visitable::visitable_derive
|
||||
);
|
||||
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
|
||||
decl_derive!(
|
||||
[Diagnostic, attributes(
|
||||
|
|
|
|||
82
compiler/rustc_macros/src/visitable.rs
Normal file
82
compiler/rustc_macros/src/visitable.rs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
use quote::quote;
|
||||
use synstructure::BindingInfo;
|
||||
|
||||
pub(super) fn visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
||||
if let syn::Data::Union(_) = s.ast().data {
|
||||
panic!("cannot derive on union")
|
||||
}
|
||||
|
||||
let has_attr = |bind: &BindingInfo<'_>, name| {
|
||||
let mut found = false;
|
||||
bind.ast().attrs.iter().for_each(|attr| {
|
||||
if !attr.path().is_ident("visitable") {
|
||||
return;
|
||||
}
|
||||
let _ = attr.parse_nested_meta(|nested| {
|
||||
if nested.path.is_ident(name) {
|
||||
found = true;
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
});
|
||||
found
|
||||
};
|
||||
|
||||
let get_attr = |bind: &BindingInfo<'_>, name: &str| {
|
||||
let mut content = None;
|
||||
bind.ast().attrs.iter().for_each(|attr| {
|
||||
if !attr.path().is_ident("visitable") {
|
||||
return;
|
||||
}
|
||||
let _ = attr.parse_nested_meta(|nested| {
|
||||
if nested.path.is_ident(name) {
|
||||
let value = nested.value()?;
|
||||
let value = value.parse()?;
|
||||
content = Some(value);
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
});
|
||||
content
|
||||
};
|
||||
|
||||
s.add_bounds(synstructure::AddBounds::Generics);
|
||||
s.bind_with(|_| synstructure::BindStyle::Ref);
|
||||
let ref_visit = s.each(|bind| {
|
||||
let extra = get_attr(bind, "extra").unwrap_or(quote! {});
|
||||
if has_attr(bind, "ignore") {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { rustc_ast_ir::try_visit!(crate::visit::Visitable::visit(#bind, __visitor, (#extra))) }
|
||||
}
|
||||
});
|
||||
|
||||
s.bind_with(|_| synstructure::BindStyle::RefMut);
|
||||
let mut_visit = s.each(|bind| {
|
||||
let extra = get_attr(bind, "extra").unwrap_or(quote! {});
|
||||
if has_attr(bind, "ignore") {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { crate::mut_visit::MutVisitable::visit_mut(#bind, __visitor, (#extra)) }
|
||||
}
|
||||
});
|
||||
|
||||
s.gen_impl(quote! {
|
||||
gen impl<'__ast, __V> crate::visit::Walkable<'__ast, __V> for @Self
|
||||
where __V: crate::visit::Visitor<'__ast>,
|
||||
{
|
||||
fn walk_ref(&'__ast self, __visitor: &mut __V) -> __V::Result {
|
||||
match *self { #ref_visit }
|
||||
<__V::Result as rustc_ast_ir::visit::VisitorResult>::output()
|
||||
}
|
||||
}
|
||||
|
||||
gen impl<__V> crate::mut_visit::MutWalkable<__V> for @Self
|
||||
where __V: crate::mut_visit::MutVisitor,
|
||||
{
|
||||
fn walk_mut(&mut self, __visitor: &mut __V) {
|
||||
match *self { #mut_visit }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -70,6 +70,7 @@ pub struct CodegenFnAttrs {
|
|||
/// switching between multiple instruction sets.
|
||||
pub instruction_set: Option<InstructionSetAttr>,
|
||||
/// The `#[align(...)]` attribute. Determines the alignment of the function body.
|
||||
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
|
||||
pub alignment: Option<Align>,
|
||||
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
|
||||
/// the function entry.
|
||||
|
|
|
|||
|
|
@ -2285,9 +2285,6 @@ rustc_queries! {
|
|||
query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
|
||||
desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
|
||||
desc { "fetching potentially unused trait imports" }
|
||||
}
|
||||
|
||||
/// All available crates in the graph, including those that should not be user-facing
|
||||
/// (such as private crates).
|
||||
|
|
|
|||
|
|
@ -3428,8 +3428,6 @@ pub struct DeducedParamAttrs {
|
|||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
providers.maybe_unused_trait_imports =
|
||||
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
|
||||
providers.extern_mod_stmt_cnum =
|
||||
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
|
||||
providers.is_panic_runtime =
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
//! This code should only compile in modules where the uninhabitedness of `Foo`
|
||||
//! is visible.
|
||||
|
||||
use rustc_span::sym;
|
||||
use rustc_type_ir::TyKind::*;
|
||||
use tracing::instrument;
|
||||
|
||||
|
|
@ -85,21 +84,6 @@ impl<'tcx> VariantDef {
|
|||
InhabitedPredicate::all(
|
||||
tcx,
|
||||
self.fields.iter().map(|field| {
|
||||
// Unstable fields are always considered to be inhabited. In the future,
|
||||
// this could be extended to be conditional on the field being unstable
|
||||
// only within the module that's querying the inhabitedness, like:
|
||||
// `let pred = pred.or(InhabitedPredicate::IsUnstable(field.did));`
|
||||
// but this is unnecessary for now, since it would only affect nightly-only
|
||||
// code or code within the standard library itself.
|
||||
// HACK: We filter out `rustc_private` fields since with the flag
|
||||
// `-Zforce-unstable-if-unmarked` we consider all unmarked fields to be
|
||||
// unstable when building the compiler.
|
||||
if tcx
|
||||
.lookup_stability(field.did)
|
||||
.is_some_and(|stab| stab.is_unstable() && stab.feature != sym::rustc_private)
|
||||
{
|
||||
return InhabitedPredicate::True;
|
||||
}
|
||||
let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx);
|
||||
if adt.is_enum() {
|
||||
return pred;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
//! of MIR building, and only after this pass we think of the program has having the
|
||||
//! normal MIR semantics.
|
||||
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
|
|
@ -28,7 +27,6 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
|
|||
// References and Boxes (`noalias` sources)
|
||||
ty::Ref(..) => true,
|
||||
ty::Adt(..) if ty.is_box() => true,
|
||||
ty::Adt(adt, _) if tcx.is_lang_item(adt.did(), LangItem::PtrUnique) => true,
|
||||
// Compound types: recurse
|
||||
ty::Array(ty, _) | ty::Slice(ty) => {
|
||||
// This does not branch so we keep the depth the same.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
|
||||
|
|
@ -83,8 +84,18 @@ pub(super) fn extract_refined_covspans<'tcx>(
|
|||
// Discard any span that overlaps with a hole.
|
||||
discard_spans_overlapping_holes(&mut covspans, &holes);
|
||||
|
||||
// Perform more refinement steps after holes have been dealt with.
|
||||
// Discard spans that overlap in unwanted ways.
|
||||
let mut covspans = remove_unwanted_overlapping_spans(covspans);
|
||||
|
||||
// For all empty spans, either enlarge them to be non-empty, or discard them.
|
||||
let source_map = tcx.sess.source_map();
|
||||
covspans.retain_mut(|covspan| {
|
||||
let Some(span) = ensure_non_empty_span(source_map, covspan.span) else { return false };
|
||||
covspan.span = span;
|
||||
true
|
||||
});
|
||||
|
||||
// Merge covspans that can be merged.
|
||||
covspans.dedup_by(|b, a| a.merge_if_eligible(b));
|
||||
|
||||
code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
|
||||
|
|
@ -230,3 +241,26 @@ fn compare_spans(a: Span, b: Span) -> std::cmp::Ordering {
|
|||
// - Both have the same start and span A extends further right
|
||||
.then_with(|| Ord::cmp(&a.hi(), &b.hi()).reverse())
|
||||
}
|
||||
|
||||
fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> {
|
||||
if !span.is_empty() {
|
||||
return Some(span);
|
||||
}
|
||||
|
||||
// The span is empty, so try to enlarge it to cover an adjacent '{' or '}'.
|
||||
source_map
|
||||
.span_to_source(span, |src, start, end| try {
|
||||
// Adjusting span endpoints by `BytePos(1)` is normally a bug,
|
||||
// but in this case we have specifically checked that the character
|
||||
// we're skipping over is one of two specific ASCII characters, so
|
||||
// adjusting by exactly 1 byte is correct.
|
||||
if src.as_bytes().get(end).copied() == Some(b'{') {
|
||||
Some(span.with_hi(span.hi() + BytePos(1)))
|
||||
} else if start > 0 && src.as_bytes()[start - 1] == b'}' {
|
||||
Some(span.with_lo(span.lo() - BytePos(1)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok()?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,8 +253,8 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Ok(())
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ElaborateDropsCtxt").finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
//! it's usually never invoked in this way.
|
||||
|
||||
use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind};
|
||||
use rustc_middle::ty::{TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt};
|
||||
use rustc_trait_selection::traits;
|
||||
use tracing::trace;
|
||||
|
||||
|
|
@ -36,14 +36,23 @@ use crate::pass_manager::MirPass;
|
|||
pub(crate) struct ImpossiblePredicates;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ImpossiblePredicates {
|
||||
#[tracing::instrument(level = "trace", skip(self, tcx, body))]
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let predicates = tcx
|
||||
.predicates_of(body.source.def_id())
|
||||
.predicates
|
||||
.iter()
|
||||
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
|
||||
if traits::impossible_predicates(tcx, traits::elaborate(tcx, predicates).collect()) {
|
||||
trace!("found unsatisfiable predicates for {:?}", body.source);
|
||||
tracing::trace!(def_id = ?body.source.def_id());
|
||||
let predicates = tcx.predicates_of(body.source.def_id()).instantiate_identity(tcx);
|
||||
tracing::trace!(?predicates);
|
||||
let predicates = predicates.predicates.into_iter().filter(|p| {
|
||||
!p.has_type_flags(
|
||||
// Only consider global clauses to simplify.
|
||||
TypeFlags::HAS_FREE_LOCAL_NAMES
|
||||
// Clauses that refer to unevaluated constants as they cause cycles.
|
||||
| TypeFlags::HAS_CT_PROJECTION,
|
||||
)
|
||||
});
|
||||
let predicates: Vec<_> = traits::elaborate(tcx, predicates).collect();
|
||||
tracing::trace!(?predicates);
|
||||
if predicates.references_error() || traits::impossible_predicates(tcx, predicates) {
|
||||
trace!("found unsatisfiable predicates");
|
||||
// Clear the body to only contain a single `unreachable` statement.
|
||||
let bbs = body.basic_blocks.as_mut();
|
||||
bbs.raw.truncate(1);
|
||||
|
|
|
|||
|
|
@ -434,8 +434,8 @@ pub(super) struct DropShimElaborator<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl fmt::Debug for DropShimElaborator<'_, '_> {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
Ok(())
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
f.debug_struct("DropShimElaborator").finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ fn remove_successors_from_switch<'tcx>(
|
|||
let is_unreachable = |bb| unreachable_blocks.contains(&bb);
|
||||
|
||||
// If there are multiple targets, we want to keep information about reachability for codegen.
|
||||
// For example (see tests/codegen/match-optimizes-away.rs)
|
||||
// For example (see tests/codegen-llvm/match-optimizes-away.rs)
|
||||
//
|
||||
// pub enum Two { A, B }
|
||||
// pub fn identity(x: Two) -> Two {
|
||||
|
|
|
|||
|
|
@ -721,6 +721,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
if adt_def.repr().simd() {
|
||||
self.fail(
|
||||
location,
|
||||
format!(
|
||||
"Projecting into SIMD type {adt_def:?} is banned by MCP#838"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
|
||||
let Some(field) = adt_def.variant(var).fields.get(f) else {
|
||||
fail_out_of_bounds(self, location);
|
||||
|
|
|
|||
|
|
@ -126,23 +126,29 @@ pub(super) fn report_suspicious_mismatch_block(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn make_unclosed_delims_error(
|
||||
unmatched: UnmatchedDelim,
|
||||
psess: &ParseSess,
|
||||
) -> Option<Diag<'_>> {
|
||||
// `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to
|
||||
// `unmatched_delims` only for error recovery in the `Parser`.
|
||||
let found_delim = unmatched.found_delim?;
|
||||
let mut spans = vec![unmatched.found_span];
|
||||
if let Some(sp) = unmatched.unclosed_span {
|
||||
spans.push(sp);
|
||||
};
|
||||
let err = psess.dcx().create_err(MismatchedClosingDelimiter {
|
||||
spans,
|
||||
delimiter: pprust::token_kind_to_string(&found_delim.as_close_token_kind()).to_string(),
|
||||
unmatched: unmatched.found_span,
|
||||
opening_candidate: unmatched.candidate_span,
|
||||
unclosed: unmatched.unclosed_span,
|
||||
});
|
||||
Some(err)
|
||||
pub(crate) fn make_errors_for_mismatched_closing_delims<'psess>(
|
||||
unmatcheds: &[UnmatchedDelim],
|
||||
psess: &'psess ParseSess,
|
||||
) -> Vec<Diag<'psess>> {
|
||||
unmatcheds
|
||||
.iter()
|
||||
.filter_map(|unmatched| {
|
||||
// `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to
|
||||
// `unmatched_delims` only for error recovery in the `Parser`.
|
||||
let found_delim = unmatched.found_delim?;
|
||||
let mut spans = vec![unmatched.found_span];
|
||||
if let Some(sp) = unmatched.unclosed_span {
|
||||
spans.push(sp);
|
||||
};
|
||||
let err = psess.dcx().create_err(MismatchedClosingDelimiter {
|
||||
spans,
|
||||
delimiter: pprust::token_kind_to_string(&found_delim.as_close_token_kind())
|
||||
.to_string(),
|
||||
unmatched: unmatched.found_span,
|
||||
opening_candidate: unmatched.candidate_span,
|
||||
unclosed: unmatched.unclosed_span,
|
||||
});
|
||||
Some(err)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use diagnostics::make_unclosed_delims_error;
|
||||
use diagnostics::make_errors_for_mismatched_closing_delims;
|
||||
use rustc_ast::ast::{self, AttrStyle};
|
||||
use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
|
|
@ -71,27 +71,23 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
|
|||
};
|
||||
let res = lexer.lex_token_trees(/* is_delimited */ false);
|
||||
|
||||
let mut unmatched_delims: Vec<_> = lexer
|
||||
.diag_info
|
||||
.unmatched_delims
|
||||
.into_iter()
|
||||
.filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess))
|
||||
.collect();
|
||||
let mut unmatched_closing_delims: Vec<_> =
|
||||
make_errors_for_mismatched_closing_delims(&lexer.diag_info.unmatched_delims, psess);
|
||||
|
||||
match res {
|
||||
Ok((_open_spacing, stream)) => {
|
||||
if unmatched_delims.is_empty() {
|
||||
if unmatched_closing_delims.is_empty() {
|
||||
Ok(stream)
|
||||
} else {
|
||||
// Return error if there are unmatched delimiters or unclosed delimiters.
|
||||
Err(unmatched_delims)
|
||||
Err(unmatched_closing_delims)
|
||||
}
|
||||
}
|
||||
Err(errs) => {
|
||||
// We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
|
||||
// because the delimiter mismatch is more likely to be the root cause of error
|
||||
unmatched_delims.extend(errs);
|
||||
Err(unmatched_delims)
|
||||
unmatched_closing_delims.extend(errs);
|
||||
Err(unmatched_closing_delims)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,45 +51,6 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
|||
}
|
||||
}
|
||||
|
||||
fn eof_err(&mut self) -> Diag<'psess> {
|
||||
let msg = "this file contains an unclosed delimiter";
|
||||
let mut err = self.dcx().struct_span_err(self.token.span, msg);
|
||||
|
||||
let unclosed_delimiter_show_limit = 5;
|
||||
let len = usize::min(unclosed_delimiter_show_limit, self.diag_info.open_delimiters.len());
|
||||
for &(_, span) in &self.diag_info.open_delimiters[..len] {
|
||||
err.span_label(span, "unclosed delimiter");
|
||||
self.diag_info.unmatched_delims.push(UnmatchedDelim {
|
||||
found_delim: None,
|
||||
found_span: self.token.span,
|
||||
unclosed_span: Some(span),
|
||||
candidate_span: None,
|
||||
});
|
||||
}
|
||||
|
||||
if let Some((_, span)) = self.diag_info.open_delimiters.get(unclosed_delimiter_show_limit)
|
||||
&& self.diag_info.open_delimiters.len() >= unclosed_delimiter_show_limit + 2
|
||||
{
|
||||
err.span_label(
|
||||
*span,
|
||||
format!(
|
||||
"another {} unclosed delimiters begin from here",
|
||||
self.diag_info.open_delimiters.len() - unclosed_delimiter_show_limit
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some((delim, _)) = self.diag_info.open_delimiters.last() {
|
||||
report_suspicious_mismatch_block(
|
||||
&mut err,
|
||||
&self.diag_info,
|
||||
self.psess.source_map(),
|
||||
*delim,
|
||||
)
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
fn lex_token_tree_open_delim(
|
||||
&mut self,
|
||||
open_delim: Delimiter,
|
||||
|
|
@ -206,13 +167,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
|||
} else if let Some(glued) = self.token.glue(&next_tok) {
|
||||
self.token = glued;
|
||||
} else {
|
||||
let this_spacing = if next_tok.is_punct() {
|
||||
Spacing::Joint
|
||||
} else if next_tok == token::Eof {
|
||||
Spacing::Alone
|
||||
} else {
|
||||
Spacing::JointHidden
|
||||
};
|
||||
let this_spacing = self.calculate_spacing(&next_tok);
|
||||
break (this_spacing, next_tok);
|
||||
}
|
||||
};
|
||||
|
|
@ -223,23 +178,64 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
|||
// Cut-down version of `bump` used when the token kind is known in advance.
|
||||
fn bump_minimal(&mut self) -> Spacing {
|
||||
let (next_tok, is_next_tok_preceded_by_whitespace) = self.next_token_from_cursor();
|
||||
|
||||
let this_spacing = if is_next_tok_preceded_by_whitespace {
|
||||
Spacing::Alone
|
||||
} else {
|
||||
if next_tok.is_punct() {
|
||||
Spacing::Joint
|
||||
} else if next_tok == token::Eof {
|
||||
Spacing::Alone
|
||||
} else {
|
||||
Spacing::JointHidden
|
||||
}
|
||||
self.calculate_spacing(&next_tok)
|
||||
};
|
||||
|
||||
self.token = next_tok;
|
||||
this_spacing
|
||||
}
|
||||
|
||||
fn calculate_spacing(&self, next_tok: &Token) -> Spacing {
|
||||
if next_tok.is_punct() {
|
||||
Spacing::Joint
|
||||
} else if *next_tok == token::Eof {
|
||||
Spacing::Alone
|
||||
} else {
|
||||
Spacing::JointHidden
|
||||
}
|
||||
}
|
||||
|
||||
fn eof_err(&mut self) -> Diag<'psess> {
|
||||
const UNCLOSED_DELIMITER_SHOW_LIMIT: usize = 5;
|
||||
let msg = "this file contains an unclosed delimiter";
|
||||
let mut err = self.dcx().struct_span_err(self.token.span, msg);
|
||||
|
||||
let len = usize::min(UNCLOSED_DELIMITER_SHOW_LIMIT, self.diag_info.open_delimiters.len());
|
||||
for &(_, span) in &self.diag_info.open_delimiters[..len] {
|
||||
err.span_label(span, "unclosed delimiter");
|
||||
self.diag_info.unmatched_delims.push(UnmatchedDelim {
|
||||
found_delim: None,
|
||||
found_span: self.token.span,
|
||||
unclosed_span: Some(span),
|
||||
candidate_span: None,
|
||||
});
|
||||
}
|
||||
|
||||
if let Some((_, span)) = self.diag_info.open_delimiters.get(UNCLOSED_DELIMITER_SHOW_LIMIT)
|
||||
&& self.diag_info.open_delimiters.len() >= UNCLOSED_DELIMITER_SHOW_LIMIT + 2
|
||||
{
|
||||
err.span_label(
|
||||
*span,
|
||||
format!(
|
||||
"another {} unclosed delimiters begin from here",
|
||||
self.diag_info.open_delimiters.len() - UNCLOSED_DELIMITER_SHOW_LIMIT
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some((delim, _)) = self.diag_info.open_delimiters.last() {
|
||||
report_suspicious_mismatch_block(
|
||||
&mut err,
|
||||
&self.diag_info,
|
||||
self.psess.source_map(),
|
||||
*delim,
|
||||
)
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
fn close_delim_err(&mut self, delim: Delimiter) -> Diag<'psess> {
|
||||
// An unexpected closing delimiter (i.e., there is no matching opening delimiter).
|
||||
let token_str = token_to_string(&self.token);
|
||||
|
|
|
|||
|
|
@ -294,13 +294,17 @@ pub fn check_builtin_meta_item(
|
|||
| sym::rustc_paren_sugar
|
||||
| sym::type_const
|
||||
| sym::repr
|
||||
| sym::align
|
||||
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres
|
||||
// ambiguity
|
||||
| sym::rustc_align
|
||||
| sym::deprecated
|
||||
| sym::optimize
|
||||
| sym::pointee
|
||||
| sym::cold
|
||||
| sym::target_feature
|
||||
| sym::rustc_allow_const_fn_unstable
|
||||
| sym::macro_use
|
||||
| sym::macro_escape
|
||||
| sym::naked
|
||||
| sym::no_mangle
|
||||
| sym::non_exhaustive
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ passes_abi_of =
|
|||
fn_abi_of({$fn_name}) = {$fn_abi}
|
||||
|
||||
passes_align_attr_application =
|
||||
`#[align(...)]` should be applied to a function item
|
||||
`#[rustc_align(...)]` should be applied to a function item
|
||||
.label = not a function item
|
||||
|
||||
passes_align_on_fields =
|
||||
|
|
@ -22,7 +22,7 @@ passes_align_on_fields =
|
|||
.warn = {-passes_previously_accepted}
|
||||
|
||||
passes_align_should_be_repr_align =
|
||||
`#[align(...)]` is not supported on {$item} items
|
||||
`#[rustc_align(...)]` is not supported on {$item} items
|
||||
.suggestion = use `#[repr(align(...))]` instead
|
||||
|
||||
passes_allow_incoherent_impl =
|
||||
|
|
@ -605,7 +605,7 @@ passes_repr_align_greater_than_target_max =
|
|||
|
||||
passes_repr_align_should_be_align =
|
||||
`#[repr(align(...))]` is not supported on {$item} items
|
||||
.help = use `#[align(...)]` instead
|
||||
.help = use `#[rustc_align(...)]` instead
|
||||
|
||||
passes_repr_conflicting =
|
||||
conflicting representation hints
|
||||
|
|
|
|||
|
|
@ -227,6 +227,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::LinkSection { span: attr_span, .. }) => {
|
||||
self.check_link_section(hir_id, *attr_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::MacroUse { span, .. }) => {
|
||||
self.check_macro_use(hir_id, sym::macro_use, *span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::MacroEscape(span)) => {
|
||||
self.check_macro_use(hir_id, sym::macro_escape, *span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Naked(attr_span)) => {
|
||||
self.check_naked(hir_id, *attr_span, span, target)
|
||||
}
|
||||
|
|
@ -362,9 +368,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
[sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target),
|
||||
[sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
|
||||
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
|
||||
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
|
||||
self.check_macro_use(hir_id, attr, target)
|
||||
}
|
||||
[sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod),
|
||||
[sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
|
||||
[sym::should_panic, ..] => {
|
||||
|
|
@ -1970,6 +1973,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
|
||||
/// Checks if the `#[align]` attributes on `item` are valid.
|
||||
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
|
||||
fn check_align(
|
||||
&self,
|
||||
span: Span,
|
||||
|
|
@ -2410,17 +2414,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_macro_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
let Some(name) = attr.name() else {
|
||||
return;
|
||||
};
|
||||
fn check_macro_use(&self, hir_id: HirId, name: Symbol, attr_span: Span, target: Target) {
|
||||
match target {
|
||||
Target::ExternCrate | Target::Mod => {}
|
||||
_ => {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::MacroUse { name },
|
||||
);
|
||||
}
|
||||
|
|
@ -2473,7 +2474,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// Warn on useless empty attributes.
|
||||
// FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute`
|
||||
let note = if attr.has_any_name(&[
|
||||
sym::macro_use,
|
||||
sym::allow,
|
||||
sym::expect,
|
||||
sym::warn,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use rustc_middle::ty::{
|
|||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym};
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
|
||||
|
||||
use crate::constructor::Constructor::*;
|
||||
use crate::constructor::{
|
||||
|
|
@ -238,10 +238,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
let is_visible =
|
||||
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
|
||||
let is_uninhabited = cx.is_uninhabited(*ty);
|
||||
let is_unstable = cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
|
||||
stab.is_unstable() && stab.feature != sym::rustc_private
|
||||
});
|
||||
let skip = is_uninhabited && (!is_visible || is_unstable);
|
||||
let skip = is_uninhabited && !is_visible;
|
||||
(ty, PrivateUninhabitedField(skip))
|
||||
});
|
||||
cx.dropless_arena.alloc_from_iter(tys)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Memory allocation implementation for StableMIR.
|
||||
//! Memory allocation implementation for rustc_public.
|
||||
//!
|
||||
//! This module is responsible for constructing stable components.
|
||||
//! All operations requiring rustc queries must be delegated
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
use rustc_abi::Align;
|
||||
use rustc_middle::mir::ConstValue;
|
||||
use rustc_middle::mir::interpret::AllocRange;
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::bridge::Error as _;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
use rustc_public_bridge::{Tables, alloc};
|
||||
|
||||
use super::Error;
|
||||
|
|
@ -35,7 +35,7 @@ pub(crate) fn new_allocation<'tcx>(
|
|||
ty: rustc_middle::ty::Ty<'tcx>,
|
||||
const_value: ConstValue<'tcx>,
|
||||
tables: &mut Tables<'tcx, BridgeTys>,
|
||||
cx: &SmirCtxt<'tcx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'tcx, BridgeTys>,
|
||||
) -> Allocation {
|
||||
try_new_allocation(ty, const_value, tables, cx)
|
||||
.unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}"))
|
||||
|
|
@ -46,7 +46,7 @@ pub(crate) fn try_new_allocation<'tcx>(
|
|||
ty: rustc_middle::ty::Ty<'tcx>,
|
||||
const_value: ConstValue<'tcx>,
|
||||
tables: &mut Tables<'tcx, BridgeTys>,
|
||||
cx: &SmirCtxt<'tcx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'tcx, BridgeTys>,
|
||||
) -> Result<Allocation, Error> {
|
||||
let layout = alloc::create_ty_and_layout(cx, ty).map_err(|e| Error::from_internal(e))?;
|
||||
match const_value {
|
||||
|
|
@ -59,7 +59,7 @@ pub(crate) fn try_new_allocation<'tcx>(
|
|||
}
|
||||
ConstValue::Indirect { alloc_id, offset } => {
|
||||
let alloc = alloc::try_new_indirect(alloc_id, cx);
|
||||
use rustc_public_bridge::context::SmirAllocRange;
|
||||
use rustc_public_bridge::context::AllocRangeHelpers;
|
||||
Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx))
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ pub(super) fn allocation_filter<'tcx>(
|
|||
alloc: &rustc_middle::mir::interpret::Allocation,
|
||||
alloc_range: AllocRange,
|
||||
tables: &mut Tables<'tcx, BridgeTys>,
|
||||
cx: &SmirCtxt<'tcx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'tcx, BridgeTys>,
|
||||
) -> Allocation {
|
||||
alloc::allocation_filter(alloc, alloc_range, tables, cx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
//! Define the interface with the Rust compiler.
|
||||
//!
|
||||
//! StableMIR users should not use any of the items in this module directly.
|
||||
//! rustc_public users should not use any of the items in this module directly.
|
||||
//! These APIs have no stability guarantee.
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::{Bridge, SmirContainer};
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
use rustc_public_bridge::{Bridge, Container};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::abi::{FnAbi, Layout, LayoutShape, ReprOptions};
|
||||
|
|
@ -66,13 +66,13 @@ impl Bridge for BridgeTys {
|
|||
type Allocation = crate::ty::Allocation;
|
||||
}
|
||||
|
||||
/// Stable public API for querying compiler information.
|
||||
/// Public API for querying compiler information.
|
||||
///
|
||||
/// All queries are delegated to [`rustc_public_bridge::context::SmirCtxt`] that provides
|
||||
/// All queries are delegated to [`rustc_public_bridge::context::CompilerCtxt`] that provides
|
||||
/// similar APIs but based on internal rustc constructs.
|
||||
///
|
||||
/// Do not use this directly. This is currently used in the macro expansion.
|
||||
pub(crate) trait SmirInterface {
|
||||
pub(crate) trait CompilerInterface {
|
||||
fn entry_fn(&self) -> Option<CrateItem>;
|
||||
/// Retrieve all items of the local crate that have a MIR associated with them.
|
||||
fn all_local_items(&self) -> CrateItems;
|
||||
|
|
@ -316,7 +316,7 @@ pub(crate) trait SmirInterface {
|
|||
fn associated_items(&self, def_id: DefId) -> AssocItems;
|
||||
}
|
||||
|
||||
impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
|
||||
impl<'tcx> CompilerInterface for Container<'tcx, BridgeTys> {
|
||||
fn entry_fn(&self) -> Option<CrateItem> {
|
||||
let mut tables = self.tables.borrow_mut();
|
||||
let cx = &*self.cx.borrow();
|
||||
|
|
@ -567,7 +567,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
|
|||
DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)),
|
||||
DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)),
|
||||
DefKind::ForeignTy => {
|
||||
use rustc_public_bridge::context::SmirTy;
|
||||
use rustc_public_bridge::context::TyHelpers;
|
||||
ForeignItemKind::Type(tables.intern_ty(cx.new_foreign(def_id)))
|
||||
}
|
||||
def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind),
|
||||
|
|
@ -1059,36 +1059,36 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
|
|||
}
|
||||
}
|
||||
|
||||
// A thread local variable that stores a pointer to [`SmirInterface`].
|
||||
// A thread local variable that stores a pointer to [`CompilerInterface`].
|
||||
scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>);
|
||||
|
||||
pub(crate) fn run<F, T>(interface: &dyn SmirInterface, f: F) -> Result<T, Error>
|
||||
pub(crate) fn run<F, T>(interface: &dyn CompilerInterface, f: F) -> Result<T, Error>
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
if TLV.is_set() {
|
||||
Err(Error::from("StableMIR already running"))
|
||||
Err(Error::from("rustc_public already running"))
|
||||
} else {
|
||||
let ptr: *const () = (&raw const interface) as _;
|
||||
TLV.set(&Cell::new(ptr), || Ok(f()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute the given function with access the [`SmirInterface`].
|
||||
/// Execute the given function with access the [`CompilerInterface`].
|
||||
///
|
||||
/// I.e., This function will load the current interface and calls a function with it.
|
||||
/// Do not nest these, as that will ICE.
|
||||
pub(crate) fn with<R>(f: impl FnOnce(&dyn SmirInterface) -> R) -> R {
|
||||
pub(crate) fn with<R>(f: impl FnOnce(&dyn CompilerInterface) -> R) -> R {
|
||||
assert!(TLV.is_set());
|
||||
TLV.with(|tlv| {
|
||||
let ptr = tlv.get();
|
||||
assert!(!ptr.is_null());
|
||||
f(unsafe { *(ptr as *const &dyn SmirInterface) })
|
||||
f(unsafe { *(ptr as *const &dyn CompilerInterface) })
|
||||
})
|
||||
}
|
||||
|
||||
fn smir_crate<'tcx>(
|
||||
cx: &SmirCtxt<'tcx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'tcx, BridgeTys>,
|
||||
crate_num: rustc_span::def_id::CrateNum,
|
||||
) -> Crate {
|
||||
let name = cx.crate_name(crate_num);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! When things go wrong, we need some error handling.
|
||||
//! There are a few different types of errors in StableMIR:
|
||||
//! There are a few different types of errors in rustc_public:
|
||||
//!
|
||||
//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
|
||||
//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::{fmt, io};
|
||||
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use rustc_public_bridge::bridge;
|
||||
|
||||
macro_rules! error {
|
||||
($fmt: literal $(,)?) => { Error(format!($fmt)) };
|
||||
|
|
@ -32,7 +32,7 @@ pub enum CompilerError<T> {
|
|||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Error(pub(crate) String);
|
||||
|
||||
impl SmirError for Error {
|
||||
impl bridge::Error for Error {
|
||||
fn new(msg: String) -> Self {
|
||||
Self(msg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use std::{fmt, io};
|
|||
|
||||
pub(crate) use rustc_public_bridge::IndexedVal;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
/// Export the rustc_internal APIs. Note that this module has no stability
|
||||
/// guarantees and it is not taken into account for semver.
|
||||
#[cfg(feature = "rustc_internal")]
|
||||
|
|
@ -288,7 +288,7 @@ impl rustc_public_bridge::bridge::Allocation<compiler_interface::BridgeTys>
|
|||
align: u64,
|
||||
mutability: rustc_middle::mir::Mutability,
|
||||
tables: &mut Tables<'tcx, compiler_interface::BridgeTys>,
|
||||
cx: &SmirCtxt<'tcx, compiler_interface::BridgeTys>,
|
||||
cx: &CompilerCtxt<'tcx, compiler_interface::BridgeTys>,
|
||||
) -> Self {
|
||||
Self {
|
||||
bytes,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::target::{Endian, MachineInfo};
|
|||
use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty};
|
||||
use crate::{Error, IndexedVal, with};
|
||||
|
||||
/// An allocation in the SMIR global memory can be either a function pointer,
|
||||
/// An allocation in the rustc_public's IR global memory can be either a function pointer,
|
||||
/// a static, or a "real" allocation with some data in it.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
||||
pub enum GlobalAlloc {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::ty::{
|
|||
};
|
||||
use crate::{Error, Opaque, Span, Symbol};
|
||||
|
||||
/// The SMIR representation of a single function.
|
||||
/// The rustc_public's IR representation of a single function.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct Body {
|
||||
pub blocks: Vec<BasicBlock>,
|
||||
|
|
@ -771,8 +771,8 @@ pub enum VarDebugInfoContents {
|
|||
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
|
||||
// is so it can be used for both Places (for which the projection elements are of type
|
||||
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
|
||||
// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use
|
||||
// ProjectionElem for Places.
|
||||
// are of type ProjectionElem<(), ()>).
|
||||
// In rustc_public's IR we don't need this generality, so we just use ProjectionElem for Places.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ProjectionElem {
|
||||
/// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt::{Debug, Formatter};
|
||||
use std::io;
|
||||
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use rustc_public_bridge::bridge;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::abi::FnAbi;
|
||||
|
|
@ -62,7 +62,7 @@ impl Instance {
|
|||
/// For more information on fallback body, see <https://github.com/rust-lang/rust/issues/93145>.
|
||||
///
|
||||
/// This call is much cheaper than `instance.body().is_some()`, since it doesn't try to build
|
||||
/// the StableMIR body.
|
||||
/// the rustc_public's IR body.
|
||||
pub fn has_body(&self) -> bool {
|
||||
with(|cx| cx.has_body(self.def.def_id()))
|
||||
}
|
||||
|
|
@ -120,9 +120,9 @@ impl Instance {
|
|||
/// Resolve an instance starting from a function definition and generic arguments.
|
||||
pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
|
||||
with(|context| {
|
||||
context
|
||||
.resolve_instance(def, args)
|
||||
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
|
||||
context.resolve_instance(def, args).ok_or_else(|| {
|
||||
bridge::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -134,9 +134,9 @@ impl Instance {
|
|||
/// Resolve an instance for a given function pointer.
|
||||
pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
|
||||
with(|context| {
|
||||
context
|
||||
.resolve_for_fn_ptr(def, args)
|
||||
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
|
||||
context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
|
||||
bridge::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -147,9 +147,9 @@ impl Instance {
|
|||
kind: ClosureKind,
|
||||
) -> Result<Instance, Error> {
|
||||
with(|context| {
|
||||
context
|
||||
.resolve_closure(def, args, kind)
|
||||
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
|
||||
context.resolve_closure(def, args, kind).ok_or_else(|| {
|
||||
bridge::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ impl Instance {
|
|||
///
|
||||
/// Allow users to check if this shim can be ignored when called directly.
|
||||
///
|
||||
/// We have decided not to export different types of Shims to StableMIR users, however, this
|
||||
/// We have decided not to export different types of Shims to rustc_public users, however, this
|
||||
/// is a query that can be very helpful for users when processing DropGlue.
|
||||
///
|
||||
/// When generating code for a Drop terminator, users can ignore an empty drop glue.
|
||||
|
|
@ -201,7 +201,7 @@ impl TryFrom<CrateItem> for Instance {
|
|||
if !context.requires_monomorphization(def_id) {
|
||||
Ok(context.mono_instance(def_id))
|
||||
} else {
|
||||
Err(Error::new("Item requires monomorphization".to_string()))
|
||||
Err(bridge::Error::new("Item requires monomorphization".to_string()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ impl TryFrom<Instance> for CrateItem {
|
|||
if value.kind == InstanceKind::Item && context.has_body(value.def.def_id()) {
|
||||
Ok(CrateItem(context.instance_def_id(value.def)))
|
||||
} else {
|
||||
Err(Error::new(format!("Item kind `{:?}` cannot be converted", value.kind)))
|
||||
Err(bridge::Error::new(format!("Item kind `{:?}` cannot be converted", value.kind)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -263,7 +263,7 @@ impl TryFrom<CrateItem> for StaticDef {
|
|||
if matches!(value.kind(), ItemKind::Static) {
|
||||
Ok(StaticDef(value.0))
|
||||
} else {
|
||||
Err(Error::new(format!("Expected a static item, but found: {value:?}")))
|
||||
Err(bridge::Error::new(format!("Expected a static item, but found: {value:?}")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Implement methods to pretty print stable MIR body.
|
||||
//! Implement methods to pretty print rustc_public's IR body.
|
||||
use std::fmt::Debug;
|
||||
use std::io::Write;
|
||||
use std::{fmt, io, iter};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! # The Stable MIR Visitor
|
||||
//! # The rustc_public's IR Visitor
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
//! Module that implements the bridge between Stable MIR and internal compiler MIR.
|
||||
//! Module that implements the bridge between rustc_public's IR and internal compiler MIR.
|
||||
//!
|
||||
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
||||
//! until stable MIR is complete.
|
||||
//! until rustc_public's IR is complete.
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::{Bridge, SmirContainer, Tables};
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
use rustc_public_bridge::{Bridge, Container, Tables};
|
||||
use rustc_span::def_id::CrateNum;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ pub mod pretty;
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if StableMIR has not been properly initialized.
|
||||
/// This function will panic if rustc_public has not been properly initialized.
|
||||
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
||||
with_container(|tables, cx| item.stable(tables, cx))
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if StableMIR has not been properly initialized.
|
||||
/// This function will panic if rustc_public has not been properly initialized.
|
||||
pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx>
|
||||
where
|
||||
S: RustcInternal,
|
||||
|
|
@ -57,10 +57,10 @@ pub fn crate_num(item: &crate::Crate) -> CrateNum {
|
|||
}
|
||||
|
||||
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
||||
// datastructures and stable MIR datastructures
|
||||
// datastructures and rustc_public's IR datastructures
|
||||
scoped_thread_local! (static TLV: Cell<*const ()>);
|
||||
|
||||
pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &SmirContainer<'tcx, B>, f: F) -> T
|
||||
pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &Container<'tcx, B>, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
|
|
@ -72,13 +72,13 @@ where
|
|||
/// Loads the current context and calls a function with it.
|
||||
/// Do not nest these, as that will ICE.
|
||||
pub(crate) fn with_container<R, B: Bridge>(
|
||||
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
|
||||
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &CompilerCtxt<'tcx, B>) -> R,
|
||||
) -> R {
|
||||
assert!(TLV.is_set());
|
||||
TLV.with(|tlv| {
|
||||
let ptr = tlv.get();
|
||||
assert!(!ptr.is_null());
|
||||
let container = ptr as *const SmirContainer<'_, B>;
|
||||
let container = ptr as *const Container<'_, B>;
|
||||
let mut tables = unsafe { (*container).tables.borrow_mut() };
|
||||
let cx = unsafe { (*container).cx.borrow() };
|
||||
f(&mut *tables, &*cx)
|
||||
|
|
@ -89,8 +89,8 @@ pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
|
|||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let smir_cx = RefCell::new(SmirCtxt::new(tcx));
|
||||
let container = SmirContainer { tables: RefCell::new(Tables::default()), cx: smir_cx };
|
||||
let compiler_cx = RefCell::new(CompilerCtxt::new(tcx));
|
||||
let container = Container { tables: RefCell::new(Tables::default()), cx: compiler_cx };
|
||||
|
||||
crate::compiler_interface::run(&container, || init(&container, f))
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ macro_rules! optional {
|
|||
|
||||
/// Prefer using [run!] and [run_with_tcx] instead.
|
||||
///
|
||||
/// This macro implements the instantiation of a StableMIR driver, and it will invoke
|
||||
/// This macro implements the instantiation of a rustc_public driver, and it will invoke
|
||||
/// the given callback after the compiler analyses.
|
||||
///
|
||||
/// The third argument determines whether the callback requires `tcx` as an argument.
|
||||
|
|
@ -191,7 +191,7 @@ macro_rules! run_driver {
|
|||
use rustc_public::CompilerError;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
pub struct StableMir<B = (), C = (), F = fn($($crate::optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C>>
|
||||
pub struct RustcPublic<B = (), C = (), F = fn($($crate::optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C>>
|
||||
where
|
||||
B: Send,
|
||||
C: Send,
|
||||
|
|
@ -201,15 +201,15 @@ macro_rules! run_driver {
|
|||
result: Option<ControlFlow<B, C>>,
|
||||
}
|
||||
|
||||
impl<B, C, F> StableMir<B, C, F>
|
||||
impl<B, C, F> RustcPublic<B, C, F>
|
||||
where
|
||||
B: Send,
|
||||
C: Send,
|
||||
F: FnOnce($($crate::optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C> + Send,
|
||||
{
|
||||
/// Creates a new `StableMir` instance, with given test_function and arguments.
|
||||
/// Creates a new `RustcPublic` instance, with given test_function and arguments.
|
||||
pub fn new(callback: F) -> Self {
|
||||
StableMir { callback: Some(callback), result: None }
|
||||
RustcPublic { callback: Some(callback), result: None }
|
||||
}
|
||||
|
||||
/// Runs the compiler against given target and tests it with `test_function`
|
||||
|
|
@ -236,7 +236,7 @@ macro_rules! run_driver {
|
|||
}
|
||||
}
|
||||
|
||||
impl<B, C, F> Callbacks for StableMir<B, C, F>
|
||||
impl<B, C, F> Callbacks for RustcPublic<B, C, F>
|
||||
where
|
||||
B: Send,
|
||||
C: Send,
|
||||
|
|
@ -265,6 +265,6 @@ macro_rules! run_driver {
|
|||
}
|
||||
}
|
||||
|
||||
StableMir::new($callback).run($args)
|
||||
RustcPublic::new($callback).run($args)
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use super::run;
|
|||
pub fn write_smir_pretty<'tcx, W: io::Write>(tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> {
|
||||
writeln!(
|
||||
w,
|
||||
"// WARNING: This is highly experimental output it's intended for stable-mir developers only."
|
||||
"// WARNING: This is highly experimental output it's intended for rustc_public developers only."
|
||||
)?;
|
||||
writeln!(
|
||||
w,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Module containing the translation from stable mir constructs to the rustc counterpart.
|
||||
//! Module containing the translation from rustc_public constructs to the rustc counterpart.
|
||||
//!
|
||||
//! This module will only include a few constructs to allow users to invoke internal rustc APIs
|
||||
//! due to incomplete stable coverage.
|
||||
|
|
@ -504,7 +504,7 @@ impl RustcInternal for ExistentialProjection {
|
|||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use crate::unstable::internal_cx::SmirExistentialProjection;
|
||||
use crate::unstable::internal_cx::ExistentialProjectionHelpers;
|
||||
tcx.new_from_args(
|
||||
self.def_id.0.internal(tables, tcx),
|
||||
self.generic_args.internal(tables, tcx),
|
||||
|
|
@ -536,7 +536,7 @@ impl RustcInternal for ExistentialTraitRef {
|
|||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use crate::unstable::internal_cx::SmirExistentialTraitRef;
|
||||
use crate::unstable::internal_cx::ExistentialTraitRefHelpers;
|
||||
tcx.new_from_args(
|
||||
self.def_id.0.internal(tables, tcx),
|
||||
self.generic_args.internal(tables, tcx),
|
||||
|
|
@ -552,7 +552,7 @@ impl RustcInternal for TraitRef {
|
|||
tables: &mut Tables<'_, BridgeTys>,
|
||||
tcx: impl InternalCx<'tcx>,
|
||||
) -> Self::T<'tcx> {
|
||||
use crate::unstable::internal_cx::SmirTraitRef;
|
||||
use crate::unstable::internal_cx::TraitRefHelpers;
|
||||
tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.args().internal(tables, tcx))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! This module holds the logic to convert rustc internal ADTs into stable mir ADTs.
|
||||
//! This module holds the logic to convert rustc internal ADTs into rustc_public ADTs.
|
||||
//!
|
||||
//! The conversion from stable to internal is not meant to be complete,
|
||||
//! and it should be added as when needed to be passed as input to rustc_public_bridge functions.
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
use std::ops::RangeInclusive;
|
||||
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
|
||||
use super::Stable;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -26,7 +26,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
(*self).stable(tables, cx)
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
self.as_ref().map(|value| value.stable(tables, cx))
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
Ok(val) => Ok(val.stable(tables, cx)),
|
||||
|
|
@ -74,7 +74,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
self.iter().map(|e| e.stable(tables, cx)).collect()
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
(self.0.stable(tables, cx), self.1.stable(tables, cx))
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
RangeInclusive::new(self.start().stable(tables, cx), self.end().stable(tables, cx))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
|
||||
use rustc_middle::ty;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
use rustc_target::callconv;
|
||||
|
||||
use crate::abi::{
|
||||
|
|
@ -21,7 +21,7 @@ use crate::{IndexedVal, opaque};
|
|||
|
||||
impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
|
||||
type T = VariantIdx;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
VariantIdx::to_val(self.as_usize())
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
|
||||
type T = crate::target::Endian;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Endian::Little => crate::target::Endian::Little,
|
||||
rustc_abi::Endian::Big => crate::target::Endian::Big,
|
||||
|
|
@ -43,7 +43,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) }
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.layout_id(cx.lift(*self).unwrap())
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
LayoutShape {
|
||||
fields: self.fields.stable(tables, cx),
|
||||
|
|
@ -85,7 +85,7 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
assert!(self.args.len() >= self.fixed_count as usize);
|
||||
assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C));
|
||||
|
|
@ -105,7 +105,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
ArgAbi {
|
||||
ty: self.layout.ty.stable(tables, cx),
|
||||
|
|
@ -118,7 +118,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
|
|||
impl<'tcx> Stable<'tcx> for CanonAbi {
|
||||
type T = CallConvention;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
CanonAbi::C => CallConvention::C,
|
||||
CanonAbi::Rust => CallConvention::Rust,
|
||||
|
|
@ -154,7 +154,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi {
|
|||
impl<'tcx> Stable<'tcx> for callconv::PassMode {
|
||||
type T = PassMode;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
callconv::PassMode::Ignore => PassMode::Ignore,
|
||||
callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
|
||||
|
|
@ -179,7 +179,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
|
||||
|
|
@ -200,7 +200,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Variants::Single { index } => {
|
||||
|
|
@ -225,7 +225,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
|
||||
|
|
@ -246,7 +246,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match *self {
|
||||
rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)),
|
||||
|
|
@ -264,7 +264,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Size {
|
||||
type T = Size;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
Size::from_bits(self.bits_usize())
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +272,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Size {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Align {
|
||||
type T = Align;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.bytes()
|
||||
}
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
|
||||
|
|
@ -301,7 +301,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Primitive::Int(length, signed) => {
|
||||
|
|
@ -318,7 +318,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
|
||||
type T = AddressSpace;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
AddressSpace(self.0)
|
||||
}
|
||||
}
|
||||
|
|
@ -326,7 +326,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
|
||||
type T = IntegerLength;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Integer::I8 => IntegerLength::I8,
|
||||
rustc_abi::Integer::I16 => IntegerLength::I16,
|
||||
|
|
@ -340,7 +340,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::Float {
|
||||
type T = FloatLength;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::Float::F16 => FloatLength::F16,
|
||||
rustc_abi::Float::F32 => FloatLength::F32,
|
||||
|
|
@ -353,7 +353,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Float {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
|
||||
type T = WrappingRange;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
WrappingRange { start: self.start, end: self.end }
|
||||
}
|
||||
}
|
||||
|
|
@ -364,7 +364,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
_tables: &mut Tables<'cx, BridgeTys>,
|
||||
_cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
_cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
ReprFlags {
|
||||
is_simd: self.intersects(Self::IS_SIMD),
|
||||
|
|
@ -381,7 +381,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
|
||||
|
|
@ -398,7 +398,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
ReprOptions {
|
||||
int: self.int.map(|int| int.stable(tables, cx)),
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::{bug, mir};
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
use rustc_public_bridge::{Tables, bridge};
|
||||
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
use crate::mir::alloc::GlobalAlloc;
|
||||
|
|
@ -19,7 +18,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::mir::Body::new(
|
||||
self.basic_blocks
|
||||
|
|
@ -54,7 +53,7 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::mir::VarDebugInfo {
|
||||
name: self.name.to_string(),
|
||||
|
|
@ -71,7 +70,7 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
Statement {
|
||||
kind: self.kind.stable(tables, cx),
|
||||
|
|
@ -85,7 +84,7 @@ impl<'tcx> Stable<'tcx> for mir::SourceInfo {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::mir::SourceInfo { span: self.span.stable(tables, cx), scope: self.scope.into() }
|
||||
}
|
||||
|
|
@ -96,7 +95,7 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
VarDebugInfoFragment {
|
||||
ty: self.ty.stable(tables, cx),
|
||||
|
|
@ -110,7 +109,7 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::VarDebugInfoContents::Place(place) => {
|
||||
|
|
@ -133,7 +132,7 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::StatementKind::Assign(assign) => crate::mir::StatementKind::Assign(
|
||||
|
|
@ -195,7 +194,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::Rvalue::*;
|
||||
match self {
|
||||
|
|
@ -259,7 +258,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::Mutability {
|
||||
type T = crate::mir::Mutability;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_hir::Mutability::*;
|
||||
match *self {
|
||||
Not => crate::mir::Mutability::Not,
|
||||
|
|
@ -270,7 +269,7 @@ impl<'tcx> Stable<'tcx> for mir::Mutability {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
|
||||
type T = crate::mir::RawPtrKind;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use mir::RawPtrKind::*;
|
||||
match *self {
|
||||
Const => crate::mir::RawPtrKind::Const,
|
||||
|
|
@ -285,7 +284,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::BorrowKind::*;
|
||||
match *self {
|
||||
|
|
@ -298,7 +297,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
|
||||
type T = crate::mir::MutBorrowKind;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::MutBorrowKind::*;
|
||||
match *self {
|
||||
Default => crate::mir::MutBorrowKind::Default,
|
||||
|
|
@ -310,7 +309,7 @@ impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind {
|
||||
type T = crate::mir::FakeBorrowKind;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::FakeBorrowKind::*;
|
||||
match *self {
|
||||
Deep => crate::mir::FakeBorrowKind::Deep,
|
||||
|
|
@ -324,7 +323,7 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::NullOp::*;
|
||||
match self {
|
||||
|
|
@ -344,7 +343,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::CastKind::*;
|
||||
match self {
|
||||
|
|
@ -364,7 +363,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
|
||||
type T = crate::mir::FakeReadCause;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::FakeReadCause::*;
|
||||
match self {
|
||||
ForMatchGuard => crate::mir::FakeReadCause::ForMatchGuard,
|
||||
|
|
@ -383,7 +382,7 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::Operand::*;
|
||||
match self {
|
||||
|
|
@ -400,7 +399,7 @@ impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::mir::ConstOperand {
|
||||
span: self.span.stable(tables, cx),
|
||||
|
|
@ -415,7 +414,7 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::mir::Place {
|
||||
local: self.local.as_usize(),
|
||||
|
|
@ -429,7 +428,7 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::ProjectionElem::*;
|
||||
match self {
|
||||
|
|
@ -464,21 +463,21 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
|
||||
type T = crate::mir::UserTypeProjection;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::Local {
|
||||
type T = crate::mir::Local;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.as_usize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::RetagKind {
|
||||
type T = crate::mir::RetagKind;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::RetagKind;
|
||||
match self {
|
||||
RetagKind::FnEntry => crate::mir::RetagKind::FnEntry,
|
||||
|
|
@ -491,7 +490,7 @@ impl<'tcx> Stable<'tcx> for mir::RetagKind {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::UnwindAction {
|
||||
type T = crate::mir::UnwindAction;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::UnwindAction;
|
||||
match self {
|
||||
UnwindAction::Continue => crate::mir::UnwindAction::Continue,
|
||||
|
|
@ -508,7 +507,7 @@ impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::NonDivergingIntrinsic;
|
||||
|
||||
|
|
@ -533,7 +532,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::AssertKind;
|
||||
match self {
|
||||
|
|
@ -580,7 +579,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::BinOp {
|
||||
type T = crate::mir::BinOp;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::BinOp;
|
||||
match self {
|
||||
BinOp::Add => crate::mir::BinOp::Add,
|
||||
|
|
@ -615,7 +614,7 @@ impl<'tcx> Stable<'tcx> for mir::BinOp {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for mir::UnOp {
|
||||
type T = crate::mir::UnOp;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::mir::UnOp;
|
||||
match self {
|
||||
UnOp::Not => crate::mir::UnOp::Not,
|
||||
|
|
@ -630,7 +629,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::AggregateKind::Array(ty) => {
|
||||
|
|
@ -676,7 +675,7 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::mir::InlineAsmOperand;
|
||||
|
||||
|
|
@ -703,7 +702,7 @@ impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::mir::Terminator;
|
||||
Terminator {
|
||||
|
|
@ -718,7 +717,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::mir::TerminatorKind;
|
||||
match self {
|
||||
|
|
@ -807,7 +806,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
self.inner().stable(tables, cx)
|
||||
}
|
||||
|
|
@ -819,9 +818,9 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_public_bridge::context::SmirAllocRange;
|
||||
use rustc_public_bridge::context::AllocRangeHelpers;
|
||||
alloc::allocation_filter(
|
||||
self,
|
||||
cx.alloc_range(rustc_abi::Size::ZERO, self.size()),
|
||||
|
|
@ -836,7 +835,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
_: &SmirCtxt<'cx, BridgeTys>,
|
||||
_: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.create_alloc_id(*self)
|
||||
}
|
||||
|
|
@ -848,7 +847,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
mir::interpret::GlobalAlloc::Function { instance, .. } => {
|
||||
|
|
@ -877,7 +876,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let id = tables.intern_mir_const(cx.lift(*self).unwrap());
|
||||
match *self {
|
||||
|
|
@ -913,8 +912,8 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
|
||||
type T = Error;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
Error::new(format!("{self:?}"))
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
bridge::Error::new(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -924,7 +923,7 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::mir::mono::MonoItem as StableMonoItem;
|
||||
match self {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use rustc_abi::FieldIdx;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
|
||||
use super::Stable;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -13,7 +13,7 @@ mod ty;
|
|||
|
||||
impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
||||
type T = crate::mir::Safety;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
rustc_hir::Safety::Unsafe => crate::mir::Safety::Unsafe,
|
||||
rustc_hir::Safety::Safe => crate::mir::Safety::Safe,
|
||||
|
|
@ -23,14 +23,14 @@ impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for FieldIdx {
|
||||
type T = usize;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.as_usize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
|
||||
type T = crate::mir::CoroutineSource;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_hir::CoroutineSource;
|
||||
match self {
|
||||
CoroutineSource::Block => crate::mir::CoroutineSource::Block,
|
||||
|
|
@ -45,7 +45,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_hir::{CoroutineDesugaring, CoroutineKind};
|
||||
match *self {
|
||||
|
|
@ -77,7 +77,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
|
|||
impl<'tcx> Stable<'tcx> for rustc_span::Symbol {
|
||||
type T = crate::Symbol;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.to_string()
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
_: &SmirCtxt<'cx, BridgeTys>,
|
||||
_: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.create_span(*self)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::{bug, mir, ty};
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
|
||||
use crate::alloc;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -14,7 +14,7 @@ use crate::unstable::Stable;
|
|||
|
||||
impl<'tcx> Stable<'tcx> for ty::AliasTyKind {
|
||||
type T = crate::ty::AliasKind;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::Projection => crate::ty::AliasKind::Projection,
|
||||
ty::Inherent => crate::ty::AliasKind::Inherent,
|
||||
|
|
@ -29,7 +29,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::AliasTy { args, def_id, .. } = self;
|
||||
crate::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) }
|
||||
|
|
@ -41,7 +41,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::AliasTerm { args, def_id, .. } = self;
|
||||
crate::ty::AliasTerm { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) }
|
||||
|
|
@ -51,7 +51,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for ty::DynKind {
|
||||
type T = crate::ty::DynKind;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::Dyn => crate::ty::DynKind::Dyn,
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::ExistentialPredicate::*;
|
||||
match self {
|
||||
|
|
@ -85,7 +85,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::ExistentialTraitRef { def_id, args, .. } = self;
|
||||
crate::ty::ExistentialTraitRef {
|
||||
|
|
@ -101,7 +101,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::TermKind;
|
||||
match self {
|
||||
|
|
@ -120,7 +120,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::ExistentialProjection { def_id, args, term, .. } = self;
|
||||
crate::ty::ExistentialProjection {
|
||||
|
|
@ -136,7 +136,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
match self {
|
||||
|
|
@ -154,7 +154,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
|
||||
type T = usize;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
self.as_usize()
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
|
|||
impl<'tcx> Stable<'tcx> for ty::AdtKind {
|
||||
type T = AdtKind;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::AdtKind::Struct => AdtKind::Struct,
|
||||
ty::AdtKind::Union => AdtKind::Union,
|
||||
|
|
@ -177,7 +177,7 @@ impl<'tcx> Stable<'tcx> for ty::FieldDef {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::ty::FieldDef {
|
||||
def: tables.create_def_id(self.did),
|
||||
|
|
@ -191,7 +191,7 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
GenericArgs(self.iter().map(|arg| arg.kind().stable(tables, cx)).collect())
|
||||
}
|
||||
|
|
@ -203,7 +203,7 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::GenericArgKind;
|
||||
match self {
|
||||
|
|
@ -225,7 +225,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::Binder;
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::EarlyBinder;
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::FnSig;
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::BoundTyKind;
|
||||
|
||||
|
|
@ -304,7 +304,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::BoundRegionKind;
|
||||
|
||||
|
|
@ -326,7 +326,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::BoundVariableKind;
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
|
|||
impl<'tcx> Stable<'tcx> for ty::IntTy {
|
||||
type T = IntTy;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::IntTy::Isize => IntTy::Isize,
|
||||
ty::IntTy::I8 => IntTy::I8,
|
||||
|
|
@ -360,7 +360,7 @@ impl<'tcx> Stable<'tcx> for ty::IntTy {
|
|||
impl<'tcx> Stable<'tcx> for ty::UintTy {
|
||||
type T = UintTy;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::UintTy::Usize => UintTy::Usize,
|
||||
ty::UintTy::U8 => UintTy::U8,
|
||||
|
|
@ -375,7 +375,7 @@ impl<'tcx> Stable<'tcx> for ty::UintTy {
|
|||
impl<'tcx> Stable<'tcx> for ty::FloatTy {
|
||||
type T = FloatTy;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::FloatTy::F16 => FloatTy::F16,
|
||||
ty::FloatTy::F32 => FloatTy::F32,
|
||||
|
|
@ -390,7 +390,7 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
tables.intern_ty(cx.lift(*self).unwrap())
|
||||
}
|
||||
|
|
@ -401,7 +401,7 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match self {
|
||||
ty::Bool => TyKind::RigidTy(RigidTy::Bool),
|
||||
|
|
@ -487,7 +487,7 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
match **self {
|
||||
ty::PatternKind::Range { start, end } => crate::ty::Pattern::Range {
|
||||
|
|
@ -507,7 +507,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ct = cx.lift(*self).unwrap();
|
||||
let kind = match ct.kind() {
|
||||
|
|
@ -540,7 +540,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for ty::ParamConst {
|
||||
type T = crate::ty::ParamConst;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use crate::ty::ParamConst;
|
||||
ParamConst { index: self.index, name: self.name.to_string() }
|
||||
}
|
||||
|
|
@ -548,7 +548,7 @@ impl<'tcx> Stable<'tcx> for ty::ParamConst {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for ty::ParamTy {
|
||||
type T = crate::ty::ParamTy;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use crate::ty::ParamTy;
|
||||
ParamTy { index: self.index, name: self.name.to_string() }
|
||||
}
|
||||
|
|
@ -559,7 +559,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::BoundTy;
|
||||
BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables, cx) }
|
||||
|
|
@ -568,7 +568,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
|
||||
type T = crate::ty::TraitSpecializationKind;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use crate::ty::TraitSpecializationKind;
|
||||
|
||||
match self {
|
||||
|
|
@ -586,7 +586,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::opaque;
|
||||
use crate::ty::TraitDecl;
|
||||
|
|
@ -616,7 +616,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::TraitRef;
|
||||
|
||||
|
|
@ -630,7 +630,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::Generics;
|
||||
|
||||
|
|
@ -655,7 +655,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics {
|
|||
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
|
||||
type T = crate::ty::GenericParamDefKind;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use crate::ty::GenericParamDefKind;
|
||||
match self {
|
||||
ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
|
||||
|
|
@ -675,7 +675,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
GenericParamDef {
|
||||
name: self.name.to_string(),
|
||||
|
|
@ -693,7 +693,7 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::ty::PredicateKind;
|
||||
match self {
|
||||
|
|
@ -731,7 +731,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_middle::ty::ClauseKind;
|
||||
match *self {
|
||||
|
|
@ -774,7 +774,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for ty::ClosureKind {
|
||||
type T = crate::ty::ClosureKind;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::ty::ClosureKind::*;
|
||||
match self {
|
||||
Fn => crate::ty::ClosureKind::Fn,
|
||||
|
|
@ -790,7 +790,7 @@ impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
|
||||
crate::ty::SubtypePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) }
|
||||
|
|
@ -803,7 +803,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::CoercePredicate { a, b } = self;
|
||||
crate::ty::CoercePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) }
|
||||
|
|
@ -813,7 +813,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
|
||||
type T = crate::ty::AliasRelationDirection;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::ty::AliasRelationDirection::*;
|
||||
match self {
|
||||
Equate => crate::ty::AliasRelationDirection::Equate,
|
||||
|
|
@ -828,7 +828,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::TraitPredicate { trait_ref, polarity } = self;
|
||||
crate::ty::TraitPredicate {
|
||||
|
|
@ -847,7 +847,7 @@ where
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::OutlivesPredicate(a, b) = self;
|
||||
crate::ty::OutlivesPredicate(a.stable(tables, cx), b.stable(tables, cx))
|
||||
|
|
@ -860,7 +860,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let ty::ProjectionPredicate { projection_term, term } = self;
|
||||
crate::ty::ProjectionPredicate {
|
||||
|
|
@ -873,7 +873,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
|
|||
impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
|
||||
type T = crate::ty::ImplPolarity;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::ty::ImplPolarity::*;
|
||||
match self {
|
||||
Positive => crate::ty::ImplPolarity::Positive,
|
||||
|
|
@ -886,7 +886,7 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
|
|||
impl<'tcx> Stable<'tcx> for ty::PredicatePolarity {
|
||||
type T = crate::ty::PredicatePolarity;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_middle::ty::PredicatePolarity::*;
|
||||
match self {
|
||||
Positive => crate::ty::PredicatePolarity::Positive,
|
||||
|
|
@ -901,7 +901,7 @@ impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
Region { kind: self.kind().stable(tables, cx) }
|
||||
}
|
||||
|
|
@ -913,7 +913,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::{BoundRegion, EarlyParamRegion, RegionKind};
|
||||
match self {
|
||||
|
|
@ -948,7 +948,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
let def = tables.instance_def(cx.lift(*self).unwrap());
|
||||
let kind = match self.def {
|
||||
|
|
@ -976,7 +976,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
|
|||
|
||||
impl<'tcx> Stable<'tcx> for ty::Variance {
|
||||
type T = crate::mir::Variance;
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::Bivariant => crate::mir::Variance::Bivariant,
|
||||
ty::Contravariant => crate::mir::Variance::Contravariant,
|
||||
|
|
@ -989,7 +989,7 @@ impl<'tcx> Stable<'tcx> for ty::Variance {
|
|||
impl<'tcx> Stable<'tcx> for ty::Movability {
|
||||
type T = crate::ty::Movability;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
match self {
|
||||
ty::Movability::Static => crate::ty::Movability::Static,
|
||||
ty::Movability::Movable => crate::ty::Movability::Movable,
|
||||
|
|
@ -1000,7 +1000,7 @@ impl<'tcx> Stable<'tcx> for ty::Movability {
|
|||
impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
|
||||
type T = crate::ty::Abi;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use rustc_abi::ExternAbi;
|
||||
|
||||
use crate::ty::Abi;
|
||||
|
|
@ -1042,7 +1042,7 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::ty::ForeignModule {
|
||||
def_id: tables.foreign_module_def(self.def_id),
|
||||
|
|
@ -1057,7 +1057,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::{AssocKind, AssocTypeData};
|
||||
match *self {
|
||||
|
|
@ -1080,7 +1080,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
|
|||
impl<'tcx> Stable<'tcx> for ty::AssocItemContainer {
|
||||
type T = crate::ty::AssocItemContainer;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
use crate::ty::AssocItemContainer;
|
||||
match self {
|
||||
ty::AssocItemContainer::Trait => AssocItemContainer::Trait,
|
||||
|
|
@ -1095,7 +1095,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::ty::AssocItem {
|
||||
def_id: tables.assoc_def(self.def_id),
|
||||
|
|
@ -1112,7 +1112,7 @@ impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
_: &SmirCtxt<'cx, BridgeTys>,
|
||||
_: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::ImplTraitInTraitData;
|
||||
match self {
|
||||
|
|
@ -1135,7 +1135,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::util::Discr<'tcx> {
|
|||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
crate::ty::Discr { val: self.val, ty: self.ty.stable(tables, cx) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use rustc_middle::ty;
|
||||
|
||||
pub(crate) trait SmirExistentialProjection<'tcx> {
|
||||
pub(crate) trait ExistentialProjectionHelpers<'tcx> {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
def_id: rustc_span::def_id::DefId,
|
||||
|
|
@ -14,7 +14,7 @@ pub(crate) trait SmirExistentialProjection<'tcx> {
|
|||
) -> ty::ExistentialProjection<'tcx>;
|
||||
}
|
||||
|
||||
pub(crate) trait SmirExistentialTraitRef<'tcx> {
|
||||
pub(crate) trait ExistentialTraitRefHelpers<'tcx> {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: rustc_span::def_id::DefId,
|
||||
|
|
@ -22,7 +22,7 @@ pub(crate) trait SmirExistentialTraitRef<'tcx> {
|
|||
) -> ty::ExistentialTraitRef<'tcx>;
|
||||
}
|
||||
|
||||
pub(crate) trait SmirTraitRef<'tcx> {
|
||||
pub(crate) trait TraitRefHelpers<'tcx> {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: rustc_span::def_id::DefId,
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
//! Implementation of InternalCx.
|
||||
|
||||
pub(crate) use helpers::*;
|
||||
use rustc_middle::ty::{List, Ty, TyCtxt};
|
||||
use rustc_middle::{mir, ty};
|
||||
pub(crate) use traits::*;
|
||||
|
||||
use super::InternalCx;
|
||||
|
||||
pub(crate) mod traits;
|
||||
pub(crate) mod helpers;
|
||||
|
||||
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T {
|
||||
impl<'tcx, T: InternalCx<'tcx>> ExistentialProjectionHelpers<'tcx> for T {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
def_id: rustc_span::def_id::DefId,
|
||||
|
|
@ -19,7 +19,7 @@ impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T {
|
||||
impl<'tcx, T: InternalCx<'tcx>> ExistentialTraitRefHelpers<'tcx> for T {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: rustc_span::def_id::DefId,
|
||||
|
|
@ -29,7 +29,7 @@ impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: InternalCx<'tcx>> SmirTraitRef<'tcx> for T {
|
||||
impl<'tcx, T: InternalCx<'tcx>> TraitRefHelpers<'tcx> for T {
|
||||
fn new_from_args(
|
||||
&self,
|
||||
trait_def_id: rustc_span::def_id::DefId,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Module that collects the things that have no stability guarantees.
|
||||
//!
|
||||
//! We want to keep StableMIR definitions and logic separate from
|
||||
//! We want to keep rustc_public's IR definitions and logic separate from
|
||||
//! any sort of conversion and usage of internal rustc code. So we
|
||||
//! restrict the usage of internal items to be inside this module.
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_middle::ty::{List, Ty, TyCtxt};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::context::CompilerCtxt;
|
||||
|
||||
use super::compiler_interface::BridgeTys;
|
||||
use crate::{CtorKind, ItemKind};
|
||||
|
|
@ -21,7 +21,7 @@ mod internal_cx;
|
|||
/// Trait that defines the methods that are fine to call from [`RustcInternal`].
|
||||
///
|
||||
/// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals
|
||||
/// should go through [`rustc_public_bridge::context::SmirCtxt`].
|
||||
/// should go through [`rustc_public_bridge::context::CompilerCtxt`].
|
||||
pub trait InternalCx<'tcx>: Copy + Clone {
|
||||
fn tcx(self) -> TyCtxt<'tcx>;
|
||||
|
||||
|
|
@ -53,29 +53,30 @@ pub trait InternalCx<'tcx>: Copy + Clone {
|
|||
fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx>;
|
||||
}
|
||||
|
||||
/// Trait used to convert between an internal MIR type to a Stable MIR type.
|
||||
/// Trait used to convert between an internal MIR type to a rustc_public's IR type.
|
||||
///
|
||||
/// This trait is currently exposed to users so they can have interoperability between internal MIR
|
||||
/// and StableMIR constructs. However, they should be used seldom and they have no influence
|
||||
/// in this crate semver.
|
||||
/// This trait is currently exposed to users so they can have interoperability
|
||||
/// between internal MIR and rustc_public's IR constructs.
|
||||
/// However, they should be used seldom and they have no influence in this crate semver.
|
||||
#[doc(hidden)]
|
||||
pub trait Stable<'tcx>: PointeeSized {
|
||||
/// The stable representation of the type implementing Stable.
|
||||
type T;
|
||||
/// Converts an object to the equivalent Stable MIR representation.
|
||||
/// Converts an object to the equivalent rustc_public's IR representation.
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
cx: &CompilerCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T;
|
||||
}
|
||||
|
||||
/// Trait used to translate a stable construct to its rustc counterpart.
|
||||
/// Trait used to translate a rustc_public's IR construct to its rustc counterpart.
|
||||
///
|
||||
/// This is basically a mirror of [Stable].
|
||||
///
|
||||
/// This trait is currently exposed to users so they can have interoperability between internal MIR
|
||||
/// and StableMIR constructs. They should be used seldom as they have no stability guarantees.
|
||||
/// This trait is currently exposed to users so they can have interoperability
|
||||
/// between internal MIR and rustc_public's IR constructs.
|
||||
/// They should be used seldom as they have no stability guarantees.
|
||||
#[doc(hidden)]
|
||||
pub trait RustcInternal {
|
||||
type T<'tcx>;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Internal memory allocator implementation for StableMIR.
|
||||
//! Internal memory allocator implementation for rustc_public.
|
||||
//!
|
||||
//! This module handles all direct interactions with rustc queries and performs
|
||||
//! the actual memory allocations. The stable interface in `rustc_public::alloc`
|
||||
|
|
@ -10,22 +10,22 @@ use rustc_middle::mir::interpret::{
|
|||
};
|
||||
use rustc_middle::ty::{Ty, layout};
|
||||
|
||||
use super::{SmirCtxt, Tables};
|
||||
use super::{CompilerCtxt, Tables};
|
||||
use crate::bridge::Allocation as _;
|
||||
use crate::{Bridge, SmirError};
|
||||
use crate::{Bridge, Error};
|
||||
|
||||
pub fn create_ty_and_layout<'tcx, B: Bridge>(
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
cx: &CompilerCtxt<'tcx, B>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<TyAndLayout<'tcx, Ty<'tcx>>, &'tcx layout::LayoutError<'tcx>> {
|
||||
use crate::context::SmirTypingEnv;
|
||||
use crate::context::TypingEnvHelpers;
|
||||
cx.tcx.layout_of(cx.fully_monomorphized().as_query_input(ty))
|
||||
}
|
||||
|
||||
pub fn try_new_scalar<'tcx, B: Bridge>(
|
||||
layout: TyAndLayout<'tcx, Ty<'tcx>>,
|
||||
scalar: Scalar,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
cx: &CompilerCtxt<'tcx, B>,
|
||||
) -> Result<Allocation, B::Error> {
|
||||
let size = scalar.size();
|
||||
let mut allocation = Allocation::new(size, layout.align.abi, AllocInit::Uninit, ());
|
||||
|
|
@ -40,7 +40,7 @@ pub fn try_new_slice<'tcx, B: Bridge>(
|
|||
layout: TyAndLayout<'tcx, Ty<'tcx>>,
|
||||
data: ConstAllocation<'tcx>,
|
||||
meta: u64,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
cx: &CompilerCtxt<'tcx, B>,
|
||||
) -> Result<Allocation, B::Error> {
|
||||
let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data);
|
||||
let ptr = Pointer::new(alloc_id.into(), Size::ZERO);
|
||||
|
|
@ -60,7 +60,7 @@ pub fn try_new_slice<'tcx, B: Bridge>(
|
|||
|
||||
pub fn try_new_indirect<'tcx, B: Bridge>(
|
||||
alloc_id: AllocId,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
cx: &CompilerCtxt<'tcx, B>,
|
||||
) -> ConstAllocation<'tcx> {
|
||||
let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory();
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ pub fn allocation_filter<'tcx, B: Bridge>(
|
|||
alloc: &rustc_middle::mir::interpret::Allocation,
|
||||
alloc_range: AllocRange,
|
||||
tables: &mut Tables<'tcx, B>,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
cx: &CompilerCtxt<'tcx, B>,
|
||||
) -> B::Allocation {
|
||||
let mut bytes: Vec<Option<u8>> = alloc
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::context::SmirCtxt;
|
||||
use super::context::CompilerCtxt;
|
||||
use super::{Bridge, Tables};
|
||||
|
||||
pub trait SmirError {
|
||||
pub trait Error {
|
||||
fn new(msg: String) -> Self;
|
||||
fn from_internal<T: Debug>(err: T) -> Self;
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ pub trait Allocation<B: Bridge> {
|
|||
align: u64,
|
||||
mutability: rustc_middle::mir::Mutability,
|
||||
tables: &mut Tables<'tcx, B>,
|
||||
cx: &SmirCtxt<'tcx, B>,
|
||||
cx: &CompilerCtxt<'tcx, B>,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
//! Logic required to produce a monomorphic stable body.
|
||||
//! Logic required to produce a monomorphic body.
|
||||
//!
|
||||
//! We first retrieve and monomorphize the rustc body representation, i.e., we generate a
|
||||
//! We retrieve and monomorphize the rustc body representation, i.e., we generate a
|
||||
//! monomorphic body using internal representation.
|
||||
//! After that, we convert the internal representation into a stable one.
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::mir;
|
||||
|
|
@ -25,7 +24,7 @@ impl<'tcx> BodyBuilder<'tcx> {
|
|||
BodyBuilder { tcx, instance }
|
||||
}
|
||||
|
||||
/// Build a stable monomorphic body for a given instance based on the MIR body.
|
||||
/// Build a monomorphic body for a given instance based on the MIR body.
|
||||
///
|
||||
/// All constants are also evaluated.
|
||||
pub(crate) fn build(mut self) -> mir::Body<'tcx> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! A set of traits that define a stable interface to rustc's internals.
|
||||
//!
|
||||
//! These traits abstract rustc's internal APIs, allowing StableMIR to maintain a stable
|
||||
//! These traits abstract rustc's internal APIs, allowing rustc_public to maintain a stable
|
||||
//! interface regardless of internal compiler changes.
|
||||
|
||||
use rustc_middle::mir::interpret::AllocRange;
|
||||
|
|
@ -8,14 +8,14 @@ use rustc_middle::ty;
|
|||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::def_id::DefId;
|
||||
|
||||
pub trait SmirTy<'tcx> {
|
||||
pub trait TyHelpers<'tcx> {
|
||||
fn new_foreign(&self, def_id: DefId) -> Ty<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirTypingEnv<'tcx> {
|
||||
pub trait TypingEnvHelpers<'tcx> {
|
||||
fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx>;
|
||||
}
|
||||
|
||||
pub trait SmirAllocRange<'tcx> {
|
||||
pub trait AllocRangeHelpers<'tcx> {
|
||||
fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
//! Implementation of StableMIR Context.
|
||||
//! Implementation of CompilerCtxt.
|
||||
|
||||
#![allow(rustc::usage_of_qualified_ty)]
|
||||
|
||||
|
|
@ -24,23 +24,23 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
|||
use rustc_span::{FileNameDisplayPreference, Span, Symbol};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{SmirAllocRange, SmirCtxt, SmirTy, SmirTypingEnv};
|
||||
use super::{AllocRangeHelpers, CompilerCtxt, TyHelpers, TypingEnvHelpers};
|
||||
use crate::builder::BodyBuilder;
|
||||
use crate::{Bridge, SmirError, Tables, filter_def_ids};
|
||||
use crate::{Bridge, Error, Tables, filter_def_ids};
|
||||
|
||||
impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> TyHelpers<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> {
|
||||
ty::Ty::new_foreign(self.tcx, def_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirTypingEnv<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> TypingEnvHelpers<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> AllocRangeHelpers<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
fn alloc_range(
|
||||
&self,
|
||||
offset: rustc_abi::Size,
|
||||
|
|
@ -50,7 +50,7 @@ impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
|
||||
pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> Option<T::Lifted> {
|
||||
self.tcx.lift(value)
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
|
|||
/// Return whether the item has a body defined by the user.
|
||||
///
|
||||
/// Note that intrinsics may have a placeholder body that shouldn't be used in practice.
|
||||
/// In StableMIR, we handle this case as if the body is not available.
|
||||
/// In rustc_public, we handle this case as if the body is not available.
|
||||
pub(crate) fn item_has_body(&self, def_id: DefId) -> bool {
|
||||
let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) {
|
||||
intrinsic.must_be_overridden
|
||||
|
|
@ -426,7 +426,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
|
|||
|
||||
/// Evaluate constant as a target usize.
|
||||
pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {
|
||||
use crate::context::SmirTypingEnv;
|
||||
use crate::context::TypingEnvHelpers;
|
||||
cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized())
|
||||
.ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Implementation of StableMIR Context.
|
||||
//! Implementation of CompilerCtxt.
|
||||
|
||||
#![allow(rustc::usage_of_qualified_ty)]
|
||||
|
||||
|
|
@ -9,30 +9,30 @@ use rustc_middle::ty;
|
|||
use rustc_middle::ty::layout::{FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOfHelpers};
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
|
||||
use crate::{Bridge, SmirError};
|
||||
use crate::{Bridge, Error};
|
||||
|
||||
mod helpers;
|
||||
mod impls;
|
||||
mod traits;
|
||||
|
||||
pub use traits::*;
|
||||
pub use helpers::*;
|
||||
|
||||
/// Provides direct access to rustc's internal queries.
|
||||
///
|
||||
/// `SmirInterface` must go through
|
||||
/// this context to obtain rustc-level information.
|
||||
pub struct SmirCtxt<'tcx, B: Bridge> {
|
||||
/// `CompilerInterface` must go through
|
||||
/// this context to obtain internal information.
|
||||
pub struct CompilerCtxt<'tcx, B: Bridge> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
_marker: PhantomData<B>,
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
|
||||
Self { tcx, _marker: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement error handling for extracting function ABI information.
|
||||
impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, B::Error>;
|
||||
|
||||
#[inline]
|
||||
|
|
@ -46,7 +46,7 @@ impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, B::Error>;
|
||||
|
||||
#[inline]
|
||||
|
|
@ -60,19 +60,19 @@ impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for CompilerCtxt<'tcx, B> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, B: Bridge> HasDataLayout for SmirCtxt<'tcx, B> {
|
||||
impl<'tcx, B: Bridge> HasDataLayout for CompilerCtxt<'tcx, B> {
|
||||
fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
|
||||
self.tcx.data_layout()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Crate that implements what will become the rustc side of Stable MIR.
|
||||
//! Crate that implements what will become the rustc side of rustc_public.
|
||||
//!
|
||||
//! This crate is responsible for building Stable MIR components from internal components.
|
||||
//! This crate serves as a proxy for making calls to rustc queries.
|
||||
//!
|
||||
//! This crate is not intended to be invoked directly by users.
|
||||
//! This crate is the public API of rustc that will be invoked by the `rustc_public` crate.
|
||||
|
|
@ -29,7 +29,7 @@ use std::hash::Hash;
|
|||
use std::ops::Index;
|
||||
|
||||
use bridge::*;
|
||||
use context::SmirCtxt;
|
||||
use context::CompilerCtxt;
|
||||
use rustc_data_structures::fx::{self, FxIndexMap};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::AllocId;
|
||||
|
|
@ -46,9 +46,9 @@ pub mod context;
|
|||
pub mod rustc_internal {}
|
||||
|
||||
/// A container which is used for TLS.
|
||||
pub struct SmirContainer<'tcx, B: Bridge> {
|
||||
pub struct Container<'tcx, B: Bridge> {
|
||||
pub tables: RefCell<Tables<'tcx, B>>,
|
||||
pub cx: RefCell<SmirCtxt<'tcx, B>>,
|
||||
pub cx: RefCell<CompilerCtxt<'tcx, B>>,
|
||||
}
|
||||
|
||||
pub struct Tables<'tcx, B: Bridge> {
|
||||
|
|
@ -210,7 +210,7 @@ impl<'tcx, B: Bridge> Tables<'tcx, B> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A trait defining types that are used to emulate StableMIR components, which is really
|
||||
/// A trait defining types that are used to emulate rustc_public components, which is really
|
||||
/// useful when programming in rustc_public-agnostic settings.
|
||||
pub trait Bridge: Sized {
|
||||
type DefId: Copy + Debug + PartialEq + IndexedVal;
|
||||
|
|
@ -222,7 +222,7 @@ pub trait Bridge: Sized {
|
|||
type MirConstId: Copy + Debug + PartialEq + IndexedVal;
|
||||
type Layout: Copy + Debug + PartialEq + IndexedVal;
|
||||
|
||||
type Error: SmirError;
|
||||
type Error: Error;
|
||||
type CrateItem: CrateItem<Self>;
|
||||
type AdtDef: AdtDef<Self>;
|
||||
type ForeignModuleDef: ForeignModuleDef<Self>;
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion =
|
|||
resolve_attributes_starting_with_rustc_are_reserved =
|
||||
attributes starting with `rustc` are reserved for use by the `rustc` compiler
|
||||
|
||||
resolve_bad_macro_import = bad macro import
|
||||
|
||||
resolve_binding_in_never_pattern =
|
||||
never patterns cannot contain variable bindings
|
||||
.suggestion = use a wildcard `_` instead
|
||||
|
|
|
|||
|
|
@ -11,11 +11,14 @@ use std::sync::Arc;
|
|||
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
|
||||
use rustc_ast::{
|
||||
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
|
||||
ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind, TyAlias,
|
||||
ForeignItemKind, Impl, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
|
||||
};
|
||||
use rustc_attr_data_structures::{AttributeKind, MacroUseArgs};
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
use rustc_expand::base::ResolverExpand;
|
||||
use rustc_expand::expand::AstFragment;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_hir::def::{self, *};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
||||
use rustc_index::bit_set::DenseBitSet;
|
||||
|
|
@ -25,6 +28,7 @@ use rustc_middle::metadata::ModChild;
|
|||
use rustc_middle::ty::{Feed, Visibility};
|
||||
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
|
||||
use rustc_span::{Ident, Span, Symbol, kw, sym};
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::Namespace::{MacroNS, TypeNS, ValueNS};
|
||||
|
|
@ -1019,42 +1023,31 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
/// Returns `true` if we should consider the underlying `extern crate` to be used.
|
||||
fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
|
||||
let mut import_all = None;
|
||||
let mut single_imports = Vec::new();
|
||||
for attr in &item.attrs {
|
||||
if attr.has_name(sym::macro_use) {
|
||||
if self.parent_scope.module.parent.is_some() {
|
||||
self.r.dcx().emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot {
|
||||
span: item.span,
|
||||
});
|
||||
}
|
||||
if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
|
||||
&& orig_name == kw::SelfLower
|
||||
{
|
||||
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
|
||||
}
|
||||
let ill_formed = |span| {
|
||||
self.r.dcx().emit_err(errors::BadMacroImport { span });
|
||||
};
|
||||
match attr.meta() {
|
||||
Some(meta) => match meta.kind {
|
||||
MetaItemKind::Word => {
|
||||
import_all = Some(meta.span);
|
||||
break;
|
||||
}
|
||||
MetaItemKind::List(meta_item_inners) => {
|
||||
for meta_item_inner in meta_item_inners {
|
||||
match meta_item_inner.ident() {
|
||||
Some(ident) if meta_item_inner.is_word() => {
|
||||
single_imports.push(ident)
|
||||
}
|
||||
_ => ill_formed(meta_item_inner.span()),
|
||||
}
|
||||
}
|
||||
}
|
||||
MetaItemKind::NameValue(..) => ill_formed(meta.span),
|
||||
},
|
||||
None => ill_formed(attr.span),
|
||||
}
|
||||
let mut single_imports = ThinVec::new();
|
||||
if let Some(Attribute::Parsed(AttributeKind::MacroUse { span, arguments })) =
|
||||
AttributeParser::parse_limited(
|
||||
self.r.tcx.sess,
|
||||
&item.attrs,
|
||||
sym::macro_use,
|
||||
item.span,
|
||||
item.id,
|
||||
None,
|
||||
)
|
||||
{
|
||||
if self.parent_scope.module.parent.is_some() {
|
||||
self.r
|
||||
.dcx()
|
||||
.emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot { span: item.span });
|
||||
}
|
||||
if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
|
||||
&& orig_name == kw::SelfLower
|
||||
{
|
||||
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span });
|
||||
}
|
||||
|
||||
match arguments {
|
||||
MacroUseArgs::UseAll => import_all = Some(span),
|
||||
MacroUseArgs::UseSpecific(imports) => single_imports = imports,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -815,13 +815,6 @@ pub(crate) struct ExternCrateLoadingMacroNotAtCrateRoot {
|
|||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_bad_macro_import, code = E0466)]
|
||||
pub(crate) struct BadMacroImport {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_extern_crate_self_requires_renaming)]
|
||||
pub(crate) struct ExternCrateSelfRequiresRenaming {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! A bunch of methods and structures more or less related to resolving macros and
|
||||
//! interface provided by `Resolver` to macro expander.
|
||||
|
||||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -13,10 +14,10 @@ use rustc_expand::base::{
|
|||
Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension,
|
||||
SyntaxExtensionKind,
|
||||
};
|
||||
use rustc_expand::compile_declarative_macro;
|
||||
use rustc_expand::expand::{
|
||||
AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
|
||||
};
|
||||
use rustc_expand::{MacroRulesMacroExpander, compile_declarative_macro};
|
||||
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
||||
use rustc_middle::middle::stability;
|
||||
|
|
@ -357,8 +358,12 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
|
|||
let SyntaxExtensionKind::LegacyBang(ref ext) = m.ext.kind else {
|
||||
continue;
|
||||
};
|
||||
let ext: &dyn Any = ext.as_ref();
|
||||
let Some(m) = ext.downcast_ref::<MacroRulesMacroExpander>() else {
|
||||
continue;
|
||||
};
|
||||
for arm_i in unused_arms.iter() {
|
||||
if let Some((ident, rule_span)) = ext.get_unused_rule(arm_i) {
|
||||
if let Some((ident, rule_span)) = m.get_unused_rule(arm_i) {
|
||||
self.lint_buffer.buffer_lint(
|
||||
UNUSED_MACRO_RULES,
|
||||
node_id,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue