From 68d099a175334939047b99888b656661f32e13e3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Sep 2019 13:23:53 +0200 Subject: [PATCH 01/16] Create new error code E0734 for stability attributes used outside of standard library --- src/librustc/error_codes.rs | 1 + src/librustc/middle/stability.rs | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index eee33846139e6..554e1a9ad828d 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2247,4 +2247,5 @@ static X: u32 = 42; E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0728, // `await` must be in an `async` function or block + E0734, // stability attributes may not be used outside of the standard library } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index c06a0feb6a993..c45ae854e99eb 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -199,8 +199,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { let name = attr.name_or_empty(); if [sym::unstable, sym::stable, sym::rustc_deprecated].contains(&name) { attr::mark_used(attr); - self.tcx.sess.span_err(attr.span, "stability attributes may not be used \ - outside of the standard library"); + struct_span_err!( + self.tcx.sess, + attr.span, + E0734, + "stability attributes may not be used outside of the standard library", + ).emit(); } } From 0ec4513d5fe23fabe353e4773682ddb341c9d20f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 25 Sep 2019 11:45:38 -0700 Subject: [PATCH 02/16] Fix format macro expansions spans to be macro-generated New Exprs generated as part of the format macro expansion should get the macro expansion span which has an expansion context, not the span of the format string which does not. --- src/libsyntax_ext/format.rs | 12 ++++++------ src/test/ui/issues/issue-27592.rs | 2 +- src/test/ui/issues/issue-27592.stderr | 7 ++----- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 2765346b333cf..8fc64021b51fc 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -695,7 +695,7 @@ impl<'a, 'b> Context<'a, 'b> { // Now create a vector containing all the arguments let args = locals.into_iter().chain(counts.into_iter()); - let args_array = self.ecx.expr_vec(self.fmtsp, args.collect()); + let args_array = self.ecx.expr_vec(self.macsp, args.collect()); // Constructs an AST equivalent to: // @@ -724,12 +724,12 @@ impl<'a, 'b> Context<'a, 'b> { // // But the nested match expression is proved to perform not as well // as series of let's; the first approach does. - let pat = self.ecx.pat_tuple(self.fmtsp, pats); - let arm = self.ecx.arm(self.fmtsp, pat, args_array); - let head = self.ecx.expr(self.fmtsp, ast::ExprKind::Tup(heads)); - let result = self.ecx.expr_match(self.fmtsp, head, vec![arm]); + let pat = self.ecx.pat_tuple(self.macsp, pats); + let arm = self.ecx.arm(self.macsp, pat, args_array); + let head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads)); + let result = self.ecx.expr_match(self.macsp, head, vec![arm]); - let args_slice = self.ecx.expr_addr_of(self.fmtsp, result); + let args_slice = self.ecx.expr_addr_of(self.macsp, result); // Now create the fmt::Arguments struct with all our locals we created. let (fn_name, fn_args) = if self.all_pieces_simple { diff --git a/src/test/ui/issues/issue-27592.rs b/src/test/ui/issues/issue-27592.rs index b023ea18ac9a9..88f70f584022d 100644 --- a/src/test/ui/issues/issue-27592.rs +++ b/src/test/ui/issues/issue-27592.rs @@ -15,5 +15,5 @@ impl ::std::fmt::Write for Stream { fn main() { write(|| format_args!("{}", String::from("Hello world"))); //~^ ERROR cannot return value referencing temporary value - //~| ERROR cannot return value referencing temporary value + //~| ERROR cannot return reference to temporary value } diff --git a/src/test/ui/issues/issue-27592.stderr b/src/test/ui/issues/issue-27592.stderr index 9d3eaa9705d44..c8649d82d7451 100644 --- a/src/test/ui/issues/issue-27592.stderr +++ b/src/test/ui/issues/issue-27592.stderr @@ -7,14 +7,11 @@ LL | write(|| format_args!("{}", String::from("Hello world"))); | | temporary value created here | returns a value referencing data owned by the current function -error[E0515]: cannot return value referencing temporary value +error[E0515]: cannot return reference to temporary value --> $DIR/issue-27592.rs:16:14 | LL | write(|| format_args!("{}", String::from("Hello world"))); - | ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | temporary value created here - | returns a value referencing data owned by the current function + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function error: aborting due to 2 previous errors From 0ebb044eb1bc1a930ae777e41347e960b8c419eb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Sep 2019 13:58:42 +0200 Subject: [PATCH 03/16] Add long error explanation for E0734 --- src/librustc/error_codes.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 554e1a9ad828d..f01efedd659cd 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2184,6 +2184,23 @@ Examples of erroneous code: static X: u32 = 42; ``` "##, + +E0734: r##" +A stability attribute has been used outside of the standard library. + +Erroneous code examples: + +```compile_fail,E0734 +#[rustc_deprecated(since = "b", reason = "text")] // invalid +#[stable(feature = "a", since = "b")] // invalid +#[unstable(feature = "b", issue = "0")] // invalid +fn foo(){} +``` + +These attributes are meant to only be used by the standard library and are +rejected in your own crates. +"##, + ; // E0006, // merged with E0005 // E0101, // replaced with E0282 @@ -2247,5 +2264,4 @@ static X: u32 = 42; E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0728, // `await` must be in an `async` function or block - E0734, // stability attributes may not be used outside of the standard library } From 2e7868389abca4314d3732efd097d6de1cb498a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Sep 2019 13:58:52 +0200 Subject: [PATCH 04/16] Update ui tests --- .../issue-43106-gating-of-rustc_deprecated.stderr | 15 ++++++++------- .../issue-43106-gating-of-stable.stderr | 15 ++++++++------- .../issue-43106-gating-of-unstable.stderr | 15 ++++++++------- .../feature-gates/feature-gate-staged_api.stderr | 5 +++-- ...ity-attribute-non-staged-force-unstable.stderr | 7 ++++--- .../stability-attribute-non-staged.stderr | 7 ++++--- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr index 4eead36910356..8c6c26f7b2d81 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr @@ -1,40 +1,40 @@ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:7:1 | LL | #![rustc_deprecated()] | ^^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:10:1 | LL | #[rustc_deprecated()] | ^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:13:17 | LL | mod inner { #![rustc_deprecated()] } | ^^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:16:5 | LL | #[rustc_deprecated()] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:19:5 | LL | #[rustc_deprecated()] struct S; | ^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:22:5 | LL | #[rustc_deprecated()] type T = S; | ^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:25:5 | LL | #[rustc_deprecated()] impl S { } @@ -42,3 +42,4 @@ LL | #[rustc_deprecated()] impl S { } error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr index 03410eabe3652..09dabd293ff97 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr @@ -1,40 +1,40 @@ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:7:1 | LL | #![stable()] | ^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:10:1 | LL | #[stable()] | ^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:13:17 | LL | mod inner { #![stable()] } | ^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:16:5 | LL | #[stable()] fn f() { } | ^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:19:5 | LL | #[stable()] struct S; | ^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:22:5 | LL | #[stable()] type T = S; | ^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:25:5 | LL | #[stable()] impl S { } @@ -42,3 +42,4 @@ LL | #[stable()] impl S { } error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr index 5952b3836aac8..49da2c59580e7 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr @@ -1,40 +1,40 @@ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:7:1 | LL | #![unstable()] | ^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:10:1 | LL | #[unstable()] | ^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:13:17 | LL | mod inner { #![unstable()] } | ^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:16:5 | LL | #[unstable()] fn f() { } | ^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:19:5 | LL | #[unstable()] struct S; | ^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:22:5 | LL | #[unstable()] type T = S; | ^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:25:5 | LL | #[unstable()] impl S { } @@ -42,3 +42,4 @@ LL | #[unstable()] impl S { } error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/feature-gates/feature-gate-staged_api.stderr b/src/test/ui/feature-gates/feature-gate-staged_api.stderr index f0db47fe8a875..a71d26ce16f5b 100644 --- a/src/test/ui/feature-gates/feature-gate-staged_api.stderr +++ b/src/test/ui/feature-gates/feature-gate-staged_api.stderr @@ -1,10 +1,10 @@ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/feature-gate-staged_api.rs:1:1 | LL | #![stable(feature = "a", since = "b")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/feature-gate-staged_api.rs:8:1 | LL | #[stable(feature = "a", since = "b")] @@ -12,3 +12,4 @@ LL | #[stable(feature = "a", since = "b")] error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/stability-attribute/stability-attribute-non-staged-force-unstable.stderr b/src/test/ui/stability-attribute/stability-attribute-non-staged-force-unstable.stderr index 77f896a86d58a..32b0f405d6fb0 100644 --- a/src/test/ui/stability-attribute/stability-attribute-non-staged-force-unstable.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-non-staged-force-unstable.stderr @@ -1,16 +1,16 @@ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/stability-attribute-non-staged-force-unstable.rs:3:1 | LL | #[unstable()] | ^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/stability-attribute-non-staged-force-unstable.rs:4:1 | LL | #[stable()] | ^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/stability-attribute-non-staged-force-unstable.rs:5:1 | LL | #[rustc_deprecated()] @@ -18,3 +18,4 @@ LL | #[rustc_deprecated()] error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0734`. diff --git a/src/test/ui/stability-attribute/stability-attribute-non-staged.stderr b/src/test/ui/stability-attribute/stability-attribute-non-staged.stderr index e98f789f54c7d..7648effc480b5 100644 --- a/src/test/ui/stability-attribute/stability-attribute-non-staged.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-non-staged.stderr @@ -1,16 +1,16 @@ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/stability-attribute-non-staged.rs:1:1 | LL | #[unstable()] | ^^^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/stability-attribute-non-staged.rs:2:1 | LL | #[stable()] | ^^^^^^^^^^^ -error: stability attributes may not be used outside of the standard library +error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/stability-attribute-non-staged.rs:3:1 | LL | #[rustc_deprecated()] @@ -18,3 +18,4 @@ LL | #[rustc_deprecated()] error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0734`. From ecfe92f75e7f9a6727efb13ea1c666e98de7ca90 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Sep 2019 13:24:59 +0200 Subject: [PATCH 05/16] Don't check error_codes files for lints --- src/tools/tidy/src/features.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 50e9116c778ea..309f3c3ecd581 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -384,7 +384,7 @@ fn map_lib_features(base_src_path: &Path, let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); if !filename.ends_with(".rs") || filename == "features.rs" || - filename == "diagnostic_list.rs" { + filename == "diagnostic_list.rs" || filename == "error_codes.rs" { return; } From ac9aed56e4dc62c4959ae0c14cec585994302c93 Mon Sep 17 00:00:00 2001 From: Tomas Tauber <2410580+tomtau@users.noreply.github.com> Date: Fri, 27 Sep 2019 21:32:04 +0800 Subject: [PATCH 06/16] getting more context for duplicate lang items (fixes #60561) Where possible, the error message includes the name of the crate that brought in the crate with duplicate lang items (which helps with debugging). This information is passed on from cstore using the `extern_crate` query. --- src/librustc/middle/cstore.rs | 9 ++++- src/librustc/middle/lang_items.rs | 34 ++++++++++++++++--- src/librustc/ty/print/pretty.rs | 2 +- src/librustc_metadata/creader.rs | 15 ++++---- src/librustc_metadata/cstore_impl.rs | 2 +- src/test/ui/duplicate_entry_error.stderr | 2 +- src/test/ui/error-codes/E0152.stderr | 2 +- .../ui/panic-handler/panic-handler-std.stderr | 2 +- 8 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index de84fcd7160df..ddf6262b7382e 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -126,10 +126,17 @@ pub struct ExternCrate { /// used to select the extern with the shortest path pub path_len: usize, + /// Crate that depends on this crate + pub dependency_of: CrateNum, +} + +impl ExternCrate { /// If true, then this crate is the crate named by the extern /// crate referenced above. If false, then this crate is a dep /// of the crate. - pub direct: bool, + pub fn is_direct(&self) -> bool { + self.dependency_of == LOCAL_CRATE + } } #[derive(Copy, Clone, Debug, HashStable)] diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index c5d9a722ae18e..cab929389d6a4 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -13,6 +13,7 @@ use crate::hir::def_id::DefId; use crate::hir::check_attr::Target; use crate::ty::{self, TyCtxt}; use crate::middle::weak_lang_items; +use crate::middle::cstore::ExternCrate; use crate::util::nodemap::FxHashMap; use syntax::ast; @@ -182,16 +183,39 @@ impl LanguageItemCollector<'tcx> { E0152, "duplicate lang item found: `{}`.", name), - None => self.tcx.sess.struct_err(&format!( - "duplicate lang item in crate `{}`: `{}`.", - self.tcx.crate_name(item_def_id.krate), - name)), + None => { + match self.tcx.extern_crate(item_def_id) { + Some(ExternCrate {dependency_of, ..}) => { + self.tcx.sess.struct_err(&format!( + "duplicate lang item in crate `{}` (which `{}` depends on): `{}`.", + self.tcx.crate_name(item_def_id.krate), + self.tcx.crate_name(*dependency_of), + name)) + }, + _ => { + self.tcx.sess.struct_err(&format!( + "duplicate lang item in crate `{}`: `{}`.", + self.tcx.crate_name(item_def_id.krate), + name)) + } + } + }, }; if let Some(span) = self.tcx.hir().span_if_local(original_def_id) { span_note!(&mut err, span, "first defined here."); } else { - err.note(&format!("first defined in crate `{}`.", + match self.tcx.extern_crate(original_def_id) { + Some(ExternCrate {dependency_of, ..}) => { + err.note(&format!( + "first defined in crate `{}` (which `{}` depends on).", + self.tcx.crate_name(original_def_id.krate), + self.tcx.crate_name(*dependency_of))); + }, + _ => { + err.note(&format!("first defined in crate `{}`.", self.tcx.crate_name(original_def_id.krate))); + } + } } err.emit(); } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 2bc87d6b8ba5e..fe0d0fad3a565 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -278,7 +278,7 @@ pub trait PrettyPrinter<'tcx>: match self.tcx().extern_crate(def_id) { Some(&ExternCrate { src: ExternCrateSource::Extern(def_id), - direct: true, + dependency_of: LOCAL_CRATE, span, .. }) => { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index af41b6a4c857f..91b9f38ebce1f 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -17,6 +17,7 @@ use rustc::middle::cstore::{ExternCrate, ExternCrateSource}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; +use rustc::hir::def_id::LOCAL_CRATE; use std::ops::Deref; use std::path::PathBuf; @@ -430,7 +431,7 @@ impl<'a> CrateLoader<'a> { mut extern_crate: ExternCrate, visited: &mut FxHashSet<(CrateNum, bool)>) { - if !visited.insert((cnum, extern_crate.direct)) { return } + if !visited.insert((cnum, extern_crate.is_direct())) { return } let cmeta = self.cstore.get_crate_data(cnum); let mut old_extern_crate = cmeta.extern_crate.borrow_mut(); @@ -441,14 +442,14 @@ impl<'a> CrateLoader<'a> { // - shorter paths to longer (tuple.2). let new_rank = ( true, - extern_crate.direct, + extern_crate.is_direct(), cmp::Reverse(extern_crate.path_len), ); let old_rank = match *old_extern_crate { None => (false, false, cmp::Reverse(usize::max_value())), Some(ref c) => ( true, - c.direct, + c.is_direct(), cmp::Reverse(c.path_len), ), }; @@ -460,7 +461,7 @@ impl<'a> CrateLoader<'a> { drop(old_extern_crate); // Propagate the extern crate info to dependencies. - extern_crate.direct = false; + extern_crate.dependency_of = cnum; for &dep_cnum in cmeta.dependencies.borrow().iter() { self.update_extern_crate(dep_cnum, extern_crate, visited); } @@ -1030,7 +1031,7 @@ impl<'a> CrateLoader<'a> { src: ExternCrateSource::Extern(def_id), span: item.span, path_len, - direct: true, + dependency_of: LOCAL_CRATE, }, &mut FxHashSet::default(), ); @@ -1057,7 +1058,7 @@ impl<'a> CrateLoader<'a> { span, // to have the least priority in `update_extern_crate` path_len: usize::max_value(), - direct: true, + dependency_of: LOCAL_CRATE, }, &mut FxHashSet::default(), ); @@ -1081,7 +1082,7 @@ impl<'a> CrateLoader<'a> { span, // to have the least priority in `update_extern_crate` path_len: usize::max_value(), - direct: true, + dependency_of: LOCAL_CRATE, }, &mut FxHashSet::default(), ); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 11121ee875dda..0cca4dfa4c5ef 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -233,7 +233,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, missing_extern_crate_item => { let r = match *cdata.extern_crate.borrow() { - Some(extern_crate) if !extern_crate.direct => true, + Some(extern_crate) if !extern_crate.is_direct() => true, _ => false, }; r diff --git a/src/test/ui/duplicate_entry_error.stderr b/src/test/ui/duplicate_entry_error.stderr index 1892ad38a594b..02be11d1fd0e5 100644 --- a/src/test/ui/duplicate_entry_error.stderr +++ b/src/test/ui/duplicate_entry_error.stderr @@ -7,7 +7,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std`. + = note: first defined in crate `std` (which `duplicate_entry_error` depends on). error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index 26e6e2e1bce7e..d4b59a1148e60 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -4,7 +4,7 @@ error[E0152]: duplicate lang item found: `arc`. LL | struct Foo; | ^^^^^^^^^^^ | - = note: first defined in crate `alloc`. + = note: first defined in crate `alloc` (which `std` depends on). error: aborting due to previous error diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr index 3224031111650..e6d24348ca825 100644 --- a/src/test/ui/panic-handler/panic-handler-std.stderr +++ b/src/test/ui/panic-handler/panic-handler-std.stderr @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std`. + = note: first defined in crate `std` (which `panic_handler_std` depends on). error: argument should be `&PanicInfo` --> $DIR/panic-handler-std.rs:7:16 From f922483112e407d69c02eb653d7e4bc0ffe2cfa0 Mon Sep 17 00:00:00 2001 From: Wojciech Baranowski Date: Thu, 26 Sep 2019 18:14:27 +0300 Subject: [PATCH 07/16] Print ParamTy span when accessing a field (#52082) --- src/librustc_typeck/check/expr.rs | 34 ++++++++- src/test/ui/typeck/issue-52082.rs | 54 +++++++++++++++ src/test/ui/typeck/issue-52082.stderr | 99 +++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/typeck/issue-52082.rs create mode 100644 src/test/ui/typeck/issue-52082.stderr diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 97fcfd7151a1c..c2beaddecd5c1 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1393,9 +1393,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = self.no_such_field_err(field.span, field, expr_t); match expr_t.kind { - ty::Adt(def, _) if !def.is_enum() => { - self.suggest_fields_on_recordish(&mut err, def, field); - } ty::Array(_, len) => { self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); } @@ -1405,6 +1402,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => {} } + let deref_t = match expr_t.kind { + ty::Ref(_, ref_t, _) => ref_t, + _ => &expr_t + }; + match deref_t.kind { + ty::Adt(def, _) if !def.is_enum() => { + self.suggest_fields_on_recordish(&mut err, def, field); + } + ty::Param(param_ty) => { + self.explain_param(&mut err, param_ty); + } + _ => {} + } + if field.name == kw::Await { // We know by construction that `.await` is either on Rust 2015 // or results in `ExprKind::Await`. Suggest switching the edition to 2018. @@ -1491,6 +1502,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } + fn explain_param( + &self, + err: &mut DiagnosticBuilder<'_>, + param: ty::ParamTy, + ) { + let generics = self.tcx.generics_of(self.body_id.owner_def_id()); + let param_def_id = generics.type_param(¶m, self.tcx).def_id; + let param_hir_id = match self.tcx.hir().as_local_hir_id(param_def_id) { + Some(x) => x, + None => return, + }; + let param_span = self.tcx.hir().span(param_hir_id); + let param_name = self.tcx.hir().ty_param_name(param_hir_id); + + err.span_note(param_span, &format!("Type parameter '{}' was declared here", param_name)); + } + fn suggest_fields_on_recordish( &self, err: &mut DiagnosticBuilder<'_>, diff --git a/src/test/ui/typeck/issue-52082.rs b/src/test/ui/typeck/issue-52082.rs new file mode 100644 index 0000000000000..c57e8149574c9 --- /dev/null +++ b/src/test/ui/typeck/issue-52082.rs @@ -0,0 +1,54 @@ +// Fix issue 52082: Confusing error if accidentially defining a type paramter with the same name as +// an existing type +// +// To this end, make sure that when trying to retrieve a field of a (reference to) type parameter, +// rustc points to the point where the parameter was defined. +#[derive(Debug)] +struct Point +{ + x: i32, + y: i32 +} + +impl Point +{ + fn add(a: &Point, b: &Point) -> Point + { + Point {x: a.x + b.x, y: a.y + b.y} + } +} + +trait Eq +{ + fn equals_ref(a: &T, b: &T) -> bool; + fn equals_val(a: T, b: T) -> bool; +} + +impl Eq for Point +{ + fn equals_ref(a: &Point, b: &Point) -> bool + { + a.x == b.x && a.y == b.y //~ ERROR no field `x` on type `&Point` [E0609] + //~|ERROR no field `x` on type `&Point` [E0609] + //~|ERROR no field `y` on type `&Point` [E0609] + //~|ERROR no field `y` on type `&Point` [E0609] + } + + fn equals_val(a: Point, b: Point) -> bool + { + a.x == b.x && a.y == b.y //~ ERROR no field `x` on type `Point` [E0609] + //~|ERROR no field `x` on type `Point` [E0609] + //~|ERROR no field `y` on type `Point` [E0609] + //~|ERROR no field `y` on type `Point` [E0609] + } +} + +fn main() +{ + let p1 = Point {x: 0, y: 10}; + let p2 = Point {x: 20, y: 42}; + println!("{:?}", Point::add(&p1, &p2)); + println!("p1: {:?}, p2: {:?}", p1, p2); + println!("&p1 == &p2: {:?}", Point::equals_ref(&p1, &p2)); + println!("p1 == p2: {:?}", Point::equals_val(p1, p2)); +} diff --git a/src/test/ui/typeck/issue-52082.stderr b/src/test/ui/typeck/issue-52082.stderr new file mode 100644 index 0000000000000..b6b616630d51f --- /dev/null +++ b/src/test/ui/typeck/issue-52082.stderr @@ -0,0 +1,99 @@ +error[E0609]: no field `x` on type `&Point` + --> $DIR/issue-52082.rs:31:11 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:29:19 + | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ^^^^^ + +error[E0609]: no field `x` on type `&Point` + --> $DIR/issue-52082.rs:31:18 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:29:19 + | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ^^^^^ + +error[E0609]: no field `y` on type `&Point` + --> $DIR/issue-52082.rs:31:25 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:29:19 + | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ^^^^^ + +error[E0609]: no field `y` on type `&Point` + --> $DIR/issue-52082.rs:31:32 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:29:19 + | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ^^^^^ + +error[E0609]: no field `x` on type `Point` + --> $DIR/issue-52082.rs:39:11 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:37:19 + | +LL | fn equals_val(a: Point, b: Point) -> bool + | ^^^^^ + +error[E0609]: no field `x` on type `Point` + --> $DIR/issue-52082.rs:39:18 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:37:19 + | +LL | fn equals_val(a: Point, b: Point) -> bool + | ^^^^^ + +error[E0609]: no field `y` on type `Point` + --> $DIR/issue-52082.rs:39:25 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:37:19 + | +LL | fn equals_val(a: Point, b: Point) -> bool + | ^^^^^ + +error[E0609]: no field `y` on type `Point` + --> $DIR/issue-52082.rs:39:32 + | +LL | a.x == b.x && a.y == b.y + | ^ + | +note: Type parameter 'Point' was declared here + --> $DIR/issue-52082.rs:37:19 + | +LL | fn equals_val(a: Point, b: Point) -> bool + | ^^^^^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0609`. From d35f25cf96f2d0e6e8d0dc4ab48b9755f7703c9c Mon Sep 17 00:00:00 2001 From: nathanwhit Date: Wed, 11 Sep 2019 22:05:26 -0400 Subject: [PATCH 08/16] Filter out stmts made for the redundant_semicolon lint when pretty-printing --- src/libsyntax/print/pprust.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a5792dab4749c..4b9c2d13f26b9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1657,9 +1657,18 @@ impl<'a> State<'a> { } } ast::StmtKind::Semi(ref expr) => { - self.space_if_not_bol(); - self.print_expr_outer_attr_style(expr, false); - self.s.word(";"); + match expr.kind { + // Filter out empty `Tup` exprs created for the `redundant_semicolon` + // lint, as they shouldn't be visible and interact poorly + // with proc macros. + ast::ExprKind::Tup(ref exprs) if exprs.is_empty() + && expr.attrs.is_empty() => (), + _ => { + self.space_if_not_bol(); + self.print_expr_outer_attr_style(expr, false); + self.s.word(";"); + } + } } ast::StmtKind::Mac(ref mac) => { let (ref mac, style, ref attrs) = **mac; From 66c33c0e92c456ddec24c0b11475e912d1507934 Mon Sep 17 00:00:00 2001 From: Nathan Date: Fri, 27 Sep 2019 22:51:25 -0400 Subject: [PATCH 09/16] Add test for redundant_semicolon lint interaction with proc macro attrs --- .../redundant-semi-proc-macro-def.rs | 12 +++++++++++ .../redundant-semi-proc-macro.rs | 19 +++++++++++++++++ .../redundant-semi-proc-macro.stderr | 21 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/test/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs create mode 100644 src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs create mode 100644 src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr diff --git a/src/test/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs b/src/test/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs new file mode 100644 index 0000000000000..5a94ccd746803 --- /dev/null +++ b/src/test/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs @@ -0,0 +1,12 @@ +// force-host +// no-prefer-dynamic +#![crate_type="proc-macro"] +#![crate_name="redundant_semi_proc_macro"] +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn should_preserve_spans(_attr: TokenStream, item: TokenStream) -> TokenStream { + eprintln!("{:?}", item); + item +} diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs new file mode 100644 index 0000000000000..f207b235735fe --- /dev/null +++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs @@ -0,0 +1,19 @@ +// aux-build:redundant-semi-proc-macro-def.rs + +#![deny(redundant_semicolon)] +extern crate redundant_semi_proc_macro; +use redundant_semi_proc_macro::should_preserve_spans; + +#[should_preserve_spans] +fn span_preservation() { + let tst = 123;; //~ ERROR unnecessary trailing semicolon + match tst { + // Redundant semicolons are parsed as empty tuple exprs + // for the lint, so ensure the lint doesn't affect + // empty tuple exprs explicitly in source. + 123 => (), + _ => () + };;; //~ ERROR unnecessary trailing semicolons +} + +fn main() {} diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr new file mode 100644 index 0000000000000..5f289c0914d6e --- /dev/null +++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr @@ -0,0 +1,21 @@ +TokenStream [Ident { ident: "fn", span: #0 bytes(197..199) }, Ident { ident: "span_preservation", span: #0 bytes(200..217) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(217..219) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(227..230) }, Ident { ident: "tst", span: #0 bytes(231..234) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(235..236) }, Literal { lit: Lit { kind: Integer, symbol: 123, suffix: None }, span: Span { lo: BytePos(237), hi: BytePos(240), ctxt: #0 } }, Punct { ch: ';', spacing: Joint, span: #0 bytes(240..241) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(241..242) }, Ident { ident: "match", span: #0 bytes(288..293) }, Ident { ident: "tst", span: #0 bytes(294..297) }, Group { delimiter: Brace, stream: TokenStream [Literal { lit: Lit { kind: Integer, symbol: 123, suffix: None }, span: Span { lo: BytePos(482), hi: BytePos(485), ctxt: #0 } }, Punct { ch: '=', spacing: Joint, span: #0 bytes(486..488) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(486..488) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(489..491) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(491..492) }, Ident { ident: "_", span: #0 bytes(501..502) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(503..505) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(503..505) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(506..508) }], span: #0 bytes(298..514) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(514..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(516..517) }], span: #0 bytes(221..561) }] +error: unnecessary trailing semicolon + --> $DIR/redundant-semi-proc-macro.rs:9:19 + | +LL | let tst = 123;; + | ^ help: remove this semicolon + | +note: lint level defined here + --> $DIR/redundant-semi-proc-macro.rs:3:9 + | +LL | #![deny(redundant_semicolon)] + | ^^^^^^^^^^^^^^^^^^^ + +error: unnecessary trailing semicolons + --> $DIR/redundant-semi-proc-macro.rs:16:7 + | +LL | };;; + | ^^ help: remove these semicolons + +error: aborting due to 2 previous errors + From 800bd3a11c45ef62726b1c29c2c165e2dbf85ae2 Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Tue, 3 Sep 2019 15:42:54 +0530 Subject: [PATCH 10/16] data_structures: Add deterministic FxHashMap and FxHashSet wrappers StableMap A wrapper for FxHashMap that allows to insert, remove, get and get_mut but no iteration support. StableSet A wrapper for FxHashSet that allows to insert, remove, get and create a sorted vector from a hashset but no iteration support. --- src/librustc_data_structures/lib.rs | 2 + src/librustc_data_structures/stable_map.rs | 99 ++++++++++++++++++++++ src/librustc_data_structures/stable_set.rs | 77 +++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 src/librustc_data_structures/stable_map.rs create mode 100644 src/librustc_data_structures/stable_set.rs diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index f7593501959c7..d6e9c479c9b8d 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -73,6 +73,7 @@ pub mod box_region; pub mod const_cstr; pub mod flock; pub mod fx; +pub mod stable_map; pub mod graph; pub mod indexed_vec; pub mod jobserver; @@ -84,6 +85,7 @@ pub mod small_c_str; pub mod snapshot_map; pub use ena::snapshot_vec; pub mod sorted_map; +pub mod stable_set; #[macro_use] pub mod stable_hasher; pub mod sync; pub mod sharded; diff --git a/src/librustc_data_structures/stable_map.rs b/src/librustc_data_structures/stable_map.rs new file mode 100644 index 0000000000000..f69f28e14b2a1 --- /dev/null +++ b/src/librustc_data_structures/stable_map.rs @@ -0,0 +1,99 @@ +pub use rustc_hash::FxHashMap; +use std::borrow::Borrow; +use std::collections::hash_map::Entry; +use std::fmt; +use std::hash::Hash; + +/// A deterministic wrapper around FxHashMap that does not provide iteration support. +/// +/// It supports insert, remove, get and get_mut functions from FxHashMap. +/// It also allows to convert hashmap to a sorted vector with the method `into_sorted_vector()`. +#[derive(Clone)] +pub struct StableMap { + base: FxHashMap, +} + +impl Default for StableMap +where + K: Eq + Hash, +{ + fn default() -> StableMap { + StableMap::new() + } +} + +impl fmt::Debug for StableMap +where + K: Eq + Hash + fmt::Debug, + V: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.base) + } +} + +impl PartialEq for StableMap +where + K: Eq + Hash, + V: PartialEq, +{ + fn eq(&self, other: &StableMap) -> bool { + self.base == other.base + } +} + +impl Eq for StableMap +where + K: Eq + Hash, + V: Eq, +{} + +impl StableMap +where + K: Eq + Hash, +{ + pub fn new() -> StableMap { + StableMap { base: FxHashMap::default() } + } + + pub fn into_sorted_vector(self) -> Vec<(K, V)> + where + K: Ord + Copy, + { + let mut vector = self.base.into_iter().collect::>(); + vector.sort_unstable_by_key(|pair| pair.0); + vector + } + + pub fn entry(&mut self, k: K) -> Entry<'_, K, V> { + self.base.entry(k) + } + + pub fn get(&self, k: &Q) -> Option<&V> + where + K: Borrow, + Q: Hash + Eq, + { + self.base.get(k) + } + + pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> + where + K: Borrow, + Q: Hash + Eq, + { + self.base.get_mut(k) + } + + pub fn insert(&mut self, k: K, v: V) -> Option { + self.base.insert(k, v) + } + + pub fn remove(&mut self, k: &Q) -> Option + where + K: Borrow, + Q: Hash + Eq, + { + self.base.remove(k) + } +} diff --git a/src/librustc_data_structures/stable_set.rs b/src/librustc_data_structures/stable_set.rs new file mode 100644 index 0000000000000..c7ca74f5fbd9d --- /dev/null +++ b/src/librustc_data_structures/stable_set.rs @@ -0,0 +1,77 @@ +pub use rustc_hash::FxHashSet; +use std::borrow::Borrow; +use std::fmt; +use std::hash::Hash; + +/// A deterministic wrapper around FxHashSet that does not provide iteration support. +/// +/// It supports insert, remove, get functions from FxHashSet. +/// It also allows to convert hashset to a sorted vector with the method `into_sorted_vector()`. +#[derive(Clone)] +pub struct StableSet { + base: FxHashSet, +} + +impl Default for StableSet +where + T: Eq + Hash, +{ + fn default() -> StableSet { + StableSet::new() + } +} + +impl fmt::Debug for StableSet +where + T: Eq + Hash + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.base) + } +} + +impl PartialEq> for StableSet +where + T: Eq + Hash, +{ + fn eq(&self, other: &StableSet) -> bool { + self.base == other.base + } +} + +impl Eq for StableSet where T: Eq + Hash {} + +impl StableSet { + pub fn new() -> StableSet { + StableSet { base: FxHashSet::default() } + } + + pub fn into_sorted_vector(self) -> Vec + where + T: Ord, + { + let mut vector = self.base.into_iter().collect::>(); + vector.sort_unstable(); + vector + } + + pub fn get(&self, value: &Q) -> Option<&T> + where + T: Borrow, + Q: Hash + Eq, + { + self.base.get(value) + } + + pub fn insert(&mut self, value: T) -> bool { + self.base.insert(value) + } + + pub fn remove(&mut self, value: &Q) -> bool + where + T: Borrow, + Q: Hash + Eq, + { + self.base.remove(value) + } +} From fd505d7fd52983a374f4087f46e2ae490b9cdb86 Mon Sep 17 00:00:00 2001 From: Nils Liberg Date: Fri, 27 Sep 2019 13:54:05 +0200 Subject: [PATCH 11/16] Improve wording in documentation of MaybeUninit --- src/libcore/mem/maybe_uninit.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 9e9e901c76d3f..792ce9dfad419 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -5,12 +5,12 @@ use crate::mem::ManuallyDrop; /// /// # Initialization invariant /// -/// The compiler, in general, assumes that variables are properly initialized -/// at their respective type. For example, a variable of reference type must -/// be aligned and non-NULL. This is an invariant that must *always* be upheld, -/// even in unsafe code. As a consequence, zero-initializing a variable of reference -/// type causes instantaneous [undefined behavior][ub], no matter whether that reference -/// ever gets used to access memory: +/// The compiler, in general, assumes that a variable is properly initialized +/// according to the requirements of the variable's type. For example, a variable of +/// reference type must be aligned and non-NULL. This is an invariant that must +/// *always* be upheld, even in unsafe code. As a consequence, zero-initializing a +/// variable of reference type causes instantaneous [undefined behavior][ub], +/// no matter whether that reference ever gets used to access memory: /// /// ```rust,no_run /// # #![allow(invalid_value)] From f3744a1b3dd1c3d6a27a6061fc1866194a453ee2 Mon Sep 17 00:00:00 2001 From: Wojciech Baranowski Date: Sat, 28 Sep 2019 14:39:19 +0300 Subject: [PATCH 12/16] Implement CRs --- src/librustc_typeck/check/expr.rs | 26 ++---- src/test/ui/derived-errors/issue-30580.stderr | 2 +- src/test/ui/issues/issue-31011.stderr | 3 + .../structs/struct-pat-derived-error.stderr | 2 +- ...52082-type-param-shadows-existing-type.rs} | 0 ...2-type-param-shadows-existing-type.stderr} | 88 +++++++------------ 6 files changed, 46 insertions(+), 75 deletions(-) rename src/test/ui/typeck/{issue-52082.rs => issue-52082-type-param-shadows-existing-type.rs} (100%) rename src/test/ui/typeck/{issue-52082.stderr => issue-52082-type-param-shadows-existing-type.stderr} (55%) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index c2beaddecd5c1..dae4db4003aeb 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1392,26 +1392,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if !expr_t.is_primitive_ty() { let mut err = self.no_such_field_err(field.span, field, expr_t); - match expr_t.kind { + match expr_t.peel_refs().kind { ty::Array(_, len) => { self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); } ty::RawPtr(..) => { self.suggest_first_deref_field(&mut err, expr, base, field); } - _ => {} - } - - let deref_t = match expr_t.kind { - ty::Ref(_, ref_t, _) => ref_t, - _ => &expr_t - }; - match deref_t.kind { ty::Adt(def, _) if !def.is_enum() => { self.suggest_fields_on_recordish(&mut err, def, field); } ty::Param(param_ty) => { - self.explain_param(&mut err, param_ty); + self.point_at_param_definition(&mut err, param_ty); } _ => {} } @@ -1502,13 +1494,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn explain_param( - &self, - err: &mut DiagnosticBuilder<'_>, - param: ty::ParamTy, - ) { + fn point_at_param_definition(&self, err: &mut DiagnosticBuilder<'_>, param: ty::ParamTy) { let generics = self.tcx.generics_of(self.body_id.owner_def_id()); - let param_def_id = generics.type_param(¶m, self.tcx).def_id; + let generic_param = generics.type_param(¶m, self.tcx); + if let ty::GenericParamDefKind::Type{synthetic: Some(..), ..} = generic_param.kind { + return; + } + let param_def_id = generic_param.def_id; let param_hir_id = match self.tcx.hir().as_local_hir_id(param_def_id) { Some(x) => x, None => return, @@ -1516,7 +1508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let param_span = self.tcx.hir().span(param_hir_id); let param_name = self.tcx.hir().ty_param_name(param_hir_id); - err.span_note(param_span, &format!("Type parameter '{}' was declared here", param_name)); + err.span_label(param_span, &format!("type parameter '{}' declared here", param_name)); } fn suggest_fields_on_recordish( diff --git a/src/test/ui/derived-errors/issue-30580.stderr b/src/test/ui/derived-errors/issue-30580.stderr index 14c575f2699a6..7bd0eaf77a95d 100644 --- a/src/test/ui/derived-errors/issue-30580.stderr +++ b/src/test/ui/derived-errors/issue-30580.stderr @@ -2,7 +2,7 @@ error[E0609]: no field `c` on type `&Foo` --> $DIR/issue-30580.rs:12:11 | LL | b.c; - | ^ + | ^ help: a field with a similar name exists: `a` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-31011.stderr b/src/test/ui/issues/issue-31011.stderr index ab0069510fcc0..c7618e0835b8d 100644 --- a/src/test/ui/issues/issue-31011.stderr +++ b/src/test/ui/issues/issue-31011.stderr @@ -4,6 +4,9 @@ error[E0609]: no field `trace` on type `&T` LL | if $ctx.trace { | ^^^^^ ... +LL | fn wrap(context: &T) -> () + | - type parameter 'T' declared here +LL | { LL | log!(context, "entered wrapper"); | --------------------------------- in this macro invocation diff --git a/src/test/ui/structs/struct-pat-derived-error.stderr b/src/test/ui/structs/struct-pat-derived-error.stderr index 673715cd3ef6b..6526ef58a4479 100644 --- a/src/test/ui/structs/struct-pat-derived-error.stderr +++ b/src/test/ui/structs/struct-pat-derived-error.stderr @@ -2,7 +2,7 @@ error[E0609]: no field `d` on type `&A` --> $DIR/struct-pat-derived-error.rs:8:31 | LL | let A { x, y } = self.d; - | ^ + | ^ help: a field with a similar name exists: `b` error[E0026]: struct `A` does not have fields named `x`, `y` --> $DIR/struct-pat-derived-error.rs:8:17 diff --git a/src/test/ui/typeck/issue-52082.rs b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.rs similarity index 100% rename from src/test/ui/typeck/issue-52082.rs rename to src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.rs diff --git a/src/test/ui/typeck/issue-52082.stderr b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.stderr similarity index 55% rename from src/test/ui/typeck/issue-52082.stderr rename to src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.stderr index b6b616630d51f..4be4c91dfc2c3 100644 --- a/src/test/ui/typeck/issue-52082.stderr +++ b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.stderr @@ -1,98 +1,74 @@ error[E0609]: no field `x` on type `&Point` - --> $DIR/issue-52082.rs:31:11 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:11 | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:29:19 - | -LL | fn equals_ref(a: &Point, b: &Point) -> bool - | ^^^^^ error[E0609]: no field `x` on type `&Point` - --> $DIR/issue-52082.rs:31:18 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:18 | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:29:19 - | -LL | fn equals_ref(a: &Point, b: &Point) -> bool - | ^^^^^ error[E0609]: no field `y` on type `&Point` - --> $DIR/issue-52082.rs:31:25 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:25 | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:29:19 - | -LL | fn equals_ref(a: &Point, b: &Point) -> bool - | ^^^^^ error[E0609]: no field `y` on type `&Point` - --> $DIR/issue-52082.rs:31:32 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:32 | +LL | fn equals_ref(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:29:19 - | -LL | fn equals_ref(a: &Point, b: &Point) -> bool - | ^^^^^ error[E0609]: no field `x` on type `Point` - --> $DIR/issue-52082.rs:39:11 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:11 | +LL | fn equals_val(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:37:19 - | -LL | fn equals_val(a: Point, b: Point) -> bool - | ^^^^^ error[E0609]: no field `x` on type `Point` - --> $DIR/issue-52082.rs:39:18 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:18 | +LL | fn equals_val(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:37:19 - | -LL | fn equals_val(a: Point, b: Point) -> bool - | ^^^^^ error[E0609]: no field `y` on type `Point` - --> $DIR/issue-52082.rs:39:25 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:25 | +LL | fn equals_val(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:37:19 - | -LL | fn equals_val(a: Point, b: Point) -> bool - | ^^^^^ error[E0609]: no field `y` on type `Point` - --> $DIR/issue-52082.rs:39:32 + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:32 | +LL | fn equals_val(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { LL | a.x == b.x && a.y == b.y | ^ - | -note: Type parameter 'Point' was declared here - --> $DIR/issue-52082.rs:37:19 - | -LL | fn equals_val(a: Point, b: Point) -> bool - | ^^^^^ error: aborting due to 8 previous errors From 9ad99c30cbf344b763602698b67c04ec3ce3de56 Mon Sep 17 00:00:00 2001 From: Wojciech Baranowski Date: Sat, 28 Sep 2019 15:26:00 +0300 Subject: [PATCH 13/16] Refactor into ban_nonexisting_field method --- src/librustc_typeck/check/expr.rs | 64 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index dae4db4003aeb..f59f908465dd3 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1390,33 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if self.method_exists(field, expr_t, expr.hir_id, true) { self.ban_take_value_of_method(expr, expr_t, field); } else if !expr_t.is_primitive_ty() { - let mut err = self.no_such_field_err(field.span, field, expr_t); - - match expr_t.peel_refs().kind { - ty::Array(_, len) => { - self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); - } - ty::RawPtr(..) => { - self.suggest_first_deref_field(&mut err, expr, base, field); - } - ty::Adt(def, _) if !def.is_enum() => { - self.suggest_fields_on_recordish(&mut err, def, field); - } - ty::Param(param_ty) => { - self.point_at_param_definition(&mut err, param_ty); - } - _ => {} - } - - if field.name == kw::Await { - // We know by construction that `.await` is either on Rust 2015 - // or results in `ExprKind::Await`. Suggest switching the edition to 2018. - err.note("to `.await` a `Future`, switch to Rust 2018"); - err.help("set `edition = \"2018\"` in `Cargo.toml`"); - err.note("for more on editions, read https://doc.rust-lang.org/edition-guide"); - } - - err.emit(); + self.ban_nonexisting_field(field, base, expr, expr_t); } else { type_error_struct!( self.tcx().sess, @@ -1432,6 +1406,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx().types.err } + fn ban_nonexisting_field( + &self, + field: ast::Ident, + base: &'tcx hir::Expr, + expr: &'tcx hir::Expr, + expr_t: Ty<'tcx>, + ) { + let mut err = self.no_such_field_err(field.span, field, expr_t); + + match expr_t.peel_refs().kind { + ty::Array(_, len) => { + self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); + } + ty::RawPtr(..) => { + self.suggest_first_deref_field(&mut err, expr, base, field); + } + ty::Adt(def, _) if !def.is_enum() => { + self.suggest_fields_on_recordish(&mut err, def, field); + } + ty::Param(param_ty) => { + self.point_at_param_definition(&mut err, param_ty); + } + _ => {} + } + + if field.name == kw::Await { + // We know by construction that `.await` is either on Rust 2015 + // or results in `ExprKind::Await`. Suggest switching the edition to 2018. + err.note("to `.await` a `Future`, switch to Rust 2018"); + err.help("set `edition = \"2018\"` in `Cargo.toml`"); + err.note("for more on editions, read https://doc.rust-lang.org/edition-guide"); + } + + err.emit(); + } + fn ban_private_field_access( &self, expr: &hir::Expr, From f6ceccea935e2ed7f55109b9a2cc2addfe894dff Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 28 Sep 2019 09:15:06 -0700 Subject: [PATCH 14/16] Upgrade async/await to "used" keywords. --- src/libsyntax_pos/symbol.rs | 8 +++--- ...018-edition-error-in-non-macro-position.rs | 14 +++++----- ...edition-error-in-non-macro-position.stderr | 28 +++++++++---------- .../await-keyword/2018-edition-error.rs | 4 +-- .../await-keyword/2018-edition-error.stderr | 20 ++++++------- src/test/ui/async-await/no-const-async.rs | 2 +- src/test/ui/async-await/no-const-async.stderr | 4 +-- .../edition-keywords-2015-2018-expansion.rs | 2 +- ...dition-keywords-2015-2018-expansion.stderr | 4 +-- .../edition-keywords-2018-2015-parsing.rs | 4 +-- .../edition-keywords-2018-2015-parsing.stderr | 8 +++--- .../edition-keywords-2018-2018-expansion.rs | 2 +- ...dition-keywords-2018-2018-expansion.stderr | 4 +-- .../edition-keywords-2018-2018-parsing.rs | 4 +-- .../edition-keywords-2018-2018-parsing.stderr | 8 +++--- src/test/ui/parser/mut-patterns.rs | 2 +- src/test/ui/parser/mut-patterns.stderr | 4 +-- 17 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 32af930ffb884..44a34070deccd 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -83,11 +83,11 @@ symbols! { Yield: "yield", // Edition-specific keywords that are used in stable Rust. + Async: "async", // >= 2018 Edition only + Await: "await", // >= 2018 Edition only Dyn: "dyn", // >= 2018 Edition only // Edition-specific keywords that are used in unstable Rust or reserved for future use. - Async: "async", // >= 2018 Edition only - Await: "await", // >= 2018 Edition only Try: "try", // >= 2018 Edition only // Special lifetime names @@ -1088,11 +1088,11 @@ pub mod sym { impl Symbol { fn is_used_keyword_2018(self) -> bool { - self == kw::Dyn + self >= kw::Async && self <= kw::Dyn } fn is_unused_keyword_2018(self) -> bool { - self >= kw::Async && self <= kw::Try + self == kw::Try } /// Used for sanity checking rustdoc keyword sections. diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs index 5d85b0a243e03..9e78f7c512014 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs +++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs @@ -3,21 +3,21 @@ #![allow(non_camel_case_types)] mod outer_mod { - pub mod await { //~ ERROR expected identifier, found reserved keyword `await` - pub struct await; //~ ERROR expected identifier, found reserved keyword `await` + pub mod await { //~ ERROR expected identifier, found keyword `await` + pub struct await; //~ ERROR expected identifier, found keyword `await` } } -use self::outer_mod::await::await; //~ ERROR expected identifier, found reserved keyword `await` -//~^ ERROR expected identifier, found reserved keyword `await` +use self::outer_mod::await::await; //~ ERROR expected identifier, found keyword `await` +//~^ ERROR expected identifier, found keyword `await` struct Foo { await: () } -//~^ ERROR expected identifier, found reserved keyword `await` +//~^ ERROR expected identifier, found keyword `await` impl Foo { fn await() {} } -//~^ ERROR expected identifier, found reserved keyword `await` +//~^ ERROR expected identifier, found keyword `await` macro_rules! await { -//~^ ERROR expected identifier, found reserved keyword `await` +//~^ ERROR expected identifier, found keyword `await` () => {} } diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr index 05f28d0a5b226..0e859466322c0 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr +++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr @@ -1,68 +1,68 @@ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:6:13 | LL | pub mod await { - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | pub mod r#await { | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:7:20 | LL | pub struct await; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | pub struct r#await; | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:10:22 | LL | use self::outer_mod::await::await; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | use self::outer_mod::r#await::await; | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:10:29 | LL | use self::outer_mod::await::await; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | use self::outer_mod::await::r#await; | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:13:14 | LL | struct Foo { await: () } - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | struct Foo { r#await: () } | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:16:15 | LL | impl Foo { fn await() {} } - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | impl Foo { fn r#await() {} } | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error-in-non-macro-position.rs:19:14 | LL | macro_rules! await { - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | macro_rules! r#await { diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.rs b/src/test/ui/async-await/await-keyword/2018-edition-error.rs index e620c27f9e36d..7ce52259acac3 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error.rs +++ b/src/test/ui/async-await/await-keyword/2018-edition-error.rs @@ -7,9 +7,9 @@ mod outer_mod { } } use self::outer_mod::await::await; //~ ERROR expected identifier - //~^ ERROR expected identifier, found reserved keyword `await` + //~^ ERROR expected identifier, found keyword `await` -macro_rules! await { () => {}; } //~ ERROR expected identifier, found reserved keyword `await` +macro_rules! await { () => {}; } //~ ERROR expected identifier, found keyword `await` fn main() { await!(); //~ ERROR expected expression, found `)` diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr index 9304928cfde5d..71f403f278eb3 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr +++ b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr @@ -1,48 +1,48 @@ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error.rs:5:13 | LL | pub mod await { - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | pub mod r#await { | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error.rs:6:20 | LL | pub struct await; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | pub struct r#await; | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error.rs:9:22 | LL | use self::outer_mod::await::await; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | use self::outer_mod::r#await::await; | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error.rs:9:29 | LL | use self::outer_mod::await::await; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | use self::outer_mod::await::r#await; | ^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/2018-edition-error.rs:12:14 | LL | macro_rules! await { () => {}; } - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | macro_rules! r#await { () => {}; } diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index bd78a18a40ed9..ef7edf8504952 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -3,5 +3,5 @@ // compile-flags: --crate-type lib pub const async fn x() {} -//~^ ERROR expected identifier, found reserved keyword `async` +//~^ ERROR expected identifier, found keyword `async` //~^^ expected `:`, found keyword `fn` diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 6d7df57e7b6af..fe0591457853e 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -1,8 +1,8 @@ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/no-const-async.rs:5:11 | LL | pub const async fn x() {} - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | pub const r#async fn x() {} diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.rs b/src/test/ui/editions/edition-keywords-2015-2018-expansion.rs index 2684c8e00b2e1..9f34a3887b7f1 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.rs +++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.rs @@ -5,7 +5,7 @@ extern crate edition_kw_macro_2018; mod one_async { - produces_async! {} //~ ERROR expected identifier, found reserved keyword + produces_async! {} //~ ERROR expected identifier, found keyword } mod two_async { produces_async_raw! {} // OK diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr index 321545740cf48..04a70cf98302f 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr @@ -1,8 +1,8 @@ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/edition-keywords-2015-2018-expansion.rs:8:5 | LL | produces_async! {} - | ^^^^^^^^^^^^^^^^^^ expected identifier, found reserved keyword + | ^^^^^^^^^^^^^^^^^^ expected identifier, found keyword | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs index fb8e0cdb4c30f..dbc0465b08e77 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -5,7 +5,7 @@ extern crate edition_kw_macro_2015; pub fn check_async() { - let mut async = 1; //~ ERROR expected identifier, found reserved keyword `async` + let mut async = 1; //~ ERROR expected identifier, found keyword `async` let mut r#async = 1; // OK r#async = consumes_async!(async); // OK @@ -15,6 +15,6 @@ pub fn check_async() { if passes_ident!(async) == 1 {} if passes_ident!(r#async) == 1 {} // OK - module::async(); //~ ERROR expected identifier, found reserved keyword `async` + module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK } diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index 3c4a153353447..be991cd0c8128 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -1,18 +1,18 @@ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/edition-keywords-2018-2015-parsing.rs:8:13 | LL | let mut async = 1; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | let mut r#async = 1; | ^^^^^^^ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/edition-keywords-2018-2015-parsing.rs:18:13 | LL | module::async(); - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | module::r#async(); diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.rs b/src/test/ui/editions/edition-keywords-2018-2018-expansion.rs index 6f766550d4734..a8e69fed6959e 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.rs +++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.rs @@ -5,7 +5,7 @@ extern crate edition_kw_macro_2018; mod one_async { - produces_async! {} //~ ERROR expected identifier, found reserved keyword `async` + produces_async! {} //~ ERROR expected identifier, found keyword `async` } mod two_async { produces_async_raw! {} // OK diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr index 8942e3ce430a8..fb12051eed409 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr @@ -1,8 +1,8 @@ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/edition-keywords-2018-2018-expansion.rs:8:5 | LL | produces_async! {} - | ^^^^^^^^^^^^^^^^^^ expected identifier, found reserved keyword + | ^^^^^^^^^^^^^^^^^^ expected identifier, found keyword | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs index 88cebf45ad8ba..5aca0839f0f15 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -5,7 +5,7 @@ extern crate edition_kw_macro_2018; pub fn check_async() { - let mut async = 1; //~ ERROR expected identifier, found reserved keyword `async` + let mut async = 1; //~ ERROR expected identifier, found keyword `async` let mut r#async = 1; // OK r#async = consumes_async!(async); // OK @@ -15,6 +15,6 @@ pub fn check_async() { if passes_ident!(async) == 1 {} if passes_ident!(r#async) == 1 {} // OK - module::async(); //~ ERROR expected identifier, found reserved keyword `async` + module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK } diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 46aa9ca34e17c..93a7627f88713 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -1,18 +1,18 @@ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/edition-keywords-2018-2018-parsing.rs:8:13 | LL | let mut async = 1; - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | let mut r#async = 1; | ^^^^^^^ -error: expected identifier, found reserved keyword `async` +error: expected identifier, found keyword `async` --> $DIR/edition-keywords-2018-2018-parsing.rs:18:13 | LL | module::async(); - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | module::r#async(); diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs index d46186a0fea0e..66fd5893af5ee 100644 --- a/src/test/ui/parser/mut-patterns.rs +++ b/src/test/ui/parser/mut-patterns.rs @@ -28,7 +28,7 @@ pub fn main() { //~| ERROR `mut` must be attached to each individual binding //~| ERROR expected identifier, found reserved keyword `yield` //~| ERROR expected identifier, found reserved keyword `become` - //~| ERROR expected identifier, found reserved keyword `await` + //~| ERROR expected identifier, found keyword `await` struct W(T, U); struct B { f: Box } diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr index 18ffaa5255870..b1cf99189f17d 100644 --- a/src/test/ui/parser/mut-patterns.stderr +++ b/src/test/ui/parser/mut-patterns.stderr @@ -62,11 +62,11 @@ help: you can escape reserved keywords to use them as identifiers LL | let mut mut yield(r#become, await) = r#yield(0, 0); | ^^^^^^^^ -error: expected identifier, found reserved keyword `await` +error: expected identifier, found keyword `await` --> $DIR/mut-patterns.rs:26:31 | LL | let mut mut yield(become, await) = r#yield(0, 0); - | ^^^^^ expected identifier, found reserved keyword + | ^^^^^ expected identifier, found keyword help: you can escape reserved keywords to use them as identifiers | LL | let mut mut yield(become, r#await) = r#yield(0, 0); From c666bd5570e62666b40d0a4c3eca7080667a92ef Mon Sep 17 00:00:00 2001 From: Mahmut Bulut Date: Sat, 28 Sep 2019 18:24:05 +0200 Subject: [PATCH 15/16] Fix typo in intrinsics op safety --- src/librustc_typeck/check/intrinsic.rs | 4 ++-- src/librustc_typeck/collect.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index dfbf8bcd0f60f..7ecb1b5a41ecd 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -63,7 +63,7 @@ fn equate_intrinsic_type<'tcx>( } /// Returns `true` if the given intrinsic is unsafe to call or not. -pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { +pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { match intrinsic { "size_of" | "min_align_of" | "needs_drop" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" | @@ -130,7 +130,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { } else if &name[..] == "abort" || &name[..] == "unreachable" { (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe) } else { - let unsafety = intrisic_operation_unsafety(&name[..]); + let unsafety = intrinsic_operation_unsafety(&name[..]); let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), tcx.mk_unit()), "size_of" | diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 82d55e0df599b..5b634c67c445b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -16,7 +16,7 @@ use crate::astconv::{AstConv, Bounds, SizedByDefault}; use crate::constrained_generic_params as cgp; -use crate::check::intrinsic::intrisic_operation_unsafety; +use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::lint; use crate::middle::resolve_lifetime as rl; use crate::middle::weak_lang_items; @@ -2368,7 +2368,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( abi: abi::Abi, ) -> ty::PolyFnSig<'tcx> { let unsafety = if abi == abi::Abi::RustIntrinsic { - intrisic_operation_unsafety(&*tcx.item_name(def_id).as_str()) + intrinsic_operation_unsafety(&*tcx.item_name(def_id).as_str()) } else { hir::Unsafety::Unsafe }; From e77dfa27cacd17878cf992b61c801f4c99056fad Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sat, 28 Sep 2019 21:02:51 +0200 Subject: [PATCH 16/16] Slice docs: fix typo --- src/libstd/primitive_docs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 02f664760c08c..3e389c40fbc01 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -567,7 +567,7 @@ mod prim_array { } #[doc(alias = "]")] #[doc(alias = "[]")] /// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here -/// means that elements are layed out so that every element is the same +/// means that elements are laid out so that every element is the same /// distance from its neighbors. /// /// *[See also the `std::slice` module](slice/index.html).*