Auto merge of #82703 - iago-lito:nonzero_add_mul_pow, r=m-ou-se
Implement nonzero arithmetics for NonZero types.
Hello'all, this is my first PR to this repo.
Non-zero natural numbers are stable by addition/multiplication/exponentiation, so it makes sense to make this arithmetic possible with `NonZeroU*`.
The major pitfall is that overflowing underlying `u*` types possibly lead to underlying `0` values, which break the major invariant of `NonZeroU*`. To accommodate it, only `checked_` and `saturating_` operations are implemented.
Other variants allowing wrapped results like `wrapping_` or `overflowing_` are ruled out *de facto*.
`impl Add<u*> for NonZeroU* { .. }` was considered, as it panics on overflow which enforces the invariant, but it does not so in release mode. I considered forcing `NonZeroU*::add` to panic in release mode by deferring the check to `u*::checked_add`, but this is less explicit for the user than directly using `NonZeroU*::checked_add`.
Following `@Lokathor's` advice on zulip, I have dropped the idea.
`@poliorcetics` on Discord also suggested implementing `_sub` operations, but I'd postpone this to another PR if there is a need for it. My opinion is that it could be useful in some cases, but that it makes less sense because non-null natural numbers are not stable by subtraction even in theory, while the overflowing problem is just about technical implementation.
One thing I don't like is that the type of the `other` arg differs in every implementation: `_add` methods accept any raw positive integer, `_mul` methods only accept non-zero values otherwise the invariant is also broken, and `_pow` only seems to accept `u32` for a reason I ignore but that seems consistent throughout `std`. Maybe there is a better way to harmonize this?
This is it, Iope I haven't forgotten anything and I'll be happy to read your feedback.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index aa9d97b..3636263 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -259,6 +259,11 @@
- name: x86_64-gnu
os: ubuntu-latest-xl
env: {}
+ - name: x86_64-gnu-stable
+ env:
+ IMAGE: x86_64-gnu
+ RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
+ os: ubuntu-latest-xl
- name: x86_64-gnu-aux
os: ubuntu-latest-xl
env: {}
diff --git a/Cargo.lock b/Cargo.lock
index 2c29663..de110c5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3693,6 +3693,7 @@
"rustc_incremental",
"rustc_index",
"rustc_llvm",
+ "rustc_metadata",
"rustc_middle",
"rustc_serialize",
"rustc_session",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index b3bac1d..93d7a59 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -623,12 +623,13 @@
PatKind::Ident(_, _, Some(p)) => p.walk(it),
// Walk into each field of struct.
- PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
+ PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
// Sequence of patterns.
- PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) | PatKind::Or(s) => {
- s.iter().for_each(|p| p.walk(it))
- }
+ PatKind::TupleStruct(_, _, s)
+ | PatKind::Tuple(s)
+ | PatKind::Slice(s)
+ | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
// Trivial wrappers over inner patterns.
PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
@@ -701,10 +702,10 @@
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
- Struct(Path, Vec<PatField>, /* recovered */ bool),
+ Struct(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
- TupleStruct(Path, Vec<P<Pat>>),
+ TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
@@ -1247,6 +1248,7 @@
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StructExpr {
+ pub qself: Option<QSelf>,
pub path: Path,
pub fields: Vec<ExprField>,
pub rest: StructRest,
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 071d41e..0b6099f 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1139,7 +1139,8 @@
visit_opt(sub, |sub| vis.visit_pat(sub));
}
PatKind::Lit(e) => vis.visit_expr(e),
- PatKind::TupleStruct(path, elems) => {
+ PatKind::TupleStruct(qself, path, elems) => {
+ vis.visit_qself(qself);
vis.visit_path(path);
visit_vec(elems, |elem| vis.visit_pat(elem));
}
@@ -1147,7 +1148,8 @@
vis.visit_qself(qself);
vis.visit_path(path);
}
- PatKind::Struct(path, fields, _etc) => {
+ PatKind::Struct(qself, path, fields, _etc) => {
+ vis.visit_qself(qself);
vis.visit_path(path);
fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
}
@@ -1333,7 +1335,8 @@
}
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
ExprKind::Struct(se) => {
- let StructExpr { path, fields, rest } = se.deref_mut();
+ let StructExpr { qself, path, fields, rest } = se.deref_mut();
+ vis.visit_qself(qself);
vis.visit_path(path);
fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
match rest {
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index f1a99bc..1ebfcf3 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -497,7 +497,10 @@
pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
match pattern.kind {
- PatKind::TupleStruct(ref path, ref elems) => {
+ PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => {
+ if let Some(ref qself) = *opt_qself {
+ visitor.visit_ty(&qself.ty);
+ }
visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat, elems);
}
@@ -507,7 +510,10 @@
}
visitor.visit_path(path, pattern.id)
}
- PatKind::Struct(ref path, ref fields, _) => {
+ PatKind::Struct(ref opt_qself, ref path, ref fields, _) => {
+ if let Some(ref qself) = *opt_qself {
+ visitor.visit_ty(&qself.ty);
+ }
visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat_field, fields);
}
@@ -740,6 +746,9 @@
visitor.visit_anon_const(count)
}
ExprKind::Struct(ref se) => {
+ if let Some(ref qself) = se.qself {
+ visitor.visit_ty(&qself.ty);
+ }
visitor.visit_path(&se.path, expression.id);
walk_list!(visitor, visit_expr_field, &se.fields);
match &se.rest {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 866f218..b9dcd08 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -237,7 +237,7 @@
hir::ExprKind::Struct(
self.arena.alloc(self.lower_qpath(
e.id,
- &None,
+ &se.qself,
&se.path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
@@ -1041,10 +1041,12 @@
/// It is not a complete check, but just tries to reject most paths early
/// if they are not tuple structs.
/// Type checking will take care of the full validation later.
- fn extract_tuple_struct_path<'a>(&mut self, expr: &'a Expr) -> Option<&'a Path> {
- // For tuple struct destructuring, it must be a non-qualified path (like in patterns).
- if let ExprKind::Path(None, path) = &expr.kind {
- // Does the path resolves to something disallowed in a tuple struct/variant pattern?
+ fn extract_tuple_struct_path<'a>(
+ &mut self,
+ expr: &'a Expr,
+ ) -> Option<(&'a Option<QSelf>, &'a Path)> {
+ if let ExprKind::Path(qself, path) = &expr.kind {
+ // Does the path resolve to something disallowed in a tuple struct/variant pattern?
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
if partial_res.unresolved_segments() == 0
&& !partial_res.base_res().expected_in_tuple_struct_pat()
@@ -1052,7 +1054,7 @@
return None;
}
}
- return Some(path);
+ return Some((qself, path));
}
None
}
@@ -1088,7 +1090,7 @@
}
// Tuple structs.
ExprKind::Call(callee, args) => {
- if let Some(path) = self.extract_tuple_struct_path(callee) {
+ if let Some((qself, path)) = self.extract_tuple_struct_path(callee) {
let (pats, rest) = self.destructure_sequence(
args,
"tuple struct or variant",
@@ -1097,7 +1099,7 @@
);
let qpath = self.lower_qpath(
callee.id,
- &None,
+ qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
@@ -1122,7 +1124,7 @@
}));
let qpath = self.lower_qpath(
lhs.id,
- &None,
+ &se.qself,
&se.path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2451409..66e6235 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -21,10 +21,10 @@
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
}
PatKind::Lit(ref e) => break hir::PatKind::Lit(self.lower_expr(e)),
- PatKind::TupleStruct(ref path, ref pats) => {
+ PatKind::TupleStruct(ref qself, ref path, ref pats) => {
let qpath = self.lower_qpath(
pattern.id,
- &None,
+ qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
@@ -47,10 +47,10 @@
);
break hir::PatKind::Path(qpath);
}
- PatKind::Struct(ref path, ref fields, etc) => {
+ PatKind::Struct(ref qself, ref path, ref fields, etc) => {
let qpath = self.lower_qpath(
pattern.id,
- &None,
+ qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index ba2da76..30aa51a 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -938,8 +938,11 @@
}
GenericParamKind::Type { default: None } => (),
GenericParamKind::Lifetime => (),
- // FIXME(const_generics_defaults)
- GenericParamKind::Const { ty: _, kw_span: _, default: _ } => (),
+ GenericParamKind::Const { ty: _, kw_span: _, default: Some(default) } => {
+ ordered_params += " = ";
+ ordered_params += &pprust::expr_to_string(&*default.value);
+ }
+ GenericParamKind::Const { ty: _, kw_span: _, default: None } => (),
}
first = false;
}
@@ -959,7 +962,7 @@
span,
&format!(
"reorder the parameters: lifetimes, {}",
- if sess.features_untracked().const_generics {
+ if sess.features_untracked().unordered_const_ty_params() {
"then consts and types"
} else {
"then types, then consts"
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 664e138..3f98944 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -705,6 +705,7 @@
"async closures are unstable",
"to use an async block, remove the `||`: `async {`"
);
+ gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental");
gate_all!(generators, "yield syntax is experimental");
gate_all!(raw_ref_op, "raw address of syntax is experimental");
gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental");
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index b7bb896..93facd2 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1713,11 +1713,16 @@
fn print_expr_struct(
&mut self,
+ qself: &Option<ast::QSelf>,
path: &ast::Path,
fields: &[ast::ExprField],
rest: &ast::StructRest,
) {
- self.print_path(path, true, 0);
+ if let Some(qself) = qself {
+ self.print_qpath(path, qself, true);
+ } else {
+ self.print_path(path, true, 0);
+ }
self.s.word("{");
self.commasep_cmnt(
Consistent,
@@ -1874,7 +1879,7 @@
self.print_expr_repeat(element, count);
}
ast::ExprKind::Struct(ref se) => {
- self.print_expr_struct(&se.path, &se.fields, &se.rest);
+ self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest);
}
ast::ExprKind::Tup(ref exprs) => {
self.print_expr_tup(exprs);
@@ -2340,8 +2345,12 @@
self.print_pat(p);
}
}
- PatKind::TupleStruct(ref path, ref elts) => {
- self.print_path(path, true, 0);
+ PatKind::TupleStruct(ref qself, ref path, ref elts) => {
+ if let Some(qself) = qself {
+ self.print_qpath(path, qself, true);
+ } else {
+ self.print_path(path, true, 0);
+ }
self.popen();
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
self.pclose();
@@ -2355,8 +2364,12 @@
PatKind::Path(Some(ref qself), ref path) => {
self.print_qpath(path, qself, false);
}
- PatKind::Struct(ref path, ref fields, etc) => {
- self.print_path(path, true, 0);
+ PatKind::Struct(ref qself, ref path, ref fields, etc) => {
+ if let Some(qself) = qself {
+ self.print_qpath(path, qself, true);
+ } else {
+ self.print_path(path, true, 0);
+ }
self.nbsp();
self.word_space("{");
self.commasep_cmnt(
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 904efed..6aadaf8 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -14,6 +14,7 @@
extern crate rustc_hir;
extern crate rustc_incremental;
extern crate rustc_index;
+extern crate rustc_metadata;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;
diff --git a/compiler/rustc_codegen_cranelift/src/metadata.rs b/compiler/rustc_codegen_cranelift/src/metadata.rs
index ab23824..db24bf6 100644
--- a/compiler/rustc_codegen_cranelift/src/metadata.rs
+++ b/compiler/rustc_codegen_cranelift/src/metadata.rs
@@ -10,7 +10,7 @@
use std::io::Write;
let metadata = tcx.encode_metadata();
- let mut compressed = tcx.metadata_encoding_version();
+ let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
object.add_rustc_section(
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index 4999cb3..d0eb691 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -27,6 +27,7 @@
rustc_incremental = { path = "../rustc_incremental" }
rustc_index = { path = "../rustc_index" }
rustc_llvm = { path = "../rustc_llvm" }
+rustc_metadata = { path = "../rustc_metadata" }
rustc_session = { path = "../rustc_session" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 893c909..cc3cbea 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -63,7 +63,7 @@
let section_name = if tcx.sess.target.is_like_osx { "__DATA,.rustc" } else { ".rustc" };
let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());
- let mut compressed = tcx.metadata_encoding_version();
+ let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
let llmeta = common::bytes_in_context(metadata_llcx, &compressed);
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 387062a..0dd3d2a 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -1,5 +1,5 @@
use crate::back::write::create_informational_target_machine;
-use crate::llvm;
+use crate::{llvm, llvm_util};
use libc::c_int;
use rustc_codegen_ssa::target_features::supported_target_features;
use rustc_data_structures::fx::FxHashSet;
@@ -84,6 +84,17 @@
if !sess.opts.debugging_opts.no_generate_arange_section {
add("-generate-arange-section", false);
}
+
+ // FIXME(nagisa): disable the machine outliner by default in LLVM versions 11, where it was
+ // introduced and up.
+ //
+ // This should remain in place until https://reviews.llvm.org/D103167 is fixed. If LLVM
+ // has been upgraded since, consider adjusting the version check below to contain an upper
+ // bound.
+ if llvm_util::get_version() >= (11, 0, 0) {
+ add("-enable-machine-outliner=never", false);
+ }
+
match sess.opts.debugging_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
MergeFunctions::Aliases => {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 6a2005b..6c9ec9e 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -5,7 +5,7 @@
use rustc_hir::def_id::CrateNum;
use rustc_middle::middle::cstore::{DllImport, LibSource};
use rustc_middle::middle::dependency_format::Linkage;
-use rustc_session::config::{self, CFGuard, CrateType, DebugInfo};
+use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest};
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
use rustc_session::search_paths::PathKind;
@@ -907,14 +907,6 @@
}
}
- fn escape_string(s: &[u8]) -> String {
- str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
- let mut x = "Non-UTF-8 output: ".to_string();
- x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
- x
- })
- }
-
match prog {
Ok(prog) => {
if !prog.status.success() {
@@ -1056,6 +1048,47 @@
// ... and otherwise we're processing a `*.dwp` packed dwarf file.
SplitDebuginfo::Packed => link_dwarf_object(sess, &out_filename),
}
+
+ if sess.target.is_like_osx {
+ if let Some(option) = osx_strip_opt(sess.opts.debugging_opts.strip) {
+ strip_symbols_in_osx(sess, &out_filename, option);
+ }
+ }
+}
+
+fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: &str) {
+ let prog = Command::new("strip").arg(option).arg(out_filename).output();
+ match prog {
+ Ok(prog) => {
+ if !prog.status.success() {
+ let mut output = prog.stderr.clone();
+ output.extend_from_slice(&prog.stdout);
+ sess.struct_warn(&format!(
+ "stripping debug info with `strip` failed: {}",
+ prog.status
+ ))
+ .note(&escape_string(&output))
+ .emit();
+ }
+ }
+ Err(e) => sess.fatal(&format!("unable to run `strip`: {}", e)),
+ }
+}
+
+fn osx_strip_opt<'a>(strip: Strip) -> Option<&'a str> {
+ match strip {
+ Strip::Debuginfo => Some("-S"),
+ Strip::Symbols => Some("-x"),
+ Strip::None => None,
+ }
+}
+
+fn escape_string(s: &[u8]) -> String {
+ str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
+ let mut x = "Non-UTF-8 output: ".to_string();
+ x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
+ x
+ })
}
fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
@@ -1894,6 +1927,8 @@
out_filename: &Path,
tmpdir: &Path,
) {
+ add_gcc_ld_path(cmd, sess, flavor);
+
add_apple_sdk(cmd, sess, flavor);
add_link_script(cmd, sess, tmpdir, crate_type);
@@ -2495,3 +2530,30 @@
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
}
}
+
+fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
+ if let Some(ld_impl) = sess.opts.debugging_opts.gcc_ld {
+ if let LinkerFlavor::Gcc = flavor {
+ match ld_impl {
+ LdImpl::Lld => {
+ let tools_path =
+ sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+ let lld_path = tools_path
+ .into_iter()
+ .map(|p| p.join("gcc-ld"))
+ .find(|p| {
+ p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
+ })
+ .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
+ cmd.cmd().arg({
+ let mut arg = OsString::from("-B");
+ arg.push(lld_path);
+ arg
+ });
+ }
+ }
+ } else {
+ sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc");
+ }
+ }
+}
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 1d53e9a..43ff664 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -526,15 +526,18 @@
fn control_flow_guard(&mut self) {}
fn debuginfo(&mut self, strip: Strip) {
+ // MacOS linker doesn't support stripping symbols directly anymore.
+ if self.sess.target.is_like_osx {
+ return;
+ }
+
match strip {
Strip::None => {}
Strip::Debuginfo => {
- // MacOS linker does not support longhand argument --strip-debug
- self.linker_arg("-S");
+ self.linker_arg("--strip-debug");
}
Strip::Symbols => {
- // MacOS linker does not support longhand argument --strip-all
- self.linker_arg("-s");
+ self.linker_arg("--strip-all");
}
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 8a22a74..49b5e84 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -18,7 +18,10 @@
let mir = fx.mir;
let mut analyzer = LocalAnalyzer::new(fx);
- for (bb, data) in mir.basic_blocks().iter_enumerated() {
+ // If there exists a local definition that dominates all uses of that local,
+ // the definition should be visited first. Traverse blocks in preorder which
+ // is a topological sort of dominance partial order.
+ for (bb, data) in traversal::preorder(&mir) {
analyzer.visit_basic_block_data(bb, data);
}
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index b10de56..c89d42e 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -205,7 +205,7 @@
];
const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- ("simd128", Some(sym::wasm_target_feature)),
+ ("simd128", None),
("atomics", Some(sym::wasm_target_feature)),
("nontrapping-fptoint", Some(sym::wasm_target_feature)),
];
diff --git a/compiler/rustc_data_structures/src/box_region.rs b/compiler/rustc_data_structures/src/box_region.rs
deleted file mode 100644
index eb6f4e8..0000000
--- a/compiler/rustc_data_structures/src/box_region.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-//! This module provides a way to deal with self-referential data.
-//!
-//! The main idea is to allocate such data in a generator frame and then
-//! give access to it by executing user-provided closures inside that generator.
-//! The module provides a safe abstraction for the latter task.
-//!
-//! The interface consists of two exported macros meant to be used together:
-//! * `declare_box_region_type` wraps a generator inside a struct with `access`
-//! method which accepts closures.
-//! * `box_region_allow_access` is a helper which should be called inside
-//! a generator to actually execute those closures.
-
-use std::marker::PhantomData;
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
-#[derive(Copy, Clone)]
-pub struct AccessAction(*mut dyn FnMut());
-
-impl AccessAction {
- pub fn get(self) -> *mut dyn FnMut() {
- self.0
- }
-}
-
-#[derive(Copy, Clone)]
-pub enum Action {
- Initial,
- Access(AccessAction),
- Complete,
-}
-
-pub struct PinnedGenerator<I, A, R> {
- generator: Pin<Box<dyn Generator<Action, Yield = YieldType<I, A>, Return = R>>>,
-}
-
-impl<I, A, R> PinnedGenerator<I, A, R> {
- pub fn new<T: Generator<Action, Yield = YieldType<I, A>, Return = R> + 'static>(
- generator: T,
- ) -> (I, Self) {
- let mut result = PinnedGenerator { generator: Box::pin(generator) };
-
- // Run it to the first yield to set it up
- let init = match Pin::new(&mut result.generator).resume(Action::Initial) {
- GeneratorState::Yielded(YieldType::Initial(y)) => y,
- _ => panic!(),
- };
-
- (init, result)
- }
-
- pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) {
- // Call the generator, which in turn will call the closure
- if let GeneratorState::Complete(_) =
- Pin::new(&mut self.generator).resume(Action::Access(AccessAction(closure)))
- {
- panic!()
- }
- }
-
- pub fn complete(&mut self) -> R {
- // Tell the generator we want it to complete, consuming it and yielding a result
- let result = Pin::new(&mut self.generator).resume(Action::Complete);
- if let GeneratorState::Complete(r) = result { r } else { panic!() }
- }
-}
-
-#[derive(PartialEq)]
-pub struct Marker<T>(PhantomData<T>);
-
-impl<T> Marker<T> {
- pub unsafe fn new() -> Self {
- Marker(PhantomData)
- }
-}
-
-pub enum YieldType<I, A> {
- Initial(I),
- Accessor(Marker<A>),
-}
-
-#[macro_export]
-#[allow_internal_unstable(fn_traits)]
-macro_rules! declare_box_region_type {
- (impl $v:vis
- $name: ident,
- $yield_type:ty,
- for($($lifetimes:tt)*),
- ($($args:ty),*) -> ($reti:ty, $retc:ty)
- ) => {
- $v struct $name($crate::box_region::PinnedGenerator<
- $reti,
- for<$($lifetimes)*> fn(($($args,)*)),
- $retc
- >);
-
- impl $name {
- fn new<T: ::std::ops::Generator<$crate::box_region::Action, Yield = $yield_type, Return = $retc> + 'static>(
- generator: T
- ) -> ($reti, Self) {
- let (initial, pinned) = $crate::box_region::PinnedGenerator::new(generator);
- (initial, $name(pinned))
- }
-
- $v fn access<F: for<$($lifetimes)*> FnOnce($($args,)*) -> R, R>(&mut self, f: F) -> R {
- // Turn the FnOnce closure into *mut dyn FnMut()
- // so we can pass it in to the generator
- let mut r = None;
- let mut f = Some(f);
- let mut_f: &mut dyn for<$($lifetimes)*> FnMut(($($args,)*)) =
- &mut |args| {
- let f = f.take().unwrap();
- r = Some(FnOnce::call_once(f, args));
- };
- let mut_f = mut_f as *mut dyn for<$($lifetimes)*> FnMut(($($args,)*));
-
- // Get the generator to call our closure
- unsafe {
- self.0.access(::std::mem::transmute(mut_f));
- }
-
- // Unwrap the result
- r.unwrap()
- }
-
- $v fn complete(mut self) -> $retc {
- self.0.complete()
- }
-
- fn initial_yield(value: $reti) -> $yield_type {
- $crate::box_region::YieldType::Initial(value)
- }
- }
- };
-
- ($v:vis $name: ident, for($($lifetimes:tt)*), ($($args:ty),*) -> ($reti:ty, $retc:ty)) => {
- declare_box_region_type!(
- impl $v $name,
- $crate::box_region::YieldType<$reti, for<$($lifetimes)*> fn(($($args,)*))>,
- for($($lifetimes)*),
- ($($args),*) -> ($reti, $retc)
- );
- };
-}
-
-#[macro_export]
-#[allow_internal_unstable(fn_traits)]
-macro_rules! box_region_allow_access {
- (for($($lifetimes:tt)*), ($($args:ty),*), ($($exprs:expr),*), $action:ident) => {
- loop {
- match $action {
- $crate::box_region::Action::Access(accessor) => {
- let accessor: &mut dyn for<$($lifetimes)*> FnMut($($args),*) = unsafe {
- ::std::mem::transmute(accessor.get())
- };
- (*accessor)(($($exprs),*));
- unsafe {
- let marker = $crate::box_region::Marker::<
- for<$($lifetimes)*> fn(($($args,)*))
- >::new();
- $action = yield $crate::box_region::YieldType::Accessor(marker);
- };
- }
- $crate::box_region::Action::Complete => break,
- $crate::box_region::Action::Initial => panic!("unexpected box_region action: Initial"),
- }
- }
- }
-}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index bbfe225..16151e9 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -10,7 +10,6 @@
#![feature(array_windows)]
#![feature(control_flow_enum)]
#![feature(in_band_lifetimes)]
-#![feature(generator_trait)]
#![feature(min_specialization)]
#![feature(auto_traits)]
#![feature(nll)]
@@ -63,7 +62,6 @@
pub mod base_n;
pub mod binary_search_util;
-pub mod box_region;
pub mod captures;
pub mod flock;
pub mod functor;
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index cb8b939..ef5b97a 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -275,7 +275,12 @@
) -> P<ast::Expr> {
self.expr(
span,
- ast::ExprKind::Struct(P(ast::StructExpr { path, fields, rest: ast::StructRest::None })),
+ ast::ExprKind::Struct(P(ast::StructExpr {
+ qself: None,
+ path,
+ fields,
+ rest: ast::StructRest::None,
+ })),
)
}
pub fn expr_struct_ident(
@@ -405,7 +410,7 @@
path: ast::Path,
subpats: Vec<P<ast::Pat>>,
) -> P<ast::Pat> {
- self.pat(span, PatKind::TupleStruct(path, subpats))
+ self.pat(span, PatKind::TupleStruct(None, path, subpats))
}
pub fn pat_struct(
&self,
@@ -413,7 +418,7 @@
path: ast::Path,
field_pats: Vec<ast::PatField>,
) -> P<ast::Pat> {
- self.pat(span, PatKind::Struct(path, field_pats, false))
+ self.pat(span, PatKind::Struct(None, path, field_pats, false))
}
pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
self.pat(span, PatKind::Tuple(pats))
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 0359f50..56a320c 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -663,6 +663,9 @@
/// Allows unnamed fields of struct and union type
(active, unnamed_fields, "1.53.0", Some(49804), None),
+ /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
+ (active, more_qualified_paths, "1.54.0", Some(80080), None),
+
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 49f418d..753b8c8 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -94,15 +94,6 @@
.iter_enumerated()
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
}
-
- pub fn all_def_path_hashes_and_def_ids(
- &self,
- krate: CrateNum,
- ) -> impl Iterator<Item = (DefPathHash, DefId)> + '_ {
- self.def_path_hashes
- .iter_enumerated()
- .map(move |(index, hash)| (*hash, DefId { krate, index }))
- }
}
/// The definition table containing node definitions.
@@ -440,6 +431,14 @@
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k)
}
+
+ #[inline(always)]
+ pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> {
+ self.table
+ .def_path_hash_to_index
+ .get(&hash)
+ .map(|&local_def_index| LocalDefId { local_def_index })
+ }
}
#[derive(Copy, Clone, PartialEq, Debug)]
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 0232654..5606075 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -5,7 +5,7 @@
TraitItem, TraitItemId, Ty, VisibilityKind,
};
use crate::hir_id::{HirId, ItemLocalId};
-use rustc_span::def_id::{DefPathHash, LocalDefId};
+use rustc_span::def_id::DefPathHash;
/// Requirements for a `StableHashingContext` to be used in this crate.
/// This is a hack to allow using the `HashStable_Generic` derive macro
@@ -21,7 +21,6 @@
fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
fn hash_hir_visibility_kind(&mut self, _: &VisibilityKind<'_>, hasher: &mut StableHasher);
fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F);
- fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash;
}
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
@@ -29,7 +28,7 @@
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
- let def_path_hash = hcx.local_def_path_hash(self.owner);
+ let def_path_hash = self.owner.to_stable_hash_key(hcx);
(def_path_hash, self.local_id)
}
}
@@ -39,7 +38,7 @@
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
- hcx.local_def_path_hash(self.def_id)
+ self.def_id.to_stable_hash_key(hcx)
}
}
@@ -48,7 +47,7 @@
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
- hcx.local_def_path_hash(self.def_id)
+ self.def_id.to_stable_hash_key(hcx)
}
}
@@ -57,7 +56,7 @@
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
- hcx.local_def_path_hash(self.def_id)
+ self.def_id.to_stable_hash_key(hcx)
}
}
@@ -66,7 +65,7 @@
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
- hcx.local_def_path_hash(self.def_id)
+ self.def_id.to_stable_hash_key(hcx)
}
}
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 303c39a..8539cc6 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -1,7 +1,6 @@
//! Code to save/load the dep-graph from files.
use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::definitions::DefPathTable;
use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
use rustc_middle::ty::query::OnDiskCache;
use rustc_serialize::opaque::Decoder;
@@ -196,10 +195,7 @@
/// If we are not in incremental compilation mode, returns `None`.
/// Otherwise, tries to load the query result cache from disk,
/// creating an empty cache if it could not be loaded.
-pub fn load_query_result_cache<'a>(
- sess: &'a Session,
- def_path_table: &DefPathTable,
-) -> Option<OnDiskCache<'a>> {
+pub fn load_query_result_cache<'a>(sess: &'a Session) -> Option<OnDiskCache<'a>> {
if sess.opts.incremental.is_none() {
return None;
}
@@ -212,7 +208,7 @@
sess.is_nightly_build(),
) {
LoadResult::Ok { data: (bytes, start_pos) } => {
- Some(OnDiskCache::new(sess, bytes, start_pos, def_path_table))
+ Some(OnDiskCache::new(sess, bytes, start_pos))
}
_ => Some(OnDiskCache::new_empty(sess.source_map())),
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index fb762d2..e3a79fe 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -64,6 +64,7 @@
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{Item, ItemKind, Node};
+use rustc_middle::dep_graph::DepContext;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{
self,
@@ -1965,7 +1966,33 @@
struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str)
}
FailureCode::Error0308(failure_str) => {
- struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str)
+ let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str);
+ if let ValuePairs::Types(ty::error::ExpectedFound { expected, found }) =
+ trace.values
+ {
+ // If a tuple of length one was expected and the found expression has
+ // parentheses around it, perhaps the user meant to write `(expr,)` to
+ // build a tuple (issue #86100)
+ match (expected.kind(), found.kind()) {
+ (ty::Tuple(_), ty::Tuple(_)) => {}
+ (ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
+ if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
+ if let Some(code) =
+ code.strip_prefix('(').and_then(|s| s.strip_suffix(')'))
+ {
+ err.span_suggestion(
+ span,
+ "use a trailing comma to create a tuple with one element",
+ format!("({},)", code),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ err
}
FailureCode::Error0644(failure_str) => {
struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str)
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index b5af2bf..c7424b9 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -2,8 +2,6 @@
#![feature(box_patterns)]
#![feature(internal_output_capture)]
#![feature(nll)]
-#![feature(generator_trait)]
-#![feature(generators)]
#![feature(once_cell)]
#![recursion_limit = "256"]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index aa7af60..9e3e96d 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -6,10 +6,10 @@
use rustc_ast::{self as ast, visit};
use rustc_codegen_ssa::back::link::emit_metadata;
use rustc_codegen_ssa::traits::CodegenBackend;
+use rustc_data_structures::parallel;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
use rustc_data_structures::temp_dir::MaybeTempDir;
-use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
use rustc_errors::{ErrorReported, PResult};
use rustc_expand::base::ExtCtxt;
use rustc_hir::def_id::LOCAL_CRATE;
@@ -47,7 +47,9 @@
use std::ffi::OsString;
use std::io::{self, BufWriter, Write};
use std::lazy::SyncLazy;
+use std::marker::PhantomPinned;
use std::path::PathBuf;
+use std::pin::Pin;
use std::rc::Rc;
use std::{env, fs, iter};
@@ -85,11 +87,83 @@
counter.count
}
-declare_box_region_type!(
- pub BoxedResolver,
- for(),
- (&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
-);
+pub use boxed_resolver::BoxedResolver;
+mod boxed_resolver {
+ use super::*;
+
+ pub struct BoxedResolver(Pin<Box<BoxedResolverInner>>);
+
+ struct BoxedResolverInner {
+ session: Lrc<Session>,
+ resolver_arenas: Option<ResolverArenas<'static>>,
+ resolver: Option<Resolver<'static>>,
+ _pin: PhantomPinned,
+ }
+
+ // Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
+ // then resolver_arenas and finally session.
+ impl Drop for BoxedResolverInner {
+ fn drop(&mut self) {
+ self.resolver.take();
+ self.resolver_arenas.take();
+ }
+ }
+
+ impl BoxedResolver {
+ pub(super) fn new<F>(session: Lrc<Session>, make_resolver: F) -> Result<(ast::Crate, Self)>
+ where
+ F: for<'a> FnOnce(
+ &'a Session,
+ &'a ResolverArenas<'a>,
+ ) -> Result<(ast::Crate, Resolver<'a>)>,
+ {
+ let mut boxed_resolver = Box::new(BoxedResolverInner {
+ session,
+ resolver_arenas: Some(Resolver::arenas()),
+ resolver: None,
+ _pin: PhantomPinned,
+ });
+ // SAFETY: `make_resolver` takes a resolver arena with an arbitrary lifetime and
+ // returns a resolver with the same lifetime as the arena. We ensure that the arena
+ // outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
+ unsafe {
+ let (crate_, resolver) = make_resolver(
+ std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
+ std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
+ boxed_resolver.resolver_arenas.as_ref().unwrap(),
+ ),
+ )?;
+ boxed_resolver.resolver = Some(resolver);
+ Ok((crate_, BoxedResolver(Pin::new_unchecked(boxed_resolver))))
+ }
+ }
+
+ pub fn access<F: for<'a> FnOnce(&mut Resolver<'a>) -> R, R>(&mut self, f: F) -> R {
+ // SAFETY: The resolver doesn't need to be pinned.
+ let mut resolver = unsafe {
+ self.0.as_mut().map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
+ };
+ f((&mut *resolver).as_mut().unwrap())
+ }
+
+ pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
+ match Rc::try_unwrap(resolver) {
+ Ok(resolver) => {
+ let mut resolver = resolver.into_inner();
+ // SAFETY: The resolver doesn't need to be pinned.
+ let mut resolver = unsafe {
+ resolver
+ .0
+ .as_mut()
+ .map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
+ };
+ resolver.take().unwrap().into_outputs()
+ }
+ Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
+ }
+ }
+ }
+}
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
@@ -111,41 +185,16 @@
// its contents but the results of name resolution on those contents. Hopefully we'll push
// this back at some point.
let crate_name = crate_name.to_string();
- let (result, resolver) = BoxedResolver::new(static move |mut action| {
- let _ = action;
- let sess = &*sess;
- let resolver_arenas = Resolver::arenas();
- let res = configure_and_expand_inner(
+ BoxedResolver::new(sess, move |sess, resolver_arenas| {
+ configure_and_expand_inner(
sess,
&lint_store,
krate,
&crate_name,
&resolver_arenas,
- &*metadata_loader,
- );
- let mut resolver = match res {
- Err(v) => {
- yield BoxedResolver::initial_yield(Err(v));
- panic!()
- }
- Ok((krate, resolver)) => {
- action = yield BoxedResolver::initial_yield(Ok(krate));
- resolver
- }
- };
- box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver), action);
- resolver.into_outputs()
- });
- result.map(|k| (k, resolver))
-}
-
-impl BoxedResolver {
- pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
- match Rc::try_unwrap(resolver) {
- Ok(resolver) => resolver.into_inner().complete(),
- Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
- }
- }
+ metadata_loader,
+ )
+ })
}
pub fn register_plugins<'a>(
@@ -231,11 +280,11 @@
fn configure_and_expand_inner<'a>(
sess: &'a Session,
- lint_store: &'a LintStore,
+ lint_store: &LintStore,
mut krate: ast::Crate,
crate_name: &str,
resolver_arenas: &'a ResolverArenas<'a>,
- metadata_loader: &'a MetadataLoaderDyn,
+ metadata_loader: Box<MetadataLoaderDyn>,
) -> Result<(ast::Crate, Resolver<'a>)> {
tracing::trace!("configure_and_expand_inner");
pre_expansion_lint(sess, lint_store, &krate, crate_name);
@@ -765,9 +814,7 @@
) -> QueryContext<'tcx> {
let sess = &compiler.session();
- let def_path_table = resolver_outputs.definitions.def_path_table();
- let query_result_on_disk_cache =
- rustc_incremental::load_query_result_cache(sess, def_path_table);
+ let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
let codegen_backend = compiler.codegen_backend();
let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 67946df..44c2a55 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -858,10 +858,10 @@
// The other cases do not contain sub-patterns.
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
// These are list-like patterns; parens can always be removed.
- TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
+ TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
self.check_unused_parens_pat(cx, p, false, false);
},
- Struct(_, fps, _) => for f in fps {
+ Struct(_, _, fps, _) => for f in fps {
self.check_unused_parens_pat(cx, &f.pat, false, false);
},
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index e9ae22f..d73cfe3 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -54,7 +54,7 @@
pub struct CrateLoader<'a> {
// Immutable configuration.
sess: &'a Session,
- metadata_loader: &'a MetadataLoaderDyn,
+ metadata_loader: Box<MetadataLoaderDyn>,
local_crate_name: Symbol,
// Mutable output.
cstore: CStore,
@@ -219,7 +219,7 @@
impl<'a> CrateLoader<'a> {
pub fn new(
sess: &'a Session,
- metadata_loader: &'a MetadataLoaderDyn,
+ metadata_loader: Box<MetadataLoaderDyn>,
local_crate_name: &str,
) -> Self {
let local_crate_stable_id =
@@ -544,7 +544,7 @@
info!("falling back to a load");
let mut locator = CrateLocator::new(
self.sess,
- self.metadata_loader,
+ &*self.metadata_loader,
name,
hash,
host_hash,
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 27842ac..2c9bad7 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -29,3 +29,5 @@
pub mod creader;
pub mod dynamic_lib;
pub mod locator;
+
+pub use rmeta::METADATA_HEADER;
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7cec4ce..9a97835 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -1,7 +1,7 @@
use crate::creader::{CStore, LoadedMacro};
use crate::foreign_modules;
use crate::native_libs;
-use crate::rmeta::{self, encoder};
+use crate::rmeta::encoder;
use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
@@ -536,10 +536,6 @@
encoder::encode_metadata(tcx)
}
- fn metadata_encoding_version(&self) -> &[u8] {
- rmeta::METADATA_HEADER
- }
-
fn allocator_kind(&self) -> Option<AllocatorKind> {
self.allocator_kind()
}
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 04fe5cf..99ea0cc 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -52,7 +52,7 @@
/// This header is followed by the position of the `CrateRoot`,
/// which is encoded as a 32-bit big-endian unsigned integer,
/// and further followed by the rustc version string.
-crate const METADATA_HEADER: &[u8; 8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
+pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
diff --git a/compiler/rustc_middle/src/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs
index b2fef73..91c81c3 100644
--- a/compiler/rustc_middle/src/ich/hcx.rs
+++ b/compiler/rustc_middle/src/ich/hcx.rs
@@ -14,7 +14,6 @@
use rustc_span::symbol::Symbol;
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
-use rustc_span::def_id::{CrateNum, CRATE_DEF_INDEX};
use smallvec::SmallVec;
use std::cmp::Ord;
use std::thread::LocalKey;
@@ -227,15 +226,8 @@
}
#[inline]
- fn hash_crate_num(&mut self, cnum: CrateNum, hasher: &mut StableHasher) {
- let hcx = self;
- hcx.def_path_hash(DefId { krate: cnum, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher);
- }
-
- #[inline]
- fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
- let hcx = self;
- hcx.def_path_hash(def_id).hash_stable(hcx, hasher);
+ fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
+ self.def_path_hash(def_id)
}
fn expn_id_cache() -> &'static LocalKey<rustc_span::ExpnIdCache> {
diff --git a/compiler/rustc_middle/src/ich/impls_hir.rs b/compiler/rustc_middle/src/ich/impls_hir.rs
index abf5683..5dfd00b 100644
--- a/compiler/rustc_middle/src/ich/impls_hir.rs
+++ b/compiler/rustc_middle/src/ich/impls_hir.rs
@@ -6,7 +6,6 @@
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
use rustc_hir::definitions::DefPathHash;
use smallvec::SmallVec;
use std::mem;
@@ -113,46 +112,6 @@
self.node_id_hashing_mode = prev_hash_node_ids;
}
-
- #[inline]
- fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash {
- self.local_def_path_hash(def_id)
- }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
- type KeyType = DefPathHash;
-
- #[inline]
- fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
- hcx.def_path_hash(*self)
- }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
- #[inline]
- fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
- hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
- }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
- type KeyType = DefPathHash;
-
- #[inline]
- fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
- hcx.def_path_hash(self.to_def_id())
- }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
- type KeyType = DefPathHash;
-
- #[inline]
- fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
- let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
- def_id.to_stable_hash_key(hcx)
- }
}
impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs
index f09449a..a7ab43d 100644
--- a/compiler/rustc_middle/src/middle/cstore.rs
+++ b/compiler/rustc_middle/src/middle/cstore.rs
@@ -215,7 +215,6 @@
// utility functions
fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
- fn metadata_encoding_version(&self) -> &[u8];
fn allocator_kind(&self) -> Option<AllocatorKind>;
}
diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs
index 776a777..1ef1024 100644
--- a/compiler/rustc_middle/src/mir/abstract_const.rs
+++ b/compiler/rustc_middle/src/mir/abstract_const.rs
@@ -1,6 +1,6 @@
//! A subset of a mir body used for const evaluatability checking.
-use crate::mir;
-use crate::ty;
+use crate::mir::{self, CastKind};
+use crate::ty::{self, Ty};
rustc_index::newtype_index! {
/// An index into an `AbstractConst`.
@@ -17,6 +17,7 @@
Binop(mir::BinOp, NodeId, NodeId),
UnaryOp(mir::UnOp, NodeId),
FunctionCall(NodeId, &'tcx [NodeId]),
+ Cast(CastKind, NodeId, Ty<'tcx>),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 62d1bc7..d13cbdd 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1288,10 +1288,6 @@
)
}
- pub fn metadata_encoding_version(self) -> Vec<u8> {
- self.cstore.metadata_encoding_version().to_vec()
- }
-
pub fn encode_metadata(self) -> EncodedMetadata {
let _prof_timer = self.prof.verbose_generic_activity("generate_crate_metadata");
self.cstore.encode_metadata(self)
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 982c8a3..bfb4c0c 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -54,7 +54,7 @@
/// ADTs with no type arguments.
pub fn is_simple_text(&self) -> bool {
match self.kind() {
- Adt(_, substs) => substs.types().next().is_none(),
+ Adt(_, substs) => substs.non_erasable_generics().next().is_none(),
Ref(_, ty, _) => ty.is_simple_text(),
_ => self.is_simple_ty(),
}
diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
index ebb52d8..5c42625 100644
--- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
@@ -10,7 +10,7 @@
use rustc_data_structures::unhash::UnhashMap;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
-use rustc_hir::definitions::{DefPathHash, DefPathTable};
+use rustc_hir::definitions::DefPathHash;
use rustc_index::vec::{Idx, IndexVec};
use rustc_query_system::dep_graph::DepContext;
use rustc_query_system::query::QueryContext;
@@ -27,7 +27,6 @@
use rustc_span::CachingSourceMapView;
use rustc_span::{BytePos, ExpnData, SourceFile, Span, DUMMY_SP};
use std::collections::hash_map::Entry;
-use std::iter::FromIterator;
use std::mem;
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
@@ -103,12 +102,6 @@
// during the next compilation session.
latest_foreign_def_path_hashes: Lock<UnhashMap<DefPathHash, RawDefId>>,
- // Maps `DefPathHashes` to their corresponding `LocalDefId`s for all
- // local items in the current compilation session. This is only populated
- // when we are in incremental mode and have loaded a pre-existing cache
- // from disk, since this map is only used when deserializing a `DefPathHash`
- // from the incremental cache.
- local_def_path_hash_to_def_id: UnhashMap<DefPathHash, LocalDefId>,
// Caches all lookups of `DefPathHashes`, both for local and foreign
// definitions. A definition from the previous compilation session
// may no longer exist in the current compilation session, so
@@ -168,12 +161,7 @@
impl<'sess> OnDiskCache<'sess> {
/// Creates a new `OnDiskCache` instance from the serialized data in `data`.
- pub fn new(
- sess: &'sess Session,
- data: Vec<u8>,
- start_pos: usize,
- def_path_table: &DefPathTable,
- ) -> Self {
+ pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> Self {
debug_assert!(sess.opts.incremental.is_some());
// Wrap in a scope so we can borrow `data`.
@@ -210,11 +198,6 @@
hygiene_context: Default::default(),
foreign_def_path_hashes: footer.foreign_def_path_hashes,
latest_foreign_def_path_hashes: Default::default(),
- local_def_path_hash_to_def_id: UnhashMap::from_iter(
- def_path_table
- .all_def_path_hashes_and_def_ids(LOCAL_CRATE)
- .map(|(hash, def_id)| (hash, def_id.as_local().unwrap())),
- ),
def_path_hash_to_def_id_cache: Default::default(),
}
}
@@ -236,7 +219,6 @@
hygiene_context: Default::default(),
foreign_def_path_hashes: Default::default(),
latest_foreign_def_path_hashes: Default::default(),
- local_def_path_hash_to_def_id: Default::default(),
def_path_hash_to_def_id_cache: Default::default(),
}
}
@@ -616,7 +598,7 @@
debug!("def_path_hash_to_def_id({:?})", hash);
// Check if the `DefPathHash` corresponds to a definition in the current
// crate
- if let Some(def_id) = self.local_def_path_hash_to_def_id.get(&hash).cloned() {
+ if let Some(def_id) = tcx.definitions.local_def_path_hash_to_def_id(hash) {
let def_id = def_id.to_def_id();
e.insert(Some(def_id));
return Some(def_id);
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 872d12c..3f426b1 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -112,7 +112,7 @@
///////////////////////////////////////////////////////////////////////////
// Relate impls
-fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
+pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::TypeAndMut<'tcx>,
b: ty::TypeAndMut<'tcx>,
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
index d2b1566..bf5f2c0 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
@@ -902,9 +902,13 @@
{
let lt_name = &src[1..ws_pos];
let ty = &src[ws_pos..];
- return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+ if !ty.trim_start().starts_with("mut") {
+ return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+ }
} else if let Some(stripped) = src.strip_prefix('&') {
- return (assignment_rhs_span, format!("&mut {}", stripped));
+ if !stripped.trim_start().starts_with("mut") {
+ return (assignment_rhs_span, format!("&mut {}", stripped));
+ }
}
}
}
diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs
index 99622fb..4e4166d 100644
--- a/compiler/rustc_mir/src/interpret/intrinsics.rs
+++ b/compiler/rustc_mir/src/interpret/intrinsics.rs
@@ -56,8 +56,12 @@
let alloc = type_name::alloc_type_name(tcx, tp_ty);
ConstValue::Slice { data: alloc, start: 0, end: alloc.len() }
}
- sym::needs_drop => ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)),
+ sym::needs_drop => {
+ ensure_monomorphic_enough(tcx, tp_ty)?;
+ ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
+ }
sym::min_align_of | sym::pref_align_of => {
+ // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
let n = match name {
sym::pref_align_of => layout.align.pref.bytes(),
@@ -71,6 +75,7 @@
ConstValue::from_u64(tcx.type_id_hash(tp_ty))
}
sym::variant_count => match tp_ty.kind() {
+ // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
ty::Projection(_)
| ty::Opaque(_, _)
diff --git a/compiler/rustc_mir/src/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs
index 11f8d38..d0c04b5 100644
--- a/compiler/rustc_mir/src/interpret/traits.rs
+++ b/compiler/rustc_mir/src/interpret/traits.rs
@@ -158,6 +158,8 @@
let size = u64::try_from(self.force_bits(size, pointer_size)?).unwrap();
let align = vtable.read_ptr_sized(pointer_size * 2)?.check_init()?;
let align = u64::try_from(self.force_bits(align, pointer_size)?).unwrap();
+ let align = Align::from_bytes(align)
+ .map_err(|e| err_ub_format!("invalid vtable: alignment {}", e))?;
if size >= self.tcx.data_layout.obj_size_bound() {
throw_ub_format!(
@@ -165,6 +167,6 @@
size is bigger than largest supported object"
);
}
- Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
+ Ok((Size::from_bytes(size), align))
}
}
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index ee6ff4d..8b05038 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -32,7 +32,6 @@
let mut just_parsed_doc_comment = false;
let start_pos = self.token_cursor.num_next_calls;
loop {
- debug!("parse_outer_attributes: self.token={:?}", self.token);
let attr = if self.check(&token::Pound) {
let inner_error_reason = if just_parsed_doc_comment {
"an inner attribute is not permitted following an outer doc comment"
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 72fdc78..b37caae 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -366,7 +366,7 @@
let mut snapshot = self.clone();
let path =
Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
- let struct_expr = snapshot.parse_struct_expr(path, AttrVec::new(), false);
+ let struct_expr = snapshot.parse_struct_expr(None, path, AttrVec::new(), false);
let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
return Some(match (struct_expr, block_tail) {
(Ok(expr), Err(mut err)) => {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index a764cf6..c8789ab 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1108,9 +1108,6 @@
self.parse_closure_expr(attrs)
} else if self.check(&token::OpenDelim(token::Bracket)) {
self.parse_array_or_repeat_expr(attrs)
- } else if self.eat_lt() {
- let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
- Ok(self.mk_expr(lo.to(path.span), ExprKind::Path(Some(qself), path), attrs))
} else if self.check_path() {
self.parse_path_start_expr(attrs)
} else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
@@ -1262,12 +1259,20 @@
}
fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
- let path = self.parse_path(PathStyle::Expr)?;
+ let (qself, path) = if self.eat_lt() {
+ let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
+ (Some(qself), path)
+ } else {
+ (None, self.parse_path(PathStyle::Expr)?)
+ };
let lo = path.span;
// `!`, as an operator, is prefix, so we know this isn't that.
let (hi, kind) = if self.eat(&token::Not) {
// MACRO INVOCATION expression
+ if qself.is_some() {
+ self.struct_span_err(path.span, "macros cannot use qualified paths").emit();
+ }
let mac = MacCall {
path,
args: self.parse_mac_args()?,
@@ -1275,13 +1280,16 @@
};
(self.prev_token.span, ExprKind::MacCall(mac))
} else if self.check(&token::OpenDelim(token::Brace)) {
- if let Some(expr) = self.maybe_parse_struct_expr(&path, &attrs) {
+ if let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path, &attrs) {
+ if qself.is_some() {
+ self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
+ }
return expr;
} else {
- (path.span, ExprKind::Path(None, path))
+ (path.span, ExprKind::Path(qself, path))
}
} else {
- (path.span, ExprKind::Path(None, path))
+ (path.span, ExprKind::Path(qself, path))
};
let expr = self.mk_expr(lo.to(hi), kind, attrs);
@@ -2247,6 +2255,7 @@
fn maybe_parse_struct_expr(
&mut self,
+ qself: Option<&ast::QSelf>,
path: &ast::Path,
attrs: &AttrVec,
) -> Option<PResult<'a, P<Expr>>> {
@@ -2255,7 +2264,7 @@
if let Err(err) = self.expect(&token::OpenDelim(token::Brace)) {
return Some(Err(err));
}
- let expr = self.parse_struct_expr(path.clone(), attrs.clone(), true);
+ let expr = self.parse_struct_expr(qself.cloned(), path.clone(), attrs.clone(), true);
if let (Ok(expr), false) = (&expr, struct_allowed) {
// This is a struct literal, but we don't can't accept them here.
self.error_struct_lit_not_allowed_here(path.span, expr.span);
@@ -2278,6 +2287,7 @@
/// Precondition: already parsed the '{'.
pub(super) fn parse_struct_expr(
&mut self,
+ qself: Option<ast::QSelf>,
pth: ast::Path,
attrs: AttrVec,
recover: bool,
@@ -2375,7 +2385,7 @@
let expr = if recover_async {
ExprKind::Err
} else {
- ExprKind::Struct(P(ast::StructExpr { path: pth, fields, rest: base }))
+ ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
};
Ok(self.mk_expr(span, expr, attrs))
}
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 0abefbd..4181222 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -859,7 +859,8 @@
/// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
if qself.is_some() {
- return self.error_qpath_before_pat(&path, "{");
+ // Feature gate the use of qualified paths in patterns
+ self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
}
self.bump();
let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
@@ -869,27 +870,17 @@
(vec![], true)
});
self.bump();
- Ok(PatKind::Struct(path, fields, etc))
+ Ok(PatKind::Struct(qself, path, fields, etc))
}
/// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
- if qself.is_some() {
- return self.error_qpath_before_pat(&path, "(");
- }
let (fields, _) =
self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?;
- Ok(PatKind::TupleStruct(path, fields))
- }
-
- /// Error when there's a qualified path, e.g. `<Foo as Bar>::Baz`
- /// as the path of e.g., a tuple or record struct pattern.
- fn error_qpath_before_pat(&mut self, path: &Path, token: &str) -> PResult<'a, PatKind> {
- let msg = &format!("unexpected `{}` after qualified path", token);
- let mut err = self.struct_span_err(self.token.span, msg);
- err.span_label(self.token.span, msg);
- err.span_label(path.span, "the qualified path");
- Err(err)
+ if qself.is_some() {
+ self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
+ }
+ Ok(PatKind::TupleStruct(qself, path, fields))
}
/// Parses the fields of a struct-like pattern.
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 4f0dcfe..9ef3f61 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -117,7 +117,7 @@
}
let expr = if this.eat(&token::OpenDelim(token::Brace)) {
- this.parse_struct_expr(path, AttrVec::new(), true)?
+ this.parse_struct_expr(None, path, AttrVec::new(), true)?
} else {
let hi = this.prev_token.span;
this.mk_expr(lo.to(hi), ExprKind::Path(None, path), AttrVec::new())
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index e64f12e..5a79a9c 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -156,6 +156,7 @@
let leaf = leaf.subst(tcx, ct.substs);
self.visit_const(leaf)
}
+ ACNode::Cast(_, _, ty) => self.visit_ty(ty),
ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 408d9b2..a21d819 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1613,10 +1613,10 @@
self.r.record_partial_res(pat.id, PartialRes::new(res));
self.r.record_pat_span(pat.id, pat.span);
}
- PatKind::TupleStruct(ref path, ref sub_patterns) => {
+ PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => {
self.smart_resolve_path(
pat.id,
- None,
+ qself.as_ref(),
path,
PathSource::TupleStruct(
pat.span,
@@ -1627,8 +1627,8 @@
PatKind::Path(ref qself, ref path) => {
self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
}
- PatKind::Struct(ref path, ..) => {
- self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
+ PatKind::Struct(ref qself, ref path, ..) => {
+ self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Struct);
}
PatKind::Or(ref ps) => {
// Add a new set of bindings to the stack. `Or` here records that when a
@@ -2288,7 +2288,7 @@
}
ExprKind::Struct(ref se) => {
- self.smart_resolve_path(expr.id, None, &se.path, PathSource::Struct);
+ self.smart_resolve_path(expr.id, se.qself.as_ref(), &se.path, PathSource::Struct);
visit::walk_expr(self, expr);
}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index fd9b897..6d5531d 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1198,7 +1198,7 @@
session: &'a Session,
krate: &Crate,
crate_name: &str,
- metadata_loader: &'a MetadataLoaderDyn,
+ metadata_loader: Box<MetadataLoaderDyn>,
arenas: &'a ResolverArenas<'a>,
) -> Resolver<'a> {
let root_local_def_id = LocalDefId { local_def_index: CRATE_DEF_INDEX };
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 5752258..2b547f8 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2417,6 +2417,7 @@
/// we have an opt-in scheme here, so one is hopefully forced to think about
/// how the hash should be calculated when adding a new command-line argument.
crate mod dep_tracking {
+ use super::LdImpl;
use super::{
CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto,
LtoCli, OptLevel, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath,
@@ -2497,6 +2498,7 @@
SymbolManglingVersion,
SourceFileHashAlgorithm,
TrimmedDefPaths,
+ Option<LdImpl>,
);
impl<T1, T2> DepTrackingHash for (T1, T2)
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 58a53b3..1946bfd 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -370,6 +370,7 @@
pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
pub const parse_split_debuginfo: &str =
"one of supported split-debuginfo modes (`off`, `packed`, or `unpacked`)";
+ pub const parse_gcc_ld: &str = "one of: no value, `lld`";
}
mod parse {
@@ -864,6 +865,15 @@
}
true
}
+
+ crate fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
+ match v {
+ None => *slot = None,
+ Some("lld") => *slot = Some(LdImpl::Lld),
+ _ => return false,
+ }
+ true
+ }
}
options! {
@@ -1067,6 +1077,7 @@
"set the optimization fuel quota for a crate"),
function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
"whether each function should go in its own section"),
+ gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
"use dark-themed colors in graphviz output (default: no)"),
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
@@ -1321,3 +1332,8 @@
Command,
Reactor,
}
+
+#[derive(Clone, Copy, Hash)]
+pub enum LdImpl {
+ Lld,
+}
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 6ee7537..bb4ac22 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -1,7 +1,7 @@
use crate::crate_disambiguator::CrateDisambiguator;
use crate::HashStableContext;
use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
@@ -308,13 +308,49 @@
rustc_data_structures::define_id_collections!(LocalDefIdMap, LocalDefIdSet, LocalDefId);
impl<CTX: HashStableContext> HashStable<CTX> for DefId {
+ #[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
- hcx.hash_def_id(*self, hasher)
+ self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
+ }
+}
+
+impl<CTX: HashStableContext> HashStable<CTX> for LocalDefId {
+ #[inline]
+ fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
+ self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
}
}
impl<CTX: HashStableContext> HashStable<CTX> for CrateNum {
+ #[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
- hcx.hash_crate_num(*self, hasher)
+ self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
+ }
+}
+
+impl<CTX: HashStableContext> ToStableHashKey<CTX> for DefId {
+ type KeyType = DefPathHash;
+
+ #[inline]
+ fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
+ hcx.def_path_hash(*self)
+ }
+}
+
+impl<CTX: HashStableContext> ToStableHashKey<CTX> for LocalDefId {
+ type KeyType = DefPathHash;
+
+ #[inline]
+ fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
+ hcx.def_path_hash(self.to_def_id())
+ }
+}
+
+impl<CTX: HashStableContext> ToStableHashKey<CTX> for CrateNum {
+ type KeyType = DefPathHash;
+
+ #[inline]
+ fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
+ self.as_def_id().to_stable_hash_key(hcx)
}
}
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 8f3b8cc..23efaf6 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -29,7 +29,7 @@
use crate::SESSION_GLOBALS;
use crate::{BytePos, CachingSourceMapView, ExpnIdCache, SourceFile, Span, DUMMY_SP};
-use crate::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use crate::def_id::{CrateNum, DefId, DefPathHash, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -1330,9 +1330,12 @@
}
impl<'a> crate::HashStableContext for DummyHashStableContext<'a> {
- fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
- def_id.krate.as_u32().hash_stable(self, hasher);
- def_id.index.as_u32().hash_stable(self, hasher);
+ #[inline]
+ fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
+ DefPathHash(Fingerprint::new(
+ def_id.krate.as_u32().into(),
+ def_id.index.as_u32().into(),
+ ))
}
fn expn_id_cache() -> &'static LocalKey<ExpnIdCache> {
@@ -1345,9 +1348,6 @@
&CACHE
}
- fn hash_crate_num(&mut self, krate: CrateNum, hasher: &mut StableHasher) {
- krate.as_u32().hash_stable(self, hasher);
- }
fn hash_spans(&self) -> bool {
true
}
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 9cf68cb..b4fe7c9 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -40,7 +40,7 @@
use hygiene::Transparency;
pub use hygiene::{DesugaringKind, ExpnData, ExpnId, ExpnKind, ForLoopLoc, MacroKind};
pub mod def_id;
-use def_id::{CrateNum, DefId, LOCAL_CRATE};
+use def_id::{CrateNum, DefId, DefPathHash, LOCAL_CRATE};
pub mod lev_distance;
mod span_encoding;
pub use span_encoding::{Span, DUMMY_SP};
@@ -1928,13 +1928,12 @@
/// This is a hack to allow using the [`HashStable_Generic`] derive macro
/// instead of implementing everything in rustc_middle.
pub trait HashStableContext {
- fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher);
+ fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
/// Obtains a cache for storing the `Fingerprint` of an `ExpnId`.
/// This method allows us to have multiple `HashStableContext` implementations
/// that hash things in a different way, without the results of one polluting
/// the cache of the other.
fn expn_id_cache() -> &'static LocalKey<ExpnIdCache>;
- fn hash_crate_num(&mut self, _: CrateNum, hasher: &mut StableHasher);
fn hash_spans(&self) -> bool;
fn span_data_to_lines_and_cols(
&mut self,
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 0dadd41..1d45cd1 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -407,7 +407,7 @@
}
fn span_to_string(&self, sp: Span, prefer_local: bool) -> String {
- if self.files.borrow().source_files.is_empty() && sp.is_dummy() {
+ if self.files.borrow().source_files.is_empty() || sp.is_dummy() {
return "no-location".to_string();
}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 31b425f..fb37c5e 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -756,6 +756,7 @@
modifiers,
module,
module_path,
+ more_qualified_paths,
more_struct_aliases,
movbe_target_feature,
move_ref_pattern,
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 8961cda..b1a9388 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -97,6 +97,16 @@
ControlFlow::CONTINUE
}
+ Node::Cast(_, _, ty) => {
+ let ty = ty.subst(tcx, ct.substs);
+ if ty.has_infer_types_or_consts() {
+ failure_kind = FailureKind::MentionsInfer;
+ } else if ty.has_param_types_or_consts() {
+ failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
+ }
+
+ ControlFlow::CONTINUE
+ }
Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}
@@ -304,6 +314,9 @@
self.nodes[func].used = true;
nodes.iter().for_each(|&n| self.nodes[n].used = true);
}
+ Node::Cast(_, operand, _) => {
+ self.nodes[operand].used = true;
+ }
}
// Nodes start as unused.
@@ -408,11 +421,19 @@
self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span);
Ok(())
}
+ Rvalue::Cast(cast_kind, ref operand, ty) => {
+ let operand = self.operand_to_node(span, operand)?;
+ self.locals[local] =
+ self.add_node(Node::Cast(cast_kind, operand, ty), span);
+ Ok(())
+ }
_ => self.error(Some(span), "unsupported rvalue")?,
}
}
// These are not actually relevant for us here, so we can ignore them.
- StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => Ok(()),
+ StatementKind::AscribeUserType(..)
+ | StatementKind::StorageLive(_)
+ | StatementKind::StorageDead(_) => Ok(()),
_ => self.error(Some(stmt.source_info.span), "unsupported statement")?,
}
}
@@ -594,6 +615,7 @@
recurse(tcx, ct.subtree(func), f)?;
args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
}
+ Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f),
}
}
@@ -676,6 +698,11 @@
&& iter::zip(a_args, b_args)
.all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
}
+ (Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty))
+ if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) =>
+ {
+ try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
+ }
_ => false,
}
}
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index d5e1bd3..7ebef7f 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -838,6 +838,7 @@
let leaf = leaf.subst(self.tcx, ct.substs);
self.visit_const(leaf)
}
+ Node::Cast(_, _, ty) => self.visit_ty(ty),
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}
@@ -859,6 +860,7 @@
let leaf = leaf.subst(self.tcx, ct.substs);
self.visit_const(leaf)
}
+ Node::Cast(_, _, ty) => self.visit_ty(ty),
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
ControlFlow::CONTINUE
}
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 29a87b1..abe5d69 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -9,7 +9,7 @@
use rustc_middle::hir::map::Map;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder};
use rustc_span::symbol::Ident;
use rustc_span::{Span, DUMMY_SP};
@@ -749,6 +749,40 @@
span: Span,
item_ident: Ident,
) -> Ty<'_> {
+ // Attempts to make the type nameable by turning FnDefs into FnPtrs.
+ struct MakeNameable<'tcx> {
+ success: bool,
+ tcx: TyCtxt<'tcx>,
+ }
+
+ impl<'tcx> MakeNameable<'tcx> {
+ fn new(tcx: TyCtxt<'tcx>) -> Self {
+ MakeNameable { success: true, tcx }
+ }
+ }
+
+ impl TypeFolder<'tcx> for MakeNameable<'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+
+ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+ if !self.success {
+ return ty;
+ }
+
+ match ty.kind() {
+ ty::FnDef(def_id, _) => self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id)),
+ // FIXME: non-capturing closures should also suggest a function pointer
+ ty::Closure(..) | ty::Generator(..) => {
+ self.success = false;
+ ty
+ }
+ _ => ty.super_fold_with(self),
+ }
+ }
+ }
+
let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id);
// If this came from a free `const` or `static mut?` item,
@@ -760,24 +794,47 @@
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
// We are typeck and have the real type, so remove that and suggest the actual type.
err.suggestions.clear();
- err.span_suggestion(
- span,
- "provide a type for the item",
- format!("{}: {}", item_ident, ty),
- Applicability::MachineApplicable,
- )
- .emit_unless(ty.references_error());
+
+ // Suggesting unnameable types won't help.
+ let mut mk_nameable = MakeNameable::new(tcx);
+ let ty = mk_nameable.fold_ty(ty);
+ let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
+ if let Some(sugg_ty) = sugg_ty {
+ err.span_suggestion(
+ span,
+ "provide a type for the item",
+ format!("{}: {}", item_ident, sugg_ty),
+ Applicability::MachineApplicable,
+ );
+ } else {
+ err.span_note(
+ tcx.hir().body(body_id).value.span,
+ &format!("however, the inferred type `{}` cannot be named", ty.to_string()),
+ );
+ }
+
+ err.emit_unless(ty.references_error());
}
None => {
let mut diag = bad_placeholder_type(tcx, vec![span]);
if !ty.references_error() {
- diag.span_suggestion(
- span,
- "replace with the correct type",
- ty.to_string(),
- Applicability::MaybeIncorrect,
- );
+ let mut mk_nameable = MakeNameable::new(tcx);
+ let ty = mk_nameable.fold_ty(ty);
+ let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
+ if let Some(sugg_ty) = sugg_ty {
+ diag.span_suggestion(
+ span,
+ "replace with the correct type",
+ sugg_ty.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ diag.span_note(
+ tcx.hir().body(body_id).value.span,
+ &format!("however, the inferred type `{}` cannot be named", ty.to_string()),
+ );
+ }
}
diag.emit();
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index eb91af8..13b4244 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1209,7 +1209,7 @@
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
impl<T> From<T> for Box<T> {
- /// Converts a generic type `T` into a `Box<T>`
+ /// Converts a `T` into a `Box<T>`
///
/// The conversion allocates on the heap and moves `t`
/// from the stack into it.
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index 2da3d6a..80d0890 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -1,6 +1,5 @@
//! impl char {}
-use crate::intrinsics::likely;
use crate::slice;
use crate::str::from_utf8_unchecked_mut;
use crate::unicode::printable::is_printable;
@@ -332,21 +331,16 @@
#[inline]
pub fn to_digit(self, radix: u32) -> Option<u32> {
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
- // the code is split up here to improve execution speed for cases where
- // the `radix` is constant and 10 or smaller
- let val = if likely(radix <= 10) {
- // If not a digit, a number greater than radix will be created.
- (self as u32).wrapping_sub('0' as u32)
- } else {
- match self {
- '0'..='9' => self as u32 - '0' as u32,
- 'a'..='z' => self as u32 - 'a' as u32 + 10,
- 'A'..='Z' => self as u32 - 'A' as u32 + 10,
- _ => return None,
+ // If not a digit, a number greater than radix will be created.
+ let mut digit = (self as u32).wrapping_sub('0' as u32);
+ if radix > 10 {
+ if digit < 10 {
+ return Some(digit);
}
- };
-
- if val < radix { Some(val) } else { None }
+ // Force the 6th bit to be set to ensure ascii is lower case.
+ digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
+ }
+ (digit < radix).then_some(digit)
}
/// Returns an iterator that yields the hexadecimal Unicode escape of a
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 0034de9..70ab27c 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1742,157 +1742,6 @@
/// Allocate at compile time. Should not be called at runtime.
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
-
- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
- /// and destination must *not* overlap.
- ///
- /// For regions of memory which might overlap, use [`copy`] instead.
- ///
- /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
- /// with the argument order swapped.
- ///
- /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
- ///
- /// # Safety
- ///
- /// Behavior is undefined if any of the following conditions are violated:
- ///
- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
- ///
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
- ///
- /// * Both `src` and `dst` must be properly aligned.
- ///
- /// * The region of memory beginning at `src` with a size of `count *
- /// size_of::<T>()` bytes must *not* overlap with the region of memory
- /// beginning at `dst` with the same size.
- ///
- /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
- /// in the region beginning at `*src` and the region beginning at `*dst` can
- /// [violate memory safety][read-ownership].
- ///
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
- /// `0`, the pointers must be non-null and properly aligned.
- ///
- /// [`read`]: crate::ptr::read
- /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
- /// [valid]: crate::ptr#safety
- ///
- /// # Examples
- ///
- /// Manually implement [`Vec::append`]:
- ///
- /// ```
- /// use std::ptr;
- ///
- /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
- /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
- /// let src_len = src.len();
- /// let dst_len = dst.len();
- ///
- /// // Ensure that `dst` has enough capacity to hold all of `src`.
- /// dst.reserve(src_len);
- ///
- /// unsafe {
- /// // The call to offset is always safe because `Vec` will never
- /// // allocate more than `isize::MAX` bytes.
- /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
- /// let src_ptr = src.as_ptr();
- ///
- /// // Truncate `src` without dropping its contents. We do this first,
- /// // to avoid problems in case something further down panics.
- /// src.set_len(0);
- ///
- /// // The two regions cannot overlap because mutable references do
- /// // not alias, and two different vectors cannot own the same
- /// // memory.
- /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
- ///
- /// // Notify `dst` that it now holds the contents of `src`.
- /// dst.set_len(dst_len + src_len);
- /// }
- /// }
- ///
- /// let mut a = vec!['r'];
- /// let mut b = vec!['u', 's', 't'];
- ///
- /// append(&mut a, &mut b);
- ///
- /// assert_eq!(a, &['r', 'u', 's', 't']);
- /// assert!(b.is_empty());
- /// ```
- ///
- /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
- #[doc(alias = "memcpy")]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
- pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
-
- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
- /// and destination may overlap.
- ///
- /// If the source and destination will *never* overlap,
- /// [`copy_nonoverlapping`] can be used instead.
- ///
- /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
- /// order swapped. Copying takes place as if the bytes were copied from `src`
- /// to a temporary array and then copied from the array to `dst`.
- ///
- /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
- ///
- /// # Safety
- ///
- /// Behavior is undefined if any of the following conditions are violated:
- ///
- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
- ///
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
- ///
- /// * Both `src` and `dst` must be properly aligned.
- ///
- /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
- /// in the region beginning at `*src` and the region beginning at `*dst` can
- /// [violate memory safety][read-ownership].
- ///
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
- /// `0`, the pointers must be non-null and properly aligned.
- ///
- /// [`read`]: crate::ptr::read
- /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
- /// [valid]: crate::ptr#safety
- ///
- /// # Examples
- ///
- /// Efficiently create a Rust vector from an unsafe buffer:
- ///
- /// ```
- /// use std::ptr;
- ///
- /// /// # Safety
- /// ///
- /// /// * `ptr` must be correctly aligned for its type and non-zero.
- /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
- /// /// * Those elements must not be used after calling this function unless `T: Copy`.
- /// # #[allow(dead_code)]
- /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
- /// let mut dst = Vec::with_capacity(elts);
- ///
- /// // SAFETY: Our precondition ensures the source is aligned and valid,
- /// // and `Vec::with_capacity` ensures that we have usable space to write them.
- /// ptr::copy(ptr, dst.as_mut_ptr(), elts);
- ///
- /// // SAFETY: We created it with this much capacity earlier,
- /// // and the previous `copy` has initialized these elements.
- /// dst.set_len(elts);
- /// dst
- /// }
- /// ```
- #[doc(alias = "memmove")]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
- pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
}
// Some functions are defined here because they accidentally got made
@@ -1906,6 +1755,192 @@
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
}
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination must *not* overlap.
+///
+/// For regions of memory which might overlap, use [`copy`] instead.
+///
+/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
+/// with the argument order swapped.
+///
+/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// * The region of memory beginning at `src` with a size of `count *
+/// size_of::<T>()` bytes must *not* overlap with the region of memory
+/// beginning at `dst` with the same size.
+///
+/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-null and properly aligned.
+///
+/// [`read`]: crate::ptr::read
+/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
+/// [valid]: crate::ptr#safety
+///
+/// # Examples
+///
+/// Manually implement [`Vec::append`]:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
+/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
+/// let src_len = src.len();
+/// let dst_len = dst.len();
+///
+/// // Ensure that `dst` has enough capacity to hold all of `src`.
+/// dst.reserve(src_len);
+///
+/// unsafe {
+/// // The call to offset is always safe because `Vec` will never
+/// // allocate more than `isize::MAX` bytes.
+/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
+/// let src_ptr = src.as_ptr();
+///
+/// // Truncate `src` without dropping its contents. We do this first,
+/// // to avoid problems in case something further down panics.
+/// src.set_len(0);
+///
+/// // The two regions cannot overlap because mutable references do
+/// // not alias, and two different vectors cannot own the same
+/// // memory.
+/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
+///
+/// // Notify `dst` that it now holds the contents of `src`.
+/// dst.set_len(dst_len + src_len);
+/// }
+/// }
+///
+/// let mut a = vec!['r'];
+/// let mut b = vec!['u', 's', 't'];
+///
+/// append(&mut a, &mut b);
+///
+/// assert_eq!(a, &['r', 'u', 's', 't']);
+/// assert!(b.is_empty());
+/// ```
+///
+/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
+#[doc(alias = "memcpy")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+#[inline]
+pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+ extern "rust-intrinsic" {
+ #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+ pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ }
+
+ // FIXME: Perform these checks only at run time
+ /*if cfg!(debug_assertions)
+ && !(is_aligned_and_not_null(src)
+ && is_aligned_and_not_null(dst)
+ && is_nonoverlapping(src, dst, count))
+ {
+ // Not panicking to keep codegen impact smaller.
+ abort();
+ }*/
+
+ // SAFETY: the safety contract for `copy_nonoverlapping` must be
+ // upheld by the caller.
+ unsafe { copy_nonoverlapping(src, dst, count) }
+}
+
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination may overlap.
+///
+/// If the source and destination will *never* overlap,
+/// [`copy_nonoverlapping`] can be used instead.
+///
+/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
+/// order swapped. Copying takes place as if the bytes were copied from `src`
+/// to a temporary array and then copied from the array to `dst`.
+///
+/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-null and properly aligned.
+///
+/// [`read`]: crate::ptr::read
+/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
+/// [valid]: crate::ptr#safety
+///
+/// # Examples
+///
+/// Efficiently create a Rust vector from an unsafe buffer:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// # Safety
+/// ///
+/// /// * `ptr` must be correctly aligned for its type and non-zero.
+/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
+/// /// * Those elements must not be used after calling this function unless `T: Copy`.
+/// # #[allow(dead_code)]
+/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
+/// let mut dst = Vec::with_capacity(elts);
+///
+/// // SAFETY: Our precondition ensures the source is aligned and valid,
+/// // and `Vec::with_capacity` ensures that we have usable space to write them.
+/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
+///
+/// // SAFETY: We created it with this much capacity earlier,
+/// // and the previous `copy` has initialized these elements.
+/// dst.set_len(elts);
+/// dst
+/// }
+/// ```
+#[doc(alias = "memmove")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+#[inline]
+pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+ extern "rust-intrinsic" {
+ #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+ fn copy<T>(src: *const T, dst: *mut T, count: usize);
+ }
+
+ // FIXME: Perform these checks only at run time
+ /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
+ // Not panicking to keep codegen impact smaller.
+ abort();
+ }*/
+
+ // SAFETY: the safety contract for `copy` must be upheld by the caller.
+ unsafe { copy(src, dst, count) }
+}
+
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
/// `val`.
///
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 96b924f..11dea40 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -138,7 +138,7 @@
/// A more complex example:
///
/// ```
- /// // The even numbers from zero to ten.
+ /// // The even numbers in the range of zero to nine.
/// let iter = (0..10).filter(|x| x % 2 == 0);
///
/// // We might iterate from zero to ten times. Knowing that it's five
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index d4e4c5b..949ef27 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -65,6 +65,7 @@
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
+#![feature(bool_to_option)]
#![feature(cfg_target_has_atomic)]
#![feature(const_heap)]
#![feature(const_alloc_layout)]
@@ -165,6 +166,7 @@
#![feature(no_niche)] // rust-lang/rust#68303
#![feature(no_coverage)] // rust-lang/rust#84605
#![feature(int_error_matching)]
+#![cfg_attr(bootstrap, feature(target_feature_11))]
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(or_patterns_back_compat)]
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 5bf47c3..c6750c5 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -682,8 +682,7 @@
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub const fn swap<T>(x: &mut T, y: &mut T) {
+pub fn swap<T>(x: &mut T, y: &mut T) {
// SAFETY: the raw pointers have been created from safe mutable references satisfying all the
// constraints on `ptr::swap_nonoverlapping_one`
unsafe {
@@ -813,8 +812,7 @@
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
-pub const fn replace<T>(dest: &mut T, src: T) -> T {
+pub fn replace<T>(dest: &mut T, src: T) -> T {
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
// such that the old value is not duplicated. Nothing is dropped and
// nothing here can panic.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 214d7c8..6a6cee0 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -430,8 +430,7 @@
}
#[inline]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub(crate) const unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
// reinterpretation of values as (chunkable) byte arrays, and the loop in the
// block optimization in `swap_nonoverlapping_bytes` is hard to rewrite back
@@ -564,8 +563,7 @@
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
-pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
+pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
// SAFETY: the caller must guarantee that `dst` is valid to be
// cast to a mutable reference (valid for writes, aligned, initialized),
// and cannot overlap `src` since `dst` must point to a distinct
@@ -871,14 +869,18 @@
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
-pub const unsafe fn write<T>(dst: *mut T, src: T) {
+pub unsafe fn write<T>(dst: *mut T, src: T) {
+ // We are calling the intrinsics directly to avoid function calls in the generated code
+ // as `intrinsics::copy_nonoverlapping` is a wrapper function.
+ extern "rust-intrinsic" {
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ }
+
// SAFETY: the caller must guarantee that `dst` is valid for writes.
// `dst` cannot overlap `src` because the caller has mutable access
// to `dst` while `src` is owned by this function.
unsafe {
copy_nonoverlapping(&src as *const T, dst, 1);
- // We are calling the intrinsic directly to avoid function calls in the generated code.
intrinsics::forget(src);
}
}
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 750279a..a642404 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1002,9 +1002,8 @@
///
/// [`ptr::write`]: crate::ptr::write()
#[stable(feature = "pointer_methods", since = "1.26.0")]
- #[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
#[inline(always)]
- pub const unsafe fn write(self, val: T)
+ pub unsafe fn write(self, val: T)
where
T: Sized,
{
diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs
index c16f540..51eca1e 100644
--- a/library/core/tests/char.rs
+++ b/library/core/tests/char.rs
@@ -67,10 +67,20 @@
assert_eq!('A'.to_digit(16), Some(10));
assert_eq!('b'.to_digit(16), Some(11));
assert_eq!('B'.to_digit(16), Some(11));
+ assert_eq!('A'.to_digit(36), Some(10));
assert_eq!('z'.to_digit(36), Some(35));
assert_eq!('Z'.to_digit(36), Some(35));
- assert_eq!(' '.to_digit(10), None);
+ assert_eq!('['.to_digit(36), None);
+ assert_eq!('`'.to_digit(36), None);
+ assert_eq!('{'.to_digit(36), None);
assert_eq!('$'.to_digit(36), None);
+ assert_eq!('@'.to_digit(16), None);
+ assert_eq!('G'.to_digit(16), None);
+ assert_eq!('g'.to_digit(16), None);
+ assert_eq!(' '.to_digit(10), None);
+ assert_eq!('/'.to_digit(10), None);
+ assert_eq!(':'.to_digit(10), None);
+ assert_eq!(':'.to_digit(11), None);
}
#[test]
diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs
index 152fed8..4acd059 100644
--- a/library/core/tests/const_ptr.rs
+++ b/library/core/tests/const_ptr.rs
@@ -49,53 +49,3 @@
const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}
-
-#[test]
-fn write() {
- use core::ptr;
-
- const fn write_aligned() -> i32 {
- let mut res = 0;
- unsafe {
- ptr::write(&mut res as *mut _, 42);
- }
- res
- }
- const ALIGNED: i32 = write_aligned();
- assert_eq!(ALIGNED, 42);
-
- const fn write_unaligned() -> [u16; 2] {
- let mut two_aligned = [0u16; 2];
- unsafe {
- let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
- ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
- }
- two_aligned
- }
- const UNALIGNED: [u16; 2] = write_unaligned();
- assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
-}
-
-#[test]
-fn mut_ptr_write() {
- const fn aligned() -> i32 {
- let mut res = 0;
- unsafe {
- (&mut res as *mut i32).write(42);
- }
- res
- }
- const ALIGNED: i32 = aligned();
- assert_eq!(ALIGNED, 42);
-
- const fn write_unaligned() -> [u16; 2] {
- let mut two_aligned = [0u16; 2];
- unsafe {
- let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
- unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
- }
- two_aligned
- }
- const UNALIGNED: [u16; 2] = write_unaligned();
- assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
-}
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index ba2b8b6..5b8e837 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -987,13 +987,13 @@
/// Capture a [closure]'s environment by value.
///
/// `move` converts any variables captured by reference or mutable reference
-/// to owned by value variables.
+/// to variables captured by value.
///
/// ```rust
-/// let capture = "hello";
-/// let closure = move || {
-/// println!("rust says {}", capture);
-/// };
+/// let data = vec![1, 2, 3];
+/// let closure = move || println!("captured {:?} by value", data);
+///
+/// // data is no longer available, it is owned by the closure
/// ```
///
/// Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though
@@ -1004,31 +1004,29 @@
/// ```rust
/// fn create_fn() -> impl Fn() {
/// let text = "Fn".to_owned();
-///
/// move || println!("This is a: {}", text)
/// }
///
/// let fn_plain = create_fn();
-///
/// fn_plain();
/// ```
///
/// `move` is often used when [threads] are involved.
///
/// ```rust
-/// let x = 5;
+/// let data = vec![1, 2, 3];
///
/// std::thread::spawn(move || {
-/// println!("captured {} by value", x)
+/// println!("captured {:?} by value", data)
/// }).join().unwrap();
///
-/// // x is no longer available
+/// // data was moved to the spawned thread, so we cannot use it here
/// ```
///
/// `move` is also valid before an async block.
///
/// ```rust
-/// let capture = "hello";
+/// let capture = "hello".to_owned();
/// let block = async move {
/// println!("rust says {} from async block", capture);
/// };
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index e591e07..0b9c9fb 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -19,7 +19,7 @@
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sys::stdio::panic_output;
use crate::sys_common::backtrace::{self, RustBacktrace};
-use crate::sys_common::rwlock::RWLock;
+use crate::sys_common::rwlock::StaticRWLock;
use crate::sys_common::thread_info;
use crate::thread;
@@ -74,7 +74,7 @@
Custom(*mut (dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send)),
}
-static HOOK_LOCK: RWLock = RWLock::new();
+static HOOK_LOCK: StaticRWLock = StaticRWLock::new();
static mut HOOK: Hook = Hook::Default;
/// Registers a custom panic hook, replacing any that was previously registered.
@@ -117,10 +117,10 @@
}
unsafe {
- HOOK_LOCK.write();
+ let guard = HOOK_LOCK.write();
let old_hook = HOOK;
HOOK = Hook::Custom(Box::into_raw(hook));
- HOOK_LOCK.write_unlock();
+ drop(guard);
if let Hook::Custom(ptr) = old_hook {
#[allow(unused_must_use)]
@@ -165,10 +165,10 @@
}
unsafe {
- HOOK_LOCK.write();
+ let guard = HOOK_LOCK.write();
let hook = HOOK;
HOOK = Hook::Default;
- HOOK_LOCK.write_unlock();
+ drop(guard);
match hook {
Hook::Default => Box::new(default_hook),
@@ -608,7 +608,7 @@
unsafe {
let mut info = PanicInfo::internal_constructor(message, location);
- HOOK_LOCK.read();
+ let _guard = HOOK_LOCK.read();
match HOOK {
// Some platforms (like wasm) know that printing to stderr won't ever actually
// print anything, and if that's the case we can skip the default
@@ -626,7 +626,6 @@
(*ptr)(&info);
}
};
- HOOK_LOCK.read_unlock();
}
if panics > 1 {
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 9d521ab..0d00f74 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -3,9 +3,7 @@
use crate::cell::UnsafeCell;
use crate::fmt;
-use crate::mem;
use crate::ops::{Deref, DerefMut};
-use crate::ptr;
use crate::sync::{poison, LockResult, TryLockError, TryLockResult};
use crate::sys_common::rwlock as sys;
@@ -66,7 +64,7 @@
/// [`Mutex`]: super::Mutex
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RwLock<T: ?Sized> {
- inner: Box<sys::RWLock>,
+ inner: sys::MovableRWLock,
poison: poison::Flag,
data: UnsafeCell<T>,
}
@@ -130,7 +128,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(t: T) -> RwLock<T> {
RwLock {
- inner: box sys::RWLock::new(),
+ inner: sys::MovableRWLock::new(),
poison: poison::Flag::new(),
data: UnsafeCell::new(t),
}
@@ -376,24 +374,8 @@
where
T: Sized,
{
- // We know statically that there are no outstanding references to
- // `self` so there's no need to lock the inner lock.
- //
- // To get the inner value, we'd like to call `data.into_inner()`,
- // but because `RwLock` impl-s `Drop`, we can't move out of it, so
- // we'll have to destructure it manually instead.
- unsafe {
- // Like `let RwLock { inner, poison, data } = self`.
- let (inner, poison, data) = {
- let RwLock { ref inner, ref poison, ref data } = self;
- (ptr::read(inner), ptr::read(poison), ptr::read(data))
- };
- mem::forget(self);
- inner.destroy(); // Keep in sync with the `Drop` impl.
- drop(inner);
-
- poison::map_result(poison.borrow(), |_| data.into_inner())
- }
+ let data = self.data.into_inner();
+ poison::map_result(self.poison.borrow(), |_| data)
}
/// Returns a mutable reference to the underlying data.
@@ -425,14 +407,6 @@
}
#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock<T> {
- fn drop(&mut self) {
- // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
- unsafe { self.inner.destroy() }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_struct("RwLock");
diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs
index 06442e9..d205818 100644
--- a/library/std/src/sys/hermit/rwlock.rs
+++ b/library/std/src/sys/hermit/rwlock.rs
@@ -8,6 +8,8 @@
state: UnsafeCell<State>,
}
+pub type MovableRWLock = Box<RWLock>;
+
enum State {
Unlocked,
Reading(usize),
diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs
index 0c96e3f..2d038b5 100644
--- a/library/std/src/sys/sgx/rwlock.rs
+++ b/library/std/src/sys/sgx/rwlock.rs
@@ -13,6 +13,8 @@
writer: SpinMutex<WaitVariable<bool>>,
}
+pub type MovableRWLock = Box<RWLock>;
+
// Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below)
//
// # Safety
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index bbc4691..41ca976 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -20,8 +20,7 @@
use crate::sys::cvt;
use crate::sys::fd;
use crate::sys::memchr;
-use crate::sys::rwlock::{RWLockReadGuard, StaticRWLock};
-use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
+use crate::sys_common::rwlock::{StaticRWLock, StaticRWLockReadGuard};
use crate::vec;
use libc::{c_char, c_int, c_void};
@@ -490,8 +489,8 @@
static ENV_LOCK: StaticRWLock = StaticRWLock::new();
-pub fn env_read_lock() -> RWLockReadGuard {
- ENV_LOCK.read_with_guard()
+pub fn env_read_lock() -> StaticRWLockReadGuard {
+ ENV_LOCK.read()
}
/// Returns a vector of (variable, value) byte-vector pairs for all the
@@ -551,7 +550,7 @@
let v = CString::new(v.as_bytes())?;
unsafe {
- let _guard = ENV_LOCK.write_with_guard();
+ let _guard = ENV_LOCK.write();
cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
}
}
@@ -560,7 +559,7 @@
let nbuf = CString::new(n.as_bytes())?;
unsafe {
- let _guard = ENV_LOCK.write_with_guard();
+ let _guard = ENV_LOCK.write();
cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
}
}
diff --git a/library/std/src/sys/unix/rwlock.rs b/library/std/src/sys/unix/rwlock.rs
index d97d9d7..b1faf12 100644
--- a/library/std/src/sys/unix/rwlock.rs
+++ b/library/std/src/sys/unix/rwlock.rs
@@ -7,6 +7,8 @@
num_readers: AtomicUsize,
}
+pub type MovableRWLock = Box<RWLock>;
+
unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}
@@ -139,55 +141,3 @@
}
}
}
-
-pub struct StaticRWLock(RWLock);
-
-impl StaticRWLock {
- pub const fn new() -> StaticRWLock {
- StaticRWLock(RWLock::new())
- }
-
- /// Acquires shared access to the underlying lock, blocking the current
- /// thread to do so.
- ///
- /// The lock is automatically unlocked when the returned guard is dropped.
- #[inline]
- pub fn read_with_guard(&'static self) -> RWLockReadGuard {
- // SAFETY: All methods require static references, therefore self
- // cannot be moved between invocations.
- unsafe {
- self.0.read();
- }
- RWLockReadGuard(&self.0)
- }
-
- /// Acquires write access to the underlying lock, blocking the current thread
- /// to do so.
- ///
- /// The lock is automatically unlocked when the returned guard is dropped.
- #[inline]
- pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
- // SAFETY: All methods require static references, therefore self
- // cannot be moved between invocations.
- unsafe {
- self.0.write();
- }
- RWLockWriteGuard(&self.0)
- }
-}
-
-pub struct RWLockReadGuard(&'static RWLock);
-
-impl Drop for RWLockReadGuard {
- fn drop(&mut self) {
- unsafe { self.0.read_unlock() }
- }
-}
-
-pub struct RWLockWriteGuard(&'static RWLock);
-
-impl Drop for RWLockWriteGuard {
- fn drop(&mut self) {
- unsafe { self.0.write_unlock() }
- }
-}
diff --git a/library/std/src/sys/unsupported/rwlock.rs b/library/std/src/sys/unsupported/rwlock.rs
index 6982b2b..8438ade 100644
--- a/library/std/src/sys/unsupported/rwlock.rs
+++ b/library/std/src/sys/unsupported/rwlock.rs
@@ -5,6 +5,8 @@
mode: Cell<isize>,
}
+pub type MovableRWLock = RWLock;
+
unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {} // no threads on this platform
diff --git a/library/std/src/sys/wasm/atomics/rwlock.rs b/library/std/src/sys/wasm/atomics/rwlock.rs
index 06442e9..64eaa2f 100644
--- a/library/std/src/sys/wasm/atomics/rwlock.rs
+++ b/library/std/src/sys/wasm/atomics/rwlock.rs
@@ -8,6 +8,8 @@
state: UnsafeCell<State>,
}
+pub type MovableRWLock = RWLock;
+
enum State {
Unlocked,
Reading(usize),
diff --git a/library/std/src/sys/windows/rwlock.rs b/library/std/src/sys/windows/rwlock.rs
index a769326..b7a5b1e 100644
--- a/library/std/src/sys/windows/rwlock.rs
+++ b/library/std/src/sys/windows/rwlock.rs
@@ -5,6 +5,8 @@
inner: UnsafeCell<c::SRWLOCK>,
}
+pub type MovableRWLock = RWLock;
+
unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
index 3705d64..07ec20f 100644
--- a/library/std/src/sys_common/rwlock.rs
+++ b/library/std/src/sys_common/rwlock.rs
@@ -1,63 +1,112 @@
use crate::sys::rwlock as imp;
-/// An OS-based reader-writer lock.
+/// An OS-based reader-writer lock, meant for use in static variables.
///
-/// This structure is entirely unsafe and serves as the lowest layer of a
-/// cross-platform binding of system rwlocks. It is recommended to use the
-/// safer types at the top level of this crate instead of this type.
-pub struct RWLock(imp::RWLock);
+/// This rwlock does not implement poisoning.
+///
+/// This rwlock has a const constructor ([`StaticRWLock::new`]), does not
+/// implement `Drop` to cleanup resources.
+pub struct StaticRWLock(imp::RWLock);
-impl RWLock {
- /// Creates a new reader-writer lock for use.
- ///
- /// Behavior is undefined if the reader-writer lock is moved after it is
- /// first used with any of the functions below.
- pub const fn new() -> RWLock {
- RWLock(imp::RWLock::new())
+impl StaticRWLock {
+ /// Creates a new rwlock for use.
+ pub const fn new() -> Self {
+ Self(imp::RWLock::new())
}
/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
///
- /// Behavior is undefined if the rwlock has been moved between this and any
- /// previous method call.
+ /// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
- pub unsafe fn read(&self) {
- self.0.read()
+ pub fn read(&'static self) -> StaticRWLockReadGuard {
+ unsafe { self.0.read() };
+ StaticRWLockReadGuard(&self.0)
+ }
+
+ /// Acquires write access to the underlying lock, blocking the current thread
+ /// to do so.
+ ///
+ /// The lock is automatically unlocked when the returned guard is dropped.
+ #[inline]
+ pub fn write(&'static self) -> StaticRWLockWriteGuard {
+ unsafe { self.0.write() };
+ StaticRWLockWriteGuard(&self.0)
+ }
+}
+
+#[must_use]
+pub struct StaticRWLockReadGuard(&'static imp::RWLock);
+
+impl Drop for StaticRWLockReadGuard {
+ #[inline]
+ fn drop(&mut self) {
+ unsafe {
+ self.0.read_unlock();
+ }
+ }
+}
+
+#[must_use]
+pub struct StaticRWLockWriteGuard(&'static imp::RWLock);
+
+impl Drop for StaticRWLockWriteGuard {
+ #[inline]
+ fn drop(&mut self) {
+ unsafe {
+ self.0.write_unlock();
+ }
+ }
+}
+
+/// An OS-based reader-writer lock.
+///
+/// This rwlock does *not* have a const constructor, cleans up its resources in
+/// its `Drop` implementation and may safely be moved (when not borrowed).
+///
+/// This rwlock does not implement poisoning.
+///
+/// This is either a wrapper around `Box<imp::RWLock>` or `imp::RWLock`,
+/// depending on the platform. It is boxed on platforms where `imp::RWLock` may
+/// not be moved.
+pub struct MovableRWLock(imp::MovableRWLock);
+
+impl MovableRWLock {
+ /// Creates a new reader-writer lock for use.
+ pub fn new() -> Self {
+ Self(imp::MovableRWLock::from(imp::RWLock::new()))
+ }
+
+ /// Acquires shared access to the underlying lock, blocking the current
+ /// thread to do so.
+ #[inline]
+ pub fn read(&self) {
+ unsafe { self.0.read() }
}
/// Attempts to acquire shared access to this lock, returning whether it
/// succeeded or not.
///
/// This function does not block the current thread.
- ///
- /// Behavior is undefined if the rwlock has been moved between this and any
- /// previous method call.
#[inline]
- pub unsafe fn try_read(&self) -> bool {
- self.0.try_read()
+ pub fn try_read(&self) -> bool {
+ unsafe { self.0.try_read() }
}
/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
- ///
- /// Behavior is undefined if the rwlock has been moved between this and any
- /// previous method call.
#[inline]
- pub unsafe fn write(&self) {
- self.0.write()
+ pub fn write(&self) {
+ unsafe { self.0.write() }
}
/// Attempts to acquire exclusive access to this lock, returning whether it
/// succeeded or not.
///
/// This function does not block the current thread.
- ///
- /// Behavior is undefined if the rwlock has been moved between this and any
- /// previous method call.
#[inline]
- pub unsafe fn try_write(&self) -> bool {
- self.0.try_write()
+ pub fn try_write(&self) -> bool {
+ unsafe { self.0.try_write() }
}
/// Unlocks previously acquired shared access to this lock.
@@ -76,13 +125,10 @@
pub unsafe fn write_unlock(&self) {
self.0.write_unlock()
}
+}
- /// Destroys OS-related resources with this RWLock.
- ///
- /// Behavior is undefined if there are any currently active users of this
- /// lock.
- #[inline]
- pub unsafe fn destroy(&self) {
- self.0.destroy()
+impl Drop for MovableRWLock {
+ fn drop(&mut self) {
+ unsafe { self.0.destroy() };
}
}
diff --git a/library/stdarch b/library/stdarch
index 37d6e18..1e05dff 160000
--- a/library/stdarch
+++ b/library/stdarch
@@ -1 +1 @@
-Subproject commit 37d6e1886369ea0176356286dc7fbd42ee5aa79c
+Subproject commit 1e05dffbeeb80ba61bf59cc63b222d538d7825ed
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index cba17c8..e4396d5 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -41,7 +41,12 @@
cmd.arg(arg);
}
if env::var_os("RUSTDOC_FUSE_LD_LLD").is_some() {
- cmd.arg("-Clink-args=-fuse-ld=lld");
+ cmd.arg("-Clink-arg=-fuse-ld=lld");
+ if cfg!(windows) {
+ cmd.arg("-Clink-arg=-Wl,/threads:1");
+ } else {
+ cmd.arg("-Clink-arg=-Wl,--threads=1");
+ }
}
// Needed to be able to run all rustdoc tests.
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 06f8bf8..bc499fd 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1142,6 +1142,7 @@
}
if self.is_fuse_ld_lld(compiler.host) {
cargo.env("RUSTC_HOST_FUSE_LD_LLD", "1");
+ cargo.env("RUSTDOC_FUSE_LD_LLD", "1");
}
if let Some(target_linker) = self.linker(target) {
@@ -1151,6 +1152,9 @@
if self.is_fuse_ld_lld(target) {
rustflags.arg("-Clink-args=-fuse-ld=lld");
}
+ self.lld_flags(target).for_each(|flag| {
+ rustdocflags.arg(&flag);
+ });
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index ed311e2..112a6ea 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1108,6 +1108,13 @@
let src_exe = exe("lld", target_compiler.host);
let dst_exe = exe("rust-lld", target_compiler.host);
builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
+ // for `-Z gcc-ld=lld`
+ let gcc_ld_dir = libdir_bin.join("gcc-ld");
+ t!(fs::create_dir(&gcc_ld_dir));
+ builder.copy(
+ &lld_install.join("bin").join(&src_exe),
+ &gcc_ld_dir.join(exe("ld", target_compiler.host)),
+ );
}
// Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index aee3c83..71ed0af 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -402,6 +402,10 @@
if builder.config.lld_enabled {
let exe = exe("rust-lld", compiler.host);
builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
+ // for `-Z gcc-ld=lld`
+ let gcc_lld_dir = dst_dir.join("gcc-ld");
+ t!(fs::create_dir(&gcc_lld_dir));
+ builder.copy(&src_dir.join(&exe), &gcc_lld_dir.join(&exe));
}
// Copy over llvm-dwp if it's there
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 21c7dd1..347236c 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -923,6 +923,21 @@
self.config.use_lld && !target.contains("msvc")
}
+ fn lld_flags(&self, target: TargetSelection) -> impl Iterator<Item = String> {
+ let mut options = [None, None];
+
+ if self.config.use_lld {
+ if self.is_fuse_ld_lld(target) {
+ options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string());
+ }
+
+ let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
+ options[1] = Some(format!("-Clink-arg=-Wl,{}", threads));
+ }
+
+ std::array::IntoIter::new(options).flatten()
+ }
+
/// Returns if this target should statically link the C runtime, if specified
fn crt_static(&self, target: TargetSelection) -> Option<bool> {
if target.contains("pc-windows-msvc") {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index cc7c143..fe4666e 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1131,19 +1131,6 @@
compare_mode: Option<&'static str>,
}
-impl Compiletest {
- fn add_lld_flags(builder: &Builder<'_>, target: TargetSelection, flags: &mut Vec<String>) {
- if builder.config.use_lld {
- if builder.is_fuse_ld_lld(target) {
- flags.push("-Clink-arg=-fuse-ld=lld".to_string());
- }
-
- let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
- flags.push(format!("-Clink-arg=-Wl,{}", threads));
- }
- }
-}
-
impl Step for Compiletest {
type Output = ();
@@ -1280,7 +1267,6 @@
}
}
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
- flags.push("-Zunstable-options".to_string());
flags.push(builder.config.cmd.rustc_args().join(" "));
if let Some(linker) = builder.linker(target) {
@@ -1289,12 +1275,12 @@
let mut hostflags = flags.clone();
hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
- Self::add_lld_flags(builder, compiler.host, &mut hostflags);
+ hostflags.extend(builder.lld_flags(compiler.host));
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
let mut targetflags = flags;
targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
- Self::add_lld_flags(builder, target, &mut targetflags);
+ targetflags.extend(builder.lld_flags(target));
cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
cmd.arg("--docck-python").arg(builder.python());
@@ -1517,6 +1503,8 @@
cmd.env("BOOTSTRAP_CARGO", &builder.initial_cargo);
+ cmd.arg("--channel").arg(&builder.config.channel);
+
builder.ci_env.force_coloring_in_ci(&mut cmd);
builder.info(&format!(
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index c2ff62e..3a47076 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -235,6 +235,7 @@
--env TOOLSTATE_REPO_ACCESS_TOKEN \
--env TOOLSTATE_REPO \
--env TOOLSTATE_PUBLISH \
+ --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \
--env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \
--init \
--rm \
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 343091c..e704071 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -407,6 +407,17 @@
- name: x86_64-gnu
<<: *job-linux-xl
+ # This job ensures commits landing on nightly still pass the full
+ # test suite on the stable channel. There are some UI tests that
+ # depend on the channel being built (for example if they include the
+ # channel name on the output), and this builder prevents landing
+ # changes that would result in broken builds after a promotion.
+ - name: x86_64-gnu-stable
+ env:
+ IMAGE: x86_64-gnu
+ RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
+ <<: *job-linux-xl
+
- name: x86_64-gnu-aux
<<: *job-linux-xl
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 35f80a9..c5e225c 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -65,7 +65,11 @@
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
# master, beta, or stable with a build to determine whether to run some checks (notably toolstate).
-export RUST_RELEASE_CHANNEL="$(cat "${ci_dir}/channel")"
+if [[ -z "${RUST_CI_OVERRIDE_RELEASE_CHANNEL+x}" ]]; then
+ export RUST_RELEASE_CHANNEL="$(cat "${ci_dir}/channel")"
+else
+ export RUST_RELEASE_CHANNEL="${RUST_CI_OVERRIDE_RELEASE_CHANNEL}"
+fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then
diff --git a/src/doc/unstable-book/src/language-features/more-qualified-paths.md b/src/doc/unstable-book/src/language-features/more-qualified-paths.md
new file mode 100644
index 0000000..857af57
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/more-qualified-paths.md
@@ -0,0 +1,29 @@
+# `more_qualified_paths`
+
+The `more_qualified_paths` feature can be used in order to enable the
+use of qualified paths in patterns.
+
+## Example
+
+```rust
+#![feature(more_qualified_paths)]
+
+fn main() {
+ // destructure through a qualified path
+ let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
+}
+
+struct StructStruct {
+ br: i8,
+}
+
+struct Foo;
+
+trait A {
+ type Assoc;
+}
+
+impl A for Foo {
+ type Assoc = StructStruct;
+}
+```
diff --git "a/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir" "b/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir"
index 42b95b5..296a459 100644
--- "a/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir"
+++ "b/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir"
@@ -85,13 +85,13 @@
bb8 (cleanup): {
StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:15: 27:16
StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:16: 27:17
- goto -> bb10; // scope 2 at $DIR/generator-storage-dead-unwind.rs:1:1: 1:1
+ goto -> bb10; // scope 2 at no-location
}
bb9 (cleanup): {
StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:15: 26:16
StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:16: 26:17
- goto -> bb10; // scope 2 at $DIR/generator-storage-dead-unwind.rs:1:1: 1:1
+ goto -> bb10; // scope 2 at no-location
}
bb10 (cleanup): {
diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
index 99c7ac8..db88f77 100644
--- a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
+++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
@@ -43,7 +43,7 @@
_6 = const 1_i32; // scope 0 at $DIR/loop_test.rs:14:17: 14:18
FakeRead(ForLet(None), _6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14
StorageDead(_6); // scope 0 at $DIR/loop_test.rs:16:5: 16:6
- goto -> bb3; // scope 0 at $DIR/loop_test.rs:1:1: 1:1
+ goto -> bb3; // scope 0 at no-location
}
bb5 (cleanup): {
diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 3395cbf..feb2503 100644
--- a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -94,8 +94,8 @@
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
-- goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
-+ goto -> bb20; // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
+- goto -> bb23; // scope 0 at no-location
++ goto -> bb20; // scope 0 at no-location
}
- bb10: {
@@ -150,8 +150,8 @@
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
-- goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
-+ goto -> bb20; // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
+- goto -> bb23; // scope 0 at no-location
++ goto -> bb20; // scope 0 at no-location
}
- bb15: {
diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
index b91aae0..bf9c2d1 100644
--- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
+++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
@@ -40,7 +40,7 @@
bb4: {
StorageDead(_4); // scope 0 at $DIR/while-storage.rs:13:9: 13:10
- goto -> bb6; // scope 0 at $DIR/while-storage.rs:1:1: 1:1
+ goto -> bb6; // scope 0 at no-location
}
bb5: {
diff --git a/src/test/run-make/issue-71519/Makefile b/src/test/run-make/issue-71519/Makefile
new file mode 100644
index 0000000..636665e
--- /dev/null
+++ b/src/test/run-make/issue-71519/Makefile
@@ -0,0 +1,6 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# needs-rust-lld
+all:
+ RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Z gcc-ld=lld -C link-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
+ $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt
diff --git a/src/test/run-make/issue-71519/main.rs b/src/test/run-make/issue-71519/main.rs
new file mode 100644
index 0000000..f8d09e8
--- /dev/null
+++ b/src/test/run-make/issue-71519/main.rs
@@ -0,0 +1,4 @@
+// test linking using cc with rust-lld injected into search path as ld
+// see rust-lang/rust#71519 for more info
+
+fn main() {}
diff --git a/src/test/rustdoc-ui/run-directory.rs b/src/test/rustdoc-ui/run-directory.rs
index 78431c0..0d432c1 100644
--- a/src/test/rustdoc-ui/run-directory.rs
+++ b/src/test/rustdoc-ui/run-directory.rs
@@ -2,8 +2,8 @@
// revisions: correct incorrect
// check-pass
-// [correct]compile-flags:--test --test-run-directory={{src-base}}
-// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage
+// [correct]compile-flags:--test --test-run-directory={{src-base}} -Zunstable-options
+// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage -Zunstable-options
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
diff --git a/src/test/rustdoc-ui/wasm-safe.rs b/src/test/rustdoc-ui/wasm-safe.rs
index 80b15ac..ba97134 100644
--- a/src/test/rustdoc-ui/wasm-safe.rs
+++ b/src/test/rustdoc-ui/wasm-safe.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(wasm_target_feature)]
-
#[cfg(any(target_arch = "wasm32", doc))]
#[target_feature(enable = "simd128")]
pub fn foo() {}
diff --git a/src/test/rustdoc/intra-doc/field.rs b/src/test/rustdoc/intra-doc/field.rs
index c67c40a..0011434 100644
--- a/src/test/rustdoc/intra-doc/field.rs
+++ b/src/test/rustdoc/intra-doc/field.rs
@@ -1,4 +1,4 @@
-// @has field/index.html '//a[@href="https://doc.rust-lang.org/nightly/core/ops/range/struct.Range.html#structfield.start"]' 'start'
-// @has field/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found'
+// @has field/index.html '//a[@href="{{channel}}/core/ops/range/struct.Range.html#structfield.start"]' 'start'
+// @has field/index.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found'
//! [start][std::ops::Range::start]
//! [not_found][std::io::ErrorKind::NotFound]
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
index f58446d..25f6490 100644
--- a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
@@ -1,3 +1,4 @@
+// compile-flags: -Z unstable-options
// NOTE: This test doesn't actually require `fulldeps`
// so we could instead use it as an `ui` test.
//
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
index b846b30..15a06e7 100644
--- a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
@@ -1,17 +1,17 @@
error: passing `TyCtxt<'tcx>` by reference
- --> $DIR/pass_ty_by_ref_self.rs:17:15
+ --> $DIR/pass_ty_by_ref_self.rs:18:15
|
LL | fn by_ref(&self) {}
| ^^^^^ help: try passing by value: `TyCtxt<'tcx>`
|
note: the lint level is defined here
- --> $DIR/pass_ty_by_ref_self.rs:7:9
+ --> $DIR/pass_ty_by_ref_self.rs:8:9
|
LL | #![deny(rustc::ty_pass_by_reference)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: passing `Ty<'tcx>` by reference
- --> $DIR/pass_ty_by_ref_self.rs:30:21
+ --> $DIR/pass_ty_by_ref_self.rs:31:21
|
LL | fn by_ref(self: &Ty<'tcx>) {}
| ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index ac2d29c..091c834 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -19,45 +19,35 @@
#![feature(rustc_private)]
+extern crate rustc_ast;
extern crate rustc_ast_pretty;
extern crate rustc_data_structures;
-extern crate rustc_ast;
extern crate rustc_parse;
extern crate rustc_session;
extern crate rustc_span;
+use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
+use rustc_ast::ptr::P;
+use rustc_ast::*;
use rustc_ast_pretty::pprust;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_parse::new_parser_from_source_str;
use rustc_session::parse::ParseSess;
-use rustc_span::source_map::{Spanned, DUMMY_SP, FileName};
use rustc_span::source_map::FilePathMapping;
+use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
use rustc_span::symbol::Ident;
-use rustc_ast::*;
-use rustc_ast::mut_visit::{self, MutVisitor, visit_clobber};
-use rustc_ast::ptr::P;
fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
let src_as_string = src.to_string();
- let mut p = new_parser_from_source_str(
- ps,
- FileName::Custom(src_as_string.clone()),
- src_as_string,
- );
+ let mut p =
+ new_parser_from_source_str(ps, FileName::Custom(src_as_string.clone()), src_as_string);
p.parse_expr().map_err(|mut e| e.cancel()).ok()
}
-
// Helper functions for building exprs
fn expr(kind: ExprKind) -> P<Expr> {
- P(Expr {
- id: DUMMY_NODE_ID,
- kind,
- span: DUMMY_SP,
- attrs: ThinVec::new(),
- tokens: None
- })
+ P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: ThinVec::new(), tokens: None })
}
fn make_x() -> P<Expr> {
@@ -83,11 +73,13 @@
1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
2 => {
let seg = PathSegment::from_ident(Ident::from_str("x"));
- iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
- seg.clone(), vec![e, make_x()], DUMMY_SP)));
- iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
- seg.clone(), vec![make_x(), e], DUMMY_SP)));
- },
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::MethodCall(seg.clone(), vec![e, make_x()], DUMMY_SP))
+ });
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::MethodCall(seg.clone(), vec![make_x(), e], DUMMY_SP))
+ });
+ }
3..=8 => {
let op = Spanned {
span: DUMMY_SP,
@@ -99,14 +91,14 @@
7 => BinOpKind::Or,
8 => BinOpKind::Lt,
_ => unreachable!(),
- }
+ },
};
iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
- },
+ }
9 => {
iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
- },
+ }
10 => {
let block = P(Block {
stmts: Vec::new(),
@@ -116,67 +108,66 @@
tokens: None,
});
iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
- },
+ }
11 => {
- let decl = P(FnDecl {
- inputs: vec![],
- output: FnRetTy::Default(DUMMY_SP),
+ let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::Closure(
+ CaptureBy::Value,
+ Async::No,
+ Movability::Movable,
+ decl.clone(),
+ e,
+ DUMMY_SP,
+ ))
});
- iter_exprs(depth - 1, &mut |e| g(
- ExprKind::Closure(CaptureBy::Value,
- Async::No,
- Movability::Movable,
- decl.clone(),
- e,
- DUMMY_SP)));
- },
+ }
12 => {
iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x(), DUMMY_SP)));
iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e, DUMMY_SP)));
- },
+ }
13 => {
iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f"))));
- },
+ }
14 => {
- iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
- Some(e), Some(make_x()), RangeLimits::HalfOpen)));
- iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
- Some(make_x()), Some(e), RangeLimits::HalfOpen)));
- },
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::Range(Some(e), Some(make_x()), RangeLimits::HalfOpen))
+ });
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::Range(Some(make_x()), Some(e), RangeLimits::HalfOpen))
+ });
+ }
15 => {
- iter_exprs(
- depth - 1,
- &mut |e| g(ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, e)),
- );
- },
+ iter_exprs(depth - 1, &mut |e| {
+ g(ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, e))
+ });
+ }
16 => {
g(ExprKind::Ret(None));
iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e))));
- },
+ }
17 => {
let path = Path::from_ident(Ident::from_str("S"));
g(ExprKind::Struct(P(StructExpr {
- path, fields: vec![], rest: StructRest::Base(make_x())
+ qself: None,
+ path,
+ fields: vec![],
+ rest: StructRest::Base(make_x()),
})));
- },
+ }
18 => {
iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
- },
+ }
19 => {
- let pat = P(Pat {
- id: DUMMY_NODE_ID,
- kind: PatKind::Wild,
- span: DUMMY_SP,
- tokens: None,
- });
+ let pat =
+ P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Wild, span: DUMMY_SP, tokens: None });
iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e)))
- },
+ }
_ => panic!("bad counter value in iter_exprs"),
}
}
}
-
// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed.
/// `MutVisitor` that removes all `ExprKind::Paren` nodes.
@@ -192,7 +183,6 @@
}
}
-
/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`.
struct AddParens;
@@ -205,7 +195,7 @@
kind: ExprKind::Paren(e),
span: DUMMY_SP,
attrs: ThinVec::new(),
- tokens: None
+ tokens: None,
})
});
}
@@ -238,9 +228,12 @@
RemoveParens.visit_expr(&mut parsed);
AddParens.visit_expr(&mut parsed);
let text2 = pprust::expr_to_string(&parsed);
- assert!(text1 == text2,
- "exprs are not equal:\n e = {:?}\n parsed = {:?}",
- text1, text2);
+ assert!(
+ text1 == text2,
+ "exprs are not equal:\n e = {:?}\n parsed = {:?}",
+ text1,
+ text2
+ );
}
});
}
diff --git a/src/test/ui-fulldeps/session-derive-errors.rs b/src/test/ui-fulldeps/session-derive-errors.rs
index 7967b32..140aaad 100644
--- a/src/test/ui-fulldeps/session-derive-errors.rs
+++ b/src/test/ui-fulldeps/session-derive-errors.rs
@@ -1,6 +1,12 @@
// check-fail
// Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
+// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
+// changing the output of this test. Since SessionDiagnostic is strictly internal to the compiler
+// the test is just ignored on stable and beta:
+// ignore-beta
+// ignore-stable
+
#![feature(rustc_private)]
#![crate_type = "lib"]
diff --git a/src/test/ui-fulldeps/session-derive-errors.stderr b/src/test/ui-fulldeps/session-derive-errors.stderr
index c6c3765..2f1debe 100644
--- a/src/test/ui-fulldeps/session-derive-errors.stderr
+++ b/src/test/ui-fulldeps/session-derive-errors.stderr
@@ -1,5 +1,5 @@
error: `#[derive(SessionDiagnostic)]` can only be used on structs
- --> $DIR/session-derive-errors.rs:28:1
+ --> $DIR/session-derive-errors.rs:34:1
|
LL | / #[error = "E0123"]
LL | |
@@ -10,31 +10,31 @@
| |_^
error: `#[label = ...]` is not a valid SessionDiagnostic struct attribute
- --> $DIR/session-derive-errors.rs:37:1
+ --> $DIR/session-derive-errors.rs:43:1
|
LL | #[label = "This is in the wrong place"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[suggestion = ...]` is not a valid SessionDiagnostic field attribute
- --> $DIR/session-derive-errors.rs:44:5
+ --> $DIR/session-derive-errors.rs:50:5
|
LL | #[suggestion = "this is the wrong kind of attribute"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `error` specified multiple times
- --> $DIR/session-derive-errors.rs:52:11
+ --> $DIR/session-derive-errors.rs:58:11
|
LL | #[error = "E0456"]
| ^^^^^^^
error: `lint` specified when `error` was already specified
- --> $DIR/session-derive-errors.rs:58:10
+ --> $DIR/session-derive-errors.rs:64:10
|
LL | #[lint = "some_useful_lint"]
| ^^^^^^^^^^^^^^^^^^
error: `code` not specified
- --> $DIR/session-derive-errors.rs:67:1
+ --> $DIR/session-derive-errors.rs:73:1
|
LL | struct ErrorCodeNotProvided {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,19 +42,19 @@
= help: use the [code = "..."] attribute to set this diagnostic's error code
error: the `#[message = "..."]` attribute can only be applied to fields of type Span
- --> $DIR/session-derive-errors.rs:95:5
+ --> $DIR/session-derive-errors.rs:101:5
|
LL | #[message = "this message is applied to a String field"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `name` doesn't refer to a field on this type
- --> $DIR/session-derive-errors.rs:102:1
+ --> $DIR/session-derive-errors.rs:108:1
|
LL | #[message = "This error has a field, and references {name}"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid format string: expected `'}'` but string was terminated
- --> $DIR/session-derive-errors.rs:110:1
+ --> $DIR/session-derive-errors.rs:116:1
|
LL | #[error = "E0123"]
| - because of this opening brace
@@ -65,7 +65,7 @@
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: invalid format string: unmatched `}` found
- --> $DIR/session-derive-errors.rs:119:1
+ --> $DIR/session-derive-errors.rs:125:1
|
LL | #[message = "This is missing an opening brace: name}"]
| ^ unmatched `}` in format string
@@ -74,25 +74,25 @@
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: The `#[label = ...]` attribute can only be applied to fields of type Span
- --> $DIR/session-derive-errors.rs:138:5
+ --> $DIR/session-derive-errors.rs:144:5
|
LL | #[label = "See here"]
| ^^^^^^^^^^^^^^^^^^^^^
error: `nonsense` is not a valid key for `#[suggestion(...)]`
- --> $DIR/session-derive-errors.rs:163:18
+ --> $DIR/session-derive-errors.rs:169:18
|
LL | #[suggestion(nonsense = "This is nonsense")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msg` is not a valid key for `#[suggestion(...)]`
- --> $DIR/session-derive-errors.rs:171:18
+ --> $DIR/session-derive-errors.rs:177:18
|
LL | #[suggestion(msg = "This is a suggestion")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing suggestion message
- --> $DIR/session-derive-errors.rs:179:7
+ --> $DIR/session-derive-errors.rs:185:7
|
LL | #[suggestion(code = "This is suggested code")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@
= help: provide a suggestion message using #[suggestion(message = "...")]
error: wrong field type for suggestion
- --> $DIR/session-derive-errors.rs:194:5
+ --> $DIR/session-derive-errors.rs:200:5
|
LL | / #[suggestion(message = "This is a message", code = "This is suggested code")]
LL | |
@@ -110,7 +110,7 @@
= help: #[suggestion(...)] should be applied to fields of type Span or (Span, Applicability)
error: type of field annotated with `#[suggestion(...)]` contains more than one Span
- --> $DIR/session-derive-errors.rs:209:5
+ --> $DIR/session-derive-errors.rs:215:5
|
LL | / #[suggestion(message = "This is a message", code = "This is suggested code")]
LL | |
@@ -118,7 +118,7 @@
| |___________________________________________^
error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
- --> $DIR/session-derive-errors.rs:217:5
+ --> $DIR/session-derive-errors.rs:223:5
|
LL | / #[suggestion(message = "This is a message", code = "This is suggested code")]
LL | |
@@ -126,7 +126,7 @@
| |____________________________________________________^
error: invalid annotation list `#[label(...)]`
- --> $DIR/session-derive-errors.rs:225:7
+ --> $DIR/session-derive-errors.rs:231:7
|
LL | #[label("wrong kind of annotation for label")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/annotate-snippet/missing-type.rs b/src/test/ui/annotate-snippet/missing-type.rs
index d0814a9..b0d8b5f 100644
--- a/src/test/ui/annotate-snippet/missing-type.rs
+++ b/src/test/ui/annotate-snippet/missing-type.rs
@@ -1,4 +1,4 @@
-// compile-flags: --error-format human-annotate-rs
+// compile-flags: --error-format human-annotate-rs -Z unstable-options
pub fn main() {
let x: Iter; //~ ERROR cannot find type `Iter` in this scope
diff --git a/src/test/ui/annotate-snippet/multispan.rs b/src/test/ui/annotate-snippet/multispan.rs
index 325252d..69d7e1a 100644
--- a/src/test/ui/annotate-snippet/multispan.rs
+++ b/src/test/ui/annotate-snippet/multispan.rs
@@ -1,5 +1,5 @@
// aux-build:multispan.rs
-// compile-flags: --error-format human-annotate-rs
+// compile-flags: --error-format human-annotate-rs -Z unstable-options
#![feature(proc_macro_hygiene)]
diff --git a/src/test/ui/associated-types/associated-type-destructuring-assignment.rs b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
new file mode 100644
index 0000000..fea7c7a
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(destructuring_assignment)]
+#![feature(more_qualified_paths)]
+
+enum E { V() }
+
+fn main() {
+ <E>::V() = E::V(); // OK, destructuring assignment
+ <E>::V {} = E::V(); // OK, destructuring assignment
+}
diff --git a/src/test/ui/associated-types/associated-type-macro.rs b/src/test/ui/associated-types/associated-type-macro.rs
new file mode 100644
index 0000000..22b5bca
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-macro.rs
@@ -0,0 +1,4 @@
+fn main() {
+ #[cfg(FALSE)]
+ <() as module>::mac!(); //~ ERROR macros cannot use qualified paths
+}
diff --git a/src/test/ui/associated-types/associated-type-macro.stderr b/src/test/ui/associated-types/associated-type-macro.stderr
new file mode 100644
index 0000000..6a4cf99
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-macro.stderr
@@ -0,0 +1,8 @@
+error: macros cannot use qualified paths
+ --> $DIR/associated-type-macro.rs:3:5
+ |
+LL | <() as module>::mac!();
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/associated-type-struct-construction.rs b/src/test/ui/associated-types/associated-type-struct-construction.rs
new file mode 100644
index 0000000..f8f8048
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-struct-construction.rs
@@ -0,0 +1,24 @@
+// Make sure that users can construct structs through associated types
+// in both expressions and patterns
+
+#![feature(more_qualified_paths)]
+
+// check-pass
+fn main() {
+ let <Foo as A>::Assoc { br } = <Foo as A>::Assoc { br: 2 };
+ assert!(br == 2);
+}
+
+struct StructStruct {
+ br: i8,
+}
+
+struct Foo;
+
+trait A {
+ type Assoc;
+}
+
+impl A for Foo {
+ type Assoc = StructStruct;
+}
diff --git a/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs b/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs
new file mode 100644
index 0000000..d5809ec
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs
@@ -0,0 +1,24 @@
+// Users cannot yet construct structs through associated types
+// in both expressions and patterns
+
+#![feature(more_qualified_paths)]
+
+fn main() {
+ let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+ //~^ ERROR expected method or associated constant, found associated type
+ //~| ERROR expected method or associated constant, found associated type
+ assert!(n == 2);
+}
+
+struct TupleStruct(i8);
+
+struct Foo;
+
+
+trait A {
+ type Assoc;
+}
+
+impl A for Foo {
+ type Assoc = TupleStruct;
+}
diff --git a/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr b/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr
new file mode 100644
index 0000000..bca7dee
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr
@@ -0,0 +1,19 @@
+error[E0575]: expected method or associated constant, found associated type `A::Assoc`
+ --> $DIR/associated-type-tuple-struct-construction.rs:7:32
+ |
+LL | let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: can't use a type alias as a constructor
+
+error[E0575]: expected method or associated constant, found associated type `A::Assoc`
+ --> $DIR/associated-type-tuple-struct-construction.rs:7:9
+ |
+LL | let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: can't use a type alias as a constructor
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0575`.
diff --git a/src/test/ui/borrowck/issue-85765.rs b/src/test/ui/borrowck/issue-85765.rs
new file mode 100644
index 0000000..b82e029
--- /dev/null
+++ b/src/test/ui/borrowck/issue-85765.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let mut test = Vec::new();
+ let rofl: &Vec<Vec<i32>> = &mut test;
+ //~^ HELP consider changing this to be a mutable reference
+ rofl.push(Vec::new());
+ //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
+ //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+}
diff --git a/src/test/ui/borrowck/issue-85765.stderr b/src/test/ui/borrowck/issue-85765.stderr
new file mode 100644
index 0000000..863c2e8
--- /dev/null
+++ b/src/test/ui/borrowck/issue-85765.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference
+ --> $DIR/issue-85765.rs:5:5
+ |
+LL | let rofl: &Vec<Vec<i32>> = &mut test;
+ | ---- help: consider changing this to be a mutable reference: `&mut Vec<Vec<i32>>`
+LL |
+LL | rofl.push(Vec::new());
+ | ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs
new file mode 100644
index 0000000..744a1c4
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(const_evaluatable_checked, const_generics)]
+#![allow(incomplete_features)]
+
+struct Foo<const N: u8>([u8; N as usize])
+where
+ [(); N as usize]:;
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:;
+
+// unifying with subtrees
+struct Evaluatable<const N: u16>;
+fn foo<const N: u8>() where Evaluatable<{N as usize as u16 }>: {
+ let _ = Foo::<N>([1; N as usize]);
+}
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
new file mode 100644
index 0000000..5437746
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
@@ -0,0 +1,20 @@
+#![feature(const_evaluatable_checked, const_generics)]
+#![allow(incomplete_features)]
+
+struct Evaluatable<const N: u128> {}
+
+struct Foo<const N: u8>([u8; N as usize])
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+where
+ Evaluatable<{N as u128}>:;
+
+struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
new file mode 100644
index 0000000..5ca04d2
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
@@ -0,0 +1,26 @@
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-2.rs:6:25
+ |
+LL | struct Foo<const N: u8>([u8; N as usize])
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-2.rs:12:26
+ |
+LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-2.rs:16:25
+ |
+LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs
new file mode 100644
index 0000000..2ca06bd
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs
@@ -0,0 +1,47 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+pub struct EvaluatableU128<const N: u128>;
+
+struct HasCastInTraitImpl<const N: usize, const M: u128>;
+impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+
+pub fn use_trait_impl<const N: usize>()
+where
+ [(); { N + 1}]:,
+ EvaluatableU128<{N as u128}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ // errors are bad but seems to be pre-existing issue #86198
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ //~^ Error: mismatched types
+ assert_impl::<HasCastInTraitImpl<14, 13>>();
+ //~^ Error: mismatched types
+}
+pub fn use_trait_impl_2<const N: usize>()
+where
+ [(); { N + 1}]:,
+ EvaluatableU128<{N as _}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ // errors are bad but seems to be pre-existing issue #86198
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ //~^ Error: mismatched types
+ assert_impl::<HasCastInTraitImpl<14, 13>>();
+ //~^ Error: mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr
new file mode 100644
index 0000000..c5237fc
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr
@@ -0,0 +1,139 @@
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:17:5
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ----- required by this bound in `use_trait_impl::assert_impl`
+...
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:17:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as u128 }`
+ found type `{ O as u128 }`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:20:5
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ----- required by this bound in `use_trait_impl::assert_impl`
+...
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:20:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as _ }`
+ found type `{ O as u128 }`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:23:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128`
+ |
+ = note: expected type `12_u128`
+ found type `13_u128`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:25:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128`
+ |
+ = note: expected type `13_u128`
+ found type `14_u128`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:35:5
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ----- required by this bound in `use_trait_impl_2::assert_impl`
+...
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:35:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as u128 }`
+ found type `{ O as u128 }`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:38:5
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ----- required by this bound in `use_trait_impl_2::assert_impl`
+...
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:38:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as _ }`
+ found type `{ O as u128 }`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:41:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128`
+ |
+ = note: expected type `12_u128`
+ found type `13_u128`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:43:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128`
+ |
+ = note: expected type `13_u128`
+ found type `14_u128`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs
new file mode 100644
index 0000000..0bb4fcf
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs
@@ -0,0 +1,29 @@
+// check-pass
+#![feature(const_evaluatable_checked, const_generics)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+pub struct EvaluatableU128<const N: u128>;
+
+struct HasCastInTraitImpl<const N: usize, const M: u128>;
+impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+
+pub fn use_trait_impl<const N: usize>() where EvaluatableU128<{N as u128}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
+ assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<13, 13>>();
+}
+pub fn use_trait_impl_2<const N: usize>() where EvaluatableU128<{N as _}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
+ assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<13, 13>>();
+}
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
index 985e7b6..29d835e 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
@@ -2,13 +2,13 @@
--> $DIR/intermixed-lifetime.rs:7:28
|
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
- | -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const N: usize, T = u32>`
+ | -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/intermixed-lifetime.rs:10:37
|
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
- | --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const N: usize, T = u32>`
+ | --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/const-generics/defaults/mismatch.full.stderr b/src/test/ui/const-generics/defaults/mismatch.full.stderr
index be4f364..4aa8401 100644
--- a/src/test/ui/const-generics/defaults/mismatch.full.stderr
+++ b/src/test/ui/const-generics/defaults/mismatch.full.stderr
@@ -5,9 +5,12 @@
| ------------- ^^ expected struct `Example`, found `()`
| |
| expected due to this
+ |
+ = note: expected struct `Example`
+ found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:14:34
+ --> $DIR/mismatch.rs:15:34
|
LL | let e: Example2::<u32, 13> = ();
| ------------------- ^^ expected struct `Example2`, found `()`
@@ -18,7 +21,7 @@
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:16:34
+ --> $DIR/mismatch.rs:18:34
|
LL | let e: Example3::<13, u32> = ();
| ------------------- ^^ expected struct `Example3`, found `()`
@@ -29,7 +32,7 @@
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:18:28
+ --> $DIR/mismatch.rs:21:28
|
LL | let e: Example3::<7> = ();
| ------------- ^^ expected struct `Example3`, found `()`
@@ -40,12 +43,15 @@
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:22:28
+ --> $DIR/mismatch.rs:24:28
|
LL | let e: Example4::<7> = ();
| ------------- ^^ expected struct `Example4`, found `()`
| |
| expected due to this
+ |
+ = note: expected struct `Example4<7_usize>`
+ found unit type `()`
error: aborting due to 5 previous errors
diff --git a/src/test/ui/const-generics/defaults/mismatch.min.stderr b/src/test/ui/const-generics/defaults/mismatch.min.stderr
index be4f364..4aa8401 100644
--- a/src/test/ui/const-generics/defaults/mismatch.min.stderr
+++ b/src/test/ui/const-generics/defaults/mismatch.min.stderr
@@ -5,9 +5,12 @@
| ------------- ^^ expected struct `Example`, found `()`
| |
| expected due to this
+ |
+ = note: expected struct `Example`
+ found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:14:34
+ --> $DIR/mismatch.rs:15:34
|
LL | let e: Example2::<u32, 13> = ();
| ------------------- ^^ expected struct `Example2`, found `()`
@@ -18,7 +21,7 @@
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:16:34
+ --> $DIR/mismatch.rs:18:34
|
LL | let e: Example3::<13, u32> = ();
| ------------------- ^^ expected struct `Example3`, found `()`
@@ -29,7 +32,7 @@
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:18:28
+ --> $DIR/mismatch.rs:21:28
|
LL | let e: Example3::<7> = ();
| ------------- ^^ expected struct `Example3`, found `()`
@@ -40,12 +43,15 @@
found unit type `()`
error[E0308]: mismatched types
- --> $DIR/mismatch.rs:22:28
+ --> $DIR/mismatch.rs:24:28
|
LL | let e: Example4::<7> = ();
| ------------- ^^ expected struct `Example4`, found `()`
| |
| expected due to this
+ |
+ = note: expected struct `Example4<7_usize>`
+ found unit type `()`
error: aborting due to 5 previous errors
diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs
index 68a640c..9d9a879 100644
--- a/src/test/ui/const-generics/defaults/mismatch.rs
+++ b/src/test/ui/const-generics/defaults/mismatch.rs
@@ -11,14 +11,17 @@
fn main() {
let e: Example::<13> = ();
//~^ Error: mismatched types
+ //~| expected struct `Example`
let e: Example2::<u32, 13> = ();
//~^ Error: mismatched types
+ //~| expected struct `Example2`
let e: Example3::<13, u32> = ();
//~^ Error: mismatched types
+ //~| expected struct `Example3`
let e: Example3::<7> = ();
//~^ Error: mismatched types
- // FIXME(const_generics_defaults): There should be a note for the error below, but it is
- // missing.
+ //~| expected struct `Example3<7_usize>`
let e: Example4::<7> = ();
//~^ Error: mismatched types
+ //~| expected struct `Example4<7_usize>`
}
diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
new file mode 100644
index 0000000..933eacb
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
@@ -0,0 +1,5 @@
+#![feature(const_generics_defaults)]
+struct Foo<const M: usize = 10, 'a>(&'a u32);
+//~^ Error lifetime parameters must be declared prior to const parameters
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
new file mode 100644
index 0000000..f50653f
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to const parameters
+ --> $DIR/param-order-err-pretty-prints-default.rs:2:33
+ |
+LL | struct Foo<const M: usize = 10, 'a>(&'a u32);
+ | ----------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const M: usize = 10>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
deleted file mode 100644
index 560795a..0000000
--- a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-struct Const<const P: &'static ()>;
-//~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter
-
-fn main() {
- const A: &'static () = unsafe {
- std::mem::transmute(10 as *const ())
- };
-
- let _ = Const::<{A}>;
-}
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr b/src/test/ui/const-generics/transmute-const-param-static-reference.min.stderr
similarity index 85%
rename from src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
rename to src/test/ui/const-generics/transmute-const-param-static-reference.min.stderr
index d612e0c..f735be9 100644
--- a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
+++ b/src/test/ui/const-generics/transmute-const-param-static-reference.min.stderr
@@ -1,5 +1,5 @@
error: `&'static ()` is forbidden as the type of a const generic parameter
- --> $DIR/transmute-const-param-static-reference.rs:1:23
+ --> $DIR/transmute-const-param-static-reference.rs:7:23
|
LL | struct Const<const P: &'static ()>;
| ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/transmute-const-param-static-reference.rs b/src/test/ui/const-generics/transmute-const-param-static-reference.rs
new file mode 100644
index 0000000..3147d61
--- /dev/null
+++ b/src/test/ui/const-generics/transmute-const-param-static-reference.rs
@@ -0,0 +1,16 @@
+// revisions: full min
+//[full] check-pass
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+struct Const<const P: &'static ()>;
+//[min]~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter
+
+fn main() {
+ const A: &'static () = unsafe {
+ std::mem::transmute(10 as *const ())
+ };
+
+ let _ = Const::<{A}>;
+}
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.rs b/src/test/ui/const-ptr/out_of_bounds_read.rs
deleted file mode 100644
index 183aa9e..0000000
--- a/src/test/ui/const-ptr/out_of_bounds_read.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// error-pattern: any use of this value will cause an error
-
-#![feature(const_ptr_read)]
-#![feature(const_ptr_offset)]
-
-fn main() {
- use std::ptr;
-
- const DATA: [u32; 1] = [42];
-
- const PAST_END_PTR: *const u32 = unsafe { DATA.as_ptr().add(1) };
-
- const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
- const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
- const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
-}
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr
deleted file mode 100644
index 6c4092e..0000000
--- a/src/test/ui/const-ptr/out_of_bounds_read.stderr
+++ /dev/null
@@ -1,59 +0,0 @@
-error: any use of this value will cause an error
- --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- |
-LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- | inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
- |
- ::: $DIR/out_of_bounds_read.rs:13:5
- |
-LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
- | ------------------------------------------------------
- |
- = note: `#[deny(const_err)]` on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
- --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- |
-LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- | inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
- | inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
- |
- ::: $DIR/out_of_bounds_read.rs:14:5
- |
-LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
- | --------------------------------------------------------
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
- --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- |
-LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- | inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
- | inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
- |
- ::: $DIR/out_of_bounds_read.rs:15:5
- |
-LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
- | --------------------------------------------------------------------
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
new file mode 100644
index 0000000..0c0e368
--- /dev/null
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
@@ -0,0 +1,21 @@
+// This test contains code with incorrect vtables in a const context:
+// - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now
+// triggers an error
+// - a similar test that triggers a previously-untested const UB error: emitted close to the above
+// error, it checks the correctness of the size
+
+trait Trait {}
+
+const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
+ unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+//~^ ERROR any use of this value will cause an error
+//~| WARNING this was previously accepted by the compiler
+//~| invalid vtable: alignment `1000` is not a power of 2
+
+const INVALID_VTABLE_SIZE: &dyn Trait =
+ unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+//~^ ERROR any use of this value will cause an error
+//~| WARNING this was previously accepted by the compiler
+//~| invalid vtable: size is bigger than largest supported object
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr b/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr
new file mode 100644
index 0000000..c937d03
--- /dev/null
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr
@@ -0,0 +1,27 @@
+error: any use of this value will cause an error
+ --> $DIR/ub-incorrect-vtable.rs:10:14
+ |
+LL | / const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
+LL | | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+ | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
+ | |
+ | invalid vtable: alignment `1000` is not a power of 2
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: any use of this value will cause an error
+ --> $DIR/ub-incorrect-vtable.rs:16:14
+ |
+LL | / const INVALID_VTABLE_SIZE: &dyn Trait =
+LL | | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+ | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
+ | |
+ | invalid vtable: size is bigger than largest supported object
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/consts/const-needs_drop-monomorphic.rs b/src/test/ui/consts/const-needs_drop-monomorphic.rs
new file mode 100644
index 0000000..9f66e3c
--- /dev/null
+++ b/src/test/ui/consts/const-needs_drop-monomorphic.rs
@@ -0,0 +1,17 @@
+// Check that evaluation of needs_drop<T> fails when T is not monomorphic.
+#![feature(const_generics)]
+#![allow(const_evaluatable_unchecked)]
+#![allow(incomplete_features)]
+
+struct Bool<const B: bool> {}
+impl Bool<true> {
+ fn assert() {}
+}
+fn f<T>() {
+ Bool::<{ std::mem::needs_drop::<T>() }>::assert();
+ //~^ ERROR no function or associated item named `assert` found
+ //~| ERROR constant expression depends on a generic parameter
+}
+fn main() {
+ f::<u32>();
+}
diff --git a/src/test/ui/consts/const-needs_drop-monomorphic.stderr b/src/test/ui/consts/const-needs_drop-monomorphic.stderr
new file mode 100644
index 0000000..0770d06
--- /dev/null
+++ b/src/test/ui/consts/const-needs_drop-monomorphic.stderr
@@ -0,0 +1,20 @@
+error[E0599]: no function or associated item named `assert` found for struct `Bool<{ std::mem::needs_drop::<T>() }>` in the current scope
+ --> $DIR/const-needs_drop-monomorphic.rs:11:46
+ |
+LL | struct Bool<const B: bool> {}
+ | -------------------------- function or associated item `assert` not found for this
+...
+LL | Bool::<{ std::mem::needs_drop::<T>() }>::assert();
+ | ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::<T>() }>` due to unsatisfied trait bounds
+
+error: constant expression depends on a generic parameter
+ --> $DIR/const-needs_drop-monomorphic.rs:11:5
+ |
+LL | Bool::<{ std::mem::needs_drop::<T>() }>::assert();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs
deleted file mode 100644
index 9dc595f..0000000
--- a/src/test/ui/consts/copy-intrinsic.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// ignore-tidy-linelength
-#![feature(const_mut_refs, const_intrinsic_copy, const_ptr_offset)]
-use std::{ptr, mem};
-
-const COPY_ZERO: () = unsafe {
- // Since we are not copying anything, this should be allowed.
- let src = ();
- let mut dst = ();
- ptr::copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
-};
-
-const COPY_OOB_1: () = unsafe {
- let mut x = 0i32;
- let dangle = (&mut x as *mut i32).wrapping_add(10);
- // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
- ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0); //~ ERROR any use of this value will cause an error
- //~| memory access failed: pointer must be in-bounds
- //~| previously accepted
-};
-const COPY_OOB_2: () = unsafe {
- let x = 0i32;
- let dangle = (&x as *const i32).wrapping_add(10);
- // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
- ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); //~ ERROR any use of this value will cause an error
- //~| memory access failed: pointer must be in-bounds
- //~| previously accepted
-};
-
-const COPY_SIZE_OVERFLOW: () = unsafe {
- let x = 0;
- let mut y = 0;
- ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
- //~| overflow computing total size of `copy`
- //~| previously accepted
-};
-const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
- let x = 0;
- let mut y = 0;
- ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
- //~| overflow computing total size of `copy_nonoverlapping`
- //~| previously accepted
-};
-
-fn main() {
-}
diff --git a/src/test/ui/consts/copy-intrinsic.stderr b/src/test/ui/consts/copy-intrinsic.stderr
deleted file mode 100644
index 2736cde..0000000
--- a/src/test/ui/consts/copy-intrinsic.stderr
+++ /dev/null
@@ -1,69 +0,0 @@
-error: any use of this value will cause an error
- --> $DIR/copy-intrinsic.rs:16:5
- |
-LL | / const COPY_OOB_1: () = unsafe {
-LL | | let mut x = 0i32;
-LL | | let dangle = (&mut x as *mut i32).wrapping_add(10);
-LL | | // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
-LL | | ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0);
- | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc4 which has size 4
-LL | |
-LL | |
-LL | | };
- | |__-
- |
- = note: `#[deny(const_err)]` on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
- --> $DIR/copy-intrinsic.rs:24:5
- |
-LL | / const COPY_OOB_2: () = unsafe {
-LL | | let x = 0i32;
-LL | | let dangle = (&x as *const i32).wrapping_add(10);
-LL | | // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
-LL | | ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0);
- | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc6 which has size 4
-LL | |
-LL | |
-LL | | };
- | |__-
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
- --> $DIR/copy-intrinsic.rs:32:5
- |
-LL | / const COPY_SIZE_OVERFLOW: () = unsafe {
-LL | | let x = 0;
-LL | | let mut y = 0;
-LL | | ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
- | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
-LL | |
-LL | |
-LL | | };
- | |__-
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
- --> $DIR/copy-intrinsic.rs:39:5
- |
-LL | / const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
-LL | | let x = 0;
-LL | | let mut y = 0;
-LL | | ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
- | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`
-LL | |
-LL | |
-LL | | };
- | |__-
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/deduplicate-diagnostics.duplicate.stderr b/src/test/ui/deduplicate-diagnostics.duplicate.stderr
index 3b100b5..cd4700c 100644
--- a/src/test/ui/deduplicate-diagnostics.duplicate.stderr
+++ b/src/test/ui/deduplicate-diagnostics.duplicate.stderr
@@ -22,12 +22,6 @@
LL | #[deny("literal")]
| ^^^^^^^^^ bad attribute argument
-error[E0452]: malformed lint attribute input
- --> $DIR/deduplicate-diagnostics.rs:8:8
- |
-LL | #[deny("literal")]
- | ^^^^^^^^^ bad attribute argument
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/deduplicate-diagnostics.rs b/src/test/ui/deduplicate-diagnostics.rs
index c5d41ff..7d1c4f5 100644
--- a/src/test/ui/deduplicate-diagnostics.rs
+++ b/src/test/ui/deduplicate-diagnostics.rs
@@ -7,5 +7,4 @@
#[deny("literal")] //~ ERROR malformed lint attribute input
//[duplicate]~| ERROR malformed lint attribute input
- //[duplicate]~| ERROR malformed lint attribute input
fn main() {}
diff --git a/src/test/ui/error-codes/E0452.rs b/src/test/ui/error-codes/E0452.rs
index 4e5a6c9..5066cd9 100644
--- a/src/test/ui/error-codes/E0452.rs
+++ b/src/test/ui/error-codes/E0452.rs
@@ -2,7 +2,5 @@
//~| ERROR E0452
//~| ERROR E0452
//~| ERROR E0452
- //~| ERROR E0452
- //~| ERROR E0452
fn main() {
}
diff --git a/src/test/ui/error-codes/E0452.stderr b/src/test/ui/error-codes/E0452.stderr
index 30c11e3..f67b740 100644
--- a/src/test/ui/error-codes/E0452.stderr
+++ b/src/test/ui/error-codes/E0452.stderr
@@ -22,18 +22,6 @@
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
-error[E0452]: malformed lint attribute input
- --> $DIR/E0452.rs:1:10
- |
-LL | #![allow(foo = "")]
- | ^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/E0452.rs:1:10
- |
-LL | #![allow(foo = "")]
- | ^^^^^^^^ bad attribute argument
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/error-codes/E0453.rs b/src/test/ui/error-codes/E0453.rs
index 6fa8dd9..ca9573c 100644
--- a/src/test/ui/error-codes/E0453.rs
+++ b/src/test/ui/error-codes/E0453.rs
@@ -3,6 +3,5 @@
#[allow(non_snake_case)]
//~^ ERROR allow(non_snake_case) incompatible
//~| ERROR allow(non_snake_case) incompatible
-//~| ERROR allow(non_snake_case) incompatible
fn main() {
}
diff --git a/src/test/ui/error-codes/E0453.stderr b/src/test/ui/error-codes/E0453.stderr
index 21c43cc..6d60dc8 100644
--- a/src/test/ui/error-codes/E0453.stderr
+++ b/src/test/ui/error-codes/E0453.stderr
@@ -16,15 +16,6 @@
LL | #[allow(non_snake_case)]
| ^^^^^^^^^^^^^^ overruled by previous forbid
-error[E0453]: allow(non_snake_case) incompatible with previous forbid
- --> $DIR/E0453.rs:3:9
- |
-LL | #![forbid(non_snake_case)]
- | -------------- `forbid` level set here
-LL |
-LL | #[allow(non_snake_case)]
- | ^^^^^^^^^^^^^^ overruled by previous forbid
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/error-codes/E0602.stderr b/src/test/ui/error-codes/E0602.stderr
index 70137cb..2b37226 100644
--- a/src/test/ui/error-codes/E0602.stderr
+++ b/src/test/ui/error-codes/E0602.stderr
@@ -6,10 +6,6 @@
|
= note: requested on the command line with `-D bogus`
-error[E0602]: unknown lint: `bogus`
- |
- = note: requested on the command line with `-D bogus`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0602`.
diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs
index b124e9b..7756074 100644
--- a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs
+++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs
@@ -1,6 +1,5 @@
#![warn(nonstandard_style, reason = "the standard should be respected")]
//~^ ERROR lint reasons are experimental
//~| ERROR lint reasons are experimental
-//~| ERROR lint reasons are experimental
fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr
index a7d5ea6..12793c7 100644
--- a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr
+++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr
@@ -16,15 +16,6 @@
= note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
= help: add `#![feature(lint_reasons)]` to the crate attributes to enable
-error[E0658]: lint reasons are experimental
- --> $DIR/feature-gate-lint-reasons.rs:1:28
- |
-LL | #![warn(nonstandard_style, reason = "the standard should be respected")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
- = help: add `#![feature(lint_reasons)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-more-qualified-paths.rs b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.rs
new file mode 100644
index 0000000..2e05acb
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.rs
@@ -0,0 +1,27 @@
+fn main() {
+ // destructure through a qualified path
+ let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
+ //~^ ERROR usage of qualified paths in this context is experimental
+ let _ = <Foo as A>::Assoc { br: 2 };
+ //~^ ERROR usage of qualified paths in this context is experimental
+ let <E>::V(..) = E::V(0);
+ //~^ ERROR usage of qualified paths in this context is experimental
+}
+
+struct StructStruct {
+ br: i8,
+}
+
+struct Foo;
+
+trait A {
+ type Assoc;
+}
+
+impl A for Foo {
+ type Assoc = StructStruct;
+}
+
+enum E {
+ V(u8)
+}
diff --git a/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr
new file mode 100644
index 0000000..b49cc40
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr
@@ -0,0 +1,30 @@
+error[E0658]: usage of qualified paths in this context is experimental
+ --> $DIR/feature-gate-more-qualified-paths.rs:3:9
+ |
+LL | let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #80080 <https://github.com/rust-lang/rust/issues/80080> for more information
+ = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+
+error[E0658]: usage of qualified paths in this context is experimental
+ --> $DIR/feature-gate-more-qualified-paths.rs:5:13
+ |
+LL | let _ = <Foo as A>::Assoc { br: 2 };
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #80080 <https://github.com/rust-lang/rust/issues/80080> for more information
+ = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+
+error[E0658]: usage of qualified paths in this context is experimental
+ --> $DIR/feature-gate-more-qualified-paths.rs:7:9
+ |
+LL | let <E>::V(..) = E::V(0);
+ | ^^^^^^
+ |
+ = note: see issue #80080 <https://github.com/rust-lang/rust/issues/80080> for more information
+ = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/intrinsics/issue-84297-reifying-copy.rs b/src/test/ui/intrinsics/issue-84297-reifying-copy.rs
new file mode 100644
index 0000000..08ba9ce
--- /dev/null
+++ b/src/test/ui/intrinsics/issue-84297-reifying-copy.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+fn main() {
+ let _unused = if true {
+ core::ptr::copy::<i32>
+ } else {
+ core::ptr::copy_nonoverlapping::<i32>
+ };
+}
diff --git a/src/test/ui/lint/crate_level_only_lint.rs b/src/test/ui/lint/crate_level_only_lint.rs
index d9673fa..38c5487 100644
--- a/src/test/ui/lint/crate_level_only_lint.rs
+++ b/src/test/ui/lint/crate_level_only_lint.rs
@@ -4,12 +4,10 @@
#![allow(uncommon_codepoints)]
//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
-//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
#[allow(uncommon_codepoints)]
//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
-//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
const BAR: f64 = 0.000001;
}
@@ -17,6 +15,5 @@
#[allow(uncommon_codepoints)]
//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
-//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
fn main() {
}
diff --git a/src/test/ui/lint/crate_level_only_lint.stderr b/src/test/ui/lint/crate_level_only_lint.stderr
index 8fb06df..83bea04 100644
--- a/src/test/ui/lint/crate_level_only_lint.stderr
+++ b/src/test/ui/lint/crate_level_only_lint.stderr
@@ -11,13 +11,13 @@
| ^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:9:9
+ --> $DIR/crate_level_only_lint.rs:8:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:17:9
+ --> $DIR/crate_level_only_lint.rs:15:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
@@ -29,34 +29,16 @@
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:9:9
+ --> $DIR/crate_level_only_lint.rs:8:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:17:9
+ --> $DIR/crate_level_only_lint.rs:15:9
|
LL | #[allow(uncommon_codepoints)]
| ^^^^^^^^^^^^^^^^^^^
-error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:4:10
- |
-LL | #![allow(uncommon_codepoints)]
- | ^^^^^^^^^^^^^^^^^^^
-
-error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:9:9
- |
-LL | #[allow(uncommon_codepoints)]
- | ^^^^^^^^^^^^^^^^^^^
-
-error: allow(uncommon_codepoints) is ignored unless specified at crate level
- --> $DIR/crate_level_only_lint.rs:17:9
- |
-LL | #[allow(uncommon_codepoints)]
- | ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 9 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/test/ui/lint/forbid-group-group-2.rs b/src/test/ui/lint/forbid-group-group-2.rs
index b12fd72..7d8a398 100644
--- a/src/test/ui/lint/forbid-group-group-2.rs
+++ b/src/test/ui/lint/forbid-group-group-2.rs
@@ -17,10 +17,4 @@
//~| WARNING previously accepted by the compiler
//~| ERROR incompatible with previous
//~| WARNING previously accepted by the compiler
-//~| ERROR incompatible with previous
-//~| WARNING previously accepted by the compiler
-//~| ERROR incompatible with previous
-//~| WARNING previously accepted by the compiler
-//~| ERROR incompatible with previous
-//~| WARNING previously accepted by the compiler
fn main() {}
diff --git a/src/test/ui/lint/forbid-group-group-2.stderr b/src/test/ui/lint/forbid-group-group-2.stderr
index 214e949..d8c09e6 100644
--- a/src/test/ui/lint/forbid-group-group-2.stderr
+++ b/src/test/ui/lint/forbid-group-group-2.stderr
@@ -75,41 +75,5 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-error: allow(nonstandard_style) incompatible with previous forbid
- --> $DIR/forbid-group-group-2.rs:7:9
- |
-LL | #![forbid(warnings)]
- | -------- `forbid` level set here
-...
-LL | #[allow(nonstandard_style)]
- | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-error: allow(nonstandard_style) incompatible with previous forbid
- --> $DIR/forbid-group-group-2.rs:7:9
- |
-LL | #![forbid(warnings)]
- | -------- `forbid` level set here
-...
-LL | #[allow(nonstandard_style)]
- | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-error: allow(nonstandard_style) incompatible with previous forbid
- --> $DIR/forbid-group-group-2.rs:7:9
- |
-LL | #![forbid(warnings)]
- | -------- `forbid` level set here
-...
-LL | #[allow(nonstandard_style)]
- | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-error: aborting due to 9 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/test/ui/lint/forbid-group-member.rs b/src/test/ui/lint/forbid-group-member.rs
index 6f1b2e9..664edea 100644
--- a/src/test/ui/lint/forbid-group-member.rs
+++ b/src/test/ui/lint/forbid-group-member.rs
@@ -12,8 +12,6 @@
//~| WARNING previously accepted
//~| WARNING incompatible with previous forbid
//~| WARNING previously accepted
-//~| WARNING incompatible with previous forbid
-//~| WARNING previously accepted
fn main() {
let a: ();
}
diff --git a/src/test/ui/lint/forbid-group-member.stderr b/src/test/ui/lint/forbid-group-member.stderr
index c818d7f..72772a4 100644
--- a/src/test/ui/lint/forbid-group-member.stderr
+++ b/src/test/ui/lint/forbid-group-member.stderr
@@ -35,17 +35,5 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-warning: allow(unused_variables) incompatible with previous forbid
- --> $DIR/forbid-group-member.rs:8:9
- |
-LL | #![forbid(unused)]
- | ------ `forbid` level set here
-LL |
-LL | #[allow(unused_variables)]
- | ^^^^^^^^^^^^^^^^ overruled by previous forbid
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-warning: 4 warnings emitted
+warning: 3 warnings emitted
diff --git a/src/test/ui/lint/forbid-member-group.rs b/src/test/ui/lint/forbid-member-group.rs
index 3279029..e2f7682 100644
--- a/src/test/ui/lint/forbid-member-group.rs
+++ b/src/test/ui/lint/forbid-member-group.rs
@@ -6,7 +6,6 @@
#[allow(unused)]
//~^ ERROR incompatible with previous forbid
//~| ERROR incompatible with previous forbid
-//~| ERROR incompatible with previous forbid
fn main() {
let a: ();
}
diff --git a/src/test/ui/lint/forbid-member-group.stderr b/src/test/ui/lint/forbid-member-group.stderr
index 1d8ab4d..39700af 100644
--- a/src/test/ui/lint/forbid-member-group.stderr
+++ b/src/test/ui/lint/forbid-member-group.stderr
@@ -16,15 +16,6 @@
LL | #[allow(unused)]
| ^^^^^^ overruled by previous forbid
-error[E0453]: allow(unused) incompatible with previous forbid
- --> $DIR/forbid-member-group.rs:6:9
- |
-LL | #![forbid(unused_variables)]
- | ---------------- `forbid` level set here
-LL |
-LL | #[allow(unused)]
- | ^^^^^^ overruled by previous forbid
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs b/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
index d4a5056..0a3e20b 100644
--- a/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
+++ b/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns elided_lifetimes_in_paths
+// compile-flags: --force-warns elided_lifetimes_in_paths -Zunstable-options
// check-pass
struct Foo<'a> {
diff --git a/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs b/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
index afd2d6e..0abc491 100644
--- a/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
+++ b/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns const_err
+// compile-flags: --force-warns const_err -Zunstable-options
// check-pass
#![allow(const_err)]
diff --git a/src/test/ui/lint/force-warn/force-allowed-warning.rs b/src/test/ui/lint/force-warn/force-allowed-warning.rs
index 5c83c52..bac0e4f 100644
--- a/src/test/ui/lint/force-warn/force-allowed-warning.rs
+++ b/src/test/ui/lint/force-warn/force-allowed-warning.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns dead_code
+// compile-flags: --force-warns dead_code -Zunstable-options
// check-pass
#![allow(dead_code)]
diff --git a/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs b/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
index 4f267f0..e721760 100644
--- a/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
+++ b/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns const_err
+// compile-flags: --force-warns const_err -Zunstable-options
// check-pass
const C: i32 = 1 / 0;
diff --git a/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs b/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
index 5501faa..0dc1ce2 100644
--- a/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
+++ b/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns dead_code
+// compile-flags: --force-warns dead_code -Zunstable-options
// check-pass
#![allow(warnings)]
diff --git a/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs b/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
index 9009971..4f637c7 100644
--- a/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
+++ b/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns nonstandard_style
+// compile-flags: --force-warns nonstandard_style -Zunstable-options
// check-pass
#![allow(warnings)]
diff --git a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
index b68b979..bb2f394a 100644
--- a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
+++ b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns bare_trait_objects
+// compile-flags: --force-warns bare_trait_objects -Zunstable-options
// check-pass
#![allow(rust_2018_idioms)]
diff --git a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
index 357a79b..fd029a3 100644
--- a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
+++ b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns rust_2018_idioms
+// compile-flags: --force-warns rust_2018_idioms -Zunstable-options
// check-pass
#![allow(bare_trait_objects)]
diff --git a/src/test/ui/lint/force-warn/force-warn-group.rs b/src/test/ui/lint/force-warn/force-warn-group.rs
index a4615df..c97eeab 100644
--- a/src/test/ui/lint/force-warn/force-warn-group.rs
+++ b/src/test/ui/lint/force-warn/force-warn-group.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns rust_2018_idioms
+// compile-flags: --force-warns rust_2018_idioms -Zunstable-options
// check-pass
#![allow(rust_2018_idioms)]
diff --git a/src/test/ui/lint/issue-80988.rs b/src/test/ui/lint/issue-80988.rs
index 16a0419..1e11620 100644
--- a/src/test/ui/lint/issue-80988.rs
+++ b/src/test/ui/lint/issue-80988.rs
@@ -11,6 +11,4 @@
//~| WARNING being phased out
//~| WARNING incompatible with previous forbid
//~| WARNING being phased out
-//~| WARNING incompatible with previous forbid
-//~| WARNING being phased out
fn main() {}
diff --git a/src/test/ui/lint/issue-80988.stderr b/src/test/ui/lint/issue-80988.stderr
index 4cae11f..deee267 100644
--- a/src/test/ui/lint/issue-80988.stderr
+++ b/src/test/ui/lint/issue-80988.stderr
@@ -35,17 +35,5 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-warning: deny(warnings) incompatible with previous forbid
- --> $DIR/issue-80988.rs:7:8
- |
-LL | #![forbid(warnings)]
- | -------- `forbid` level set here
-LL |
-LL | #[deny(warnings)]
- | ^^^^^^^^ overruled by previous forbid
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-warning: 4 warnings emitted
+warning: 3 warnings emitted
diff --git a/src/test/ui/lint/issue-83477.rs b/src/test/ui/lint/issue-83477.rs
index 0eba52a..ab62f0c 100644
--- a/src/test/ui/lint/issue-83477.rs
+++ b/src/test/ui/lint/issue-83477.rs
@@ -1,3 +1,4 @@
+// compile-flags: -Zunstable-options
// check-pass
#![warn(rustc::internal)]
diff --git a/src/test/ui/lint/issue-83477.stderr b/src/test/ui/lint/issue-83477.stderr
index dbe0c9e..028890f 100644
--- a/src/test/ui/lint/issue-83477.stderr
+++ b/src/test/ui/lint/issue-83477.stderr
@@ -1,5 +1,5 @@
warning: unknown lint: `rustc::foo::bar::default_hash_types`
- --> $DIR/issue-83477.rs:4:9
+ --> $DIR/issue-83477.rs:5:9
|
LL | #[allow(rustc::foo::bar::default_hash_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
@@ -7,19 +7,19 @@
= note: `#[warn(unknown_lints)]` on by default
warning: unknown lint: `rustc::foo::default_hash_types`
- --> $DIR/issue-83477.rs:8:9
+ --> $DIR/issue-83477.rs:9:9
|
LL | #[allow(rustc::foo::default_hash_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
warning: Prefer FxHashMap over HashMap, it has better performance
- --> $DIR/issue-83477.rs:13:31
+ --> $DIR/issue-83477.rs:14:31
|
LL | let _ = std::collections::HashMap::<String, String>::new();
| ^^^^^^^ help: use: `FxHashMap`
|
note: the lint level is defined here
- --> $DIR/issue-83477.rs:2:9
+ --> $DIR/issue-83477.rs:3:9
|
LL | #![warn(rustc::internal)]
| ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/lint-forbid-attr.rs b/src/test/ui/lint/lint-forbid-attr.rs
index 13ebb6d..6d4cfd8 100644
--- a/src/test/ui/lint/lint-forbid-attr.rs
+++ b/src/test/ui/lint/lint-forbid-attr.rs
@@ -3,6 +3,5 @@
#[allow(deprecated)]
//~^ ERROR allow(deprecated) incompatible
//~| ERROR allow(deprecated) incompatible
-//~| ERROR allow(deprecated) incompatible
fn main() {
}
diff --git a/src/test/ui/lint/lint-forbid-attr.stderr b/src/test/ui/lint/lint-forbid-attr.stderr
index cb0b25d..48228c5 100644
--- a/src/test/ui/lint/lint-forbid-attr.stderr
+++ b/src/test/ui/lint/lint-forbid-attr.stderr
@@ -16,15 +16,6 @@
LL | #[allow(deprecated)]
| ^^^^^^^^^^ overruled by previous forbid
-error[E0453]: allow(deprecated) incompatible with previous forbid
- --> $DIR/lint-forbid-attr.rs:3:9
- |
-LL | #![forbid(deprecated)]
- | ---------- `forbid` level set here
-LL |
-LL | #[allow(deprecated)]
- | ^^^^^^^^^^ overruled by previous forbid
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/lint/lint-forbid-cmdline.rs b/src/test/ui/lint/lint-forbid-cmdline.rs
index 38bb8d2..5246ccb 100644
--- a/src/test/ui/lint/lint-forbid-cmdline.rs
+++ b/src/test/ui/lint/lint-forbid-cmdline.rs
@@ -2,6 +2,5 @@
#[allow(deprecated)] //~ ERROR allow(deprecated) incompatible
//~| ERROR allow(deprecated) incompatible
- //~| ERROR allow(deprecated) incompatible
fn main() {
}
diff --git a/src/test/ui/lint/lint-forbid-cmdline.stderr b/src/test/ui/lint/lint-forbid-cmdline.stderr
index 5b1b015..0a92e58 100644
--- a/src/test/ui/lint/lint-forbid-cmdline.stderr
+++ b/src/test/ui/lint/lint-forbid-cmdline.stderr
@@ -14,14 +14,6 @@
|
= note: `forbid` lint level was set on command line
-error[E0453]: allow(deprecated) incompatible with previous forbid
- --> $DIR/lint-forbid-cmdline.rs:3:9
- |
-LL | #[allow(deprecated)]
- | ^^^^^^^^^^ overruled by previous forbid
- |
- = note: `forbid` lint level was set on command line
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/lint/lint-malformed.rs b/src/test/ui/lint/lint-malformed.rs
index cf55707..188e702 100644
--- a/src/test/ui/lint/lint-malformed.rs
+++ b/src/test/ui/lint/lint-malformed.rs
@@ -3,6 +3,4 @@
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
- //~| ERROR malformed lint attribute
- //~| ERROR malformed lint attribute
fn main() { }
diff --git a/src/test/ui/lint/lint-malformed.stderr b/src/test/ui/lint/lint-malformed.stderr
index 6dc8d49..b3a41a7 100644
--- a/src/test/ui/lint/lint-malformed.stderr
+++ b/src/test/ui/lint/lint-malformed.stderr
@@ -28,18 +28,6 @@
LL | #![allow(bar = "baz")]
| ^^^^^^^^^^^ bad attribute argument
-error[E0452]: malformed lint attribute input
- --> $DIR/lint-malformed.rs:2:10
- |
-LL | #![allow(bar = "baz")]
- | ^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/lint-malformed.rs:2:10
- |
-LL | #![allow(bar = "baz")]
- | ^^^^^^^^^^^ bad attribute argument
-
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/lint/lint-removed-cmdline.stderr b/src/test/ui/lint/lint-removed-cmdline.stderr
index fc2ba92..9be532e 100644
--- a/src/test/ui/lint/lint-removed-cmdline.stderr
+++ b/src/test/ui/lint/lint-removed-cmdline.stderr
@@ -10,10 +10,6 @@
|
= note: requested on the command line with `-D raw_pointer_derive`
-warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
- |
- = note: requested on the command line with `-D raw_pointer_derive`
-
error: unused variable: `unused`
--> $DIR/lint-removed-cmdline.rs:12:17
|
@@ -27,5 +23,5 @@
| ^^^^^^^^
= note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
-error: aborting due to previous error; 4 warnings emitted
+error: aborting due to previous error; 3 warnings emitted
diff --git a/src/test/ui/lint/lint-renamed-cmdline.stderr b/src/test/ui/lint/lint-renamed-cmdline.stderr
index 1c37a5b..8dfd61a 100644
--- a/src/test/ui/lint/lint-renamed-cmdline.stderr
+++ b/src/test/ui/lint/lint-renamed-cmdline.stderr
@@ -10,10 +10,6 @@
|
= note: requested on the command line with `-D bare_trait_object`
-warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
- |
- = note: requested on the command line with `-D bare_trait_object`
-
error: unused variable: `unused`
--> $DIR/lint-renamed-cmdline.rs:8:17
|
@@ -27,5 +23,5 @@
| ^^^^^^
= note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
-error: aborting due to previous error; 4 warnings emitted
+error: aborting due to previous error; 3 warnings emitted
diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr
index 66d64e8..a11ee76 100644
--- a/src/test/ui/lint/lint-unexported-no-mangle.stderr
+++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr
@@ -22,14 +22,6 @@
|
= note: requested on the command line with `-F private_no_mangle_statics`
-warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported
- |
- = note: requested on the command line with `-F private_no_mangle_fns`
-
-warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported
- |
- = note: requested on the command line with `-F private_no_mangle_statics`
-
error: const items should never be `#[no_mangle]`
--> $DIR/lint-unexported-no-mangle.rs:9:1
|
@@ -48,5 +40,5 @@
| |
| help: try a static value: `pub static`
-error: aborting due to 2 previous errors; 8 warnings emitted
+error: aborting due to 2 previous errors; 6 warnings emitted
diff --git a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr
index 27e7ee7..3855d55 100644
--- a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr
+++ b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr
@@ -16,15 +16,6 @@
= help: did you mean: `dead_code`
= note: requested on the command line with `-D dead_cod`
-error[E0602]: unknown lint: `bogus`
- |
- = note: requested on the command line with `-D bogus`
-
-error[E0602]: unknown lint: `dead_cod`
- |
- = help: did you mean: `dead_code`
- = note: requested on the command line with `-D dead_cod`
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0602`.
diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs
index 03cf067..cd693ae 100644
--- a/src/test/ui/lint/reasons-erroneous.rs
+++ b/src/test/ui/lint/reasons-erroneous.rs
@@ -3,15 +3,11 @@
#![warn(absolute_paths_not_starting_with_crate, reason = 0)]
//~^ ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason must be a string literal
//~| NOTE reason must be a string literal
//~| NOTE reason must be a string literal
#![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
//~^ ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason must be a string literal
//~| NOTE reason must be a string literal
//~| NOTE reason must be a string literal
#![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
@@ -19,10 +15,6 @@
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE bad attribute argument
-//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
@@ -32,10 +24,6 @@
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE bad attribute argument
-//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
@@ -45,10 +33,6 @@
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE bad attribute argument
-//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
//~| NOTE bad attribute argument
@@ -56,15 +40,11 @@
#![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
//~^ ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason in lint attribute must come last
//~| NOTE reason in lint attribute must come last
//~| NOTE reason in lint attribute must come last
#![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
//~^ ERROR malformed lint attribute
//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason in lint attribute must come last
//~| NOTE reason in lint attribute must come last
//~| NOTE reason in lint attribute must come last
#![warn(missing_copy_implementations, reason)]
diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr
index d7926b7..f65ca08 100644
--- a/src/test/ui/lint/reasons-erroneous.stderr
+++ b/src/test/ui/lint/reasons-erroneous.stderr
@@ -5,61 +5,61 @@
| ^ reason must be a string literal
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:10:40
+ --> $DIR/reasons-erroneous.rs:8:40
|
LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:17:29
+ --> $DIR/reasons-erroneous.rs:13:29
|
LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:17:29
+ --> $DIR/reasons-erroneous.rs:13:29
|
LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:30:23
+ --> $DIR/reasons-erroneous.rs:22:23
|
LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:30:23
+ --> $DIR/reasons-erroneous.rs:22:23
|
LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:43:36
+ --> $DIR/reasons-erroneous.rs:31:36
|
LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:43:36
+ --> $DIR/reasons-erroneous.rs:31:36
|
LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:56:44
+ --> $DIR/reasons-erroneous.rs:40:44
|
LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
| ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:63:25
+ --> $DIR/reasons-erroneous.rs:45:25
|
LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
warning: unknown lint: `reason`
- --> $DIR/reasons-erroneous.rs:70:39
+ --> $DIR/reasons-erroneous.rs:50:39
|
LL | #![warn(missing_copy_implementations, reason)]
| ^^^^^^
@@ -73,119 +73,59 @@
| ^ reason must be a string literal
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:10:40
+ --> $DIR/reasons-erroneous.rs:8:40
|
LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:17:29
+ --> $DIR/reasons-erroneous.rs:13:29
|
LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:17:29
+ --> $DIR/reasons-erroneous.rs:13:29
|
LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:30:23
+ --> $DIR/reasons-erroneous.rs:22:23
|
LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:30:23
+ --> $DIR/reasons-erroneous.rs:22:23
|
LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:43:36
+ --> $DIR/reasons-erroneous.rs:31:36
|
LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:43:36
+ --> $DIR/reasons-erroneous.rs:31:36
|
LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:56:44
+ --> $DIR/reasons-erroneous.rs:40:44
|
LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
| ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:63:25
+ --> $DIR/reasons-erroneous.rs:45:25
|
LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:3:58
- |
-LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
- | ^ reason must be a string literal
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:10:40
- |
-LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:17:29
- |
-LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:17:29
- |
-LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:30:23
- |
-LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:30:23
- |
-LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:43:36
- |
-LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:43:36
- |
-LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:56:44
- |
-LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
- | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
-
-error[E0452]: malformed lint attribute input
- --> $DIR/reasons-erroneous.rs:63:25
- |
-LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
-
-error: aborting due to 30 previous errors; 1 warning emitted
+error: aborting due to 20 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/lint/register-tool-lint.rs b/src/test/ui/lint/register-tool-lint.rs
index 0ba5a37..17d3afb 100644
--- a/src/test/ui/lint/register-tool-lint.rs
+++ b/src/test/ui/lint/register-tool-lint.rs
@@ -7,5 +7,3 @@
//~| HELP add `#![register_tool(abc)]`
//~| ERROR unknown tool name `abc`
//~| HELP add `#![register_tool(abc)]`
-//~| ERROR unknown tool name `abc`
-//~| HELP add `#![register_tool(abc)]`
diff --git a/src/test/ui/lint/register-tool-lint.stderr b/src/test/ui/lint/register-tool-lint.stderr
index 750c74c..842d845 100644
--- a/src/test/ui/lint/register-tool-lint.stderr
+++ b/src/test/ui/lint/register-tool-lint.stderr
@@ -14,14 +14,6 @@
|
= help: add `#![register_tool(abc)]` to the crate root
-error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
- --> $DIR/register-tool-lint.rs:5:9
- |
-LL | #![warn(abc::my_lint)]
- | ^^^
- |
- = help: add `#![register_tool(abc)]` to the crate root
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0710`.
diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr
index 21342e2..d175143 100644
--- a/src/test/ui/lint/use_suggestion_json.stderr
+++ b/src/test/ui/lint/use_suggestion_json.stderr
@@ -1,420 +1,3 @@
-{
- "message": "cannot find type `Iter` in this scope",
- "code": {
- "code": "E0412",
- "explanation": "A used type name is not in scope.
+{"message":"`--error-format=pretty-json` is unstable","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: `--error-format=pretty-json` is unstable\u001b[0m
-Erroneous code examples:
-
-```compile_fail,E0412
-impl Something {} // error: type name `Something` is not in scope
-
-// or:
-
-trait Foo {
- fn bar(N); // error: type name `N` is not in scope
-}
-
-// or:
-
-fn foo(x: T) {} // type name `T` is not in scope
-```
-
-To fix this error, please verify you didn't misspell the type name, you did
-declare it or imported it into the scope. Examples:
-
-```
-struct Something;
-
-impl Something {} // ok!
-
-// or:
-
-trait Foo {
- type N;
-
- fn bar(_: Self::N); // ok!
-}
-
-// or:
-
-fn foo<T>(x: T) {} // ok!
-```
-
-Another case that causes this error is when a type is imported into a parent
-module. To fix this, you can follow the suggestion and use File directly or
-`use super::File;` which will import the types from the parent namespace. An
-example that causes this error is below:
-
-```compile_fail,E0412
-use std::fs::File;
-
-mod foo {
- fn some_function(f: File) {}
-}
-```
-
-```
-use std::fs::File;
-
-mod foo {
- // either
- use super::File;
- // or
- // use std::fs::File;
- fn foo(f: File) {}
-}
-# fn main() {} // don't insert it for us; that'll break imports
-```
-"
- },
- "level": "error",
- "spans": [
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 541,
- "byte_end": 545,
- "line_start": 12,
- "line_end": 12,
- "column_start": 12,
- "column_end": 16,
- "is_primary": true,
- "text": [
- {
- "text": " let x: Iter;",
- "highlight_start": 12,
- "highlight_end": 16
- }
- ],
- "label": "not found in this scope",
- "suggested_replacement": null,
- "suggestion_applicability": null,
- "expansion": null
- }
- ],
- "children": [
- {
- "message": "consider importing one of these items",
- "code": null,
- "level": "help",
- "spans": [
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::binary_heap::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::btree_map::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::btree_set::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::hash_map::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::hash_set::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::linked_list::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::collections::vec_deque::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::option::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::path::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::result::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::slice::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- },
- {
- "file_name": "$DIR/use_suggestion_json.rs",
- "byte_start": 518,
- "byte_end": 518,
- "line_start": 11,
- "line_end": 11,
- "column_start": 1,
- "column_end": 1,
- "is_primary": true,
- "text": [
- {
- "text": "fn main() {",
- "highlight_start": 1,
- "highlight_end": 1
- }
- ],
- "label": null,
- "suggested_replacement": "use std::sync::mpsc::Iter;
-
-",
- "suggestion_applicability": "Unspecified",
- "expansion": null
- }
- ],
- "children": [],
- "rendered": null
- }
- ],
- "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m let x: Iter;\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider importing one of these items\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::binary_heap::Iter;\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::btree_map::Iter;\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::btree_set::Iter;\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::hash_map::Iter;\u001b[0m
-\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m and 8 other candidates\u001b[0m
-
-"
-}
-{
- "message": "aborting due to previous error",
- "code": null,
- "level": "error",
- "spans": [],
- "children": [],
- "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to previous error\u001b[0m
-
-"
-}
-{
- "message": "For more information about this error, try `rustc --explain E0412`.",
- "code": null,
- "level": "failure-note",
- "spans": [],
- "children": [],
- "rendered": "\u001b[0m\u001b[1mFor more information about this error, try `rustc --explain E0412`.\u001b[0m
-"
-}
+"}
diff --git a/src/test/ui/parser/brace-after-qualified-path-in-match.rs b/src/test/ui/parser/brace-after-qualified-path-in-match.rs
deleted file mode 100644
index f415208..0000000
--- a/src/test/ui/parser/brace-after-qualified-path-in-match.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
- match 10 {
- <T as Trait>::Type{key: value} => (),
- //~^ ERROR unexpected `{` after qualified path
- _ => (),
- }
-}
diff --git a/src/test/ui/parser/brace-after-qualified-path-in-match.stderr b/src/test/ui/parser/brace-after-qualified-path-in-match.stderr
deleted file mode 100644
index d6fdf35..0000000
--- a/src/test/ui/parser/brace-after-qualified-path-in-match.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: unexpected `{` after qualified path
- --> $DIR/brace-after-qualified-path-in-match.rs:3:27
- |
-LL | <T as Trait>::Type{key: value} => (),
- | ------------------^ unexpected `{` after qualified path
- | |
- | the qualified path
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/paren-after-qualified-path-in-match.rs b/src/test/ui/parser/paren-after-qualified-path-in-match.rs
deleted file mode 100644
index 68b1c2b..0000000
--- a/src/test/ui/parser/paren-after-qualified-path-in-match.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
- match 10 {
- <T as Trait>::Type(2) => (),
- //~^ ERROR unexpected `(` after qualified path
- _ => (),
- }
-}
diff --git a/src/test/ui/parser/paren-after-qualified-path-in-match.stderr b/src/test/ui/parser/paren-after-qualified-path-in-match.stderr
deleted file mode 100644
index af21f91..0000000
--- a/src/test/ui/parser/paren-after-qualified-path-in-match.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: unexpected `(` after qualified path
- --> $DIR/paren-after-qualified-path-in-match.rs:3:27
- |
-LL | <T as Trait>::Type(2) => (),
- | ------------------^ unexpected `(` after qualified path
- | |
- | the qualified path
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/reify-intrinsic.rs b/src/test/ui/reify-intrinsic.rs
index 05535b9..9eb2f72 100644
--- a/src/test/ui/reify-intrinsic.rs
+++ b/src/test/ui/reify-intrinsic.rs
@@ -1,6 +1,6 @@
// check-fail
-#![feature(intrinsics)]
+#![feature(core_intrinsics, intrinsics)]
fn a() {
let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
@@ -14,8 +14,8 @@
fn c() {
let _ = [
- std::intrinsics::copy_nonoverlapping::<i32>,
- std::intrinsics::copy::<i32>,
+ std::intrinsics::likely,
+ std::intrinsics::unlikely,
//~^ ERROR cannot coerce
];
}
diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr
index 5d82fdb..69c11b5 100644
--- a/src/test/ui/reify-intrinsic.stderr
+++ b/src/test/ui/reify-intrinsic.stderr
@@ -22,11 +22,11 @@
error[E0308]: cannot coerce intrinsics to function pointers
--> $DIR/reify-intrinsic.rs:18:9
|
-LL | std::intrinsics::copy::<i32>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
+LL | std::intrinsics::unlikely,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
|
- = note: expected type `unsafe extern "rust-intrinsic" fn(_, _, _) {copy_nonoverlapping::<i32>}`
- found fn item `unsafe extern "rust-intrinsic" fn(_, _, _) {std::intrinsics::copy::<i32>}`
+ = note: expected type `extern "rust-intrinsic" fn(_) -> _ {likely}`
+ found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/simd/wasm-simd-indirect.rs b/src/test/ui/simd/wasm-simd-indirect.rs
index deac593..88f92fc 100644
--- a/src/test/ui/simd/wasm-simd-indirect.rs
+++ b/src/test/ui/simd/wasm-simd-indirect.rs
@@ -1,7 +1,5 @@
// build-pass
-#![cfg_attr(target_arch = "wasm32", feature(wasm_simd, wasm_target_feature))]
-
#[cfg(target_arch = "wasm32")]
fn main() {
unsafe {
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs
new file mode 100644
index 0000000..fa9d1a8
--- /dev/null
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs
@@ -0,0 +1,25 @@
+// Tests that a suggestion is issued for type mismatch errors when a
+// 1-tuple is expected and a parenthesized expression of non-tuple
+// type is supplied.
+
+fn foo<T>(_t: (T,)) {}
+struct S { _s: (String,) }
+
+fn main() {
+ let _x: (i32,) = (5);
+ //~^ ERROR: mismatched types [E0308]
+ //~| HELP: use a trailing comma to create a tuple with one element
+
+ foo((Some(3)));
+ //~^ ERROR: mismatched types [E0308]
+ //~| HELP: use a trailing comma to create a tuple with one element
+
+ let _s = S { _s: ("abc".to_string()) };
+ //~^ ERROR: mismatched types [E0308]
+ //~| HELP: use a trailing comma to create a tuple with one element
+
+ // Do not issue the suggestion if the found type is already a tuple.
+ let t = (1, 2);
+ let _x: (i32,) = (t);
+ //~^ ERROR: mismatched types [E0308]
+}
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
new file mode 100644
index 0000000..5753796
--- /dev/null
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
@@ -0,0 +1,55 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-86100-tuple-paren-comma.rs:9:22
+ |
+LL | let _x: (i32,) = (5);
+ | ------ ^^^ expected tuple, found integer
+ | |
+ | expected due to this
+ |
+ = note: expected tuple `(i32,)`
+ found type `{integer}`
+help: use a trailing comma to create a tuple with one element
+ |
+LL | let _x: (i32,) = (5,);
+ | ^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-86100-tuple-paren-comma.rs:13:9
+ |
+LL | foo((Some(3)));
+ | ^^^^^^^^^ expected tuple, found enum `Option`
+ |
+ = note: expected tuple `(_,)`
+ found enum `Option<{integer}>`
+help: use a trailing comma to create a tuple with one element
+ |
+LL | foo((Some(3),));
+ | ^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-86100-tuple-paren-comma.rs:17:22
+ |
+LL | let _s = S { _s: ("abc".to_string()) };
+ | ^^^^^^^^^^^^^^^^^^^ expected tuple, found struct `String`
+ |
+ = note: expected tuple `(String,)`
+ found struct `String`
+help: use a trailing comma to create a tuple with one element
+ |
+LL | let _s = S { _s: ("abc".to_string(),) };
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-86100-tuple-paren-comma.rs:23:22
+ |
+LL | let _x: (i32,) = (t);
+ | ------ ^^^ expected a tuple with 1 element, found one with 2 elements
+ | |
+ | expected due to this
+ |
+ = note: expected tuple `(i32,)`
+ found tuple `({integer}, {integer})`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/unnamable-types.rs b/src/test/ui/suggestions/unnamable-types.rs
new file mode 100644
index 0000000..5d06164
--- /dev/null
+++ b/src/test/ui/suggestions/unnamable-types.rs
@@ -0,0 +1,39 @@
+// Test that we do not suggest to add type annotations for unnamable types.
+
+#![crate_type="lib"]
+#![feature(generators)]
+
+const A = 5;
+//~^ ERROR: missing type for `const` item
+//~| HELP: provide a type for the item
+
+static B: _ = "abc";
+//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE: not allowed in type signatures
+//~| HELP: replace with the correct type
+
+
+// FIXME: this should also suggest a function pointer, as the closure is non-capturing
+const C: _ = || 42;
+//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE: not allowed in type signatures
+//~| NOTE: however, the inferred type
+
+struct S<T> { t: T }
+const D = S { t: { let i = 0; move || -> i32 { i } } };
+//~^ ERROR: missing type for `const` item
+//~| NOTE: however, the inferred type
+
+
+fn foo() -> i32 { 42 }
+const E = foo;
+//~^ ERROR: missing type for `const` item
+//~| HELP: provide a type for the item
+const F = S { t: foo };
+//~^ ERROR: missing type for `const` item
+//~| HELP: provide a type for the item
+
+
+const G = || -> i32 { yield 0; return 1; };
+//~^ ERROR: missing type for `const` item
+//~| NOTE: however, the inferred type
diff --git a/src/test/ui/suggestions/unnamable-types.stderr b/src/test/ui/suggestions/unnamable-types.stderr
new file mode 100644
index 0000000..2c81667
--- /dev/null
+++ b/src/test/ui/suggestions/unnamable-types.stderr
@@ -0,0 +1,66 @@
+error: missing type for `const` item
+ --> $DIR/unnamable-types.rs:6:7
+ |
+LL | const A = 5;
+ | ^ help: provide a type for the item: `A: i32`
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+ --> $DIR/unnamable-types.rs:10:11
+ |
+LL | static B: _ = "abc";
+ | ^
+ | |
+ | not allowed in type signatures
+ | help: replace with the correct type: `&str`
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+ --> $DIR/unnamable-types.rs:17:10
+ |
+LL | const C: _ = || 42;
+ | ^ not allowed in type signatures
+ |
+note: however, the inferred type `[closure@$DIR/unnamable-types.rs:17:14: 17:19]` cannot be named
+ --> $DIR/unnamable-types.rs:17:14
+ |
+LL | const C: _ = || 42;
+ | ^^^^^
+
+error: missing type for `const` item
+ --> $DIR/unnamable-types.rs:23:7
+ |
+LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
+ | ^
+ |
+note: however, the inferred type `S<[closure@$DIR/unnamable-types.rs:23:31: 23:51]>` cannot be named
+ --> $DIR/unnamable-types.rs:23:11
+ |
+LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing type for `const` item
+ --> $DIR/unnamable-types.rs:29:7
+ |
+LL | const E = foo;
+ | ^ help: provide a type for the item: `E: fn() -> i32`
+
+error: missing type for `const` item
+ --> $DIR/unnamable-types.rs:32:7
+ |
+LL | const F = S { t: foo };
+ | ^ help: provide a type for the item: `F: S<fn() -> i32>`
+
+error: missing type for `const` item
+ --> $DIR/unnamable-types.rs:37:7
+ |
+LL | const G = || -> i32 { yield 0; return 1; };
+ | ^
+ |
+note: however, the inferred type `[generator@$DIR/unnamable-types.rs:37:11: 37:43 {i32, ()}]` cannot be named
+ --> $DIR/unnamable-types.rs:37:11
+ |
+LL | const G = || -> i32 { yield 0; return 1; };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/thread-local-static.rs b/src/test/ui/thread-local-static.rs
index c7fee9e..dc542fe 100644
--- a/src/test/ui/thread-local-static.rs
+++ b/src/test/ui/thread-local-static.rs
@@ -11,6 +11,7 @@
//~| ERROR mutable references are not allowed
//~| ERROR use of mutable static is unsafe
//~| constant functions cannot refer to statics
+ //~| ERROR calls in constant functions are limited to constant functions
}
fn main() {}
diff --git a/src/test/ui/thread-local-static.stderr b/src/test/ui/thread-local-static.stderr
index 08bf593..a213282 100644
--- a/src/test/ui/thread-local-static.stderr
+++ b/src/test/ui/thread-local-static.stderr
@@ -30,6 +30,12 @@
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/thread-local-static.rs:9:5
+ |
+LL | std::mem::swap(x, &mut STATIC_VAR_2)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/thread-local-static.rs:9:23
|
@@ -38,7 +44,7 @@
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
-Some errors have detailed explanations: E0013, E0133, E0658.
+Some errors have detailed explanations: E0013, E0015, E0133, E0658.
For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs
index 9e4aa7a..ef27532 100644
--- a/src/test/ui/tool_lints.rs
+++ b/src/test/ui/tool_lints.rs
@@ -1,5 +1,4 @@
#[warn(foo::bar)]
//~^ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
-//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
fn main() {}
diff --git a/src/test/ui/tool_lints.stderr b/src/test/ui/tool_lints.stderr
index e06f6dd..d36cd19 100644
--- a/src/test/ui/tool_lints.stderr
+++ b/src/test/ui/tool_lints.stderr
@@ -14,14 +14,6 @@
|
= help: add `#![register_tool(foo)]` to the crate root
-error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
- --> $DIR/tool_lints.rs:1:8
- |
-LL | #[warn(foo::bar)]
- | ^^^
- |
- = help: add `#![register_tool(foo)]` to the crate root
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0710`.
diff --git a/src/test/ui/unknown-lint-tool-name.rs b/src/test/ui/unknown-lint-tool-name.rs
index 84ab7c1..cd5d2f0 100644
--- a/src/test/ui/unknown-lint-tool-name.rs
+++ b/src/test/ui/unknown-lint-tool-name.rs
@@ -1,8 +1,6 @@
#![deny(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
- //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
#[allow(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
- //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
fn main() {}
diff --git a/src/test/ui/unknown-lint-tool-name.stderr b/src/test/ui/unknown-lint-tool-name.stderr
index 1d14551..5f8349c 100644
--- a/src/test/ui/unknown-lint-tool-name.stderr
+++ b/src/test/ui/unknown-lint-tool-name.stderr
@@ -7,7 +7,7 @@
= help: add `#![register_tool(foo)]` to the crate root
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
- --> $DIR/unknown-lint-tool-name.rs:5:9
+ --> $DIR/unknown-lint-tool-name.rs:4:9
|
LL | #[allow(foo::bar)]
| ^^^
@@ -23,29 +23,13 @@
= help: add `#![register_tool(foo)]` to the crate root
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
- --> $DIR/unknown-lint-tool-name.rs:5:9
+ --> $DIR/unknown-lint-tool-name.rs:4:9
|
LL | #[allow(foo::bar)]
| ^^^
|
= help: add `#![register_tool(foo)]` to the crate root
-error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
- --> $DIR/unknown-lint-tool-name.rs:1:9
- |
-LL | #![deny(foo::bar)]
- | ^^^
- |
- = help: add `#![register_tool(foo)]` to the crate root
-
-error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
- --> $DIR/unknown-lint-tool-name.rs:5:9
- |
-LL | #[allow(foo::bar)]
- | ^^^
- |
- = help: add `#![register_tool(foo)]` to the crate root
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0710`.
diff --git a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
index 3e1527e..e69df03 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
@@ -1,7 +1,7 @@
// --extern-location with bad location type
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=badloc:in-the-test-file
+// compile-flags:--extern-location bar=badloc:in-the-test-file -Z unstable-options
#![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
index 6fdf710..aee6233 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
@@ -1,7 +1,7 @@
// --extern-location with a raw reference
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:[{"malformed
+// compile-flags:--extern-location bar=json:[{"malformed -Z unstable-options
#![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
index 02a9869..c7988cd 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
@@ -2,7 +2,7 @@
// check-pass
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:{"key":123,"value":{}} --error-format json
+// compile-flags:--extern-location bar=json:{"key":123,"value":{}} --error-format json -Z unstable-options
#![warn(unused_crate_dependencies)]
//~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
index 5fc8397..001ec6a 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
+++ b/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
@@ -1,4 +1,4 @@
-{"message":"external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":169,"byte_end":169,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":177,"byte_end":202,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"key":123,"value":{}}}],"rendered":"warning: external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`
+{"message":"external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":189,"byte_end":189,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":197,"byte_end":222,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"key":123,"value":{}}}],"rendered":"warning: external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`
--> $DIR/extern-loc-json-json.rs:7:1
|
LL | #![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json.rs
index 212610d..c0d76c8 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-json.rs
@@ -2,7 +2,7 @@
// check-pass
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:{"key":123,"value":{}}
+// compile-flags:--extern-location bar=json:{"key":123,"value":{}} -Z unstable-options
#![warn(unused_crate_dependencies)]
//~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
index 4768365..3590b9c 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
@@ -1,7 +1,7 @@
// --extern-location with no type
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=missing-loc-type
+// compile-flags:--extern-location bar=missing-loc-type -Z unstable-options
#![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
index 207615c..64c3d77 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
@@ -2,7 +2,7 @@
// check-pass
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw:in-the-test-file --error-format json
+// compile-flags:--extern-location bar=raw:in-the-test-file --error-format json -Z unstable-options
#![warn(unused_crate_dependencies)]
//~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
index 25f0999..4083bd5 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
@@ -1,4 +1,4 @@
-{"message":"external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":162,"byte_end":162,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":170,"byte_end":195,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar` at `in-the-test-file`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"raw extern location","code":null,"level":"help","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":0,"byte_end":0,"line_start":1,"line_end":1,"column_start":1,"column_end":1,"is_primary":true,"text":[],"label":null,"suggested_replacement":"in-the-test-file","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":"in-the-test-file"}],"rendered":"warning: external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`
+{"message":"external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":182,"byte_end":182,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":190,"byte_end":215,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar` at `in-the-test-file`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"raw extern location","code":null,"level":"help","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":0,"byte_end":0,"line_start":1,"line_end":1,"column_start":1,"column_end":1,"is_primary":true,"text":[],"label":null,"suggested_replacement":"in-the-test-file","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":"in-the-test-file"}],"rendered":"warning: external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`
--> $DIR/extern-loc-raw-json.rs:7:1
|
LL | #![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
index 65b6426..a9e7afb 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
@@ -1,7 +1,7 @@
// --extern-location with a raw reference
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw
+// compile-flags:--extern-location bar=raw -Z unstable-options
#![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw.rs b/src/test/ui/unused-crate-deps/extern-loc-raw.rs
index fc3fed1..27d0975 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw.rs
@@ -2,7 +2,7 @@
// check-pass
// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw:in-the-test-file
+// compile-flags:--extern-location bar=raw:in-the-test-file -Z unstable-options
#![warn(unused_crate_dependencies)]
//~^ WARNING external crate `bar` unused in
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
index 329a000..2201cf5 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
@@ -5,7 +5,7 @@
use super::UNNEEDED_FIELD_PATTERN;
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
- if let PatKind::Struct(ref npat, ref pfields, _) = pat.kind {
+ if let PatKind::Struct(_, ref npat, ref pfields, _) = pat.kind {
let mut wilds = 0;
let type_name = npat
.segments
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
index 4dd032d..df04453 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
@@ -7,7 +7,7 @@
use super::UNNEEDED_WILDCARD_PATTERN;
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
- if let PatKind::TupleStruct(_, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
+ if let PatKind::TupleStruct(_, _, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
if let Some(rest_index) = patterns.iter().position(|pat| pat.is_rest()) {
if let Some((left_index, left_pat)) = patterns[..rest_index]
.iter()
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index 5292af5..1a23e6a 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -139,7 +139,7 @@
self.check_ident(ident);
}
},
- PatKind::Struct(_, ref fields, _) => {
+ PatKind::Struct(_, _, ref fields, _) => {
for field in fields {
if !field.is_shorthand {
self.visit_pat(&field.pat);
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 3e985fa..1b3c457 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -1,6 +1,6 @@
#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
-use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path};
+use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path, eq_maybe_qself};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{meets_msrv, msrvs, over};
use rustc_ast::mut_visit::*;
@@ -273,16 +273,16 @@
|k| always_pat!(k, Tuple(ps) => ps),
),
// Transform `S(pre, x, post) | ... | S(pre, y, post)` into `S(pre, x | y, post)`.
- TupleStruct(path1, ps1) => extend_with_matching_product(
+ TupleStruct(qself1, path1, ps1) => extend_with_matching_product(
ps1, start, alternatives,
|k, ps1, idx| matches!(
k,
- TupleStruct(path2, ps2) if eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
+ TupleStruct(qself2, path2, ps2) if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
),
- |k| always_pat!(k, TupleStruct(_, ps) => ps),
+ |k| always_pat!(k, TupleStruct(_, _, ps) => ps),
),
// Transform a record pattern `S { fp_0, ..., fp_n }`.
- Struct(path1, fps1, rest1) => extend_with_struct_pat(path1, fps1, *rest1, start, alternatives),
+ Struct(qself1, path1, fps1, rest1) => extend_with_struct_pat(qself1, path1, fps1, *rest1, start, alternatives),
};
alternatives[focus_idx].kind = focus_kind;
@@ -294,6 +294,7 @@
/// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
/// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
fn extend_with_struct_pat(
+ qself1: &Option<ast::QSelf>,
path1: &ast::Path,
fps1: &mut Vec<ast::PatField>,
rest1: bool,
@@ -306,8 +307,9 @@
start,
alternatives,
|k| {
- matches!(k, Struct(path2, fps2, rest2)
+ matches!(k, Struct(qself2, path2, fps2, rest2)
if rest1 == *rest2 // If one struct pattern has `..` so must the other.
+ && eq_maybe_qself(qself1, qself2)
&& eq_path(path1, path2)
&& fps1.len() == fps2.len()
&& fps1.iter().enumerate().all(|(idx_1, fp1)| {
@@ -323,7 +325,7 @@
}))
},
// Extract `p2_k`.
- |k| always_pat!(k, Struct(_, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat),
+ |k| always_pat!(k, Struct(_, _, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat),
);
extend_with_tail_or(&mut fps1[idx].pat, tail_or)
})
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 93e10c8..e6d84bc 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -47,9 +47,9 @@
| (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
(Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
- (TupleStruct(lp, lfs), TupleStruct(rp, rfs)) => eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
- (Struct(lp, lfs, lr), Struct(rp, rfs, rr)) => {
- lr == rr && eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
+ (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
+ (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {
+ lr == rr && eq_maybe_qself(lqself, rqself) &&eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
},
(Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
@@ -78,6 +78,14 @@
l.position == r.position && eq_ty(&l.ty, &r.ty)
}
+pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
+ match (l, r) {
+ (Some(l), Some(r)) => eq_qself(l, r),
+ (None, None) => true,
+ _ => false
+ }
+}
+
pub fn eq_path(l: &Path, r: &Path) -> bool {
over(&l.segments, &r.segments, |l, r| eq_path_seg(l, r))
}
@@ -170,7 +178,8 @@
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
(Struct(lse), Struct(rse)) => {
- eq_path(&lse.path, &rse.path)
+ eq_maybe_qself(&lse.qself, &rse.qself)
+ && eq_path(&lse.path, &rse.path)
&& eq_struct_rest(&lse.rest, &rse.rest)
&& unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r))
},
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 8037d67..b913d1c 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -116,8 +116,8 @@
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
-pub const PTR_COPY: [&str; 4] = ["core", "intrinsics", "", "copy"];
-pub const PTR_COPY_NONOVERLAPPING: [&str; 4] = ["core", "intrinsics", "", "copy_nonoverlapping"];
+pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"];
+pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"];
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"];
pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"];
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 408c0b8..a5b526b 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -346,6 +346,9 @@
/// whether to run `tidy` when a rustdoc test fails
pub has_tidy: bool,
+ /// The current Rust channel
+ pub channel: String,
+
// Configuration for various run-make tests frobbing things like C compilers
// or querying about various LLVM component information.
pub cc: String,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 983934d..26c1710 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -50,6 +50,15 @@
let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
+ // for `-Z gcc-ld=lld`
+ let has_rust_lld = config
+ .compile_lib_path
+ .join("rustlib")
+ .join(&config.target)
+ .join("bin")
+ .join("gcc-ld")
+ .join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
+ .exists();
iter_header(testfile, None, rdr, &mut |ln| {
// we should check if any only-<platform> exists and if it exists
@@ -136,6 +145,10 @@
if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
props.ignore = true;
}
+
+ if !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld") {
+ props.ignore = true;
+ }
}
if let Some(s) = config.parse_aux_build(ln) {
@@ -438,6 +451,9 @@
if let Some(edition) = config.parse_edition(ln) {
self.compile_flags.push(format!("--edition={}", edition));
+ if edition == "2021" {
+ self.compile_flags.push("-Zunstable-options".to_string());
+ }
}
config.parse_and_update_revisions(ln, &mut self.revisions);
@@ -876,6 +892,7 @@
name == util::get_arch(&self.target) || // architecture
name == util::get_pointer_width(&self.target) || // pointer width
name == self.stage_id.split('-').next().unwrap() || // stage
+ name == self.channel || // channel
(self.target != self.host && name == "cross-compile") ||
(name == "endian-big" && util::is_big_endian(&self.target)) ||
(self.remote_test_client.is_some() && name == "remote") ||
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index ca7458d..2c607b6 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -55,6 +55,7 @@
"--llvm-components=",
"--android-cross-path=",
"--target=x86_64-unknown-linux-gnu",
+ "--channel=nightly",
];
let args = args.iter().map(ToString::to_string).collect();
crate::parse_config(args)
@@ -235,6 +236,20 @@
}
#[test]
+fn channel() {
+ let mut config = config();
+ config.channel = "beta".into();
+
+ assert!(parse_rs(&config, "// ignore-beta").ignore);
+ assert!(parse_rs(&config, "// only-nightly").ignore);
+ assert!(parse_rs(&config, "// only-stable").ignore);
+
+ assert!(!parse_rs(&config, "// only-beta").ignore);
+ assert!(!parse_rs(&config, "// ignore-nightly").ignore);
+ assert!(!parse_rs(&config, "// ignore-stable").ignore);
+}
+
+#[test]
fn test_extract_version_range() {
use super::{extract_llvm_version, extract_version_range};
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 08ee8fc..c854663 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -144,7 +144,8 @@
"enable this to generate a Rustfix coverage file, which is saved in \
`./<build_base>/rustfix_missing_coverage.txt`",
)
- .optflag("h", "help", "show this message");
+ .optflag("h", "help", "show this message")
+ .reqopt("", "channel", "current Rust channel", "CHANNEL");
let (argv0, args_) = args.split_first().unwrap();
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
@@ -278,6 +279,7 @@
compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse),
rustfix_coverage: matches.opt_present("rustfix-coverage"),
has_tidy,
+ channel: matches.opt_str("channel").unwrap(),
cc: matches.opt_str("cc").unwrap(),
cxx: matches.opt_str("cxx").unwrap(),
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 931c822..02dffaa 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1785,6 +1785,9 @@
get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), is_dylib);
rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
}
+ if !self.props.aux_crates.is_empty() {
+ rustc.arg("-Zunstable-options");
+ }
aux_dir
}
@@ -2488,6 +2491,7 @@
{
let mut diff_output = File::create(&diff_filename).unwrap();
+ let mut wrote_data = false;
for entry in walkdir::WalkDir::new(out_dir) {
let entry = entry.expect("failed to read file");
let extension = entry.path().extension().and_then(|p| p.to_str());
@@ -2500,17 +2504,28 @@
if let Ok(s) = std::fs::read(&expected_path) { s } else { continue };
let actual_path = entry.path();
let actual = std::fs::read(&actual_path).unwrap();
- diff_output
- .write_all(&unified_diff::diff(
- &expected,
- &expected_path.to_string_lossy(),
- &actual,
- &actual_path.to_string_lossy(),
- 3,
- ))
- .unwrap();
+ let diff = unified_diff::diff(
+ &expected,
+ &expected_path.to_string_lossy(),
+ &actual,
+ &actual_path.to_string_lossy(),
+ 3,
+ );
+ wrote_data |= !diff.is_empty();
+ diff_output.write_all(&diff).unwrap();
}
}
+
+ if !wrote_data {
+ println!("note: diff is identical to nightly rustdoc");
+ assert!(diff_output.metadata().unwrap().len() == 0);
+ return;
+ } else if self.config.verbose {
+ eprintln!("printing diff:");
+ let mut buf = Vec::new();
+ diff_output.read_to_end(&mut buf).unwrap();
+ std::io::stderr().lock().write_all(&mut buf).unwrap();
+ }
}
match self.config.color {
diff --git a/src/tools/miri b/src/tools/miri
index c8713c2..e5c3af6 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit c8713c2f9fc1e28c90876b9ec9557d8c5729757b
+Subproject commit e5c3af6f516311cc4b1fc017c58d83b7442cbc34
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index ced382c..bca9f77 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -107,7 +107,9 @@
}
ast::ExprKind::Unary(op, ref subexpr) => rewrite_unary_op(context, op, subexpr, shape),
ast::ExprKind::Struct(ref struct_expr) => {
- let ast::StructExpr { fields, path, rest } = &**struct_expr;
+ let ast::StructExpr {
+ fields, path, rest, ..
+ } = &**struct_expr;
rewrite_struct_lit(context, path, fields, rest, &expr.attrs, expr.span, shape)
}
ast::ExprKind::Tup(ref items) => {
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index 6824fc6..fa0ef26 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -45,7 +45,7 @@
| ast::PatKind::Path(..)
| ast::PatKind::Range(..) => false,
ast::PatKind::Tuple(ref subpats) => subpats.len() <= 1,
- ast::PatKind::TupleStruct(ref path, ref subpats) => {
+ ast::PatKind::TupleStruct(_, ref path, ref subpats) => {
path.segments.len() <= 1 && subpats.len() <= 1
}
ast::PatKind::Box(ref p) | ast::PatKind::Ref(ref p, _) | ast::PatKind::Paren(ref p) => {
@@ -226,7 +226,7 @@
PatKind::Path(ref q_self, ref path) => {
rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
}
- PatKind::TupleStruct(ref path, ref pat_vec) => {
+ PatKind::TupleStruct(_, ref path, ref pat_vec) => {
let path_str = rewrite_path(context, PathContext::Expr, None, path, shape)?;
rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
}
@@ -244,7 +244,7 @@
.collect();
Some(format!("[{}]", rw.join(", ")))
}
- PatKind::Struct(ref path, ref fields, ellipsis) => {
+ PatKind::Struct(_, ref path, ref fields, ellipsis) => {
rewrite_struct_pat(path, fields, ellipsis, self.span, context, shape)
}
PatKind::MacCall(ref mac) => {
diff --git a/src/version b/src/version
index b7921ae..094d6ad 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.54.0
+1.55.0