Auto merge of #73756 - Manishearth:rollup-aehswb2, r=Manishearth
Rollup of 13 pull requests Successful merges: - #72620 (Omit DW_AT_linkage_name when it is the same as DW_AT_name) - #72967 (Don't move cursor in search box when using arrows to navigate results) - #73102 (proc_macro: Stop flattening groups with dummy spans) - #73297 (Support configurable deny-warnings for all in-tree crates.) - #73507 (Cleanup MinGW LLVM linkage workaround) - #73588 (Fix handling of reserved registers for ARM inline asm) - #73597 (Record span of `const` kw in GenericParamKind) - #73629 (Make AssocOp Copy) - #73681 (Update Chalk to 0.14) - #73707 (Fix links in `SliceIndex` documentation) - #73719 (emitter: column width defaults to 140) - #73729 (disable collectionbenches for android) - #73748 (Add code block to code in documentation of `List::rebase_onto`) Failed merges: r? @ghost
This commit is contained in:
commit
9672b5e95c
79 changed files with 646 additions and 295 deletions
49
Cargo.lock
49
Cargo.lock
|
@ -434,9 +434,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "chalk-derive"
|
||||
version = "0.11.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9bd01eab87277d973183a1d2e56bace1c11f8242c52c20636fb7dddf343ac9"
|
||||
checksum = "d463e01905d607e181de72e8608721d3269f29176c9a14ce037011316ae7131d"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3",
|
||||
"quote 1.0.2",
|
||||
|
@ -446,20 +446,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "chalk-engine"
|
||||
version = "0.11.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c7a637c3d17ed555aef16e16952a5d1e127bd55178cc30be22afeb92da90c7d"
|
||||
checksum = "efaf428f5398d36284f79690cf988762b7c091249f50a6c11db613a46c057000"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"chalk-ir",
|
||||
"rustc-hash",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chalk-ir"
|
||||
version = "0.11.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "595e5735ded16c3f3dc348f7b15bbb2521a0080b1863cac38ad5271589944670"
|
||||
checksum = "fd3fdc1e9f68498ffe80f4a23b0b95f1ca6fb21d5a4c9b0c085fab3ca712bdbe"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"lazy_static",
|
||||
|
@ -467,9 +468,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "chalk-solve"
|
||||
version = "0.11.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d9d938139db425867a30cc0cfec0269406d8238d0571d829041eaa7a8455d11"
|
||||
checksum = "5b9fd4102807b7ebe8fb034fa0f488c5656e1966d3261b558b81a08d519cdb29"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"chalk-engine",
|
||||
|
@ -478,6 +479,7 @@ dependencies = [
|
|||
"itertools 0.9.0",
|
||||
"petgraph",
|
||||
"rustc-hash",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5332,6 +5334,37 @@ dependencies = [
|
|||
"syn 0.15.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a41f40ed0e162c911ac6fcb53ecdc8134c46905fdbbae8c50add462a538b495f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99bbad0de3fd923c9c3232ead88510b783e5a4d16a6154adffa3d53308de984c"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.2"
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::install;
|
|||
use crate::native;
|
||||
use crate::run;
|
||||
use crate::test;
|
||||
use crate::tool;
|
||||
use crate::tool::{self, SourceType};
|
||||
use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir};
|
||||
use crate::{Build, DocTests, GitRepo, Mode};
|
||||
|
||||
|
@ -759,6 +759,7 @@ impl<'a> Builder<'a> {
|
|||
&self,
|
||||
compiler: Compiler,
|
||||
mode: Mode,
|
||||
source_type: SourceType,
|
||||
target: Interned<String>,
|
||||
cmd: &str,
|
||||
) -> Cargo {
|
||||
|
@ -1125,7 +1126,7 @@ impl<'a> Builder<'a> {
|
|||
|
||||
cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
|
||||
|
||||
if !mode.is_tool() {
|
||||
if source_type == SourceType::InTree {
|
||||
// When extending this list, add the new lints to the RUSTFLAGS of the
|
||||
// build_bootstrap function of src/bootstrap/bootstrap.py as well as
|
||||
// some code doesn't go through this `rustc` wrapper.
|
||||
|
|
|
@ -44,7 +44,13 @@ impl Step for Std {
|
|||
let target = self.target;
|
||||
let compiler = builder.compiler(0, builder.config.build);
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
|
||||
let mut cargo = builder.cargo(
|
||||
compiler,
|
||||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
);
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
||||
builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
|
||||
|
@ -92,8 +98,13 @@ impl Step for Rustc {
|
|||
|
||||
builder.ensure(Std { target });
|
||||
|
||||
let mut cargo =
|
||||
builder.cargo(compiler, Mode::Rustc, target, cargo_subcommand(builder.kind));
|
||||
let mut cargo = builder.cargo(
|
||||
compiler,
|
||||
Mode::Rustc,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
);
|
||||
rustc_cargo(builder, &mut cargo, target);
|
||||
|
||||
builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
|
||||
|
@ -113,7 +124,7 @@ impl Step for Rustc {
|
|||
}
|
||||
|
||||
macro_rules! tool_check_step {
|
||||
($name:ident, $path:expr) => {
|
||||
($name:ident, $path:expr, $source_type:expr) => {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct $name {
|
||||
pub target: Interned<String>,
|
||||
|
@ -145,7 +156,7 @@ macro_rules! tool_check_step {
|
|||
target,
|
||||
cargo_subcommand(builder.kind),
|
||||
$path,
|
||||
SourceType::InTree,
|
||||
$source_type,
|
||||
&[],
|
||||
);
|
||||
|
||||
|
@ -184,8 +195,12 @@ macro_rules! tool_check_step {
|
|||
};
|
||||
}
|
||||
|
||||
tool_check_step!(Rustdoc, "src/tools/rustdoc");
|
||||
tool_check_step!(Clippy, "src/tools/clippy");
|
||||
tool_check_step!(Rustdoc, "src/tools/rustdoc", SourceType::InTree);
|
||||
// Clippy is a hybrid. It is an external tool, but uses a git subtree instead
|
||||
// of a submodule. Since the SourceType only drives the deny-warnings
|
||||
// behavior, treat it as in-tree so that any new warnings in clippy will be
|
||||
// rejected.
|
||||
tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
|
||||
|
||||
/// Cargo's output path for the standard library in a given stage, compiled
|
||||
/// by a particular compiler for the specified target.
|
||||
|
|
|
@ -20,13 +20,13 @@ use filetime::FileTime;
|
|||
use serde::Deserialize;
|
||||
|
||||
use crate::builder::Cargo;
|
||||
use crate::dist;
|
||||
use crate::native;
|
||||
use crate::util::{exe, is_dylib, symlink_dir};
|
||||
use crate::{Compiler, DependencyType, GitRepo, Mode};
|
||||
|
||||
use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
|
||||
use crate::cache::{Interned, INTERNER};
|
||||
use crate::dist;
|
||||
use crate::native;
|
||||
use crate::tool::SourceType;
|
||||
use crate::util::{exe, is_dylib, symlink_dir};
|
||||
use crate::{Compiler, DependencyType, GitRepo, Mode};
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Std {
|
||||
|
@ -87,7 +87,7 @@ impl Step for Std {
|
|||
target_deps.extend(copy_third_party_objects(builder, &compiler, target));
|
||||
target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
||||
builder.info(&format!(
|
||||
|
@ -513,7 +513,7 @@ impl Step for Rustc {
|
|||
target: builder.config.build,
|
||||
});
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build");
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build");
|
||||
rustc_cargo(builder, &mut cargo, target);
|
||||
|
||||
builder.info(&format!(
|
||||
|
|
|
@ -435,7 +435,8 @@ impl Step for Std {
|
|||
t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css")));
|
||||
|
||||
let run_cargo_rustdoc_for = |package: &str| {
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, target, "rustdoc");
|
||||
let mut cargo =
|
||||
builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
|
||||
compile::std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
||||
// Keep a whitelist so we do not build internal stdlib crates, these will be
|
||||
|
@ -534,7 +535,7 @@ impl Step for Rustc {
|
|||
t!(symlink_dir_force(&builder.config, &out, &out_dir));
|
||||
|
||||
// Build cargo command.
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "doc");
|
||||
cargo.env(
|
||||
"RUSTDOCFLAGS",
|
||||
"--document-private-items \
|
||||
|
|
|
@ -301,16 +301,21 @@ pub enum Mode {
|
|||
/// Build codegen libraries, placing output in the "stageN-codegen" directory
|
||||
Codegen,
|
||||
|
||||
/// Build some tools, placing output in the "stageN-tools" directory. The
|
||||
/// "other" here is for miscellaneous sets of tools that are built using the
|
||||
/// bootstrap compiler in its entirety (target libraries and all).
|
||||
/// Typically these tools compile with stable Rust.
|
||||
/// Build a tool, placing output in the "stage0-bootstrap-tools"
|
||||
/// directory. This is for miscellaneous sets of tools that are built
|
||||
/// using the bootstrap stage0 compiler in its entirety (target libraries
|
||||
/// and all). Typically these tools compile with stable Rust.
|
||||
ToolBootstrap,
|
||||
|
||||
/// Compile a tool which uses all libraries we compile (up to rustc).
|
||||
/// Doesn't use the stage0 compiler libraries like "other", and includes
|
||||
/// tools like rustdoc, cargo, rls, etc.
|
||||
/// Build a tool which uses the locally built std, placing output in the
|
||||
/// "stageN-tools" directory. Its usage is quite rare, mainly used by
|
||||
/// compiletest which needs libtest.
|
||||
ToolStd,
|
||||
|
||||
/// Build a tool which uses the locally built rustc and the target std,
|
||||
/// placing the output in the "stageN-tools" directory. This is used for
|
||||
/// anything that needs a fully functional rustc, such as rustdoc, clippy,
|
||||
/// cargo, rls, rustfmt, miri, etc.
|
||||
ToolRustc,
|
||||
}
|
||||
|
||||
|
|
|
@ -367,7 +367,8 @@ impl Step for Miri {
|
|||
extra_features: Vec::new(),
|
||||
});
|
||||
if let (Some(miri), Some(_cargo_miri)) = (miri, cargo_miri) {
|
||||
let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "install");
|
||||
let mut cargo =
|
||||
builder.cargo(compiler, Mode::ToolRustc, SourceType::Submodule, host, "install");
|
||||
cargo.arg("xargo");
|
||||
// Configure `cargo install` path. cargo adds a `bin/`.
|
||||
cargo.env("CARGO_INSTALL_ROOT", &builder.out);
|
||||
|
@ -1696,7 +1697,8 @@ impl Step for Crate {
|
|||
// we're working with automatically.
|
||||
let compiler = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||
|
||||
let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
|
||||
let mut cargo =
|
||||
builder.cargo(compiler, mode, SourceType::InTree, target, test_kind.subcommand());
|
||||
match mode {
|
||||
Mode::Std => {
|
||||
compile::std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::util::{add_dylib_path, exe, CiEnv};
|
|||
use crate::Compiler;
|
||||
use crate::Mode;
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum SourceType {
|
||||
InTree,
|
||||
Submodule,
|
||||
|
@ -226,14 +226,10 @@ pub fn prepare_tool_cargo(
|
|||
source_type: SourceType,
|
||||
extra_features: &[String],
|
||||
) -> CargoCommand {
|
||||
let mut cargo = builder.cargo(compiler, mode, target, command);
|
||||
let mut cargo = builder.cargo(compiler, mode, source_type, target, command);
|
||||
let dir = builder.src.join(path);
|
||||
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
|
||||
|
||||
if source_type == SourceType::Submodule {
|
||||
cargo.env("RUSTC_EXTERNAL_TOOL", "1");
|
||||
}
|
||||
|
||||
let mut features = extra_features.to_vec();
|
||||
if builder.build.config.cargo_native_static {
|
||||
if path.ends_with("cargo")
|
||||
|
@ -596,6 +592,7 @@ macro_rules! tool_extended {
|
|||
$path:expr,
|
||||
$tool_name:expr,
|
||||
stable = $stable:expr,
|
||||
$(in_tree = $in_tree:expr,)*
|
||||
$extra_deps:block;)+) => {
|
||||
$(
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
|
@ -647,7 +644,11 @@ macro_rules! tool_extended {
|
|||
path: $path,
|
||||
extra_features: $sel.extra_features,
|
||||
is_optional_tool: true,
|
||||
source_type: SourceType::Submodule,
|
||||
source_type: if false $(|| $in_tree)* {
|
||||
SourceType::InTree
|
||||
} else {
|
||||
SourceType::Submodule
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -659,8 +660,8 @@ macro_rules! tool_extended {
|
|||
// to make `./x.py build <tool>` work.
|
||||
tool_extended!((self, builder),
|
||||
Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, {};
|
||||
CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, {};
|
||||
Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, {};
|
||||
CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
|
||||
Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
|
||||
Miri, miri, "src/tools/miri", "miri", stable=false, {};
|
||||
CargoMiri, miri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {};
|
||||
Rls, rls, "src/tools/rls", "rls", stable=true, {
|
||||
|
|
|
@ -474,7 +474,7 @@ Here is the list of currently supported register classes:
|
|||
| AArch64 | `reg` | `x[0-28]`, `x30` | `r` |
|
||||
| AArch64 | `vreg` | `v[0-31]` | `w` |
|
||||
| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
|
||||
| ARM | `reg` | `r[0-r10]`, `r12`, `r14` | `r` |
|
||||
| ARM | `reg` | `r[0-5]` `r7`\*, `r[8-10]`, `r11`\*, `r12`, `r14` | `r` |
|
||||
| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
|
||||
| ARM (ARM) | `reg_thumb` | `r[0-r10]`, `r12`, `r14` | `l` |
|
||||
| ARM | `sreg` | `s[0-31]` | `t` |
|
||||
|
@ -497,6 +497,8 @@ Here is the list of currently supported register classes:
|
|||
> Note #2: On x86-64 the high byte registers (e.g. `ah`) are only available when used as an explicit register. Specifying the `reg_byte` register class for an operand will always allocate a low byte register.
|
||||
>
|
||||
> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
|
||||
>
|
||||
> Note #4: On ARM the frame pointer is either `r7` or `r11` depending on the platform.
|
||||
|
||||
Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
|
||||
|
||||
|
@ -591,7 +593,9 @@ Some registers cannot be used for input or output operands:
|
|||
| Architecture | Unsupported register | Reason |
|
||||
| ------------ | -------------------- | ------ |
|
||||
| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. |
|
||||
| All | `bp` (x86), `r11` (ARM), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon) | The frame pointer cannot be used as an input or output. |
|
||||
| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon) | The frame pointer cannot be used as an input or output. |
|
||||
| ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. |
|
||||
| ARM | `r6` | `r6` is used internally by LLVM as a base pointer and therefore cannot be used as an input or output. |
|
||||
| x86 | `k0` | This is a constant zero register which can't be modified. |
|
||||
| x86 | `ip` | This is the program counter, not a real register. |
|
||||
| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// Disabling on android for the time being
|
||||
// See https://github.com/rust-lang/rust/issues/73535#event-3477699747
|
||||
#![cfg(not(target_os = "android"))]
|
||||
#![feature(btree_drain_filter)]
|
||||
#![feature(map_first_last)]
|
||||
#![feature(repr_simd)]
|
||||
|
|
|
@ -2817,6 +2817,7 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
|
|||
/// performing any bounds checking.
|
||||
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
|
||||
/// even if the resulting reference is not used.
|
||||
///
|
||||
/// [undefined behavior]: ../../reference/behavior-considered-undefined.html
|
||||
#[unstable(feature = "slice_index_methods", issue = "none")]
|
||||
unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
|
||||
|
@ -2825,6 +2826,7 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
|
|||
/// performing any bounds checking.
|
||||
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
|
||||
/// even if the resulting reference is not used.
|
||||
///
|
||||
/// [undefined behavior]: ../../reference/behavior-considered-undefined.html
|
||||
#[unstable(feature = "slice_index_methods", issue = "none")]
|
||||
unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
|
||||
|
|
|
@ -335,6 +335,8 @@ pub enum GenericParamKind {
|
|||
},
|
||||
Const {
|
||||
ty: P<Ty>,
|
||||
/// Span of the `const` keyword.
|
||||
kw_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -475,7 +475,7 @@ impl MetaItem {
|
|||
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
|
||||
Path { span, segments }
|
||||
}
|
||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt, _), .. })) => match *nt {
|
||||
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
||||
token::Nonterminal::NtPath(ref path) => path.clone(),
|
||||
_ => return None,
|
||||
|
|
|
@ -656,7 +656,7 @@ pub fn noop_visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
|
|||
*span = ident.span;
|
||||
return; // Avoid visiting the span for the second time.
|
||||
}
|
||||
token::Interpolated(nt) => {
|
||||
token::Interpolated(nt, _) => {
|
||||
let mut nt = Lrc::make_mut(nt);
|
||||
vis.visit_interpolated(&mut nt);
|
||||
}
|
||||
|
@ -762,7 +762,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
|
|||
GenericParamKind::Type { default } => {
|
||||
visit_opt(default, |default| vis.visit_ty(default));
|
||||
}
|
||||
GenericParamKind::Const { ty } => {
|
||||
GenericParamKind::Const { ty, kw_span: _ } => {
|
||||
vis.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,6 +182,15 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
|
|||
.contains(&name)
|
||||
}
|
||||
|
||||
/// A hack used to pass AST fragments to attribute and derive macros
|
||||
/// as a single nonterminal token instead of a token stream.
|
||||
/// FIXME: It needs to be removed, but there are some compatibility issues (see #73345).
|
||||
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
|
||||
pub enum FlattenGroup {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
|
||||
pub enum TokenKind {
|
||||
/* Expression-operator symbols. */
|
||||
|
@ -236,7 +245,7 @@ pub enum TokenKind {
|
|||
/// treat regular and interpolated lifetime identifiers in the same way.
|
||||
Lifetime(Symbol),
|
||||
|
||||
Interpolated(Lrc<Nonterminal>),
|
||||
Interpolated(Lrc<Nonterminal>, FlattenGroup),
|
||||
|
||||
// Can be expanded into several tokens.
|
||||
/// A doc comment.
|
||||
|
@ -343,7 +352,7 @@ impl Token {
|
|||
/// if they keep spans or perform edition checks.
|
||||
pub fn uninterpolated_span(&self) -> Span {
|
||||
match &self.kind {
|
||||
Interpolated(nt) => nt.span(),
|
||||
Interpolated(nt, _) => nt.span(),
|
||||
_ => self.span,
|
||||
}
|
||||
}
|
||||
|
@ -382,7 +391,7 @@ impl Token {
|
|||
ModSep | // global path
|
||||
Lifetime(..) | // labeled loop
|
||||
Pound => true, // expression attributes
|
||||
Interpolated(ref nt) => match **nt {
|
||||
Interpolated(ref nt, _) => match **nt {
|
||||
NtLiteral(..) |
|
||||
NtExpr(..) |
|
||||
NtBlock(..) |
|
||||
|
@ -408,7 +417,7 @@ impl Token {
|
|||
Lifetime(..) | // lifetime bound in trait object
|
||||
Lt | BinOp(Shl) | // associated path
|
||||
ModSep => true, // global path
|
||||
Interpolated(ref nt) => match **nt {
|
||||
Interpolated(ref nt, _) => match **nt {
|
||||
NtTy(..) | NtPath(..) => true,
|
||||
_ => false,
|
||||
},
|
||||
|
@ -420,7 +429,7 @@ impl Token {
|
|||
pub fn can_begin_const_arg(&self) -> bool {
|
||||
match self.kind {
|
||||
OpenDelim(Brace) => true,
|
||||
Interpolated(ref nt) => match **nt {
|
||||
Interpolated(ref nt, _) => match **nt {
|
||||
NtExpr(..) | NtBlock(..) | NtLiteral(..) => true,
|
||||
_ => false,
|
||||
},
|
||||
|
@ -455,7 +464,7 @@ impl Token {
|
|||
match self.uninterpolate().kind {
|
||||
Literal(..) | BinOp(Minus) => true,
|
||||
Ident(name, false) if name.is_bool_lit() => true,
|
||||
Interpolated(ref nt) => match &**nt {
|
||||
Interpolated(ref nt, _) => match &**nt {
|
||||
NtLiteral(_) => true,
|
||||
NtExpr(e) => match &e.kind {
|
||||
ast::ExprKind::Lit(_) => true,
|
||||
|
@ -476,7 +485,7 @@ impl Token {
|
|||
// otherwise returns the original token.
|
||||
pub fn uninterpolate(&self) -> Cow<'_, Token> {
|
||||
match &self.kind {
|
||||
Interpolated(nt) => match **nt {
|
||||
Interpolated(nt, _) => match **nt {
|
||||
NtIdent(ident, is_raw) => {
|
||||
Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span))
|
||||
}
|
||||
|
@ -523,7 +532,7 @@ impl Token {
|
|||
|
||||
/// Returns `true` if the token is an interpolated path.
|
||||
fn is_path(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind {
|
||||
if let Interpolated(ref nt, _) = self.kind {
|
||||
if let NtPath(..) = **nt {
|
||||
return true;
|
||||
}
|
||||
|
@ -535,7 +544,7 @@ impl Token {
|
|||
/// That is, is this a pre-parsed expression dropped into the token stream
|
||||
/// (which happens while parsing the result of macro expansion)?
|
||||
pub fn is_whole_expr(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind {
|
||||
if let Interpolated(ref nt, _) = self.kind {
|
||||
if let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt {
|
||||
return true;
|
||||
}
|
||||
|
@ -546,7 +555,7 @@ impl Token {
|
|||
|
||||
// Is the token an interpolated block (`$b:block`)?
|
||||
pub fn is_whole_block(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind {
|
||||
if let Interpolated(ref nt, _) = self.kind {
|
||||
if let NtBlock(..) = **nt {
|
||||
return true;
|
||||
}
|
||||
|
@ -724,7 +733,7 @@ impl Token {
|
|||
b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate)
|
||||
}
|
||||
|
||||
(&Interpolated(_), &Interpolated(_)) => false,
|
||||
(&Interpolated(..), &Interpolated(..)) => false,
|
||||
|
||||
_ => panic!("forgot to add a token?"),
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ impl Lit {
|
|||
token::Lit::new(token::Bool, name, None)
|
||||
}
|
||||
token::Literal(lit) => lit,
|
||||
token::Interpolated(ref nt) => {
|
||||
token::Interpolated(ref nt, _) => {
|
||||
if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt {
|
||||
if let ast::ExprKind::Lit(lit) = &expr.kind {
|
||||
return Ok(lit.clone());
|
||||
|
|
|
@ -5,7 +5,7 @@ use rustc_span::symbol::kw;
|
|||
/// Associative operator with precedence.
|
||||
///
|
||||
/// This is the enum which specifies operator precedence and fixity to the parser.
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AssocOp {
|
||||
/// `+`
|
||||
Add,
|
||||
|
|
|
@ -1001,6 +1001,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
asm::InlineAsmReg::parse(
|
||||
sess.asm_arch?,
|
||||
|feature| sess.target_features.contains(&Symbol::intern(feature)),
|
||||
&sess.target.target,
|
||||
s,
|
||||
)
|
||||
.map_err(|e| {
|
||||
|
|
|
@ -1027,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
fn lower_token(&mut self, token: Token) -> TokenStream {
|
||||
match token.kind {
|
||||
token::Interpolated(nt) => {
|
||||
token::Interpolated(nt, _) => {
|
||||
let tts = (self.nt_to_tokenstream)(&nt, &self.sess.parse_sess, token.span);
|
||||
self.lower_token_stream(tts)
|
||||
}
|
||||
|
@ -2230,7 +2230,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
(hir::ParamName::Plain(param.ident), kind)
|
||||
}
|
||||
GenericParamKind::Const { ref ty } => {
|
||||
GenericParamKind::Const { ref ty, kw_span: _ } => {
|
||||
let ty = self
|
||||
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
|
||||
this.lower_ty(&ty, ImplTraitContext::disallowed())
|
||||
|
|
|
@ -1135,9 +1135,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
generics.params.iter().map(|param| {
|
||||
let ident = Some(param.ident.to_string());
|
||||
let (kind, ident) = match ¶m.kind {
|
||||
GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, ident),
|
||||
GenericParamKind::Type { .. } => (ParamKindOrd::Type, ident),
|
||||
GenericParamKind::Const { ref ty } => {
|
||||
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
|
||||
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
|
||||
GenericParamKind::Const { ref ty, kw_span: _ } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
(ParamKindOrd::Const, Some(format!("const {}: {}", param.ident, ty)))
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>)
|
|||
token::Shebang(s) => format!("/* shebang: {}*/", s),
|
||||
token::Unknown(s) => s.to_string(),
|
||||
|
||||
token::Interpolated(ref nt) => nonterminal_to_string(nt),
|
||||
token::Interpolated(ref nt, _) => nonterminal_to_string(nt),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2578,7 +2578,7 @@ impl<'a> State<'a> {
|
|||
s.print_type(default)
|
||||
}
|
||||
}
|
||||
ast::GenericParamKind::Const { ref ty } => {
|
||||
ast::GenericParamKind::Const { ref ty, kw_span: _ } => {
|
||||
s.word_space("const");
|
||||
s.print_ident(param.ident);
|
||||
s.s.space();
|
||||
|
|
|
@ -123,7 +123,7 @@ fn inject_impl_of_structural_trait(
|
|||
*default = None;
|
||||
ast::GenericArg::Type(cx.ty_ident(span, param.ident))
|
||||
}
|
||||
ast::GenericParamKind::Const { ty: _ } => {
|
||||
ast::GenericParamKind::Const { ty: _, kw_span: _ } => {
|
||||
ast::GenericArg::Const(cx.const_ident(span, param.ident))
|
||||
}
|
||||
})
|
||||
|
|
|
@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
|
|||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::ich::NodeIdHashingMode;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::interpret::truncate;
|
||||
use rustc_middle::mir::{self, Field, GeneratorLayout};
|
||||
use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
|
||||
|
@ -2382,9 +2381,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
|
|||
}
|
||||
|
||||
let tcx = cx.tcx;
|
||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||
|
||||
let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
|
||||
// We may want to remove the namespace scope if we're in an extern block (see
|
||||
// https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952).
|
||||
let var_scope = get_namespace_for_item(cx, def_id);
|
||||
|
@ -2401,14 +2398,11 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
|
|||
let variable_type = Instance::mono(cx.tcx, def_id).monomorphic_ty(cx.tcx);
|
||||
let type_metadata = type_metadata(cx, variable_type, span);
|
||||
let var_name = tcx.item_name(def_id).as_str();
|
||||
let linkage_name = if no_mangle {
|
||||
None
|
||||
} else {
|
||||
Some(mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name.as_str())
|
||||
};
|
||||
let linkage_name: &str =
|
||||
&mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name.as_str();
|
||||
// When empty, linkage_name field is omitted,
|
||||
// which is what we want for no_mangle statics
|
||||
let linkage_name = linkage_name.as_deref().unwrap_or("");
|
||||
let linkage_name = if var_name == linkage_name { "" } else { linkage_name };
|
||||
|
||||
let global_align = cx.align_of(variable_type);
|
||||
|
||||
|
|
|
@ -267,9 +267,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
let substs = instance.substs.truncate_to(self.tcx(), generics);
|
||||
let template_parameters = get_template_parameters(self, &generics, substs, &mut name);
|
||||
|
||||
// Get the linkage_name, which is just the symbol name
|
||||
let linkage_name = mangled_name_of_instance(self, instance);
|
||||
let linkage_name = linkage_name.name.as_str();
|
||||
let linkage_name: &str = &mangled_name_of_instance(self, instance).name.as_str();
|
||||
// Omit the linkage_name if it is the same as subprogram name.
|
||||
let linkage_name = if &name == linkage_name { "" } else { linkage_name };
|
||||
|
||||
// FIXME(eddyb) does this need to be separate from `loc.line` for some reason?
|
||||
let scope_line = loc.line;
|
||||
|
|
|
@ -156,6 +156,10 @@ const ARM_WHITELIST: &[(&str, Option<Symbol>)] = &[
|
|||
("vfp2", Some(sym::arm_target_feature)),
|
||||
("vfp3", Some(sym::arm_target_feature)),
|
||||
("vfp4", Some(sym::arm_target_feature)),
|
||||
// This is needed for inline assembly, but shouldn't be stabilized as-is
|
||||
// since it should be enabled per-function using #[instruction_set], not
|
||||
// #[target_feature].
|
||||
("thumb-mode", Some(sym::arm_target_feature)),
|
||||
];
|
||||
|
||||
const AARCH64_WHITELIST: &[(&str, Option<Symbol>)] = &[
|
||||
|
|
|
@ -31,6 +31,9 @@ use std::path::Path;
|
|||
use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
|
||||
use termcolor::{Buffer, Color, WriteColor};
|
||||
|
||||
/// Default column width, used in tests and when terminal dimensions cannot be determined.
|
||||
const DEFAULT_COLUMN_WIDTH: usize = 140;
|
||||
|
||||
/// Describes the way the content of the `rendered` field of the json output is generated
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum HumanReadableErrorType {
|
||||
|
@ -74,7 +77,8 @@ struct Margin {
|
|||
pub computed_left: usize,
|
||||
/// The end of the line to be displayed.
|
||||
pub computed_right: usize,
|
||||
/// The current width of the terminal. 140 by default and in tests.
|
||||
/// The current width of the terminal. Uses value of `DEFAULT_COLUMN_WIDTH` constant by default
|
||||
/// and in tests.
|
||||
pub column_width: usize,
|
||||
/// The end column of a span label, including the span. Doesn't account for labels not in the
|
||||
/// same line as the span.
|
||||
|
@ -1414,11 +1418,11 @@ impl EmitterWriter {
|
|||
let column_width = if let Some(width) = self.terminal_width {
|
||||
width.saturating_sub(code_offset)
|
||||
} else if self.ui_testing {
|
||||
140
|
||||
DEFAULT_COLUMN_WIDTH
|
||||
} else {
|
||||
termize::dimensions()
|
||||
.map(|(w, _)| w.saturating_sub(code_offset))
|
||||
.unwrap_or(usize::MAX)
|
||||
.unwrap_or(DEFAULT_COLUMN_WIDTH)
|
||||
};
|
||||
|
||||
let margin = Margin::new(
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::module::DirectoryOwnership;
|
|||
use rustc_ast::ast::{self, Attribute, NodeId, PatKind};
|
||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::token::{self, FlattenGroup};
|
||||
use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
|
||||
use rustc_ast::visit::{AssocCtxt, Visitor};
|
||||
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
|
||||
|
@ -142,7 +142,7 @@ impl Annotatable {
|
|||
| Annotatable::StructField(..)
|
||||
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
|
||||
};
|
||||
TokenTree::token(token::Interpolated(Lrc::new(nt)), DUMMY_SP).into()
|
||||
TokenTree::token(token::Interpolated(Lrc::new(nt), FlattenGroup::Yes), DUMMY_SP).into()
|
||||
}
|
||||
|
||||
pub fn expect_item(self) -> P<ast::Item> {
|
||||
|
@ -374,7 +374,7 @@ where
|
|||
impl MutVisitor for AvoidInterpolatedIdents {
|
||||
fn visit_tt(&mut self, tt: &mut tokenstream::TokenTree) {
|
||||
if let tokenstream::TokenTree::Token(token) = tt {
|
||||
if let token::Interpolated(nt) = &token.kind {
|
||||
if let token::Interpolated(nt, _) = &token.kind {
|
||||
if let token::NtIdent(ident, is_raw) = **nt {
|
||||
*tt = tokenstream::TokenTree::token(
|
||||
token::Ident(ident.name, is_raw),
|
||||
|
|
|
@ -785,12 +785,12 @@ fn may_begin_with(token: &Token, name: Symbol) -> bool {
|
|||
sym::literal => token.can_begin_literal_maybe_minus(),
|
||||
sym::vis => match token.kind {
|
||||
// The follow-set of :vis + "priv" keyword + interpolated
|
||||
token::Comma | token::Ident(..) | token::Interpolated(_) => true,
|
||||
token::Comma | token::Ident(..) | token::Interpolated(..) => true,
|
||||
_ => token.can_begin_type(),
|
||||
},
|
||||
sym::block => match token.kind {
|
||||
token::OpenDelim(token::Brace) => true,
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(ref nt, _) => match **nt {
|
||||
token::NtItem(_)
|
||||
| token::NtPat(_)
|
||||
| token::NtTy(_)
|
||||
|
@ -804,7 +804,7 @@ fn may_begin_with(token: &Token, name: Symbol) -> bool {
|
|||
},
|
||||
sym::path | sym::meta => match token.kind {
|
||||
token::ModSep | token::Ident(..) => true,
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(ref nt, _) => match **nt {
|
||||
token::NtPath(_) | token::NtMeta(_) => true,
|
||||
_ => may_be_ident(&nt),
|
||||
},
|
||||
|
@ -823,12 +823,12 @@ fn may_begin_with(token: &Token, name: Symbol) -> bool {
|
|||
token::ModSep | // path
|
||||
token::Lt | // path (UFCS constant)
|
||||
token::BinOp(token::Shl) => true, // path (double UFCS)
|
||||
token::Interpolated(ref nt) => may_be_ident(nt),
|
||||
token::Interpolated(ref nt, _) => may_be_ident(nt),
|
||||
_ => false,
|
||||
},
|
||||
sym::lifetime => match token.kind {
|
||||
token::Lifetime(_) => true,
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(ref nt, _) => match **nt {
|
||||
token::NtLifetime(_) | token::NtTT(_) => true,
|
||||
_ => false,
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
|
|||
|
||||
use rustc_ast::ast::MacCall;
|
||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::token::{self, NtTT, Token};
|
||||
use rustc_ast::token::{self, FlattenGroup, NtTT, Token};
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -240,7 +240,10 @@ pub(super) fn transcribe<'a>(
|
|||
result.push(tt.clone().into());
|
||||
} else {
|
||||
marker.visit_span(&mut sp);
|
||||
let token = TokenTree::token(token::Interpolated(nt.clone()), sp);
|
||||
let token = TokenTree::token(
|
||||
token::Interpolated(nt.clone(), FlattenGroup::No),
|
||||
sp,
|
||||
);
|
||||
result.push(token.into());
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::base::{self, *};
|
|||
use crate::proc_macro_server;
|
||||
|
||||
use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::token::{self, FlattenGroup};
|
||||
use rustc_ast::tokenstream::{self, TokenStream};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Applicability, ErrorReported};
|
||||
|
@ -102,7 +102,7 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||
}
|
||||
}
|
||||
|
||||
let token = token::Interpolated(Lrc::new(token::NtItem(item)));
|
||||
let token = token::Interpolated(Lrc::new(token::NtItem(item)), FlattenGroup::Yes);
|
||||
let input = tokenstream::TokenTree::token(token, DUMMY_SP).into();
|
||||
|
||||
let server = proc_macro_server::Rustc::new(ecx);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::base::ExtCtxt;
|
||||
|
||||
use rustc_ast::ast;
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::token::{self, FlattenGroup};
|
||||
use rustc_ast::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
|
||||
use rustc_ast::util::comments;
|
||||
use rustc_ast_pretty::pprust;
|
||||
|
@ -60,7 +60,12 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
|
|||
let Token { kind, span } = match tree {
|
||||
tokenstream::TokenTree::Delimited(span, delim, tts) => {
|
||||
let delimiter = Delimiter::from_internal(delim);
|
||||
return TokenTree::Group(Group { delimiter, stream: tts, span });
|
||||
return TokenTree::Group(Group {
|
||||
delimiter,
|
||||
stream: tts,
|
||||
span,
|
||||
flatten: FlattenGroup::No,
|
||||
});
|
||||
}
|
||||
tokenstream::TokenTree::Token(token) => token,
|
||||
};
|
||||
|
@ -167,6 +172,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
|
|||
delimiter: Delimiter::Bracket,
|
||||
stream,
|
||||
span: DelimSpan::from_single(span),
|
||||
flatten: FlattenGroup::No,
|
||||
}));
|
||||
if style == ast::AttrStyle::Inner {
|
||||
stack.push(tt!(Punct::new('!', false)));
|
||||
|
@ -174,12 +180,13 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
|
|||
tt!(Punct::new('#', false))
|
||||
}
|
||||
|
||||
Interpolated(nt) => {
|
||||
Interpolated(nt, flatten) => {
|
||||
let stream = nt_to_tokenstream(&nt, sess, span);
|
||||
TokenTree::Group(Group {
|
||||
delimiter: Delimiter::None,
|
||||
stream,
|
||||
span: DelimSpan::from_single(span),
|
||||
flatten,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -195,7 +202,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
|
|||
|
||||
let (ch, joint, span) = match self {
|
||||
TokenTree::Punct(Punct { ch, joint, span }) => (ch, joint, span),
|
||||
TokenTree::Group(Group { delimiter, stream, span }) => {
|
||||
TokenTree::Group(Group { delimiter, stream, span, .. }) => {
|
||||
return tokenstream::TokenTree::Delimited(span, delimiter.to_internal(), stream)
|
||||
.into();
|
||||
}
|
||||
|
@ -283,6 +290,10 @@ pub struct Group {
|
|||
delimiter: Delimiter,
|
||||
stream: TokenStream,
|
||||
span: DelimSpan,
|
||||
/// A hack used to pass AST fragments to attribute and derive macros
|
||||
/// as a single nonterminal token instead of a token stream.
|
||||
/// FIXME: It needs to be removed, but there are some compatibility issues (see #73345).
|
||||
flatten: FlattenGroup,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -437,14 +448,12 @@ impl server::TokenStreamIter for Rustc<'_> {
|
|||
let next = iter.cursor.next_with_joint()?;
|
||||
Some(TokenTree::from_internal((next, self.sess, &mut iter.stack)))
|
||||
})?;
|
||||
// HACK: The condition "dummy span + group with empty delimiter" represents an AST
|
||||
// fragment approximately converted into a token stream. This may happen, for
|
||||
// example, with inputs to proc macro attributes, including derives. Such "groups"
|
||||
// need to flattened during iteration over stream's token trees.
|
||||
// Eventually this needs to be removed in favor of keeping original token trees
|
||||
// and not doing the roundtrip through AST.
|
||||
// A hack used to pass AST fragments to attribute and derive macros
|
||||
// as a single nonterminal token instead of a token stream.
|
||||
// Such token needs to be "unwrapped" and not represented as a delimited group.
|
||||
// FIXME: It needs to be removed, but there are some compatibility issues (see #73345).
|
||||
if let TokenTree::Group(ref group) = tree {
|
||||
if group.delimiter == Delimiter::None && group.span.entire().is_dummy() {
|
||||
if matches!(group.flatten, FlattenGroup::Yes) {
|
||||
iter.cursor.append(group.stream.clone());
|
||||
continue;
|
||||
}
|
||||
|
@ -456,7 +465,12 @@ impl server::TokenStreamIter for Rustc<'_> {
|
|||
|
||||
impl server::Group for Rustc<'_> {
|
||||
fn new(&mut self, delimiter: Delimiter, stream: Self::TokenStream) -> Self::Group {
|
||||
Group { delimiter, stream, span: DelimSpan::from_single(server::Span::call_site(self)) }
|
||||
Group {
|
||||
delimiter,
|
||||
stream,
|
||||
span: DelimSpan::from_single(server::Span::call_site(self)),
|
||||
flatten: FlattenGroup::No,
|
||||
}
|
||||
}
|
||||
fn delimiter(&mut self, group: &Self::Group) -> Delimiter {
|
||||
group.delimiter
|
||||
|
|
|
@ -293,11 +293,9 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
// LLVM requires symbols from this library, but apparently they're not printed
|
||||
// during llvm-config?
|
||||
// Libstdc++ depends on pthread which Rust doesn't link on MinGW
|
||||
// since nothing else requires it.
|
||||
if target.contains("windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=static-nobundle=gcc_s");
|
||||
println!("cargo:rustc-link-lib=static-nobundle=pthread");
|
||||
println!("cargo:rustc-link-lib=dylib=uuid");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" }
|
|||
rustc_ast = { path = "../librustc_ast" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
byteorder = { version = "1.3" }
|
||||
chalk-ir = "0.11.0"
|
||||
chalk-ir = "0.14.0"
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
measureme = "0.7.1"
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
|
|
|
@ -10,6 +10,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
|||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
|
@ -77,6 +78,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
|
|||
type DefId = DefId;
|
||||
type InternedAdtId = &'tcx AdtDef;
|
||||
type Identifier = ();
|
||||
type FnAbi = Abi;
|
||||
|
||||
fn debug_program_clause_implication(
|
||||
pci: &chalk_ir::ProgramClauseImplication<Self>,
|
||||
|
|
|
@ -336,8 +336,10 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
|
|||
///
|
||||
/// For example given:
|
||||
///
|
||||
/// ```no_run
|
||||
/// trait X<S> { fn f<T>(); }
|
||||
/// impl<U> X<U> for U { fn f<V>() {} }
|
||||
/// ```
|
||||
///
|
||||
/// * If `self` is `[Self, S, T]`: the identity substs of `f` in the trait.
|
||||
/// * If `source_ancestor` is the def_id of the trait.
|
||||
|
|
|
@ -155,7 +155,7 @@ impl<'a> Parser<'a> {
|
|||
/// The delimiters or `=` are still put into the resulting token stream.
|
||||
pub fn parse_attr_item(&mut self) -> PResult<'a, ast::AttrItem> {
|
||||
let item = match self.token.kind {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(ref nt, _) => match **nt {
|
||||
Nonterminal::NtMeta(ref item) => Some(item.clone().into_inner()),
|
||||
_ => None,
|
||||
},
|
||||
|
@ -254,7 +254,7 @@ impl<'a> Parser<'a> {
|
|||
/// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
|
||||
pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
|
||||
let nt_meta = match self.token.kind {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(ref nt, _) => match **nt {
|
||||
token::NtMeta(ref e) => Some(e.clone()),
|
||||
_ => None,
|
||||
},
|
||||
|
|
|
@ -26,7 +26,7 @@ use std::mem;
|
|||
/// `token::Interpolated` tokens.
|
||||
macro_rules! maybe_whole_expr {
|
||||
($p:expr) => {
|
||||
if let token::Interpolated(nt) = &$p.token.kind {
|
||||
if let token::Interpolated(nt, _) = &$p.token.kind {
|
||||
match &**nt {
|
||||
token::NtExpr(e) | token::NtLiteral(e) => {
|
||||
let e = e.clone();
|
||||
|
|
|
@ -47,21 +47,21 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
|
||||
let lo = self.token.span;
|
||||
let const_span = self.token.span;
|
||||
|
||||
self.expect_keyword(kw::Const)?;
|
||||
let ident = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty()?;
|
||||
|
||||
self.sess.gated_spans.gate(sym::const_generics, lo.to(self.prev_token.span));
|
||||
self.sess.gated_spans.gate(sym::const_generics, const_span.to(self.prev_token.span));
|
||||
|
||||
Ok(GenericParam {
|
||||
ident,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
attrs: preceding_attrs.into(),
|
||||
bounds: Vec::new(),
|
||||
kind: GenericParamKind::Const { ty },
|
||||
kind: GenericParamKind::Const { ty, kw_span: const_span },
|
||||
is_placeholder: false,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1780,7 +1780,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
fn is_named_param(&self) -> bool {
|
||||
let offset = match self.token.kind {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(ref nt, _) => match **nt {
|
||||
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
|
||||
_ => 0,
|
||||
},
|
||||
|
|
|
@ -54,7 +54,7 @@ enum BlockMode {
|
|||
#[macro_export]
|
||||
macro_rules! maybe_whole {
|
||||
($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
|
||||
if let token::Interpolated(nt) = &$p.token.kind {
|
||||
if let token::Interpolated(nt, _) = &$p.token.kind {
|
||||
if let token::$constructor(x) = &**nt {
|
||||
let $x = x.clone();
|
||||
$p.bump();
|
||||
|
@ -69,7 +69,7 @@ macro_rules! maybe_whole {
|
|||
macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
||||
($self: expr, $allow_qpath_recovery: expr) => {
|
||||
if $allow_qpath_recovery && $self.look_ahead(1, |t| t == &token::ModSep) {
|
||||
if let token::Interpolated(nt) = &$self.token.kind {
|
||||
if let token::Interpolated(nt, _) = &$self.token.kind {
|
||||
if let token::NtTy(ty) = &**nt {
|
||||
let ty = ty.clone();
|
||||
$self.bump();
|
||||
|
@ -922,7 +922,7 @@ impl<'a> Parser<'a> {
|
|||
if self.eat(&token::Eq) {
|
||||
let eq_span = self.prev_token.span;
|
||||
let mut is_interpolated_expr = false;
|
||||
if let token::Interpolated(nt) = &self.token.kind {
|
||||
if let token::Interpolated(nt, _) = &self.token.kind {
|
||||
if let token::NtExpr(..) = **nt {
|
||||
is_interpolated_expr = true;
|
||||
}
|
||||
|
|
|
@ -515,7 +515,7 @@ impl<'a> Parser<'a> {
|
|||
self.recover_additional_muts();
|
||||
|
||||
// Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
|
||||
if let token::Interpolated(ref nt) = self.token.kind {
|
||||
if let token::Interpolated(ref nt, _) = self.token.kind {
|
||||
if let token::NtPat(_) = **nt {
|
||||
self.expected_ident_found().emit();
|
||||
}
|
||||
|
|
|
@ -1325,7 +1325,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
|||
}
|
||||
|
||||
fn visit_token(&mut self, t: Token) {
|
||||
if let token::Interpolated(nt) = t.kind {
|
||||
if let token::Interpolated(nt, _) = t.kind {
|
||||
if let token::NtExpr(ref expr) = *nt {
|
||||
if let ast::ExprKind::MacCall(..) = expr.kind {
|
||||
self.visit_invoc(expr.id);
|
||||
|
|
|
@ -256,7 +256,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
|
|||
}
|
||||
|
||||
fn visit_token(&mut self, t: Token) {
|
||||
if let token::Interpolated(nt) = t.kind {
|
||||
if let token::Interpolated(nt, _) = t.kind {
|
||||
if let token::NtExpr(ref expr) = *nt {
|
||||
if let ExprKind::MacCall(..) = expr.kind {
|
||||
self.visit_macro_invoc(expr.id);
|
||||
|
|
|
@ -536,8 +536,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
|
||||
for param in &generics.params {
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => self.visit_generic_param(param),
|
||||
GenericParamKind::Type { ref default, .. } => {
|
||||
GenericParamKind::Lifetime => self.visit_generic_param(param),
|
||||
GenericParamKind::Type { ref default } => {
|
||||
for bound in ¶m.bounds {
|
||||
self.visit_param_bound(bound);
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
// Allow all following defaults to refer to this type parameter.
|
||||
default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name));
|
||||
}
|
||||
GenericParamKind::Const { ref ty } => {
|
||||
GenericParamKind::Const { ref ty, kw_span: _ } => {
|
||||
for bound in ¶m.bounds {
|
||||
self.visit_param_bound(bound);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -58,6 +59,37 @@ impl ArmInlineAsmRegClass {
|
|||
}
|
||||
}
|
||||
|
||||
// This uses the same logic as useR7AsFramePointer in LLVM
|
||||
fn frame_pointer_is_r7(mut has_feature: impl FnMut(&str) -> bool, target: &Target) -> bool {
|
||||
target.options.is_like_osx || (!target.options.is_like_windows && has_feature("thumb-mode"))
|
||||
}
|
||||
|
||||
fn frame_pointer_r11(
|
||||
_arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target: &Target,
|
||||
_allocating: bool,
|
||||
) -> Result<(), &'static str> {
|
||||
if !frame_pointer_is_r7(has_feature, target) {
|
||||
Err("the frame pointer (r11) cannot be used as an operand for inline asm")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn frame_pointer_r7(
|
||||
_arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target: &Target,
|
||||
_allocating: bool,
|
||||
) -> Result<(), &'static str> {
|
||||
if frame_pointer_is_r7(has_feature, target) {
|
||||
Err("the frame pointer (r7) cannot be used as an operand for inline asm")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
def_regs! {
|
||||
Arm ArmInlineAsmReg ArmInlineAsmRegClass {
|
||||
r0: reg, reg_thumb = ["r0", "a1"],
|
||||
|
@ -66,11 +98,11 @@ def_regs! {
|
|||
r3: reg, reg_thumb = ["r3", "a4"],
|
||||
r4: reg, reg_thumb = ["r4", "v1"],
|
||||
r5: reg, reg_thumb = ["r5", "v2"],
|
||||
r6: reg, reg_thumb = ["r6", "v3"],
|
||||
r7: reg, reg_thumb = ["r7", "v4"],
|
||||
r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7,
|
||||
r8: reg = ["r8", "v5"],
|
||||
r9: reg = ["r9", "v6", "rfp"],
|
||||
r10: reg = ["r10", "sl"],
|
||||
r11: reg = ["r11", "fp"] % frame_pointer_r11,
|
||||
r12: reg = ["r12", "ip"],
|
||||
r14: reg = ["r14", "lr"],
|
||||
s0: sreg, sreg_low16 = ["s0"],
|
||||
|
@ -153,8 +185,8 @@ def_regs! {
|
|||
q13: qreg = ["q13"],
|
||||
q14: qreg = ["q14"],
|
||||
q15: qreg = ["q15"],
|
||||
#error = ["r11", "fp"] =>
|
||||
"the frame pointer cannot be used as an operand for inline asm",
|
||||
#error = ["r6", "v3"] =>
|
||||
"r6 is used internally by LLVM and cannot be used as an operand for inline asm",
|
||||
#error = ["r13", "sp"] =>
|
||||
"the stack pointer cannot be used as an operand for inline asm",
|
||||
#error = ["r15", "pc"] =>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::abi::Size;
|
||||
use crate::spec::Target;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
@ -83,12 +84,13 @@ macro_rules! def_regs {
|
|||
pub fn parse(
|
||||
_arch: super::InlineAsmArch,
|
||||
mut _has_feature: impl FnMut(&str) -> bool,
|
||||
_target: &crate::spec::Target,
|
||||
name: &str,
|
||||
) -> Result<Self, &'static str> {
|
||||
match name {
|
||||
$(
|
||||
$($alias)|* | $reg_name => {
|
||||
$($filter(_arch, &mut _has_feature, false)?;)?
|
||||
$($filter(_arch, &mut _has_feature, _target, false)?;)?
|
||||
Ok(Self::$reg)
|
||||
}
|
||||
)*
|
||||
|
@ -103,6 +105,7 @@ macro_rules! def_regs {
|
|||
pub(super) fn fill_reg_map(
|
||||
_arch: super::InlineAsmArch,
|
||||
mut _has_feature: impl FnMut(&str) -> bool,
|
||||
_target: &crate::spec::Target,
|
||||
_map: &mut rustc_data_structures::fx::FxHashMap<
|
||||
super::InlineAsmRegClass,
|
||||
rustc_data_structures::fx::FxHashSet<super::InlineAsmReg>,
|
||||
|
@ -111,7 +114,7 @@ macro_rules! def_regs {
|
|||
#[allow(unused_imports)]
|
||||
use super::{InlineAsmReg, InlineAsmRegClass};
|
||||
$(
|
||||
if $($filter(_arch, &mut _has_feature, true).is_ok() &&)? true {
|
||||
if $($filter(_arch, &mut _has_feature, _target, true).is_ok() &&)? true {
|
||||
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
|
||||
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
|
||||
}
|
||||
|
@ -234,6 +237,7 @@ impl InlineAsmReg {
|
|||
pub fn parse(
|
||||
arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target: &Target,
|
||||
name: Symbol,
|
||||
) -> Result<Self, &'static str> {
|
||||
// FIXME: use direct symbol comparison for register names
|
||||
|
@ -241,20 +245,22 @@ impl InlineAsmReg {
|
|||
let name = name.as_str();
|
||||
Ok(match arch {
|
||||
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
|
||||
Self::X86(X86InlineAsmReg::parse(arch, has_feature, &name)?)
|
||||
Self::X86(X86InlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||
}
|
||||
InlineAsmArch::Arm => {
|
||||
Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||
}
|
||||
InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, &name)?),
|
||||
InlineAsmArch::AArch64 => {
|
||||
Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, &name)?)
|
||||
Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||
}
|
||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
|
||||
Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, &name)?)
|
||||
Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||
}
|
||||
InlineAsmArch::Nvptx64 => {
|
||||
Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, &name)?)
|
||||
Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||
}
|
||||
InlineAsmArch::Hexagon => {
|
||||
Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, &name)?)
|
||||
Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, &name)?)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -536,36 +542,37 @@ impl fmt::Display for InlineAsmType {
|
|||
pub fn allocatable_registers(
|
||||
arch: InlineAsmArch,
|
||||
has_feature: impl FnMut(&str) -> bool,
|
||||
target: &crate::spec::Target,
|
||||
) -> FxHashMap<InlineAsmRegClass, FxHashSet<InlineAsmReg>> {
|
||||
match arch {
|
||||
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
|
||||
let mut map = x86::regclass_map();
|
||||
x86::fill_reg_map(arch, has_feature, &mut map);
|
||||
x86::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Arm => {
|
||||
let mut map = arm::regclass_map();
|
||||
arm::fill_reg_map(arch, has_feature, &mut map);
|
||||
arm::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::AArch64 => {
|
||||
let mut map = aarch64::regclass_map();
|
||||
aarch64::fill_reg_map(arch, has_feature, &mut map);
|
||||
aarch64::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
|
||||
let mut map = riscv::regclass_map();
|
||||
riscv::fill_reg_map(arch, has_feature, &mut map);
|
||||
riscv::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Nvptx64 => {
|
||||
let mut map = nvptx::regclass_map();
|
||||
nvptx::fill_reg_map(arch, has_feature, &mut map);
|
||||
nvptx::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Hexagon => {
|
||||
let mut map = hexagon::regclass_map();
|
||||
hexagon::fill_reg_map(arch, has_feature, &mut map);
|
||||
hexagon::fill_reg_map(arch, has_feature, target, &mut map);
|
||||
map
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -50,6 +51,7 @@ impl RiscVInlineAsmRegClass {
|
|||
fn not_e(
|
||||
_arch: InlineAsmArch,
|
||||
mut has_feature: impl FnMut(&str) -> bool,
|
||||
_target: &Target,
|
||||
_allocating: bool,
|
||||
) -> Result<(), &'static str> {
|
||||
if has_feature("e") {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use crate::spec::Target;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -131,6 +132,7 @@ impl X86InlineAsmRegClass {
|
|||
fn x86_64_only(
|
||||
arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target: &Target,
|
||||
_allocating: bool,
|
||||
) -> Result<(), &'static str> {
|
||||
match arch {
|
||||
|
@ -143,6 +145,7 @@ fn x86_64_only(
|
|||
fn high_byte(
|
||||
arch: InlineAsmArch,
|
||||
_has_feature: impl FnMut(&str) -> bool,
|
||||
_target: &Target,
|
||||
allocating: bool,
|
||||
) -> Result<(), &'static str> {
|
||||
match arch {
|
||||
|
|
|
@ -7,17 +7,17 @@ use crate::traits::{
|
|||
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, FulfillmentError, FulfillmentErrorCode,
|
||||
ObligationCause, PredicateObligation, SelectionError, TraitEngine,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub struct FulfillmentContext<'tcx> {
|
||||
obligations: FxHashSet<PredicateObligation<'tcx>>,
|
||||
obligations: FxIndexSet<PredicateObligation<'tcx>>,
|
||||
}
|
||||
|
||||
impl FulfillmentContext<'tcx> {
|
||||
crate fn new() -> Self {
|
||||
FulfillmentContext { obligations: FxHashSet::default() }
|
||||
FulfillmentContext { obligations: FxIndexSet::default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ fn environment<'tcx>(
|
|||
};
|
||||
|
||||
// FIXME(eddyb) isn't the unordered nature of this a hazard?
|
||||
let mut inputs = FxHashSet::default();
|
||||
let mut inputs = FxIndexSet::default();
|
||||
|
||||
match node_kind {
|
||||
// In a trait impl, we assume that the header trait ref and all its
|
||||
|
@ -140,7 +140,8 @@ fn in_environment(
|
|||
None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
|
||||
// FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
|
||||
// and ui/generics/generic-static-methods
|
||||
_ => bug!("non-empty `ParamEnv` with no def-id"),
|
||||
//_ => bug!("non-empty `ParamEnv` with no def-id"),
|
||||
_ => ty::List::empty(),
|
||||
};
|
||||
|
||||
ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }
|
||||
|
@ -195,7 +196,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
|
||||
let mut errors = Vec::new();
|
||||
let mut next_round = FxHashSet::default();
|
||||
let mut next_round = FxIndexSet::default();
|
||||
let mut making_progress;
|
||||
|
||||
loop {
|
||||
|
@ -203,7 +204,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
|
||||
// We iterate over all obligations, and record if we are able
|
||||
// to unambiguously prove at least one obligation.
|
||||
for obligation in self.obligations.drain() {
|
||||
for obligation in self.obligations.drain(..) {
|
||||
let goal_in_environment = in_environment(infcx, &obligation);
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let canonical_goal =
|
||||
|
|
|
@ -16,8 +16,8 @@ rustc_hir = { path = "../librustc_hir" }
|
|||
rustc_index = { path = "../librustc_index" }
|
||||
rustc_ast = { path = "../librustc_ast" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
chalk-ir = "0.11.0"
|
||||
chalk-solve = "0.11.0"
|
||||
chalk-ir = "0.14.0"
|
||||
chalk-solve = "0.14.0"
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
rustc_infer = { path = "../librustc_infer" }
|
||||
rustc_trait_selection = { path = "../librustc_trait_selection" }
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use rustc_middle::traits::ChalkRustInterner as RustInterner;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Binder, TyCtxt};
|
||||
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt};
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
||||
|
@ -85,14 +85,29 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
.iter()
|
||||
.map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
|
||||
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
|
||||
let associated_ty_ids: Vec<_> = self
|
||||
.tcx
|
||||
.associated_items(def_id)
|
||||
.in_definition_order()
|
||||
.filter(|i| i.kind == AssocKind::Type)
|
||||
.map(|i| chalk_ir::AssocTypeId(i.def_id))
|
||||
.collect();
|
||||
|
||||
let well_known =
|
||||
if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::SizedTrait)
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Sized)
|
||||
} else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::CopyTrait)
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Copy)
|
||||
} else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::CloneTrait)
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Clone)
|
||||
} else if self.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Drop)
|
||||
} else if self.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Fn)
|
||||
} else if self.tcx.lang_items().fn_once_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce)
|
||||
} else if self.tcx.lang_items().fn_mut_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::FnMut)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -110,7 +125,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
non_enumerable: true,
|
||||
coinductive: false,
|
||||
},
|
||||
associated_ty_ids: vec![],
|
||||
associated_ty_ids,
|
||||
well_known,
|
||||
})
|
||||
}
|
||||
|
@ -156,6 +171,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
flags: chalk_solve::rust_ir::AdtFlags {
|
||||
upstream: !adt_def.did.is_local(),
|
||||
fundamental: adt_def.is_fundamental(),
|
||||
phantom_data: adt_def.is_phantom_data(),
|
||||
},
|
||||
});
|
||||
return struct_datum;
|
||||
|
@ -176,28 +192,32 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
|
||||
|
||||
let sig = self.tcx.fn_sig(def_id);
|
||||
// FIXME(chalk): collect into an intermediate SmallVec here since
|
||||
// we need `TypeFoldable` for `no_bound_vars`
|
||||
let argument_types: Binder<Vec<_>> =
|
||||
sig.map_bound(|i| i.inputs().iter().copied().collect());
|
||||
let argument_types = argument_types
|
||||
.no_bound_vars()
|
||||
.expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
|
||||
let inputs_and_output = sig.inputs_and_output();
|
||||
let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
|
||||
&self.interner,
|
||||
self.tcx,
|
||||
&inputs_and_output,
|
||||
);
|
||||
|
||||
let argument_types = inputs_and_output[..inputs_and_output.len() - 1]
|
||||
.iter()
|
||||
.map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner))
|
||||
.collect();
|
||||
|
||||
let return_type = sig
|
||||
.output()
|
||||
.no_bound_vars()
|
||||
.expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
|
||||
let return_type = inputs_and_output[inputs_and_output.len() - 1]
|
||||
.subst(self.tcx, &bound_vars)
|
||||
.lower_into(&self.interner);
|
||||
|
||||
let bound =
|
||||
chalk_solve::rust_ir::FnDefDatumBound { argument_types, where_clauses, return_type };
|
||||
let bound = chalk_solve::rust_ir::FnDefDatumBound {
|
||||
inputs_and_output: chalk_ir::Binders::new(
|
||||
iobinders,
|
||||
chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type },
|
||||
),
|
||||
where_clauses,
|
||||
};
|
||||
Arc::new(chalk_solve::rust_ir::FnDefDatum {
|
||||
id: fn_def_id,
|
||||
abi: sig.abi(),
|
||||
binders: chalk_ir::Binders::new(binders, bound),
|
||||
})
|
||||
}
|
||||
|
@ -326,9 +346,16 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
&self,
|
||||
opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
|
||||
) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
|
||||
// FIXME(chalk): actually lower opaque ty
|
||||
let bound_vars = bound_vars_for_item(self.tcx, opaque_ty_id.0);
|
||||
let binders = binders_for(&self.interner, bound_vars);
|
||||
let predicates = self.tcx.predicates_defined_on(opaque_ty_id.0).predicates;
|
||||
let where_clauses: Vec<_> = predicates
|
||||
.iter()
|
||||
.map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
|
||||
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
|
||||
|
||||
let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
|
||||
bounds: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), vec![]),
|
||||
bounds: chalk_ir::Binders::new(binders, where_clauses),
|
||||
};
|
||||
Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
|
||||
opaque_ty_id,
|
||||
|
@ -346,7 +373,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
) -> Option<bool> {
|
||||
use chalk_ir::TyData::*;
|
||||
match well_known {
|
||||
chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty {
|
||||
chalk_solve::rust_ir::WellKnownTrait::Sized => match ty {
|
||||
Apply(apply) => match apply.name {
|
||||
chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
|
||||
ty::AdtKind::Struct | ty::AdtKind::Union => None,
|
||||
|
@ -364,8 +391,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
| InferenceVar(_, _)
|
||||
| BoundVar(_) => None,
|
||||
},
|
||||
chalk_solve::rust_ir::WellKnownTrait::CopyTrait
|
||||
| chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty {
|
||||
chalk_solve::rust_ir::WellKnownTrait::Copy
|
||||
| chalk_solve::rust_ir::WellKnownTrait::Clone => match ty {
|
||||
Apply(apply) => match apply.name {
|
||||
chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
|
||||
ty::AdtKind::Struct | ty::AdtKind::Union => None,
|
||||
|
@ -383,7 +410,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
| InferenceVar(_, _)
|
||||
| BoundVar(_) => None,
|
||||
},
|
||||
chalk_solve::rust_ir::WellKnownTrait::DropTrait => None,
|
||||
chalk_solve::rust_ir::WellKnownTrait::Drop => None,
|
||||
chalk_solve::rust_ir::WellKnownTrait::Fn => None,
|
||||
chalk_solve::rust_ir::WellKnownTrait::FnMut => None,
|
||||
chalk_solve::rust_ir::WellKnownTrait::FnOnce => None,
|
||||
chalk_solve::rust_ir::WellKnownTrait::Unsize => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,17 +430,17 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
well_known_trait: chalk_solve::rust_ir::WellKnownTrait,
|
||||
) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> {
|
||||
use chalk_solve::rust_ir::WellKnownTrait::*;
|
||||
let t = match well_known_trait {
|
||||
SizedTrait => {
|
||||
self.tcx.lang_items().sized_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
|
||||
}
|
||||
CopyTrait => self.tcx.lang_items().copy_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
|
||||
CloneTrait => {
|
||||
self.tcx.lang_items().clone_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
|
||||
}
|
||||
DropTrait => self.tcx.lang_items().drop_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
|
||||
let def_id = match well_known_trait {
|
||||
Sized => self.tcx.lang_items().sized_trait(),
|
||||
Copy => self.tcx.lang_items().copy_trait(),
|
||||
Clone => self.tcx.lang_items().clone_trait(),
|
||||
Drop => self.tcx.lang_items().drop_trait(),
|
||||
Fn => self.tcx.lang_items().fn_trait(),
|
||||
FnMut => self.tcx.lang_items().fn_mut_trait(),
|
||||
FnOnce => self.tcx.lang_items().fn_once_trait(),
|
||||
Unsize => self.tcx.lang_items().unsize_trait(),
|
||||
};
|
||||
Some(t)
|
||||
def_id.map(|t| chalk_ir::TraitId(t))
|
||||
}
|
||||
|
||||
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
|
||||
|
@ -423,6 +454,87 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
// FIXME(chalk): actually get hidden ty
|
||||
self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner)
|
||||
}
|
||||
|
||||
fn closure_kind(
|
||||
&self,
|
||||
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
|
||||
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
|
||||
) -> chalk_solve::rust_ir::ClosureKind {
|
||||
let kind = &substs.parameters(&self.interner)[substs.len(&self.interner) - 3];
|
||||
match kind.assert_ty_ref(&self.interner).data(&self.interner) {
|
||||
chalk_ir::TyData::Apply(apply) => match apply.name {
|
||||
chalk_ir::TypeName::Scalar(scalar) => match scalar {
|
||||
chalk_ir::Scalar::Int(int_ty) => match int_ty {
|
||||
chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn,
|
||||
chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut,
|
||||
chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce,
|
||||
_ => bug!("bad closure kind"),
|
||||
},
|
||||
_ => bug!("bad closure kind"),
|
||||
},
|
||||
_ => bug!("bad closure kind"),
|
||||
},
|
||||
_ => bug!("bad closure kind"),
|
||||
}
|
||||
}
|
||||
|
||||
fn closure_inputs_and_output(
|
||||
&self,
|
||||
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
|
||||
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
|
||||
) -> chalk_ir::Binders<chalk_solve::rust_ir::FnDefInputsAndOutputDatum<RustInterner<'tcx>>>
|
||||
{
|
||||
let sig = &substs.parameters(&self.interner)[substs.len(&self.interner) - 2];
|
||||
match sig.assert_ty_ref(&self.interner).data(&self.interner) {
|
||||
chalk_ir::TyData::Function(f) => {
|
||||
let substitution = f.substitution.parameters(&self.interner);
|
||||
let return_type =
|
||||
substitution.last().unwrap().assert_ty_ref(&self.interner).clone();
|
||||
// Closure arguments are tupled
|
||||
let argument_tuple = substitution[0].assert_ty_ref(&self.interner);
|
||||
let argument_types = match argument_tuple.data(&self.interner) {
|
||||
chalk_ir::TyData::Apply(apply) => match apply.name {
|
||||
chalk_ir::TypeName::Tuple(_) => apply
|
||||
.substitution
|
||||
.iter(&self.interner)
|
||||
.map(|arg| arg.assert_ty_ref(&self.interner))
|
||||
.cloned()
|
||||
.collect(),
|
||||
_ => bug!("Expecting closure FnSig args to be tupled."),
|
||||
},
|
||||
_ => bug!("Expecting closure FnSig args to be tupled."),
|
||||
};
|
||||
|
||||
chalk_ir::Binders::new(
|
||||
chalk_ir::VariableKinds::from(
|
||||
&self.interner,
|
||||
(0..f.num_binders).map(|_| chalk_ir::VariableKind::Lifetime),
|
||||
),
|
||||
chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type },
|
||||
)
|
||||
}
|
||||
_ => panic!("Invalid sig."),
|
||||
}
|
||||
}
|
||||
|
||||
fn closure_upvars(
|
||||
&self,
|
||||
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
|
||||
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
|
||||
) -> chalk_ir::Binders<chalk_ir::Ty<RustInterner<'tcx>>> {
|
||||
let inputs_and_output = self.closure_inputs_and_output(_closure_id, substs);
|
||||
let tuple = substs.parameters(&self.interner).last().unwrap().assert_ty_ref(&self.interner);
|
||||
inputs_and_output.map_ref(|_| tuple.clone())
|
||||
}
|
||||
|
||||
fn closure_fn_substitution(
|
||||
&self,
|
||||
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
|
||||
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
|
||||
) -> chalk_ir::Substitution<RustInterner<'tcx>> {
|
||||
let substitution = &substs.parameters(&self.interner)[0..substs.len(&self.interner) - 3];
|
||||
chalk_ir::Substitution::from(&self.interner, substitution)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
|
||||
|
|
|
@ -43,6 +43,8 @@ use rustc_span::def_id::DefId;
|
|||
|
||||
use std::collections::btree_map::{BTreeMap, Entry};
|
||||
|
||||
use chalk_ir::fold::shift::Shift;
|
||||
|
||||
/// Essentially an `Into` with a `&RustInterner` parameter
|
||||
crate trait LowerInto<'tcx, T> {
|
||||
/// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
|
||||
|
@ -82,7 +84,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
|||
collect_bound_vars(interner, interner.tcx, predicate);
|
||||
|
||||
Some(
|
||||
chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
|
||||
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_ir::ProgramClauseImplication {
|
||||
consequence: chalk_ir::DomainGoal::FromEnv(
|
||||
|
@ -102,7 +104,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
|||
collect_bound_vars(interner, interner.tcx, predicate);
|
||||
|
||||
Some(
|
||||
chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
|
||||
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_ir::ProgramClauseImplication {
|
||||
consequence: chalk_ir::DomainGoal::Holds(
|
||||
|
@ -127,7 +129,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
|||
collect_bound_vars(interner, interner.tcx, predicate);
|
||||
|
||||
Some(
|
||||
chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
|
||||
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_ir::ProgramClauseImplication {
|
||||
consequence: chalk_ir::DomainGoal::Holds(
|
||||
|
@ -153,13 +155,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
|||
}
|
||||
}
|
||||
ChalkEnvironmentClause::TypeFromEnv(ty) => Some(
|
||||
chalk_ir::ProgramClauseData::Implies(chalk_ir::ProgramClauseImplication {
|
||||
consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
|
||||
ty.lower_into(interner),
|
||||
)),
|
||||
conditions: chalk_ir::Goals::new(interner),
|
||||
priority: chalk_ir::ClausePriority::High,
|
||||
})
|
||||
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
|
||||
chalk_ir::VariableKinds::new(interner),
|
||||
chalk_ir::ProgramClauseImplication {
|
||||
consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
|
||||
ty.lower_into(interner).shifted_in(interner),
|
||||
)),
|
||||
conditions: chalk_ir::Goals::new(interner),
|
||||
priority: chalk_ir::ClausePriority::High,
|
||||
},
|
||||
))
|
||||
.intern(interner),
|
||||
),
|
||||
});
|
||||
|
@ -416,12 +421,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
|
|||
})
|
||||
.intern(interner)
|
||||
}
|
||||
// FIXME(chalk): add region
|
||||
Dynamic(predicates, _region) => {
|
||||
TyData::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner) })
|
||||
.intern(interner)
|
||||
}
|
||||
Closure(_def_id, _) => unimplemented!(),
|
||||
Dynamic(predicates, region) => TyData::Dyn(chalk_ir::DynTy {
|
||||
bounds: predicates.lower_into(interner),
|
||||
lifetime: region.lower_into(interner),
|
||||
})
|
||||
.intern(interner),
|
||||
Closure(def_id, substs) => apply(
|
||||
chalk_ir::TypeName::Closure(chalk_ir::ClosureId(def_id)),
|
||||
substs.lower_into(interner),
|
||||
),
|
||||
Generator(_def_id, _substs, _) => unimplemented!(),
|
||||
GeneratorWitness(_) => unimplemented!(),
|
||||
Never => apply(chalk_ir::TypeName::Never, empty()),
|
||||
|
@ -624,7 +632,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
|
|||
}
|
||||
|
||||
(0..parameters.len()).for_each(|i| {
|
||||
parameters.get(&(i as u32)).expect("Skipped bound var index.");
|
||||
parameters.get(&(i as u32)).expect(&format!("Skipped bound var index `{:?}`.", i));
|
||||
});
|
||||
|
||||
let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
|
||||
|
|
|
@ -133,6 +133,7 @@ crate fn evaluate_goal<'tcx>(
|
|||
},
|
||||
chalk_ir::TypeName::Array => unimplemented!(),
|
||||
chalk_ir::TypeName::FnDef(_) => unimplemented!(),
|
||||
chalk_ir::TypeName::Closure(_) => unimplemented!(),
|
||||
chalk_ir::TypeName::Never => unimplemented!(),
|
||||
chalk_ir::TypeName::Tuple(_size) => unimplemented!(),
|
||||
chalk_ir::TypeName::Slice => unimplemented!(),
|
||||
|
|
|
@ -278,7 +278,7 @@ fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type>
|
|||
type_.def_id().and_then(|did| build_ty(cx, did))
|
||||
}
|
||||
|
||||
pub fn build_ty(cx: &DocContext, did: DefId) -> Option<clean::Type> {
|
||||
pub fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
|
||||
match cx.tcx.def_kind(did) {
|
||||
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => {
|
||||
Some(cx.tcx.type_of(did).clean(cx))
|
||||
|
|
|
@ -328,7 +328,7 @@ pub fn strip_path(path: &Path) -> Path {
|
|||
Path { global: path.global, res: path.res, segments }
|
||||
}
|
||||
|
||||
pub fn qpath_to_string(p: &hir::QPath) -> String {
|
||||
pub fn qpath_to_string(p: &hir::QPath<'_>) -> String {
|
||||
let segments = match *p {
|
||||
hir::QPath::Resolved(_, ref path) => &path.segments,
|
||||
hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(),
|
||||
|
@ -417,7 +417,7 @@ impl ToSource for rustc_span::Span {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn name_from_pat(p: &hir::Pat) -> String {
|
||||
pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
|
||||
use rustc_hir::*;
|
||||
debug!("trying to get a name from pattern: {:?}", p);
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ pub struct ProcMacro<'hir> {
|
|||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType {
|
||||
pub fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {
|
||||
match *vdata {
|
||||
hir::VariantData::Struct(..) => Plain,
|
||||
hir::VariantData::Tuple(..) => Tuple,
|
||||
|
|
|
@ -1408,6 +1408,7 @@ function defocusSearchBar() {
|
|||
|
||||
addClass(actives[currentTab][0].previousElementSibling, "highlighted");
|
||||
removeClass(actives[currentTab][0], "highlighted");
|
||||
e.preventDefault();
|
||||
} else if (e.which === 40) { // down
|
||||
if (!actives[currentTab].length) {
|
||||
var results = document.getElementById("results").childNodes;
|
||||
|
@ -1421,6 +1422,7 @@ function defocusSearchBar() {
|
|||
addClass(actives[currentTab][0].nextElementSibling, "highlighted");
|
||||
removeClass(actives[currentTab][0], "highlighted");
|
||||
}
|
||||
e.preventDefault();
|
||||
} else if (e.which === 13) { // return
|
||||
if (actives[currentTab].length) {
|
||||
document.location.href =
|
||||
|
|
|
@ -166,7 +166,7 @@ pub fn run(options: Options) -> Result<(), String> {
|
|||
}
|
||||
|
||||
// Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
|
||||
fn scrape_test_config(krate: &::rustc_hir::Crate) -> TestOptions {
|
||||
fn scrape_test_config(krate: &::rustc_hir::Crate<'_>) -> TestOptions {
|
||||
use rustc_ast_pretty::pprust;
|
||||
|
||||
let mut opts =
|
||||
|
@ -973,7 +973,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
|
|||
intravisit::NestedVisitorMap::All(self.map)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &'hir hir::Item) {
|
||||
fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
|
||||
let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind {
|
||||
rustc_hir_pretty::id_to_string(&self.map, self_ty.hir_id)
|
||||
} else {
|
||||
|
@ -985,19 +985,19 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'hir hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, item: &'hir hir::TraitItem<'_>) {
|
||||
self.visit_testable(item.ident.to_string(), &item.attrs, item.hir_id, item.span, |this| {
|
||||
intravisit::walk_trait_item(this, item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'hir hir::ImplItem) {
|
||||
fn visit_impl_item(&mut self, item: &'hir hir::ImplItem<'_>) {
|
||||
self.visit_testable(item.ident.to_string(), &item.attrs, item.hir_id, item.span, |this| {
|
||||
intravisit::walk_impl_item(this, item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem<'_>) {
|
||||
self.visit_testable(item.ident.to_string(), &item.attrs, item.hir_id, item.span, |this| {
|
||||
intravisit::walk_foreign_item(this, item);
|
||||
});
|
||||
|
@ -1005,8 +1005,8 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
|
|||
|
||||
fn visit_variant(
|
||||
&mut self,
|
||||
v: &'hir hir::Variant,
|
||||
g: &'hir hir::Generics,
|
||||
v: &'hir hir::Variant<'_>,
|
||||
g: &'hir hir::Generics<'_>,
|
||||
item_id: hir::HirId,
|
||||
) {
|
||||
self.visit_testable(v.ident.to_string(), &v.attrs, v.id, v.span, |this| {
|
||||
|
@ -1014,13 +1014,13 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, f: &'hir hir::StructField) {
|
||||
fn visit_struct_field(&mut self, f: &'hir hir::StructField<'_>) {
|
||||
self.visit_testable(f.ident.to_string(), &f.attrs, f.hir_id, f.span, |this| {
|
||||
intravisit::walk_struct_field(this, f);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef) {
|
||||
fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef<'_>) {
|
||||
self.visit_testable(
|
||||
macro_def.ident.to_string(),
|
||||
¯o_def.attrs,
|
||||
|
|
|
@ -62,7 +62,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
self.exact_paths.entry(did).or_insert_with(|| def_id_to_path(tcx, did));
|
||||
}
|
||||
|
||||
pub fn visit(mut self, krate: &'tcx hir::Crate) -> Module<'tcx> {
|
||||
pub fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
|
||||
let mut module = self.visit_mod_contents(
|
||||
krate.item.span,
|
||||
krate.item.attrs,
|
||||
|
@ -84,10 +84,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_variant_data(
|
||||
&mut self,
|
||||
item: &'tcx hir::Item,
|
||||
item: &'tcx hir::Item<'_>,
|
||||
name: Symbol,
|
||||
sd: &'tcx hir::VariantData,
|
||||
generics: &'tcx hir::Generics,
|
||||
sd: &'tcx hir::VariantData<'_>,
|
||||
generics: &'tcx hir::Generics<'_>,
|
||||
) -> Struct<'tcx> {
|
||||
debug!("visiting struct");
|
||||
let struct_type = struct_type_from_def(&*sd);
|
||||
|
@ -105,10 +105,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_union_data(
|
||||
&mut self,
|
||||
item: &'tcx hir::Item,
|
||||
item: &'tcx hir::Item<'_>,
|
||||
name: Symbol,
|
||||
sd: &'tcx hir::VariantData,
|
||||
generics: &'tcx hir::Generics,
|
||||
sd: &'tcx hir::VariantData<'_>,
|
||||
generics: &'tcx hir::Generics<'_>,
|
||||
) -> Union<'tcx> {
|
||||
debug!("visiting union");
|
||||
let struct_type = struct_type_from_def(&*sd);
|
||||
|
@ -126,10 +126,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_enum_def(
|
||||
&mut self,
|
||||
it: &'tcx hir::Item,
|
||||
it: &'tcx hir::Item<'_>,
|
||||
name: Symbol,
|
||||
def: &'tcx hir::EnumDef,
|
||||
generics: &'tcx hir::Generics,
|
||||
def: &'tcx hir::EnumDef<'_>,
|
||||
generics: &'tcx hir::Generics<'_>,
|
||||
) -> Enum<'tcx> {
|
||||
debug!("visiting enum");
|
||||
Enum {
|
||||
|
@ -156,11 +156,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
fn visit_fn(
|
||||
&mut self,
|
||||
om: &mut Module<'tcx>,
|
||||
item: &'tcx hir::Item,
|
||||
item: &'tcx hir::Item<'_>,
|
||||
name: Symbol,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
decl: &'tcx hir::FnDecl<'_>,
|
||||
header: hir::FnHeader,
|
||||
generics: &'tcx hir::Generics,
|
||||
generics: &'tcx hir::Generics<'_>,
|
||||
body: hir::BodyId,
|
||||
) {
|
||||
debug!("visiting fn");
|
||||
|
@ -231,7 +231,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
&mut self,
|
||||
span: Span,
|
||||
attrs: &'tcx [ast::Attribute],
|
||||
vis: &'tcx hir::Visibility,
|
||||
vis: &'tcx hir::Visibility<'_>,
|
||||
id: hir::HirId,
|
||||
m: &'tcx hir::Mod<'tcx>,
|
||||
name: Option<Symbol>,
|
||||
|
@ -375,7 +375,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
ret
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item, renamed: Option<Ident>, om: &mut Module<'tcx>) {
|
||||
fn visit_item(
|
||||
&mut self,
|
||||
item: &'tcx hir::Item<'_>,
|
||||
renamed: Option<Ident>,
|
||||
om: &mut Module<'tcx>,
|
||||
) {
|
||||
debug!("visiting item {:?}", item);
|
||||
let ident = renamed.unwrap_or(item.ident);
|
||||
|
||||
|
@ -587,7 +592,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_foreign_item(
|
||||
&mut self,
|
||||
item: &'tcx hir::ForeignItem,
|
||||
item: &'tcx hir::ForeignItem<'_>,
|
||||
renamed: Option<Ident>,
|
||||
om: &mut Module<'tcx>,
|
||||
) {
|
||||
|
@ -607,7 +612,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Convert each `exported_macro` into a doc item.
|
||||
fn visit_local_macro(&self, def: &'tcx hir::MacroDef, renamed: Option<Symbol>) -> Macro<'tcx> {
|
||||
fn visit_local_macro(
|
||||
&self,
|
||||
def: &'tcx hir::MacroDef<'_>,
|
||||
renamed: Option<Symbol>,
|
||||
) -> Macro<'tcx> {
|
||||
debug!("visit_local_macro: {}", def.ident);
|
||||
let tts = def.ast.body.inner_tokens().trees().collect::<Vec<_>>();
|
||||
// Extract the spans of all matchers. They represent the "interface" of the macro.
|
||||
|
|
42
src/test/codegen/debug-linkage-name.rs
Normal file
42
src/test/codegen/debug-linkage-name.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Verifies that linkage name is omitted when it is
|
||||
// the same as variable / function name.
|
||||
//
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
// compile-flags: -C debuginfo=2
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub mod xyz {
|
||||
// CHECK: !DIGlobalVariable(name: "A",
|
||||
// CHECK: linkageName:
|
||||
// CHECK-SAME: line: 12,
|
||||
pub static A: u32 = 1;
|
||||
|
||||
// CHECK: !DIGlobalVariable(name: "B",
|
||||
// CHECK-NOT: linkageName:
|
||||
// CHECK-SAME: line: 18,
|
||||
#[no_mangle]
|
||||
pub static B: u32 = 2;
|
||||
|
||||
// CHECK: !DIGlobalVariable(name: "C",
|
||||
// CHECK-NOT: linkageName:
|
||||
// CHECK-SAME: line: 24,
|
||||
#[export_name = "C"]
|
||||
pub static C: u32 = 2;
|
||||
|
||||
// CHECK: !DISubprogram(name: "e",
|
||||
// CHECK: linkageName:
|
||||
// CHECK-SAME: line: 29,
|
||||
pub extern fn e() {}
|
||||
|
||||
// CHECK: !DISubprogram(name: "f",
|
||||
// CHECK-NOT: linkageName:
|
||||
// CHECK-SAME: line: 35,
|
||||
#[no_mangle]
|
||||
pub extern fn f() {}
|
||||
|
||||
// CHECK: !DISubprogram(name: "g",
|
||||
// CHECK-NOT: linkageName:
|
||||
// CHECK-SAME: line: 41,
|
||||
#[export_name = "g"]
|
||||
pub extern fn g() {}
|
||||
}
|
39
src/test/ui/chalkify/closure.rs
Normal file
39
src/test/ui/chalkify/closure.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// check-fail
|
||||
// compile-flags: -Z chalk
|
||||
|
||||
fn main() -> () {
|
||||
let t = || {};
|
||||
t();
|
||||
|
||||
let mut a = 0;
|
||||
let mut b = move || {
|
||||
a = 1;
|
||||
};
|
||||
b();
|
||||
|
||||
let mut c = b;
|
||||
|
||||
c();
|
||||
b();
|
||||
|
||||
let mut a = 0;
|
||||
let mut b = || {
|
||||
a = 1;
|
||||
};
|
||||
b();
|
||||
|
||||
let mut c = b;
|
||||
|
||||
c();
|
||||
b(); //~ ERROR
|
||||
|
||||
// FIXME(chalk): this doesn't quite work
|
||||
/*
|
||||
let b = |c| {
|
||||
c
|
||||
};
|
||||
|
||||
let a = &32;
|
||||
b(a);
|
||||
*/
|
||||
}
|
18
src/test/ui/chalkify/closure.stderr
Normal file
18
src/test/ui/chalkify/closure.stderr
Normal file
|
@ -0,0 +1,18 @@
|
|||
error[E0382]: borrow of moved value: `b`
|
||||
--> $DIR/closure.rs:28:5
|
||||
|
|
||||
LL | let mut c = b;
|
||||
| - value moved here
|
||||
...
|
||||
LL | b();
|
||||
| ^ value borrowed here after move
|
||||
|
|
||||
note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
|
||||
--> $DIR/closure.rs:21:9
|
||||
|
|
||||
LL | a = 1;
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
|
@ -23,15 +23,10 @@ impl<T> Bar for Option<T> {
|
|||
type Item = Option<T>;
|
||||
}
|
||||
|
||||
// FIXME(chalk): the ordering of these two errors differs between CI and local
|
||||
// We need to figure out why its non-deterministic
|
||||
/*
|
||||
impl Bar for f32 {
|
||||
//^ ERROR the trait bound `f32: Foo` is not satisfied
|
||||
type Item = f32;
|
||||
//^ ERROR the trait bound `f32: Foo` is not satisfied
|
||||
//~^ ERROR the trait bound `f32: Foo` is not satisfied
|
||||
}
|
||||
*/
|
||||
|
||||
trait Baz<U: ?Sized> where U: Foo { }
|
||||
|
||||
|
|
|
@ -11,7 +11,18 @@ LL | impl Foo for str { }
|
|||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
|
||||
error[E0277]: the trait bound `f32: Foo` is not satisfied
|
||||
--> $DIR/impl_wf.rs:40:6
|
||||
--> $DIR/impl_wf.rs:27:17
|
||||
|
|
||||
LL | trait Bar {
|
||||
| --- required by a bound in this
|
||||
LL | type Item: Foo;
|
||||
| --- required by this bound in `Bar`
|
||||
...
|
||||
LL | type Item = f32;
|
||||
| ^^^ the trait `Foo` is not implemented for `f32`
|
||||
|
||||
error[E0277]: the trait bound `f32: Foo` is not satisfied
|
||||
--> $DIR/impl_wf.rs:35:6
|
||||
|
|
||||
LL | trait Baz<U: ?Sized> where U: Foo { }
|
||||
| --- required by this bound in `Baz`
|
||||
|
@ -19,6 +30,6 @@ LL | trait Baz<U: ?Sized> where U: Foo { }
|
|||
LL | impl Baz<f32> for f32 { }
|
||||
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// run-pass
|
||||
// compile-flags: -Z chalk
|
||||
// FIXME(chalk): remove when uncommented
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
trait Foo { }
|
||||
|
||||
|
@ -11,8 +9,6 @@ struct S<T: Foo> {
|
|||
x: T,
|
||||
}
|
||||
|
||||
// FIXME(chalk): need late-bound regions on FnDefs
|
||||
/*
|
||||
fn only_foo<T: Foo>(_x: &T) { }
|
||||
|
||||
impl<T> S<T> {
|
||||
|
@ -21,7 +17,6 @@ impl<T> S<T> {
|
|||
only_foo(&self.x)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
trait Bar { }
|
||||
impl Bar for u32 { }
|
||||
|
@ -31,16 +26,10 @@ fn only_bar<T: Bar>() { }
|
|||
impl<T> S<T> {
|
||||
// Test that the environment of `dummy_bar` adds up with the environment
|
||||
// of the inherent impl.
|
||||
// FIXME(chalk): need late-bound regions on FnDefs
|
||||
/*
|
||||
fn dummy_bar<U: Bar>(&self) {
|
||||
only_foo(&self.x);
|
||||
only_bar::<U>();
|
||||
}
|
||||
*/
|
||||
fn dummy_bar<U: Bar>() {
|
||||
only_bar::<U>();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -48,10 +37,6 @@ fn main() {
|
|||
x: 5,
|
||||
};
|
||||
|
||||
// FIXME(chalk): need late-bound regions on FnDefs
|
||||
/*
|
||||
s.dummy_foo();
|
||||
s.dummy_bar::<u32>();
|
||||
*/
|
||||
S::<i32>::dummy_bar::<u32>();
|
||||
s.dummy_foo();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// FIXME(chalk): should fail, see comments
|
||||
// check-pass
|
||||
// check-fail
|
||||
// compile-flags: -Z chalk
|
||||
|
||||
#![feature(trivial_bounds)]
|
||||
|
@ -10,7 +10,6 @@ trait Bar {
|
|||
trait Foo: Bar { }
|
||||
|
||||
struct S where S: Foo;
|
||||
//~^ WARN Trait bound S: Foo does not depend on any type or lifetime parameters
|
||||
|
||||
impl Foo for S {
|
||||
}
|
||||
|
@ -26,10 +25,6 @@ fn foo<T: Foo>() {
|
|||
fn main() {
|
||||
// For some reason, the error is duplicated...
|
||||
|
||||
// FIXME(chalk): this order of this duplicate error seems non-determistic
|
||||
// and causes test to fail
|
||||
/*
|
||||
foo::<S>() // ERROR the type `S` is not well-formed (chalk)
|
||||
//^ ERROR the type `S` is not well-formed (chalk)
|
||||
*/
|
||||
foo::<S>() //~ ERROR the type `S` is not well-formed (chalk)
|
||||
//~^ ERROR the type `S` is not well-formed (chalk)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
warning: Trait bound S: Foo does not depend on any type or lifetime parameters
|
||||
--> $DIR/recursive_where_clause_on_type.rs:12:19
|
||||
error: the type `S` is not well-formed (chalk)
|
||||
--> $DIR/recursive_where_clause_on_type.rs:28:11
|
||||
|
|
||||
LL | struct S where S: Foo;
|
||||
| ^^^
|
||||
LL | foo::<S>()
|
||||
| ^
|
||||
|
||||
error: the type `S` is not well-formed (chalk)
|
||||
--> $DIR/recursive_where_clause_on_type.rs:28:5
|
||||
|
|
||||
= note: `#[warn(trivial_bounds)]` on by default
|
||||
LL | foo::<S>()
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: 1 warning emitted
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
|
||||
//! by rustbuild (in `src/bootstrap/dist.rs`).
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![deny(warnings)]
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
|
@ -476,7 +476,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
|
|||
&& match (&l.kind, &r.kind) {
|
||||
(Lifetime, Lifetime) => true,
|
||||
(Type { default: l }, Type { default: r }) => both(l, r, |l, r| eq_ty(l, r)),
|
||||
(Const { ty: l }, Const { ty: r }) => eq_ty(l, r),
|
||||
(Const { ty: l, kw_span: _ }, Const { ty: r, kw_span: _ }) => eq_ty(l, r),
|
||||
_ => false,
|
||||
}
|
||||
&& over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![crate_name = "compiletest"]
|
||||
#![deny(warnings)]
|
||||
// The `test` crate is the only unstable feature
|
||||
// allowed here, just to share similar code.
|
||||
#![feature(test)]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(rustc_private)]
|
||||
#![deny(warnings)]
|
||||
|
||||
extern crate env_logger;
|
||||
extern crate rustc_ast;
|
||||
|
|
|
@ -165,7 +165,7 @@ struct StrError(String);
|
|||
impl Error for StrError {}
|
||||
|
||||
impl std::fmt::Display for StrError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ struct WithContext {
|
|||
}
|
||||
|
||||
impl std::fmt::Display for WithContext {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.context)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
//! A few whitelisted exceptions are allowed as there's known bugs in rustdoc,
|
||||
//! but this should catch the majority of "broken link" cases.
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
//! Here is also where we bake in the support to spawn the QEMU emulator as
|
||||
//! well.
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::prelude::*;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
//! themselves having support libraries. All data over the TCP sockets is in a
|
||||
//! basically custom format suiting our needs.
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
#[cfg(not(windows))]
|
||||
use std::fs::Permissions;
|
||||
#[cfg(not(windows))]
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//! etc. This is run by default on `./x.py test` and as part of the auto
|
||||
//! builders. The tidy checks can be executed with `./x.py test tidy`.
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use tidy::*;
|
||||
|
||||
use std::env;
|
||||
|
|
|
@ -67,6 +67,7 @@ const EXCEPTION_PATHS: &[&str] = &[
|
|||
// std testing crates, okay for now at least
|
||||
"src/libcore/tests",
|
||||
"src/liballoc/tests/lib.rs",
|
||||
"src/liballoc/benches/lib.rs",
|
||||
// The `VaList` implementation must have platform specific code.
|
||||
// The Windows implementation of a `va_list` is always a character
|
||||
// pointer regardless of the target architecture. As a result,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//! Auto-generate stub docs for the unstable book
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
|
|
Loading…
Add table
Reference in a new issue