From 003a636e760d50f4e1e96101f8e9994ac3758135 Mon Sep 17 00:00:00 2001 From: Ariel Davis Date: Fri, 20 Aug 2021 22:24:22 -0400 Subject: [PATCH 01/14] Add an example for deriving PartialOrd on enums For some reason, I always forget which variants are smaller and which are larger when you derive PartialOrd on an enum. And the wording in the current docs is not entirely clear to me. So, I often end up making a small enum, deriving PartialOrd on it, and then writing a `#[test]` with an assert that the top one is smaller than the bottom one (or the other way around) to figure out which way the deriving goes. So then I figured, it would be great if the standard library docs just had that example, so if I keep forgetting, at least I can figure it out quickly by looking at std's docs. --- library/core/src/cmp.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 79610bb409d37..4e82b65539460 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -660,6 +660,18 @@ impl Clone for Reverse { /// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a /// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the top-to-bottom declaration order of the struct's members. /// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order. +/// This means variants at the top are less than variants at the bottom. +/// Here's an example: +/// +/// ``` +/// #[derive(PartialEq, PartialOrd)] +/// enum Size { +/// Small, +/// Large, +/// } +/// +/// assert!(Size::Small < Size::Large); +/// ``` /// /// ## Lexicographical comparison /// From af1b65cb18d5fa1358d1ae7a8ed3b1f7c635b6b5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 26 Aug 2021 12:46:01 +0200 Subject: [PATCH 02/14] Path remapping: Make behavior of diagnostics output dependent on presence of --remap-path-prefix. --- .../src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/lib.rs | 2 +- .../src/debuginfo/metadata.rs | 11 +++++-- .../src/annotate_snippet_emitter_writer.rs | 2 +- compiler/rustc_errors/src/emitter.rs | 8 ++--- compiler/rustc_errors/src/json.rs | 2 +- compiler/rustc_expand/src/base.rs | 2 +- .../src/infer/error_reporting/mod.rs | 9 ++---- .../rustc_mir/src/interpret/eval_context.rs | 5 +-- compiler/rustc_parse/src/lib.rs | 2 +- compiler/rustc_span/src/lib.rs | 31 +++++++++++++------ compiler/rustc_span/src/source_map.rs | 23 ++++++++++---- .../clippy/clippy_lints/src/macro_use.rs | 7 ++--- 13 files changed, 65 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index c471da83de234..14a593a71ce78 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -66,7 +66,7 @@ impl<'tcx> DebugContext<'tcx> { rustc_interface::util::version_str().unwrap_or("unknown version"), cranelift_codegen::VERSION, ); - let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(false).into_owned(); + let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped).into_owned(); let (name, file_info) = match tcx.sess.local_crate_source_file.clone() { Some(path) => { let name = path.to_string_lossy().into_owned(); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 4ef53663ca0d9..6c7c8cbc311f9 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -74,7 +74,7 @@ mod vtable; mod prelude { pub(crate) use std::convert::{TryFrom, TryInto}; - pub(crate) use rustc_span::Span; + pub(crate) use rustc_span::{Span, FileNameDisplayPreference}; pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub(crate) use rustc_middle::bug; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8ff2f1cc6520f..346c51c5426d8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -35,6 +35,7 @@ use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::{self, DebugInfo}; use rustc_span::symbol::{Interner, Symbol}; +use rustc_span::FileNameDisplayPreference; use rustc_span::{self, SourceFile, SourceFileHash, Span}; use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding}; use rustc_target::abi::{Int, Pointer, F32, F64}; @@ -771,7 +772,13 @@ pub fn file_metadata(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll let hash = Some(&source_file.src_hash); let file_name = Some(source_file.name.prefer_remapped().to_string()); let directory = if source_file.is_real_file() && !source_file.is_imported() { - Some(cx.sess().opts.working_dir.to_string_lossy(false).to_string()) + Some( + cx.sess() + .opts + .working_dir + .to_string_lossy(FileNameDisplayPreference::Remapped) + .to_string(), + ) } else { // If the path comes from an upstream crate we assume it has been made // independent of the compiler's working directory one way or another. @@ -999,7 +1006,7 @@ pub fn compile_unit_metadata( let producer = format!("clang LLVM ({})", rustc_producer); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); - let work_dir = tcx.sess.opts.working_dir.to_string_lossy(false); + let work_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped); let flags = "\0"; let output_filenames = tcx.output_filenames(()); let out_dir = &output_filenames.out_directory; diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 2253007ce3027..1eb497460e63c 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -126,7 +126,7 @@ impl AnnotateSnippetEmitterWriter { } // owned: line source, line index, annotations type Owned = (String, usize, Vec); - let filename = primary_lo.file.name.prefer_local(); + let filename = source_map.filename_for_diagnostics(&primary_lo.file.name); let origin = filename.to_string_lossy(); let annotated_files: Vec = annotated_files .into_iter() diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 25777f4133b94..29f352ae58559 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1320,7 +1320,7 @@ impl EmitterWriter { buffer_msg_line_offset, &format!( "{}:{}:{}", - loc.file.name.prefer_local(), + sm.filename_for_diagnostics(&loc.file.name), sm.doctest_offset_line(&loc.file.name, loc.line), loc.col.0 + 1, ), @@ -1334,7 +1334,7 @@ impl EmitterWriter { 0, &format!( "{}:{}:{}: ", - loc.file.name.prefer_local(), + sm.filename_for_diagnostics(&loc.file.name), sm.doctest_offset_line(&loc.file.name, loc.line), loc.col.0 + 1, ), @@ -1362,12 +1362,12 @@ impl EmitterWriter { }; format!( "{}:{}{}", - annotated_file.file.name.prefer_local(), + sm.filename_for_diagnostics(&annotated_file.file.name), sm.doctest_offset_line(&annotated_file.file.name, first_line.line_index), col ) } else { - format!("{}", annotated_file.file.name.prefer_local()) + format!("{}", sm.filename_for_diagnostics(&annotated_file.file.name)) }; buffer.append(buffer_msg_line_offset + 1, &loc, Style::LineAndColumn); for _ in 0..max_line_num_len { diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 1b6cd04cca642..dde978cd8c6ce 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -464,7 +464,7 @@ impl DiagnosticSpan { }); DiagnosticSpan { - file_name: start.file.name.prefer_local().to_string(), + file_name: je.sm.filename_for_diagnostics(&start.file.name).to_string(), byte_start: start.file.original_relative_byte_pos(span.lo()).0, byte_end: start.file.original_relative_byte_pos(span.hi()).0, line_start: start.line, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index a4b7bdd9155cc..1fd48309af976 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1113,7 +1113,7 @@ impl<'a> ExtCtxt<'a> { span, &format!( "cannot resolve relative path in non-file source `{}`", - other.prefer_local() + self.source_map().filename_for_diagnostics(&other) ), )); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 299dcf5f17a87..6a7c924aaef09 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1626,14 +1626,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (TypeError::Sorts(values), extra) => { let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) { (true, ty::Opaque(def_id, _)) => { - let pos = self - .tcx - .sess - .source_map() - .lookup_char_pos(self.tcx.def_span(*def_id).lo()); + let sm = self.tcx.sess.source_map(); + let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); format!( " (opaque type at <{}:{}:{}>)", - pos.file.name.prefer_local(), + sm.filename_for_diagnostics(&pos.file.name), pos.line, pos.col.to_usize() + 1, ) diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 516ef4f4e53ca..f62efea9612ee 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -272,11 +272,12 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { write!(f, "inside `{}`", self.instance)?; } if !self.span.is_dummy() { - let lo = tcx.sess.source_map().lookup_char_pos(self.span.lo()); + let sm = tcx.sess.source_map(); + let lo = sm.lookup_char_pos(self.span.lo()); write!( f, " at {}:{}:{}", - lo.file.name.prefer_local(), + sm.filename_for_diagnostics(&lo.file.name), lo.line, lo.col.to_usize() + 1 )?; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 73e05a35277ec..bf76dedd252ca 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -190,7 +190,7 @@ pub fn maybe_file_to_stream( let src = source_file.src.as_ref().unwrap_or_else(|| { sess.span_diagnostic.bug(&format!( "cannot lex `source_file` without source: {}", - source_file.name.prefer_local() + sess.source_map().filename_for_diagnostics(&source_file.name) )); }); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 89e032b222fec..73a626e653804 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -260,11 +260,12 @@ impl RealFileName { } } - pub fn to_string_lossy(&self, prefer_local: bool) -> Cow<'_, str> { - if prefer_local { - self.local_path_if_available().to_string_lossy() - } else { - self.remapped_path_if_available().to_string_lossy() + pub fn to_string_lossy(&self, display_pref: FileNameDisplayPreference) -> Cow<'_, str> { + match display_pref { + FileNameDisplayPreference::Local => self.local_path_if_available().to_string_lossy(), + FileNameDisplayPreference::Remapped => { + self.remapped_path_if_available().to_string_lossy() + } } } } @@ -300,9 +301,15 @@ impl From for FileName { } } +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +pub enum FileNameDisplayPreference { + Remapped, + Local, +} + pub struct FileNameDisplay<'a> { inner: &'a FileName, - prefer_local: bool, + display_pref: FileNameDisplayPreference, } impl fmt::Display for FileNameDisplay<'_> { @@ -310,7 +317,7 @@ impl fmt::Display for FileNameDisplay<'_> { use FileName::*; match *self.inner { Real(ref name) => { - write!(fmt, "{}", name.to_string_lossy(self.prefer_local)) + write!(fmt, "{}", name.to_string_lossy(self.display_pref)) } QuoteExpansion(_) => write!(fmt, ""), MacroExpansion(_) => write!(fmt, ""), @@ -328,7 +335,7 @@ impl fmt::Display for FileNameDisplay<'_> { impl FileNameDisplay<'_> { pub fn to_string_lossy(&self) -> Cow<'_, str> { match self.inner { - FileName::Real(ref inner) => inner.to_string_lossy(self.prefer_local), + FileName::Real(ref inner) => inner.to_string_lossy(self.display_pref), _ => Cow::from(format!("{}", self)), } } @@ -352,13 +359,17 @@ impl FileName { } pub fn prefer_remapped(&self) -> FileNameDisplay<'_> { - FileNameDisplay { inner: self, prefer_local: false } + FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Remapped } } // This may include transient local filesystem information. // Must not be embedded in build outputs. pub fn prefer_local(&self) -> FileNameDisplay<'_> { - FileNameDisplay { inner: self, prefer_local: true } + FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Local } + } + + pub fn display(&self, display_pref: FileNameDisplayPreference) -> FileNameDisplay<'_> { + FileNameDisplay { inner: self, display_pref } } pub fn macro_expansion_source_code(src: &str) -> FileName { diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 2c3af802be55a..dc06f02a64ce3 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -427,7 +427,7 @@ impl SourceMap { } } - fn span_to_string(&self, sp: Span, prefer_local: bool) -> String { + fn span_to_string(&self, sp: Span, filename_display_pref: FileNameDisplayPreference) -> String { if self.files.borrow().source_files.is_empty() || sp.is_dummy() { return "no-location".to_string(); } @@ -436,7 +436,7 @@ impl SourceMap { let hi = self.lookup_char_pos(sp.hi()); format!( "{}:{}:{}: {}:{}", - if prefer_local { lo.file.name.prefer_local() } else { lo.file.name.prefer_remapped() }, + lo.file.name.display(filename_display_pref), lo.line, lo.col.to_usize() + 1, hi.line, @@ -446,20 +446,24 @@ impl SourceMap { /// Format the span location suitable for embedding in build artifacts pub fn span_to_embeddable_string(&self, sp: Span) -> String { - self.span_to_string(sp, false) + self.span_to_string(sp, FileNameDisplayPreference::Remapped) } /// Format the span location to be printed in diagnostics. Must not be emitted /// to build artifacts as this may leak local file paths. Use span_to_embeddable_string /// for string suitable for embedding. pub fn span_to_diagnostic_string(&self, sp: Span) -> String { - self.span_to_string(sp, true) + self.span_to_string(sp, self.path_mapping.filename_display_for_diagnostics) } pub fn span_to_filename(&self, sp: Span) -> FileName { self.lookup_char_pos(sp.lo()).file.name.clone() } + pub fn filename_for_diagnostics<'a>(&self, filename: &'a FileName) -> FileNameDisplay<'a> { + filename.display(self.path_mapping.filename_display_for_diagnostics) + } + pub fn is_multiline(&self, sp: Span) -> bool { let lo = self.lookup_source_file_idx(sp.lo()); let hi = self.lookup_source_file_idx(sp.hi()); @@ -1002,15 +1006,22 @@ impl SourceMap { #[derive(Clone)] pub struct FilePathMapping { mapping: Vec<(PathBuf, PathBuf)>, + filename_display_for_diagnostics: FileNameDisplayPreference, } impl FilePathMapping { pub fn empty() -> FilePathMapping { - FilePathMapping { mapping: vec![] } + FilePathMapping::new(Vec::new()) } pub fn new(mapping: Vec<(PathBuf, PathBuf)>) -> FilePathMapping { - FilePathMapping { mapping } + let filename_display_for_diagnostics = if mapping.is_empty() { + FileNameDisplayPreference::Local + } else { + FileNameDisplayPreference::Remapped + }; + + FilePathMapping { mapping, filename_display_for_diagnostics } } /// Applies any path prefix substitution as defined by the mapping. diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index a371f8bbd3cb4..39f7ade3f81f6 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -47,11 +47,8 @@ pub struct MacroRefData { impl MacroRefData { pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self { - let mut path = cx - .sess() - .source_map() - .span_to_filename(callee) - .prefer_local() + let sm = cx.sess().source_map(); + let mut path = sm.filename_for_diagnostics(&sm.span_to_filename(callee)) .to_string(); // std lib paths are <::std::module::file type> From 8436fe1f2938878aeb2b1b542cd7d54a605b1c70 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 20 Aug 2021 20:35:42 +0100 Subject: [PATCH 03/14] Add test for showing remapped path in diagnostics --- src/test/ui/remap-path-prefix.rs | 5 +++++ src/test/ui/remap-path-prefix.stderr | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/test/ui/remap-path-prefix.rs create mode 100644 src/test/ui/remap-path-prefix.stderr diff --git a/src/test/ui/remap-path-prefix.rs b/src/test/ui/remap-path-prefix.rs new file mode 100644 index 0000000000000..66a397bc7dbef --- /dev/null +++ b/src/test/ui/remap-path-prefix.rs @@ -0,0 +1,5 @@ +// compile-flags: --remap-path-prefix={{src-base}}=remapped + +fn main() { + ferris //~ ERROR cannot find value `ferris` in this scope +} diff --git a/src/test/ui/remap-path-prefix.stderr b/src/test/ui/remap-path-prefix.stderr new file mode 100644 index 0000000000000..a20cf6b4df80e --- /dev/null +++ b/src/test/ui/remap-path-prefix.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `ferris` in this scope + --> remapped/remap-path-prefix.rs:4:5 + | +LL | ferris + | ^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From c296c89be601a57597a1c262b9e3a4c9b4d056cf Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 27 Aug 2021 12:43:07 +0200 Subject: [PATCH 04/14] Fix remap-path-prefix UI test case. --- src/test/ui/remap-path-prefix.rs | 6 +++++- src/test/ui/remap-path-prefix.stderr | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/ui/remap-path-prefix.rs b/src/test/ui/remap-path-prefix.rs index 66a397bc7dbef..2eef970997708 100644 --- a/src/test/ui/remap-path-prefix.rs +++ b/src/test/ui/remap-path-prefix.rs @@ -1,5 +1,9 @@ // compile-flags: --remap-path-prefix={{src-base}}=remapped fn main() { - ferris //~ ERROR cannot find value `ferris` in this scope + // We cannot actually put an ERROR marker here because + // the file name in the error message is not what the + // test framework expects (since the filename gets remapped). + // We still test the expected error in the stderr file. + ferris } diff --git a/src/test/ui/remap-path-prefix.stderr b/src/test/ui/remap-path-prefix.stderr index a20cf6b4df80e..ad6a35d1256cd 100644 --- a/src/test/ui/remap-path-prefix.stderr +++ b/src/test/ui/remap-path-prefix.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `ferris` in this scope - --> remapped/remap-path-prefix.rs:4:5 + --> remapped/remap-path-prefix.rs:8:5 | LL | ferris | ^^^^^^ not found in this scope From c6d800d85439d0a95a2943905d0fd3842fa4dd20 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 27 Aug 2021 10:57:28 +0000 Subject: [PATCH 05/14] Point at unclosed delimiters as part of the primary MultiSpan Both the place where the parser encounters a needed closed delimiter and the unclosed opening delimiter are important, so they should get the same level of highlighting in the output. --- .../rustc_parse/src/parser/diagnostics.rs | 12 ++++- compiler/rustc_parse/src/parser/mod.rs | 9 +++- src/test/ui/parser/issue-10636-1.stderr | 4 +- src/test/ui/parser/issue-10636-2.stderr | 4 +- src/test/ui/parser/issue-58856-1.stderr | 4 +- src/test/ui/parser/issue-58856-2.stderr | 4 +- src/test/ui/parser/issue-60075.stderr | 4 +- src/test/ui/parser/issue-62973.stderr | 12 ++--- src/test/ui/parser/issue-63116.stderr | 4 +- .../issue-66357-unexpected-unreachable.stderr | 4 +- ...invalid-syntax-in-enum-discriminant.stderr | 48 +++++++++---------- .../macro-mismatched-delim-brace-paren.stderr | 4 +- .../macro-mismatched-delim-paren-brace.stderr | 4 +- src/test/ui/parser/parser-recovery-2.stderr | 4 +- .../parser/unclosed-delimiter-in-dep.stderr | 4 +- src/test/ui/parser/unclosed_delim_mod.stderr | 4 +- src/test/ui/parser/use-unclosed-brace.stderr | 4 +- .../ui/resolve/token-error-correct-2.stderr | 4 +- .../ui/resolve/token-error-correct-3.stderr | 4 +- .../ui/resolve/token-error-correct-4.stderr | 4 +- .../ui/resolve/token-error-correct.stderr | 4 +- 21 files changed, 82 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 273fbea358021..cdc1d1cf99f3c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1432,12 +1432,22 @@ impl<'a> Parser<'a> { // the most sense, which is immediately after the last token: // // {foo(bar {}} - // - ^ + // ^ ^ // | | // | help: `)` may belong here // | // unclosed delimiter if let Some(sp) = unmatched.unclosed_span { + let mut primary_span: Vec = + err.span.primary_spans().iter().cloned().collect(); + primary_span.push(sp); + let mut primary_span: MultiSpan = primary_span.into(); + for span_label in err.span.span_labels() { + if let Some(label) = span_label.label { + primary_span.push_span_label(span_label.span, label); + } + } + err.set_span(primary_span); err.span_label(sp, "unclosed delimiter"); } // Backticks should be removed to apply suggestions. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 4c3c140d17100..64f7a447fea3c 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -33,7 +33,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::PResult; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError}; use rustc_session::parse::ParseSess; -use rustc_span::source_map::{Span, DUMMY_SP}; +use rustc_span::source_map::{MultiSpan, Span, DUMMY_SP}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use tracing::debug; @@ -1335,8 +1335,13 @@ crate fn make_unclosed_delims_error( // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to // `unmatched_braces` only for error recovery in the `Parser`. let found_delim = unmatched.found_delim?; + let span: MultiSpan = if let Some(sp) = unmatched.unclosed_span { + vec![unmatched.found_span, sp].into() + } else { + unmatched.found_span.into() + }; let mut err = sess.span_diagnostic.struct_span_err( - unmatched.found_span, + span, &format!( "mismatched closing delimiter: `{}`", pprust::token_kind_to_string(&token::CloseDelim(found_delim)), diff --git a/src/test/ui/parser/issue-10636-1.stderr b/src/test/ui/parser/issue-10636-1.stderr index ff90cb97096f7..1e6294ebe1691 100644 --- a/src/test/ui/parser/issue-10636-1.stderr +++ b/src/test/ui/parser/issue-10636-1.stderr @@ -1,8 +1,8 @@ error: mismatched closing delimiter: `)` - --> $DIR/issue-10636-1.rs:4:1 + --> $DIR/issue-10636-1.rs:1:12 | LL | struct Obj { - | - unclosed delimiter + | ^ unclosed delimiter ... LL | ) | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/issue-10636-2.stderr b/src/test/ui/parser/issue-10636-2.stderr index 5b9a9b7f06c39..d4f2da9e3ab6f 100644 --- a/src/test/ui/parser/issue-10636-2.stderr +++ b/src/test/ui/parser/issue-10636-2.stderr @@ -1,8 +1,8 @@ error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` - --> $DIR/issue-10636-2.rs:5:25 + --> $DIR/issue-10636-2.rs:5:15 | LL | option.map(|some| 42; - | - ^ help: `)` may belong here + | ^ ^ help: `)` may belong here | | | unclosed delimiter diff --git a/src/test/ui/parser/issue-58856-1.stderr b/src/test/ui/parser/issue-58856-1.stderr index f1abb40ed7a73..2afb26d175834 100644 --- a/src/test/ui/parser/issue-58856-1.stderr +++ b/src/test/ui/parser/issue-58856-1.stderr @@ -1,8 +1,8 @@ error: expected one of `)`, `,`, or `:`, found `>` - --> $DIR/issue-58856-1.rs:3:14 + --> $DIR/issue-58856-1.rs:3:9 | LL | fn b(self> - | - ^ help: `)` may belong here + | ^ ^ help: `)` may belong here | | | unclosed delimiter diff --git a/src/test/ui/parser/issue-58856-2.stderr b/src/test/ui/parser/issue-58856-2.stderr index 303b5eacc3296..627dd389059cd 100644 --- a/src/test/ui/parser/issue-58856-2.stderr +++ b/src/test/ui/parser/issue-58856-2.stderr @@ -1,8 +1,8 @@ error: expected one of `)` or `,`, found `->` - --> $DIR/issue-58856-2.rs:6:26 + --> $DIR/issue-58856-2.rs:6:19 | LL | fn how_are_you(&self -> Empty { - | - -^^ + | ^ -^^ | | | | | help: `)` may belong here | unclosed delimiter diff --git a/src/test/ui/parser/issue-60075.stderr b/src/test/ui/parser/issue-60075.stderr index e3b7f4ad420e8..210ef700cd4bc 100644 --- a/src/test/ui/parser/issue-60075.stderr +++ b/src/test/ui/parser/issue-60075.stderr @@ -17,10 +17,10 @@ LL | } | - item list ends here error: mismatched closing delimiter: `)` - --> $DIR/issue-60075.rs:6:10 + --> $DIR/issue-60075.rs:4:31 | LL | fn qux() -> Option { - | - unclosed delimiter + | ^ unclosed delimiter LL | let _ = if true { LL | }); | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/issue-62973.stderr b/src/test/ui/parser/issue-62973.stderr index 3065d642fe105..51d835e732988 100644 --- a/src/test/ui/parser/issue-62973.stderr +++ b/src/test/ui/parser/issue-62973.stderr @@ -21,10 +21,10 @@ LL | | ^ error: expected one of `,` or `}`, found `{` - --> $DIR/issue-62973.rs:6:25 + --> $DIR/issue-62973.rs:6:8 | LL | fn p() { match s { v, E { [) {) } - | - - -^ expected one of `,` or `}` + | ^ - -^ expected one of `,` or `}` | | | | | | | help: `}` may belong here | | while parsing this struct @@ -56,18 +56,18 @@ LL | | ^ expected one of `.`, `?`, `{`, or an operator error: mismatched closing delimiter: `)` - --> $DIR/issue-62973.rs:6:28 + --> $DIR/issue-62973.rs:6:27 | LL | fn p() { match s { v, E { [) {) } - | -^ mismatched closing delimiter + | ^^ mismatched closing delimiter | | | unclosed delimiter error: mismatched closing delimiter: `)` - --> $DIR/issue-62973.rs:6:31 + --> $DIR/issue-62973.rs:6:30 | LL | fn p() { match s { v, E { [) {) } - | -^ mismatched closing delimiter + | ^^ mismatched closing delimiter | | | unclosed delimiter diff --git a/src/test/ui/parser/issue-63116.stderr b/src/test/ui/parser/issue-63116.stderr index 4766dfafea1c9..cfdd99d1434ae 100644 --- a/src/test/ui/parser/issue-63116.stderr +++ b/src/test/ui/parser/issue-63116.stderr @@ -13,10 +13,10 @@ LL | impl W $DIR/issue-63116.rs:3:16 + --> $DIR/issue-63116.rs:3:14 | LL | impl W $DIR/issue-66357-unexpected-unreachable.rs:12:14 + --> $DIR/issue-66357-unexpected-unreachable.rs:12:13 | LL | fn f() { |[](* } - | -^ help: `)` may belong here + | ^^ help: `)` may belong here | | | unclosed delimiter diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr index f20ec75535354..34f1397ce1d5b 100644 --- a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -1,107 +1,107 @@ error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 | LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 | LL | V = [Vec::new; { [].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 | LL | V = [Vec::new; { [0].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 | LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 | LL | V = [Vec::new; { [].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 | LL | V = [Vec::new; { [0].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 | LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 | LL | V = [Vec::new; { [].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 | LL | V = [Vec::new; { [0].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 | LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24 | LL | V = [Vec::new; { [].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24 | LL | V = [Vec::new; { [0].len() ].len() as isize, - | - - ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter | | | | | unclosed delimiter | closing delimiter possibly meant for this diff --git a/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr b/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr index 93c5ab383d488..077d318004896 100644 --- a/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr +++ b/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr @@ -1,8 +1,8 @@ error: mismatched closing delimiter: `)` - --> $DIR/macro-mismatched-delim-brace-paren.rs:6:5 + --> $DIR/macro-mismatched-delim-brace-paren.rs:4:10 | LL | foo! { - | - unclosed delimiter + | ^ unclosed delimiter LL | bar, "baz", 1, 2.0 LL | ) | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr index 424c7a60c196f..967a3e6fdc11b 100644 --- a/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr +++ b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr @@ -10,10 +10,10 @@ LL | } | ^ unexpected closing delimiter error: mismatched closing delimiter: `}` - --> $DIR/macro-mismatched-delim-paren-brace.rs:4:5 + --> $DIR/macro-mismatched-delim-paren-brace.rs:2:10 | LL | foo! ( - | - unclosed delimiter + | ^ unclosed delimiter LL | bar, "baz", 1, 2.0 LL | } | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/parser-recovery-2.stderr b/src/test/ui/parser/parser-recovery-2.stderr index cd3da4c71f0b5..0980d033fe73a 100644 --- a/src/test/ui/parser/parser-recovery-2.stderr +++ b/src/test/ui/parser/parser-recovery-2.stderr @@ -5,10 +5,10 @@ LL | let x = y.; | ^ error: mismatched closing delimiter: `)` - --> $DIR/parser-recovery-2.rs:6:5 + --> $DIR/parser-recovery-2.rs:4:14 | LL | fn bar() { - | - unclosed delimiter + | ^ unclosed delimiter LL | let x = foo(); LL | ) | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr index 00861a5a3d49a..1366ef1bba8bf 100644 --- a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr +++ b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr @@ -1,10 +1,10 @@ error: mismatched closing delimiter: `}` - --> $DIR/unclosed_delim_mod.rs:7:1 + --> $DIR/unclosed_delim_mod.rs:5:7 | LL | pub fn new() -> Result { | - closing delimiter possibly meant for this LL | Ok(Value { - | - unclosed delimiter + | ^ unclosed delimiter LL | } LL | } | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/unclosed_delim_mod.stderr b/src/test/ui/parser/unclosed_delim_mod.stderr index 9c16707212367..a46d020b9672e 100644 --- a/src/test/ui/parser/unclosed_delim_mod.stderr +++ b/src/test/ui/parser/unclosed_delim_mod.stderr @@ -1,10 +1,10 @@ error: mismatched closing delimiter: `}` - --> $DIR/unclosed_delim_mod.rs:7:1 + --> $DIR/unclosed_delim_mod.rs:5:7 | LL | pub fn new() -> Result { | - closing delimiter possibly meant for this LL | Ok(Value { - | - unclosed delimiter + | ^ unclosed delimiter LL | } LL | } | ^ mismatched closing delimiter diff --git a/src/test/ui/parser/use-unclosed-brace.stderr b/src/test/ui/parser/use-unclosed-brace.stderr index d29a68f821481..438fe9c47eac1 100644 --- a/src/test/ui/parser/use-unclosed-brace.stderr +++ b/src/test/ui/parser/use-unclosed-brace.stderr @@ -8,10 +8,10 @@ LL | fn main() {} | ^ error: expected one of `,`, `::`, `as`, or `}`, found `;` - --> $DIR/use-unclosed-brace.rs:4:19 + --> $DIR/use-unclosed-brace.rs:4:10 | LL | use foo::{bar, baz; - | - ^ + | ^ ^ | | | | | expected one of `,`, `::`, `as`, or `}` | | help: `}` may belong here diff --git a/src/test/ui/resolve/token-error-correct-2.stderr b/src/test/ui/resolve/token-error-correct-2.stderr index 4014af2f41b61..cca9f2dc88ca0 100644 --- a/src/test/ui/resolve/token-error-correct-2.stderr +++ b/src/test/ui/resolve/token-error-correct-2.stderr @@ -1,8 +1,8 @@ error: mismatched closing delimiter: `)` - --> $DIR/token-error-correct-2.rs:6:5 + --> $DIR/token-error-correct-2.rs:4:12 | LL | if foo { - | - unclosed delimiter + | ^ unclosed delimiter LL | LL | ) | ^ mismatched closing delimiter diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index 31087e394adfe..77c87c78466b1 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -1,8 +1,8 @@ error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` - --> $DIR/token-error-correct-3.rs:13:35 + --> $DIR/token-error-correct-3.rs:13:21 | LL | callback(path.as_ref(); - | - ^ help: `)` may belong here + | ^ ^ help: `)` may belong here | | | unclosed delimiter diff --git a/src/test/ui/resolve/token-error-correct-4.stderr b/src/test/ui/resolve/token-error-correct-4.stderr index 64aff54ba7311..81e5a13369159 100644 --- a/src/test/ui/resolve/token-error-correct-4.stderr +++ b/src/test/ui/resolve/token-error-correct-4.stderr @@ -1,8 +1,8 @@ error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` - --> $DIR/token-error-correct-4.rs:9:21 + --> $DIR/token-error-correct-4.rs:9:12 | LL | setsuna(kazusa(); - | - ^ help: `)` may belong here + | ^ ^ help: `)` may belong here | | | unclosed delimiter diff --git a/src/test/ui/resolve/token-error-correct.stderr b/src/test/ui/resolve/token-error-correct.stderr index bf300ecd78173..ca0c4c18ad4ba 100644 --- a/src/test/ui/resolve/token-error-correct.stderr +++ b/src/test/ui/resolve/token-error-correct.stderr @@ -1,10 +1,10 @@ error: mismatched closing delimiter: `}` - --> $DIR/token-error-correct.rs:6:1 + --> $DIR/token-error-correct.rs:4:12 | LL | fn main() { | - closing delimiter possibly meant for this LL | foo(bar(; - | - unclosed delimiter + | ^ unclosed delimiter LL | LL | } | ^ mismatched closing delimiter From 4cdfa5bc5f15e466b5062b3cd8c4294bd92697c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 30 Aug 2021 10:16:03 +0300 Subject: [PATCH 06/14] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 996300f4a061e..d15f646ff17e2 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 996300f4a061e895a339a909fddce94f68ce7d19 +Subproject commit d15f646ff17e2da0d4e8dc2754ba83213cf1a8bb From 446c42945d7518e848ba9b9f7c844d6b3cc7b892 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 30 Aug 2021 11:37:02 +0200 Subject: [PATCH 07/14] Fix LLVM libunwind build for non-musl targets Broken in #85600 --- src/bootstrap/compile.rs | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8f27adaed8453..df9e9bce41527 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -142,6 +142,14 @@ fn copy_and_stamp( target_deps.push((target, dependency_type)); } +fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: &Path) -> PathBuf { + let libunwind_path = builder.ensure(native::Libunwind { target }); + let libunwind_source = libunwind_path.join("libunwind.a"); + let libunwind_target = libdir.join("libunwind.a"); + builder.copy(&libunwind_source, &libunwind_target); + libunwind_target +} + /// Copies third party objects needed by various targets. fn copy_third_party_objects( builder: &Builder<'_>, @@ -167,6 +175,15 @@ fn copy_third_party_objects( ); } + if target == "x86_64-fortanix-unknown-sgx" + || builder.config.llvm_libunwind == LlvmLibunwind::InTree + && (target.contains("linux") || target.contains("fuchsia")) + { + let libunwind_path = + copy_llvm_libunwind(builder, target, &builder.sysroot_libdir(*compiler, target)); + target_deps.push((libunwind_path, DependencyType::Target)); + } + target_deps } @@ -208,6 +225,9 @@ fn copy_self_contained_objects( builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained)); } + + let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained); + target_deps.push((libunwind_path, DependencyType::TargetSelfContained)); } else if target.ends_with("-wasi") { let srcdir = builder .wasi_root(target) @@ -234,18 +254,6 @@ fn copy_self_contained_objects( } } - if target.contains("musl") - || target.contains("x86_64-fortanix-unknown-sgx") - || builder.config.llvm_libunwind == LlvmLibunwind::InTree - && (target.contains("linux") || target.contains("fuchsia")) - { - let libunwind_path = builder.ensure(native::Libunwind { target }); - let libunwind_source = libunwind_path.join("libunwind.a"); - let libunwind_target = libdir_self_contained.join("libunwind.a"); - builder.copy(&libunwind_source, &libunwind_target); - target_deps.push((libunwind_target, DependencyType::TargetSelfContained)); - } - target_deps } From 14cbb4b78d532532f611d5653f169319bdf50b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 30 Aug 2021 11:49:05 +0200 Subject: [PATCH 08/14] Add regression test for a spurious import --- src/test/run-make/wasm-spurious-import/Makefile | 7 +++++++ src/test/run-make/wasm-spurious-import/main.rs | 14 ++++++++++++++ src/test/run-make/wasm-spurious-import/verify.js | 9 +++++++++ 3 files changed, 30 insertions(+) create mode 100644 src/test/run-make/wasm-spurious-import/Makefile create mode 100644 src/test/run-make/wasm-spurious-import/main.rs create mode 100644 src/test/run-make/wasm-spurious-import/verify.js diff --git a/src/test/run-make/wasm-spurious-import/Makefile b/src/test/run-make/wasm-spurious-import/Makefile new file mode 100644 index 0000000000000..1bb59dc1bfa41 --- /dev/null +++ b/src/test/run-make/wasm-spurious-import/Makefile @@ -0,0 +1,7 @@ +-include ../../run-make-fulldeps/tools.mk + +# only-wasm32-bare + +all: + $(RUSTC) main.rs -C overflow-checks=yes -C panic=abort -C lto -C opt-level=z --target wasm32-unknown-unknown + $(NODE) verify.js $(TMPDIR)/main.wasm diff --git a/src/test/run-make/wasm-spurious-import/main.rs b/src/test/run-make/wasm-spurious-import/main.rs new file mode 100644 index 0000000000000..fcbead5e28bd2 --- /dev/null +++ b/src/test/run-make/wasm-spurious-import/main.rs @@ -0,0 +1,14 @@ +#![crate_type = "cdylib"] +#![no_std] + +#[panic_handler] +fn my_panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[no_mangle] +pub fn multer(a: i128, b: i128) -> i128 { + // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported + // panic function in case of a bug. We verify that no imports exist in our verifier. + a * b +} diff --git a/src/test/run-make/wasm-spurious-import/verify.js b/src/test/run-make/wasm-spurious-import/verify.js new file mode 100644 index 0000000000000..d3b2101b6623c --- /dev/null +++ b/src/test/run-make/wasm-spurious-import/verify.js @@ -0,0 +1,9 @@ +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let imports = WebAssembly.Module.imports(m); +console.log('imports', imports); +assert.strictEqual(imports.length, 0); From 8539a3c001c4ae7400d5b4643681ee8e7dbfff24 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 29 Aug 2021 08:56:32 +0100 Subject: [PATCH 09/14] sunos systems add sanitizer supported. --- compiler/rustc_target/src/spec/x86_64_pc_solaris.rs | 3 ++- compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs | 3 ++- src/bootstrap/native.rs | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs index b78e43d4fe9b6..34b6d2901c820 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); @@ -8,6 +8,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call; + base.supported_sanitizers = SanitizerSet::ADDRESS; Target { llvm_target: "x86_64-pc-solaris".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs index d3f9349d99b8e..ec196a7f82329 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs @@ -1,10 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, SanitizerSet, Target}; pub fn target() -> Target { let mut base = super::illumos_base::opts(); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); + base.supported_sanitizers = SanitizerSet::ADDRESS; Target { // LLVM does not currently have a separate illumos target, diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 0a23d4fff6bda..8cf43eac404c6 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -839,6 +839,8 @@ fn supported_sanitizers( "x86_64-unknown-netbsd" => { common_libs("netbsd", "x86_64", &["asan", "lsan", "msan", "tsan"]) } + "x86_64-unknown-illumos" => common_libs("illumos", "x86_64", &["asan"]), + "x86_64-pc-solaris" => common_libs("solaris", "x86_64", &["asan"]), "x86_64-unknown-linux-gnu" => { common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"]) } From fc2a2650e2e8d86a9eab06eb1a03ff1a0641cd58 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 Sep 2021 11:41:06 +0200 Subject: [PATCH 10/14] cleanup const generics FIXME --- .../src/traits/object_safety.rs | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 041fd65e8fa49..57b8a84300ff9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -820,10 +820,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( } } - fn visit_const(&mut self, ct: &ty::Const<'tcx>) -> ControlFlow { - // First check if the type of this constant references `Self`. - self.visit_ty(ct.ty)?; - + fn visit_unevaluated_const( + &mut self, + uv: ty::Unevaluated<'tcx>, + ) -> ControlFlow { // Constants can only influence object safety if they reference `Self`. // This is only possible for unevaluated constants, so we walk these here. // @@ -837,7 +837,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // This shouldn't really matter though as we can't really use any // constants which are not considered const evaluatable. use rustc_middle::mir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::from_const(self.tcx, ct) { + if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() { Node::Leaf(leaf) => { let leaf = leaf.subst(self.tcx, ct.substs); @@ -852,31 +852,6 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( ControlFlow::CONTINUE } } - - fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow { - if let ty::PredicateKind::ConstEvaluatable(ct) = pred.kind().skip_binder() { - // FIXME(generic_const_exprs): We should probably deduplicate the logic for - // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to - // take a `ty::Const` instead. - use rustc_middle::mir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::new(self.tcx, ct) { - const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() { - Node::Leaf(leaf) => { - 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 - } - }) - } else { - ControlFlow::CONTINUE - } - } else { - pred.super_visit_with(self) - } - } } value From 7207194dbbeb92a27dcfae0f7d1143ec3d6506d3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 Sep 2021 11:42:52 +0200 Subject: [PATCH 11/14] update FIXME --- compiler/rustc_typeck/src/outlives/implicit_infer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 9fe26711f2102..3f7a350b11c31 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -120,7 +120,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( // Luckily the only types contained in default substs are type // parameters which don't matter here. // - // FIXME(const_generics): Once more complex const parameter types + // FIXME(const_param_types): Once complex const parameter types // are allowed, this might be incorrect. I think that we will still be // fine, as all outlives relations of the const param types should also // be part of the adt containing it, but we should still both update the From d18ff40a3d9de01dbff4fe7f6ba7fa6db7c65752 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 Sep 2021 17:43:07 +0200 Subject: [PATCH 12/14] use the correct feature gate Co-authored-by: Boxy --- compiler/rustc_typeck/src/outlives/implicit_infer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 3f7a350b11c31..0e96601d89fd8 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -120,7 +120,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( // Luckily the only types contained in default substs are type // parameters which don't matter here. // - // FIXME(const_param_types): Once complex const parameter types + // FIXME(adt_const_params): Once complex const parameter types // are allowed, this might be incorrect. I think that we will still be // fine, as all outlives relations of the const param types should also // be part of the adt containing it, but we should still both update the From 9da8e2a2fa902e644b4de143a379e339ed054afe Mon Sep 17 00:00:00 2001 From: ast-ral Date: Wed, 1 Sep 2021 20:52:30 -0700 Subject: [PATCH 13/14] remove redundant / misplaced sentence from docs --- library/core/src/ptr/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 02c9dadc0868d..014170604ecaa 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -182,10 +182,6 @@ mod mut_ptr; /// // Ensure that the last item was dropped. /// assert!(weak.upgrade().is_none()); /// ``` -/// -/// Notice that the compiler performs this copy automatically when dropping packed structs, -/// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` -/// manually. #[stable(feature = "drop_in_place", since = "1.8.0")] #[lang = "drop_in_place"] #[allow(unconditional_recursion)] From 99407584161510e5ab3c6453700537bf6123e158 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 26 Aug 2021 17:18:03 +0300 Subject: [PATCH 14/14] expand: Treat more macro calls as statement macro calls --- compiler/rustc_ast/src/mut_visit.rs | 12 ++- compiler/rustc_expand/src/expand.rs | 100 +++++++++++++++------- compiler/rustc_expand/src/lib.rs | 1 + compiler/rustc_expand/src/placeholders.rs | 25 +----- src/test/ui/macros/issue-87877.rs | 25 ++++++ 5 files changed, 108 insertions(+), 55 deletions(-) create mode 100644 src/test/ui/macros/issue-87877.rs diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 368a23e34290d..3c6ea56799e08 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1380,7 +1380,17 @@ pub fn noop_flat_map_stmt( ) -> SmallVec<[Stmt; 1]> { vis.visit_id(&mut id); vis.visit_span(&mut span); - noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| Stmt { id, kind, span }).collect() + let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis) + .into_iter() + .map(|kind| Stmt { id, kind, span }) + .collect(); + if stmts.len() > 1 { + panic!( + "cloning statement `NodeId`s is prohibited by default, \ + the visitor should implement custom statement visiting" + ); + } + stmts } pub fn noop_flat_map_stmt_kind( diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 16e086e32f63d..3ccf9f446a63e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -12,7 +12,7 @@ use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; -use rustc_ast::{AstLike, Block, Inline, ItemKind, Local, MacArgs, MacCall}; +use rustc_ast::{AstLike, Block, Inline, ItemKind, MacArgs, MacCall}; use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem}; use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe}; use rustc_ast_pretty::pprust; @@ -559,7 +559,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.force_mode = orig_force_mode; // Finally incorporate all the expanded macros into the input AST fragment. - let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic); + let mut placeholder_expander = PlaceholderExpander::default(); while let Some(expanded_fragments) = expanded_fragments.pop() { for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() { placeholder_expander @@ -1061,13 +1061,51 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { attr } + fn take_stmt_bang( + &mut self, + stmt: ast::Stmt, + ) -> Result<(bool, MacCall, Vec), ast::Stmt> { + match stmt.kind { + StmtKind::MacCall(mac) => { + let MacCallStmt { mac, style, attrs, .. } = mac.into_inner(); + Ok((style == MacStmtStyle::Semicolon, mac, attrs.into())) + } + StmtKind::Item(ref item) if matches!(item.kind, ItemKind::MacCall(..)) => { + match stmt.kind { + StmtKind::Item(item) => match item.into_inner() { + ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => { + Ok((mac.args.need_semicolon(), mac, attrs)) + } + _ => unreachable!(), + }, + _ => unreachable!(), + } + } + StmtKind::Semi(ref expr) if matches!(expr.kind, ast::ExprKind::MacCall(..)) => { + match stmt.kind { + StmtKind::Semi(expr) => match expr.into_inner() { + ast::Expr { kind: ast::ExprKind::MacCall(mac), attrs, .. } => { + Ok((mac.args.need_semicolon(), mac, attrs.into())) + } + _ => unreachable!(), + }, + _ => unreachable!(), + } + } + StmtKind::Local(..) | StmtKind::Empty | StmtKind::Item(..) | StmtKind::Semi(..) => { + Err(stmt) + } + StmtKind::Expr(..) => unreachable!(), + } + } + fn configure(&mut self, node: T) -> Option { self.cfg.configure(node) } // Detect use of feature-gated or invalid attributes on macro invocations // since they will not be detected after macro expansion. - fn check_attributes(&mut self, attrs: &[ast::Attribute], call: &MacCall) { + fn check_attributes(&self, attrs: &[ast::Attribute], call: &MacCall) { let features = self.cx.ecfg.features.unwrap(); let mut attrs = attrs.iter().peekable(); let mut span: Option = None; @@ -1177,11 +1215,6 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { }); } - // This is needed in order to set `lint_node_id` for `let` statements - fn visit_local(&mut self, local: &mut P) { - assign_id!(self, &mut local.id, || noop_visit_local(local, self)); - } - fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { let mut arm = configure!(self, arm); @@ -1299,31 +1332,39 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { let mut stmt = configure!(self, stmt); - // we'll expand attributes on expressions separately - if !stmt.is_expr() { + // We pull macro invocations (both attributes and fn-like macro calls) out of their + // `StmtKind`s and treat them as statement macro invocations, not as items or expressions. + // FIXME: invocations in semicolon-less expressions positions are expanded as expressions, + // changing that requires some compatibility measures. + let mut stmt = if !stmt.is_expr() { if let Some(attr) = self.take_first_attr(&mut stmt) { return self .collect_attr(attr, Annotatable::Stmt(P(stmt)), AstFragmentKind::Stmts) .make_stmts(); } - } - if let StmtKind::MacCall(mac) = stmt.kind { - let MacCallStmt { mac, style, attrs, tokens: _ } = mac.into_inner(); - self.check_attributes(&attrs, &mac); - let mut placeholder = - self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts(); - - // If this is a macro invocation with a semicolon, then apply that - // semicolon to the final statement produced by expansion. - if style == MacStmtStyle::Semicolon { - if let Some(stmt) = placeholder.pop() { - placeholder.push(stmt.add_trailing_semicolon()); + let span = stmt.span; + match self.take_stmt_bang(stmt) { + Ok((add_semicolon, mac, attrs)) => { + self.check_attributes(&attrs, &mac); + let mut stmts = + self.collect_bang(mac, span, AstFragmentKind::Stmts).make_stmts(); + + // If this is a macro invocation with a semicolon, then apply that + // semicolon to the final statement produced by expansion. + if add_semicolon { + if let Some(stmt) = stmts.pop() { + stmts.push(stmt.add_trailing_semicolon()); + } + } + + return stmts; } + Err(stmt) => stmt, } - - return placeholder; - } + } else { + stmt + }; // The only way that we can end up with a `MacCall` expression statement, // (as opposed to a `StmtKind::MacCall`) is if we have a macro as the @@ -1338,14 +1379,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } - // The placeholder expander gives ids to statements, so we avoid folding the id here. - // We don't use `assign_id!` - it will be called when we visit statement's contents - // (e.g. an expression, item, or local) - let ast::Stmt { id, kind, span } = stmt; - let res = noop_flat_map_stmt_kind(kind, self) - .into_iter() - .map(|kind| ast::Stmt { id, kind, span }) - .collect(); + let res = assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)); self.cx.current_expansion.is_trailing_mac = false; res diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index aaded7ba23bbd..c6dc66e99fe94 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -10,6 +10,7 @@ #![feature(proc_macro_span)] #![feature(try_blocks)] #![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard +#![recursion_limit = "256"] #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 6586ba138fb99..8e78fcbb8dbc1 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -1,4 +1,3 @@ -use crate::base::ExtCtxt; use crate::expand::{AstFragment, AstFragmentKind}; use rustc_ast as ast; @@ -175,17 +174,12 @@ pub fn placeholder( } } -pub struct PlaceholderExpander<'a, 'b> { +#[derive(Default)] +pub struct PlaceholderExpander { expanded_fragments: FxHashMap, - cx: &'a mut ExtCtxt<'b>, - monotonic: bool, } -impl<'a, 'b> PlaceholderExpander<'a, 'b> { - pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self { - PlaceholderExpander { cx, expanded_fragments: FxHashMap::default(), monotonic } - } - +impl PlaceholderExpander { pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) { fragment.mut_visit_with(self); self.expanded_fragments.insert(id, fragment); @@ -196,7 +190,7 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> { } } -impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { +impl MutVisitor for PlaceholderExpander { fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { if arm.is_placeholder { self.remove(arm.id).make_arms() @@ -360,15 +354,4 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { _ => noop_visit_ty(ty, self), } } - - fn visit_block(&mut self, block: &mut P) { - noop_visit_block(block, self); - - for stmt in block.stmts.iter_mut() { - if self.monotonic { - assert_eq!(stmt.id, ast::DUMMY_NODE_ID); - stmt.id = self.cx.resolver.next_node_id(); - } - } - } } diff --git a/src/test/ui/macros/issue-87877.rs b/src/test/ui/macros/issue-87877.rs new file mode 100644 index 0000000000000..a40e2c5f9705a --- /dev/null +++ b/src/test/ui/macros/issue-87877.rs @@ -0,0 +1,25 @@ +// check-pass + +macro_rules! two_items { + () => { + extern "C" {} + extern "C" {} + }; +} + +macro_rules! single_expr_funneler { + ($expr:expr) => { + $expr; // note the semicolon, it changes the statement kind during parsing + }; +} + +macro_rules! single_item_funneler { + ($item:item) => { + $item + }; +} + +fn main() { + single_expr_funneler! { two_items! {} } + single_item_funneler! { two_items! {} } +}