Auto merge of #95299 - mkroening:rm-hermitkernel, r=joshtriplett Remove hermitkernel targets RustyHermit now maintains custom json targets, which are distributed with the kernel: https://github.com/hermitcore/libhermit-rs/pull/395 See https://github.com/hermitcore/rusty-hermit/issues/197#issuecomment-1076667961 CC: `@stlankes,` `@bstrie`
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index c9c973b..6f78c81 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs
@@ -2361,8 +2361,8 @@ pub fn emit_errors(&mut self) -> Option<ErrorGuaranteed> { if !self.errors.buffered.is_empty() { self.errors.buffered.sort_by_key(|diag| diag.sort_span); - for diag in self.errors.buffered.drain(..) { - self.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag); + for mut diag in self.errors.buffered.drain(..) { + self.infcx.tcx.sess.diagnostic().emit_diagnostic(&mut diag); } }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index e235721..1d11e6d 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1748,7 +1748,7 @@ pub fn check(&self, sess: &Session, blocking: bool) { if let Some(code) = diag.code { d.code(code); } - handler.emit_diagnostic(&d); + handler.emit_diagnostic(&mut d); } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { let msg = msg.strip_prefix("error: ").unwrap_or(&msg);
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index eb01e261..223b3ad 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -255,8 +255,8 @@ pub fn check_body(&mut self) { // "secondary" errors if they occurred. let secondary_errors = mem::take(&mut self.secondary_errors); if self.error_emitted.is_none() { - for error in secondary_errors { - self.tcx.sess.diagnostic().emit_diagnostic(&error); + for mut error in secondary_errors { + self.tcx.sess.diagnostic().emit_diagnostic(&mut error); } } else { assert!(self.tcx.sess.has_errors().is_some());
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 91bb38e..667c63b 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs
@@ -1181,8 +1181,8 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // a .span_bug or .bug call has already printed what // it wants to print. if !info.payload().is::<rustc_errors::ExplicitBug>() { - let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); - handler.emit_diagnostic(&d); + let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); + handler.emit_diagnostic(&mut d); } let mut xs: Vec<Cow<'static, str>> = vec![
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index c380455..5f59eba 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -70,7 +70,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType { AnnotationType::Error } Level::Warning => AnnotationType::Warning, - Level::Note => AnnotationType::Note, + Level::Note | Level::OnceNote => AnnotationType::Note, Level::Help => AnnotationType::Help, // FIXME(#59346): Not sure how to map this level Level::FailureNote => AnnotationType::Error,
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 5c36c3c..00ecbbb 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -135,7 +135,12 @@ pub fn is_error(&self) -> bool { | Level::Error { .. } | Level::FailureNote => true, - Level::Warning | Level::Note | Level::Help | Level::Allow | Level::Expect(_) => false, + Level::Warning + | Level::Note + | Level::OnceNote + | Level::Help + | Level::Allow + | Level::Expect(_) => false, } } @@ -335,11 +340,25 @@ pub fn highlighted_note(&mut self, msg: Vec<(String, Style)>) -> &mut Self { /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. + pub fn note_once(&mut self, msg: &str) -> &mut Self { + self.sub(Level::OnceNote, msg, MultiSpan::new(), None); + self + } + + /// Prints the span with a note above it. + /// This is like [`Diagnostic::note()`], but it gets its own span. pub fn span_note<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Note, msg, sp.into(), None); self } + /// Prints the span with a note above it. + /// This is like [`Diagnostic::note()`], but it gets its own span. + pub fn span_note_once<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self { + self.sub(Level::OnceNote, msg, sp.into(), None); + self + } + /// Add a warning attached to this diagnostic. pub fn warn(&mut self, msg: &str) -> &mut Self { self.sub(Level::Warning, msg, MultiSpan::new(), None);
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 7247163..088f609 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -128,7 +128,7 @@ fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Se DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - let guar = handler.emit_diagnostic(&db.inner.diagnostic); + let guar = handler.emit_diagnostic(&mut db.inner.diagnostic); // Only allow a guarantee if the `level` wasn't switched to a // non-error - the field isn't `pub`, but the whole `Diagnostic` @@ -190,7 +190,7 @@ fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Se DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&db.inner.diagnostic); + handler.emit_diagnostic(&mut db.inner.diagnostic); } // `.emit()` was previously called, disallowed from repeating it. DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} @@ -396,11 +396,17 @@ pub fn span_labels( ) -> &mut Self); forward!(pub fn note(&mut self, msg: &str) -> &mut Self); + forward!(pub fn note_once(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_note( &mut self, sp: impl Into<MultiSpan>, msg: &str, ) -> &mut Self); + forward!(pub fn span_note_once( + &mut self, + sp: impl Into<MultiSpan>, + msg: &str, + ) -> &mut Self); forward!(pub fn warn(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_warn(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> &mut Self); forward!(pub fn help(&mut self, msg: &str) -> &mut Self); @@ -500,11 +506,11 @@ fn drop(&mut self) { // No `.emit()` or `.cancel()` calls. DiagnosticBuilderState::Emittable(handler) => { if !panicking() { - handler.emit_diagnostic(&Diagnostic::new( + handler.emit_diagnostic(&mut Diagnostic::new( Level::Bug, "the following error was constructed but not emitted", )); - handler.emit_diagnostic(&self.diagnostic); + handler.emit_diagnostic(&mut self.diagnostic); panic!(); } }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 831d408..93b7201 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs
@@ -542,7 +542,7 @@ fn emit_diagnostic(&mut self, d: &Diagnostic) { if let Some(ref note) = self.fatal_note { d.note(note); } - self.fatal_handler.emit_diagnostic(&d); + self.fatal_handler.emit_diagnostic(&mut d); } } }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index c719e49..2f2f6ed 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs
@@ -4,6 +4,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(crate_visibility_modifier)] +#![feature(drain_filter)] #![feature(backtrace)] #![feature(if_let_guard)] #![feature(let_else)] @@ -919,7 +920,7 @@ pub fn force_print_diagnostic(&self, db: Diagnostic) { self.inner.borrow_mut().force_print_diagnostic(db) } - pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed> { + pub fn emit_diagnostic(&self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> { self.inner.borrow_mut().emit_diagnostic(diagnostic) } @@ -993,25 +994,25 @@ fn must_teach(&mut self, code: &DiagnosticId) -> bool { self.taught_diagnostics.insert(code.clone()) } - fn force_print_diagnostic(&mut self, db: Diagnostic) { - self.emitter.emit_diagnostic(&db); + fn force_print_diagnostic(&mut self, mut db: Diagnostic) { + self.emitter.emit_diagnostic(&mut db); } /// Emit all stashed diagnostics. fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> { let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>(); let mut reported = None; - diags.iter().for_each(|diag| { + for mut diag in diags { if diag.is_error() { reported = Some(ErrorGuaranteed(())); } - self.emit_diagnostic(diag); - }); + self.emit_diagnostic(&mut diag); + } reported } // FIXME(eddyb) this should ideally take `diagnostic` by value. - fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed> { + fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> { if diagnostic.level == Level::DelayedBug { // FIXME(eddyb) this should check for `has_errors` and stop pushing // once *any* errors were emitted (and truncate `delayed_span_bugs` @@ -1070,7 +1071,23 @@ fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed // Only emit the diagnostic if we've been asked to deduplicate and // haven't already emitted an equivalent diagnostic. if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { - self.emitter.emit_diagnostic(diagnostic); + debug!(?diagnostic); + debug!(?self.emitted_diagnostics); + let already_emitted_sub = |sub: &mut SubDiagnostic| { + debug!(?sub); + if sub.level != Level::OnceNote { + return false; + } + let mut hasher = StableHasher::new(); + sub.hash(&mut hasher); + let diagnostic_hash = hasher.finish(); + debug!(?diagnostic_hash); + !self.emitted_diagnostics.insert(diagnostic_hash) + }; + + diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {}); + + self.emitter.emit_diagnostic(&diagnostic); if diagnostic.is_error() { self.deduplicated_err_count += 1; } else if diagnostic.level == Warning { @@ -1221,22 +1238,22 @@ fn delay_span_bug(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> ErrorGuaran let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); diagnostic.set_span(sp.into()); diagnostic.note(&format!("delayed at {}", std::panic::Location::caller())); - self.emit_diagnostic(&diagnostic).unwrap() + self.emit_diagnostic(&mut diagnostic).unwrap() } // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). fn delay_good_path_bug(&mut self, msg: &str) { - let diagnostic = Diagnostic::new(Level::DelayedBug, msg); + let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); if self.flags.report_delayed_bugs { - self.emit_diagnostic(&diagnostic); + self.emit_diagnostic(&mut diagnostic); } let backtrace = std::backtrace::Backtrace::force_capture(); self.delayed_good_path_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); } fn failure(&mut self, msg: &str) { - self.emit_diagnostic(&Diagnostic::new(FailureNote, msg)); + self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg)); } fn fatal(&mut self, msg: &str) -> FatalError { @@ -1253,11 +1270,11 @@ fn emit(&mut self, level: Level, msg: &str) -> ErrorGuaranteed { if self.treat_err_as_bug() { self.bug(msg); } - self.emit_diagnostic(&Diagnostic::new(level, msg)).unwrap() + self.emit_diagnostic(&mut Diagnostic::new(level, msg)).unwrap() } fn bug(&mut self, msg: &str) -> ! { - self.emit_diagnostic(&Diagnostic::new(Bug, msg)); + self.emit_diagnostic(&mut Diagnostic::new(Bug, msg)); panic::panic_any(ExplicitBug); } @@ -1267,7 +1284,7 @@ fn flush_delayed(&mut self, bugs: impl IntoIterator<Item = Diagnostic>, explanat if no_bugs { // Put the overall explanation before the `DelayedBug`s, to // frame them better (e.g. separate warnings from them). - self.emit_diagnostic(&Diagnostic::new(Bug, explanation)); + self.emit_diagnostic(&mut Diagnostic::new(Bug, explanation)); no_bugs = false; } @@ -1283,7 +1300,7 @@ fn flush_delayed(&mut self, bugs: impl IntoIterator<Item = Diagnostic>, explanat } bug.level = Level::Bug; - self.emit_diagnostic(&bug); + self.emit_diagnostic(&mut bug); } // Panic with `ExplicitBug` to avoid "unexpected panic" messages. @@ -1350,6 +1367,8 @@ pub enum Level { }, Warning, Note, + /// A note that is only emitted once. + OnceNote, Help, FailureNote, Allow, @@ -1372,7 +1391,7 @@ fn color(self) -> ColorSpec { Warning => { spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); } - Note => { + Note | OnceNote => { spec.set_fg(Some(Color::Green)).set_intense(true); } Help => { @@ -1389,7 +1408,7 @@ pub fn to_str(self) -> &'static str { Bug | DelayedBug => "error: internal compiler error", Fatal | Error { .. } => "error", Warning => "warning", - Note => "note", + Note | OnceNote => "note", Help => "help", FailureNote => "failure-note", Allow => panic!("Shouldn't call on allowed error"),
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 0aef598..5bd4bee 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -771,8 +771,8 @@ fn sub( ) { diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None); } - fn emit(&mut self, diag: Self::Diagnostic) { - self.sess().span_diagnostic.emit_diagnostic(&diag); + fn emit(&mut self, mut diag: Self::Diagnostic) { + self.sess().span_diagnostic.emit_diagnostic(&mut diag); } }
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index b13f0b0..9b32884 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -111,7 +111,7 @@ use rustc_session::{Session, StableCrateId}; use std::fs as std_fs; -use std::io; +use std::io::{self, ErrorKind}; use std::mem; use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -371,7 +371,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name); debug!("finalize_session_directory() - new path: {}", new_path.display()); - match std_fs::rename(&*incr_comp_session_dir, &new_path) { + match rename_path_with_retry(&*incr_comp_session_dir, &new_path, 3) { Ok(_) => { debug!("finalize_session_directory() - directory renamed successfully"); @@ -961,3 +961,24 @@ fn safe_remove_file(p: &Path) -> io::Result<()> { result => result, } } + +// On Windows the compiler would sometimes fail to rename the session directory because +// the OS thought something was still being accessed in it. So we retry a few times to give +// the OS time to catch up. +// See https://github.com/rust-lang/rust/issues/86929. +fn rename_path_with_retry(from: &Path, to: &Path, mut retries_left: usize) -> std::io::Result<()> { + loop { + match std_fs::rename(from, to) { + Ok(()) => return Ok(()), + Err(e) => { + if retries_left > 0 && e.kind() == ErrorKind::PermissionDenied { + // Try again after a short waiting period. + std::thread::sleep(Duration::from_millis(50)); + retries_left -= 1; + } else { + return Err(e); + } + } + } + } +}
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 94991fd..ff80828 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs
@@ -28,7 +28,7 @@ use super::*; use rustc_middle::ty::relate::{Relate, TypeRelation}; -use rustc_middle::ty::Const; +use rustc_middle::ty::{Const, ImplSubject}; pub struct At<'a, 'tcx> { pub infcx: &'a InferCtxt<'a, 'tcx>, @@ -272,6 +272,29 @@ pub fn glb<T>(self, a: T, b: T) -> InferResult<'tcx, T> } } +impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> { + fn to_trace( + tcx: TyCtxt<'tcx>, + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + match (a, b) { + (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => { + ToTrace::to_trace(tcx, cause, a_is_expected, trait_ref_a, trait_ref_b) + } + (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => { + ToTrace::to_trace(tcx, cause, a_is_expected, ty_a, ty_b) + } + (ImplSubject::Trait(_), ImplSubject::Inherent(_)) + | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => { + bug!("can not trace TraitRef and Ty"); + } + } + } +} + impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { fn to_trace( _: TyCtxt<'tcx>,
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index f6d8fc5..170dd11 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs
@@ -52,7 +52,7 @@ macro_rules! arena_types { Vec<rustc_middle::traits::query::OutlivesBound<'tcx>> > >, - [] dtorck_constraint: rustc_middle::traits::query::DtorckConstraint<'tcx>, + [] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, [] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, [] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, [] type_op_subtype:
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 1053f0c..a9e22d1 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -7,10 +7,10 @@ pub mod place; use crate::ty::query::Providers; -use crate::ty::TyCtxt; +use crate::ty::{ImplSubject, TyCtxt}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::*; use rustc_query_system::ich::StableHashingContext; use rustc_span::DUMMY_SP; @@ -54,6 +54,12 @@ pub fn hir(self) -> map::Map<'tcx> { pub fn parent_module(self, id: HirId) -> LocalDefId { self.parent_module_from_def_id(id.owner) } + + pub fn impl_subject(self, def_id: DefId) -> ImplSubject<'tcx> { + self.impl_trait_ref(def_id) + .map(ImplSubject::Trait) + .unwrap_or_else(|| ImplSubject::Inherent(self.type_of(def_id))) + } } pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index dc1fe5f..1f0cd90 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs
@@ -12,7 +12,7 @@ builtin::{self, FORBIDDEN_LINT_GROUPS}, FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, }; -use rustc_session::{DiagnosticMessageId, Session}; +use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; use rustc_span::{symbol, Span, Symbol, DUMMY_SP}; @@ -245,7 +245,6 @@ pub fn forget_guarantee(self) -> LintDiagnosticBuilder<'a, ()> { } pub fn explain_lint_level_source( - sess: &Session, lint: &'static Lint, level: Level, src: LintLevelSource, @@ -254,11 +253,7 @@ pub fn explain_lint_level_source( let name = lint.name_lower(); match src { LintLevelSource::Default => { - sess.diag_note_once( - err, - DiagnosticMessageId::from(lint), - &format!("`#[{}({})]` on by default", level.as_str(), name), - ); + err.note_once(&format!("`#[{}({})]` on by default", level.as_str(), name)); } LintLevelSource::CommandLine(lint_flag_val, orig_level) => { let flag = match orig_level { @@ -273,46 +268,29 @@ pub fn explain_lint_level_source( }; let hyphen_case_lint_name = name.replace('_', "-"); if lint_flag_val.as_str() == name { - sess.diag_note_once( - err, - DiagnosticMessageId::from(lint), - &format!( - "requested on the command line with `{} {}`", - flag, hyphen_case_lint_name - ), - ); + err.note_once(&format!( + "requested on the command line with `{} {}`", + flag, hyphen_case_lint_name + )); } else { let hyphen_case_flag_val = lint_flag_val.as_str().replace('_', "-"); - sess.diag_note_once( - err, - DiagnosticMessageId::from(lint), - &format!( - "`{} {}` implied by `{} {}`", - flag, hyphen_case_lint_name, flag, hyphen_case_flag_val - ), - ); + err.note_once(&format!( + "`{} {}` implied by `{} {}`", + flag, hyphen_case_lint_name, flag, hyphen_case_flag_val + )); } } LintLevelSource::Node(lint_attr_name, src, reason) => { if let Some(rationale) = reason { err.note(rationale.as_str()); } - sess.diag_span_note_once( - err, - DiagnosticMessageId::from(lint), - src, - "the lint level is defined here", - ); + err.span_note_once(src, "the lint level is defined here"); if lint_attr_name.as_str() != name { let level_str = level.as_str(); - sess.diag_note_once( - err, - DiagnosticMessageId::from(lint), - &format!( - "`#[{}({})]` implied by `#[{}({})]`", - level_str, name, level_str, lint_attr_name - ), - ); + err.note_once(&format!( + "`#[{}({})]` implied by `#[{}({})]`", + level_str, name, level_str, lint_attr_name + )); } } } @@ -412,7 +390,7 @@ fn struct_lint_level_impl<'s, 'd>( return; } - explain_lint_level_source(sess, lint, level, src, &mut err); + explain_lint_level_source(lint, level, src, &mut err); let name = lint.name_lower(); let is_force_warn = matches!(level, Level::ForceWarn);
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 219af6c..fd6e241 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -17,9 +17,9 @@ use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer}; use rustc_session::parse::feature_err_issue; -use rustc_session::{DiagnosticMessageId, Session}; +use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::{MultiSpan, Span}; +use rustc_span::Span; use std::num::NonZeroU32; #[derive(PartialEq, Clone, Copy, Debug)] @@ -94,30 +94,15 @@ pub fn report_unstable( None => format!("use of unstable library feature '{}'", &feature), }; - let msp: MultiSpan = span.into(); - let sm = &sess.parse_sess.source_map(); - let span_key = msp.primary_span().and_then(|sp: Span| { - if !sp.is_dummy() { - let file = sm.lookup_char_pos(sp.lo()).file; - if file.is_imported() { None } else { Some(span) } - } else { - None + if is_soft { + soft_handler(SOFT_UNSTABLE, span, &msg) + } else { + let mut err = + feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg); + if let Some((inner_types, ref msg, sugg, applicability)) = suggestion { + err.span_suggestion(inner_types, msg, sugg, applicability); } - }); - - let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); - let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - if is_soft { - soft_handler(SOFT_UNSTABLE, span, &msg) - } else { - let mut err = - feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg); - if let Some((inner_types, ref msg, sugg, applicability)) = suggestion { - err.span_suggestion(inner_types, msg, sugg, applicability); - } - err.emit(); - } + err.emit(); } }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cd6ff82..95260e9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs
@@ -549,7 +549,7 @@ query adt_dtorck_constraint( key: DefId - ) -> Result<&'tcx DtorckConstraint<'tcx>, NoSolution> { + ) -> Result<&'tcx DropckConstraint<'tcx>, NoSolution> { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } }
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 07cfe83..d43492c 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs
@@ -143,7 +143,7 @@ pub fn into_kinds_reporting_overflows( /// A set of constraints that need to be satisfied in order for /// a type to be valid for destruction. #[derive(Clone, Debug, HashStable)] -pub struct DtorckConstraint<'tcx> { +pub struct DropckConstraint<'tcx> { /// Types that are required to be alive in order for this /// type to be valid for destruction. pub outlives: Vec<ty::subst::GenericArg<'tcx>>, @@ -157,17 +157,17 @@ pub struct DtorckConstraint<'tcx> { pub overflows: Vec<Ty<'tcx>>, } -impl<'tcx> DtorckConstraint<'tcx> { - pub fn empty() -> DtorckConstraint<'tcx> { - DtorckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] } +impl<'tcx> DropckConstraint<'tcx> { + pub fn empty() -> DropckConstraint<'tcx> { + DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] } } } -impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> { - fn from_iter<I: IntoIterator<Item = DtorckConstraint<'tcx>>>(iter: I) -> Self { +impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> { + fn from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self { let mut result = Self::empty(); - for DtorckConstraint { outlives, dtorck_types, overflows } in iter { + for DropckConstraint { outlives, dtorck_types, overflows } in iter { result.outlives.extend(outlives); result.dtorck_types.extend(dtorck_types); result.overflows.extend(overflows);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 3124cc5..31db66d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -44,6 +44,7 @@ use rustc_span::Span; use rustc_target::abi::Align; +use std::fmt::Debug; use std::hash::Hash; use std::ops::ControlFlow; use std::{fmt, str}; @@ -172,6 +173,12 @@ pub struct ImplHeader<'tcx> { pub predicates: Vec<Predicate<'tcx>>, } +#[derive(Copy, Clone, Debug, TypeFoldable)] +pub enum ImplSubject<'tcx> { + Trait(TraitRef<'tcx>), + Inherent(Ty<'tcx>), +} + #[derive( Copy, Clone,
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index fe036f4..9e48c56 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs
@@ -23,7 +23,7 @@ CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution, }; use crate::traits::query::{ - DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult, + DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult, OutlivesBound, }; use crate::traits::specialization_graph;
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 5d6cbcf..d9b5556 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -7,7 +7,7 @@ use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar}; use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; -use crate::ty::{self, Term, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable}; use rustc_hir as ast; use rustc_hir::def_id::DefId; use rustc_span::DUMMY_SP; @@ -356,6 +356,30 @@ fn relate<R: TypeRelation<'tcx>>( } } +impl<'tcx> Relate<'tcx> for ImplSubject<'tcx> { + #[inline] + fn relate<R: TypeRelation<'tcx>>( + relation: &mut R, + a: ImplSubject<'tcx>, + b: ImplSubject<'tcx>, + ) -> RelateResult<'tcx, ImplSubject<'tcx>> { + match (a, b) { + (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => { + let trait_ref = ty::TraitRef::relate(relation, trait_ref_a, trait_ref_b)?; + Ok(ImplSubject::Trait(trait_ref)) + } + (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => { + let ty = Ty::relate(relation, ty_a, ty_b)?; + Ok(ImplSubject::Inherent(ty)) + } + (ImplSubject::Trait(_), ImplSubject::Inherent(_)) + | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => { + bug!("can not relate TraitRef and Ty"); + } + } + } +} + impl<'tcx> Relate<'tcx> for Ty<'tcx> { #[inline] fn relate<R: TypeRelation<'tcx>>(
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index f8d0e44..8de0599 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -554,7 +554,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root); assert_eq!(level, Level::Allow); lint::explain_lint_level_source( - tcx.sess, UNSAFE_OP_IN_UNSAFE_FN, Level::Allow, source,
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index a3e6646..0ce86a7 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs
@@ -49,8 +49,8 @@ macro_rules! panictry_buffer { match $e { Ok(e) => e, Err(errs) => { - for e in errs { - $handler.emit_diagnostic(&e); + for mut e in errs { + $handler.emit_diagnostic(&mut e); } FatalError.raise() } @@ -167,8 +167,8 @@ fn try_file_to_source_file( fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) -> Lrc<SourceFile> { match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, - Err(d) => { - sess.span_diagnostic.emit_diagnostic(&d); + Err(mut d) => { + sess.span_diagnostic.emit_diagnostic(&mut d); FatalError.raise(); } }
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index a080b4a3..f7655e5 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -784,8 +784,8 @@ fn emit_side_effects<Ctxt: QueryContext<DepKind = K>>( let handle = tcx.dep_context().sess().diagnostic(); - for diagnostic in side_effects.diagnostics { - handle.emit_diagnostic(&diagnostic); + for mut diagnostic in side_effects.diagnostics { + handle.emit_diagnostic(&mut diagnostic); } } }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2c3ddae..34218e8 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -9,7 +9,7 @@ use crate::imports::{Import, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; -use crate::{CrateLint, Determinacy, ExternPreludeEntry, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError}; use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError}; @@ -235,16 +235,16 @@ fn as_mut(&mut self) -> &mut Resolver<'a> { impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { - self.resolve_visibility_speculative(vis, false).unwrap_or_else(|err| { + self.try_resolve_visibility(vis, true).unwrap_or_else(|err| { self.r.report_vis_error(err); ty::Visibility::Public }) } - fn resolve_visibility_speculative<'ast>( + fn try_resolve_visibility<'ast>( &mut self, vis: &'ast ast::Visibility, - speculative: bool, + finalize: bool, ) -> Result<ty::Visibility, VisResolutionError<'ast>> { let parent_scope = &self.parent_scope; match vis.kind { @@ -296,13 +296,11 @@ fn resolve_visibility_speculative<'ast>( &segments, Some(TypeNS), parent_scope, - !speculative, - path.span, - CrateLint::SimplePath(id), + if finalize { Finalize::SimplePath(id, path.span) } else { Finalize::No }, ) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => { let res = module.res().expect("visibility resolved to unnamed block"); - if !speculative { + if finalize { self.r.record_partial_res(id, PartialRes::new(res)); } if module.is_normal() { @@ -772,7 +770,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) { // correct visibilities for unnamed field placeholders specifically, so the // constructor visibility should still be determined correctly. let field_vis = self - .resolve_visibility_speculative(&field.vis, true) + .try_resolve_visibility(&field.vis, false) .unwrap_or(ty::Visibility::Public); if ctor_vis.is_at_least(field_vis, &*self.r) { ctor_vis = field_vis; @@ -1131,8 +1129,7 @@ fn process_macro_use_imports(&mut self, item: &Item, module: Module<'a>) -> bool ident, MacroNS, &self.parent_scope, - false, - ident.span, + None, ); if let Ok(binding) = result { let import = macro_use_import(self, ident.span); @@ -1272,9 +1269,9 @@ fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> { let vis = match item.kind { // Visibilities must not be resolved non-speculatively twice // and we already resolved this one as a `fn` item visibility. - ItemKind::Fn(..) => self - .resolve_visibility_speculative(&item.vis, true) - .unwrap_or(ty::Visibility::Public), + ItemKind::Fn(..) => { + self.try_resolve_visibility(&item.vis, false).unwrap_or(ty::Visibility::Public) + } _ => self.resolve_visibility(&item.vis), }; if vis != ty::Visibility::Public {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e88b6a5..d168500 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -24,10 +24,8 @@ use crate::imports::{Import, ImportKind, ImportResolver}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; -use crate::{ - BindingError, CrateLint, HasGenericParams, MacroRulesScope, Module, ModuleOrUniformRoot, -}; -use crate::{NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; +use crate::{BindingError, HasGenericParams, MacroRulesScope, Module, ModuleOrUniformRoot}; +use crate::{Finalize, NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet, Segment}; type Res = def::Res<ast::NodeId>; @@ -1076,9 +1074,8 @@ fn lookup_import_candidates_from_module<FilterFn>( ident, ScopeSet::All(ns, false), &parent_scope, + None, false, - false, - ident.span, ) { let desc = match binding.res() { Res::Def(DefKind::Macro(MacroKind::Bang), _) => { @@ -1405,10 +1402,10 @@ pub(crate) fn make_path_suggestion( _ => return None, } - self.make_missing_self_suggestion(span, path.clone(), parent_scope) - .or_else(|| self.make_missing_crate_suggestion(span, path.clone(), parent_scope)) - .or_else(|| self.make_missing_super_suggestion(span, path.clone(), parent_scope)) - .or_else(|| self.make_external_crate_suggestion(span, path, parent_scope)) + self.make_missing_self_suggestion(path.clone(), parent_scope) + .or_else(|| self.make_missing_crate_suggestion(path.clone(), parent_scope)) + .or_else(|| self.make_missing_super_suggestion(path.clone(), parent_scope)) + .or_else(|| self.make_external_crate_suggestion(path, parent_scope)) } /// Suggest a missing `self::` if that resolves to an correct module. @@ -1420,13 +1417,12 @@ pub(crate) fn make_path_suggestion( /// ``` fn make_missing_self_suggestion( &mut self, - span: Span, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, ) -> Option<(Vec<Segment>, Vec<String>)> { // Replace first ident with `self` and check if that is valid. path[0].ident.name = kw::SelfLower; - let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, Vec::new())) } else { None } } @@ -1440,13 +1436,12 @@ fn make_missing_self_suggestion( /// ``` fn make_missing_crate_suggestion( &mut self, - span: Span, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, ) -> Option<(Vec<Segment>, Vec<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Crate; - let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No); debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some(( @@ -1472,13 +1467,12 @@ fn make_missing_crate_suggestion( /// ``` fn make_missing_super_suggestion( &mut self, - span: Span, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, ) -> Option<(Vec<Segment>, Vec<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Super; - let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, Vec::new())) } else { None } } @@ -1495,7 +1489,6 @@ fn make_missing_super_suggestion( /// name as the first part of path. fn make_external_crate_suggestion( &mut self, - span: Span, mut path: Vec<Segment>, parent_scope: &ParentScope<'b>, ) -> Option<(Vec<Segment>, Vec<String>)> { @@ -1513,7 +1506,7 @@ fn make_external_crate_suggestion( for name in extern_crate_names.into_iter() { // Replace first ident with a crate name and check if that is valid. path[0].ident.name = name; - let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, Finalize::No); debug!( "make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 70ade7a..4f0dad1 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs
@@ -6,7 +6,7 @@ use crate::{module_to_string, names_to_string}; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; -use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak}; +use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak}; use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding}; use rustc_ast::NodeId; @@ -123,10 +123,6 @@ pub fn is_nested(&self) -> bool { _ => false, } } - - crate fn crate_lint(&self) -> CrateLint { - CrateLint::UsePath { root_id: self.root_id, root_span: self.root_span } - } } #[derive(Clone, Default, Debug)] @@ -179,8 +175,7 @@ impl<'a> Resolver<'a> { ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - record_used: bool, - path_span: Span, + finalize: Option<Span>, ) -> Result<&'a NameBinding<'a>, Determinacy> { self.resolve_ident_in_module_unadjusted_ext( module, @@ -188,14 +183,13 @@ impl<'a> Resolver<'a> { ns, parent_scope, false, - record_used, - path_span, + finalize, ) .map_err(|(determinacy, _)| determinacy) } /// Attempts to resolve `ident` in namespaces `ns` of `module`. - /// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete. + /// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete. crate fn resolve_ident_in_module_unadjusted_ext( &mut self, module: ModuleOrUniformRoot<'a>, @@ -203,8 +197,7 @@ impl<'a> Resolver<'a> { ns: Namespace, parent_scope: &ParentScope<'a>, restricted_shadowing: bool, - record_used: bool, - path_span: Span, + finalize: Option<Span>, ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let module = match module { ModuleOrUniformRoot::Module(module) => module, @@ -214,9 +207,8 @@ impl<'a> Resolver<'a> { ident, ScopeSet::AbsolutePath(ns), parent_scope, - record_used, - record_used, - path_span, + finalize, + finalize.is_some(), ); return binding.map_err(|determinacy| (determinacy, Weak::No)); } @@ -224,7 +216,7 @@ impl<'a> Resolver<'a> { assert!(!restricted_shadowing); return if ns != TypeNS { Err((Determined, Weak::No)) - } else if let Some(binding) = self.extern_prelude_get(ident, !record_used) { + } else if let Some(binding) = self.extern_prelude_get(ident, finalize.is_some()) { Ok(binding) } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() { // Macro-expanded `extern crate` items can add names to extern prelude. @@ -254,9 +246,8 @@ impl<'a> Resolver<'a> { ident, scopes, parent_scope, - record_used, - record_used, - path_span, + finalize, + finalize.is_some(), ); return binding.map_err(|determinacy| (determinacy, Weak::No)); } @@ -266,7 +257,7 @@ impl<'a> Resolver<'a> { let resolution = self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports. - if let Some(binding) = resolution.binding { + if let Some(binding) = resolution.binding && let Some(path_span) = finalize { if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT { if let NameBindingKind::Res(_, true) = binding.kind { self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); @@ -284,7 +275,7 @@ impl<'a> Resolver<'a> { if usable { Ok(binding) } else { Err((Determined, Weak::No)) } }; - if record_used { + if let Some(path_span) = finalize { return resolution .binding .and_then(|binding| { @@ -357,14 +348,8 @@ impl<'a> Resolver<'a> { let ImportKind::Single { source: ident, .. } = single_import.kind else { unreachable!(); }; - match self.resolve_ident_in_module( - module, - ident, - ns, - &single_import.parent_scope, - false, - path_span, - ) { + match self.resolve_ident_in_module(module, ident, ns, &single_import.parent_scope, None) + { Err(Determined) => continue, Ok(binding) if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) => @@ -438,8 +423,7 @@ impl<'a> Resolver<'a> { ident, ns, adjusted_parent_scope, - false, - path_span, + None, ); match result { @@ -787,14 +771,8 @@ fn resolve_import(&mut self, import: &'b Import<'b>) -> bool { // For better failure detection, pretend that the import will // not define any names while resolving its module path. let orig_vis = import.vis.replace(ty::Visibility::Invisible); - let path_res = self.r.resolve_path( - &import.module_path, - None, - &import.parent_scope, - false, - import.span, - import.crate_lint(), - ); + let path_res = + self.r.resolve_path(&import.module_path, None, &import.parent_scope, Finalize::No); import.vis.set(orig_vis); match path_res { @@ -833,8 +811,7 @@ fn resolve_import(&mut self, import: &'b Import<'b>) -> bool { source, ns, &import.parent_scope, - false, - import.span, + None, ); import.vis.set(orig_vis); source_bindings[ns].set(binding); @@ -887,14 +864,13 @@ fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImport _ => None, }; let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); - let path_res = self.r.resolve_path( - &import.module_path, - None, - &import.parent_scope, - true, - import.span, - import.crate_lint(), - ); + let finalize = Finalize::UsePath { + root_id: import.root_id, + root_span: import.root_span, + path_span: import.span, + }; + let path_res = + self.r.resolve_path(&import.module_path, None, &import.parent_scope, finalize); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; if let Some(orig_unusable_binding) = orig_unusable_binding { self.r.unusable_binding = orig_unusable_binding; @@ -981,12 +957,7 @@ fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImport // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(Ident::empty())); - self.r.lint_if_path_starts_with_module( - import.crate_lint(), - &full_path, - import.span, - None, - ); + self.r.lint_if_path_starts_with_module(finalize, &full_path, None); } if let ModuleOrUniformRoot::Module(module) = module { @@ -1024,8 +995,7 @@ fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImport ident, ns, &import.parent_scope, - true, - import.span, + Some(import.span), ); this.last_import_segment = orig_last_import_segment; this.unusable_binding = orig_unusable_binding; @@ -1086,8 +1056,7 @@ fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImport ident, ns, &import.parent_scope, - true, - import.span, + Some(import.span), ); if binding.is_ok() { all_ns_failed = false; @@ -1253,12 +1222,7 @@ fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImport full_path.push(Segment::from_ident(ident)); self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - this.lint_if_path_starts_with_module( - import.crate_lint(), - &full_path, - import.span, - Some(binding), - ); + this.lint_if_path_starts_with_module(finalize, &full_path, Some(binding)); } }); } @@ -1314,9 +1278,8 @@ fn check_for_redundant_imports( target, ScopeSet::All(ns, false), &import.parent_scope, + None, false, - false, - import.span, ) { Ok(other_binding) => { is_redundant[ns] = Some(
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d5b1aa0..bb05a3d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs
@@ -7,7 +7,7 @@ use RibKind::*; -use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding}; +use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding}; use crate::{Module, ModuleOrUniformRoot, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; @@ -483,7 +483,11 @@ fn visit_ty(&mut self, ty: &'ast Ty) { TyKind::ImplicitSelf => { let self_ty = Ident::with_dummy_span(kw::SelfUpper); let res = self - .resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span) + .resolve_ident_in_lexical_scope( + self_ty, + TypeNS, + Finalize::SimplePath(ty.id, ty.span), + ) .map_or(Res::Err, |d| d.res()); self.r.record_partial_res(ty.id, PartialRes::new(res)); } @@ -675,8 +679,7 @@ fn visit_generic_arg(&mut self, arg: &'ast GenericArg) { self.resolve_ident_in_lexical_scope( path.segments[0].ident, ns, - None, - path.span, + Finalize::No, ) .is_some() }; @@ -751,15 +754,13 @@ fn resolve_ident_in_lexical_scope( &mut self, ident: Ident, ns: Namespace, - record_used_id: Option<NodeId>, - path_span: Span, + finalize: Finalize, ) -> Option<LexicalScopeBinding<'a>> { self.r.resolve_ident_in_lexical_scope( ident, ns, &self.parent_scope, - record_used_id, - path_span, + finalize, &self.ribs[ns], ) } @@ -768,19 +769,9 @@ fn resolve_path( &mut self, path: &[Segment], opt_ns: Option<Namespace>, // `None` indicates a module path in import - record_used: bool, - path_span: Span, - crate_lint: CrateLint, + finalize: Finalize, ) -> PathResult<'a> { - self.r.resolve_path_with_ribs( - path, - opt_ns, - &self.parent_scope, - record_used, - path_span, - crate_lint, - Some(&self.ribs), - ) + self.r.resolve_path_with_ribs(path, opt_ns, &self.parent_scope, finalize, Some(&self.ribs)) } // AST resolution @@ -943,15 +934,15 @@ fn future_proof_import(&mut self, use_tree: &UseTree) { }; for &ns in nss { - match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) { + match self.resolve_ident_in_lexical_scope(ident, ns, Finalize::No) { Some(LexicalScopeBinding::Res(..)) => { report_error(self, ns); } Some(LexicalScopeBinding::Item(binding)) => { let orig_unusable_binding = replace(&mut self.r.unusable_binding, Some(binding)); - if let Some(LexicalScopeBinding::Res(..)) = self - .resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) + if let Some(LexicalScopeBinding::Res(..)) = + self.resolve_ident_in_lexical_scope(ident, ns, Finalize::No) { report_error(self, ns); } @@ -1246,25 +1237,14 @@ fn with_optional_trait_ref<T>( if let Some(trait_ref) = opt_trait_ref { let path: Vec<_> = Segment::from_path(&trait_ref.path); let res = self.smart_resolve_path_fragment( - trait_ref.ref_id, None, &path, - trait_ref.path.span, PathSource::Trait(AliasPossibility::No), - CrateLint::SimplePath(trait_ref.ref_id), + Finalize::SimplePath(trait_ref.ref_id, trait_ref.path.span), ); - let res = res.base_res(); - if res != Res::Err { - if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path( - &path, - Some(TypeNS), - true, - trait_ref.path.span, - CrateLint::SimplePath(trait_ref.ref_id), - ) { - new_id = Some(res.def_id()); - new_val = Some((module, trait_ref.clone())); - } + if let Some(def_id) = res.base_res().opt_def_id() { + new_id = Some(def_id); + new_val = Some((self.r.expect_module(def_id), trait_ref.clone())); } } let original_trait_ref = replace(&mut self.current_trait_ref, new_val); @@ -1702,7 +1682,7 @@ fn resolve_pattern_inner( // then fall back to a fresh binding. let has_sub = sub.is_some(); let res = self - .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) + .try_resolve_as_non_binding(pat_src, bmode, ident, has_sub) .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings)); self.r.record_partial_res(pat.id, PartialRes::new(res)); self.r.record_pat_span(pat.id, pat.span); @@ -1813,7 +1793,6 @@ fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut IdentMap<Res> { fn try_resolve_as_non_binding( &mut self, pat_src: PatternSource, - pat: &Pat, bm: BindingMode, ident: Ident, has_sub: bool, @@ -1823,7 +1802,7 @@ fn try_resolve_as_non_binding( // also be interpreted as a path to e.g. a constant, variant, etc. let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not); - let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?; + let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, Finalize::No)?; let (res, binding) = match ls_binding { LexicalScopeBinding::Item(binding) if is_syntactic_ambiguity && binding.is_ambiguity() => @@ -1912,35 +1891,34 @@ fn smart_resolve_path( source: PathSource<'ast>, ) { self.smart_resolve_path_fragment( - id, qself, &Segment::from_path(path), - path.span, source, - CrateLint::SimplePath(id), + Finalize::SimplePath(id, path.span), ); } fn smart_resolve_path_fragment( &mut self, - id: NodeId, qself: Option<&QSelf>, path: &[Segment], - span: Span, source: PathSource<'ast>, - crate_lint: CrateLint, + finalize: Finalize, ) -> PartialRes { tracing::debug!( - "smart_resolve_path_fragment(id={:?}, qself={:?}, path={:?})", - id, + "smart_resolve_path_fragment(qself={:?}, path={:?}, finalize={:?})", qself, - path + path, + finalize, ); let ns = source.namespace(); + let (id, path_span) = + finalize.node_id_and_path_span().expect("unexpected speculative resolution"); let report_errors = |this: &mut Self, res: Option<Res>| { if this.should_report_errs() { - let (err, candidates) = this.smart_resolve_report_errors(path, span, source, res); + let (err, candidates) = + this.smart_resolve_report_errors(path, path_span, source, res); let def_id = this.parent_scope.module.nearest_parent_mod(); let instead = res.is_some(); @@ -1978,7 +1956,7 @@ fn smart_resolve_path_fragment( }; let (mut err, candidates) = - this.smart_resolve_report_errors(path, span, PathSource::Type, None); + this.smart_resolve_report_errors(path, path_span, PathSource::Type, None); if candidates.is_empty() { err.cancel(); @@ -2027,13 +2005,12 @@ fn smart_resolve_path_fragment( }; let partial_res = match self.resolve_qpath_anywhere( - id, qself, path, ns, - span, + path_span, source.defer_to_typeck(), - crate_lint, + finalize, ) { Ok(Some(partial_res)) if partial_res.unresolved_segments() == 0 => { if source.is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err @@ -2060,14 +2037,14 @@ fn smart_resolve_path_fragment( std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std))); std_path.extend(path); if let PathResult::Module(_) | PathResult::NonModule(_) = - self.resolve_path(&std_path, Some(ns), false, span, CrateLint::No) + self.resolve_path(&std_path, Some(ns), Finalize::No) { // Check if we wrote `str::from_utf8` instead of `std::str::from_utf8` let item_span = - path.iter().last().map_or(span, |segment| segment.ident.span); + path.iter().last().map_or(path_span, |segment| segment.ident.span); - self.r.confused_type_with_std_module.insert(item_span, span); - self.r.confused_type_with_std_module.insert(span, span); + self.r.confused_type_with_std_module.insert(item_span, path_span); + self.r.confused_type_with_std_module.insert(path_span, path_span); } } @@ -2093,19 +2070,18 @@ fn smart_resolve_path_fragment( partial_res } - fn self_type_is_available(&mut self, span: Span) -> bool { + fn self_type_is_available(&mut self) -> bool { let binding = self.resolve_ident_in_lexical_scope( Ident::with_dummy_span(kw::SelfUpper), TypeNS, - None, - span, + Finalize::No, ); if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false } } - fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool { + fn self_value_is_available(&mut self, self_span: Span) -> bool { let ident = Ident::new(kw::SelfLower, self_span); - let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span); + let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, Finalize::No); if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false } } @@ -2127,19 +2103,18 @@ fn should_report_errs(&self) -> bool { // Resolve in alternative namespaces if resolution in the primary namespace fails. fn resolve_qpath_anywhere( &mut self, - id: NodeId, qself: Option<&QSelf>, path: &[Segment], primary_ns: Namespace, span: Span, defer_to_typeck: bool, - crate_lint: CrateLint, + finalize: Finalize, ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> { let mut fin_res = None; for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() { if i == 0 || ns != primary_ns { - match self.resolve_qpath(id, qself, path, ns, span, crate_lint)? { + match self.resolve_qpath(qself, path, ns, finalize)? { Some(partial_res) if partial_res.unresolved_segments() == 0 || defer_to_typeck => { @@ -2172,16 +2147,14 @@ fn resolve_qpath_anywhere( /// Handles paths that may refer to associated items. fn resolve_qpath( &mut self, - id: NodeId, qself: Option<&QSelf>, path: &[Segment], ns: Namespace, - span: Span, - crate_lint: CrateLint, + finalize: Finalize, ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> { debug!( - "resolve_qpath(id={:?}, qself={:?}, path={:?}, ns={:?}, span={:?})", - id, qself, path, ns, span, + "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})", + qself, path, ns, finalize, ); if let Some(qself) = qself { @@ -2208,15 +2181,15 @@ fn resolve_qpath( // *actually* appears, so for the purposes of the crate // lint we pass along information that this is the trait // name from a fully qualified path, and this also - // contains the full span (the `CrateLint::QPathTrait`). + // contains the full span (the `Finalize::QPathTrait`). let ns = if qself.position + 1 == path.len() { ns } else { TypeNS }; let partial_res = self.smart_resolve_path_fragment( - id, None, &path[..=qself.position], - span, PathSource::TraitItem(ns), - CrateLint::QPathTrait { qpath_id: id, qpath_span: qself.path_span }, + finalize.node_id_and_path_span().map_or(Finalize::No, |(qpath_id, path_span)| { + Finalize::QPathTrait { qpath_id, qpath_span: qself.path_span, path_span } + }), ); // The remaining segments (the `C` in our example) will @@ -2228,7 +2201,7 @@ fn resolve_qpath( ))); } - let result = match self.resolve_path(&path, Some(ns), true, span, crate_lint) { + let result = match self.resolve_path(&path, Some(ns), finalize) { PathResult::NonModule(path_res) => path_res, PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => { PartialRes::new(module.res().unwrap()) @@ -2266,15 +2239,10 @@ fn resolve_qpath( && result.base_res() != Res::Err && path[0].ident.name != kw::PathRoot && path[0].ident.name != kw::DollarCrate + && let Some((id, path_span)) = finalize.node_id_and_path_span() { let unqualified_result = { - match self.resolve_path( - &[*path.last().unwrap()], - Some(ns), - false, - span, - CrateLint::No, - ) { + match self.resolve_path(&[*path.last().unwrap()], Some(ns), Finalize::No) { PathResult::NonModule(path_res) => path_res.base_res(), PathResult::Module(ModuleOrUniformRoot::Module(module)) => { module.res().unwrap() @@ -2284,7 +2252,7 @@ fn resolve_qpath( }; if result.base_res() == unqualified_result { let lint = lint::builtin::UNUSED_QUALIFICATIONS; - self.r.lint_buffer.buffer_lint(lint, id, span, "unnecessary qualification") + self.r.lint_buffer.buffer_lint(lint, id, path_span, "unnecessary qualification") } }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 1394f40..038ba22 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2,7 +2,7 @@ use crate::late::lifetimes::{ElisionFailureInfo, LifetimeContext}; use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind}; use crate::path_names_to_string; -use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{Finalize, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, Segment}; use rustc_ast::visit::FnKind; @@ -187,12 +187,11 @@ pub(crate) fn smart_resolve_report_errors( (String::new(), "the crate root".to_string()) } else { let mod_path = &path[..path.len() - 1]; - let mod_prefix = - match self.resolve_path(mod_path, Some(TypeNS), false, span, CrateLint::No) { - PathResult::Module(ModuleOrUniformRoot::Module(module)) => module.res(), - _ => None, - } - .map_or_else(String::new, |res| format!("{} ", res.descr())); + let mod_prefix = match self.resolve_path(mod_path, Some(TypeNS), Finalize::No) { + PathResult::Module(ModuleOrUniformRoot::Module(module)) => module.res(), + _ => None, + } + .map_or_else(String::new, |res| format!("{} ", res.descr())); (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) }; ( @@ -232,7 +231,7 @@ pub(crate) fn smart_resolve_report_errors( _ => {} } - let is_assoc_fn = self.self_type_is_available(span); + let is_assoc_fn = self.self_type_is_available(); // Emit help message for fake-self from other languages (e.g., `this` in Javascript). if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn { err.span_suggestion_short( @@ -241,7 +240,7 @@ pub(crate) fn smart_resolve_report_errors( "self".to_string(), Applicability::MaybeIncorrect, ); - if !self.self_value_is_available(path[0].ident.span, span) { + if !self.self_value_is_available(path[0].ident.span) { if let Some((FnKind::Fn(_, _, sig, ..), fn_span)) = &self.diagnostic_metadata.current_function { @@ -402,9 +401,9 @@ pub(crate) fn smart_resolve_report_errors( ); } } - if path.len() == 1 && self.self_type_is_available(span) { + if path.len() == 1 && self.self_type_is_available() { if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { - let self_is_available = self.self_value_is_available(path[0].ident.span, span); + let self_is_available = self.self_value_is_available(path[0].ident.span); match candidate { AssocSuggestion::Field => { if self_is_available { @@ -461,7 +460,7 @@ pub(crate) fn smart_resolve_report_errors( } // Try Levenshtein algorithm. - let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected, span); + let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected); // Try context-dependent help if relaxed lookup didn't work. if let Some(res) = res { if self.smart_resolve_context_dependent_help( @@ -562,7 +561,7 @@ pub(crate) fn smart_resolve_report_errors( } // If the trait has a single item (which wasn't matched by Levenshtein), suggest it - let suggestion = self.get_single_associated_item(&path, span, &source, is_expected); + let suggestion = self.get_single_associated_item(&path, &source, is_expected); self.r.add_typo_suggestion(&mut err, suggestion, ident_span); } if fallback { @@ -641,14 +640,13 @@ fn detect_assoct_type_constraint_meant_as_path(&self, base_span: Span, err: &mut fn get_single_associated_item( &mut self, path: &[Segment], - span: Span, source: &PathSource<'_>, filter_fn: &impl Fn(Res) -> bool, ) -> Option<TypoSuggestion> { if let crate::PathSource::TraitItem(_) = source { let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(mod_path, None, false, span, CrateLint::No) + self.resolve_path(mod_path, None, Finalize::No) { let resolutions = self.r.resolutions(module).borrow(); let targets: Vec<_> = @@ -699,13 +697,12 @@ fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diagnost { // use this to verify that ident is a type param. let Ok(Some(partial_res)) = self.resolve_qpath_anywhere( - bounded_ty.id, None, &Segment::from_path(path), Namespace::TypeNS, span, true, - CrateLint::No, + Finalize::No, ) else { return false; }; @@ -724,13 +721,12 @@ fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diagnost if let ast::TyKind::Path(None, type_param_path) = &ty.peel_refs().kind { // Confirm that the `SelfTy` is a type parameter. let Ok(Some(partial_res)) = self.resolve_qpath_anywhere( - bounded_ty.id, None, &Segment::from_path(type_param_path), Namespace::TypeNS, span, true, - CrateLint::No, + Finalize::No, ) else { return false; }; @@ -1292,8 +1288,7 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> { ident, ns, &self.parent_scope, - false, - module.span, + None, ) { let res = binding.res(); if filter_fn(res) { @@ -1323,7 +1318,6 @@ fn lookup_typo_candidate( path: &[Segment], ns: Namespace, filter_fn: &impl Fn(Res) -> bool, - span: Span, ) -> Option<TypoSuggestion> { let mut names = Vec::new(); if path.len() == 1 { @@ -1384,7 +1378,7 @@ fn lookup_typo_candidate( // Search in module. let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(mod_path, Some(TypeNS), false, span, CrateLint::No) + self.resolve_path(mod_path, Some(TypeNS), Finalize::No) { self.r.add_module_candidates(module, &mut names, &filter_fn); }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 77fd711..19eeae4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs
@@ -13,6 +13,7 @@ #![feature(drain_filter)] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] +#![feature(let_chains)] #![feature(let_else)] #![feature(never_type)] #![feature(nll)] @@ -54,9 +55,9 @@ use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::AccessLevels; -use rustc_middle::span_bug; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools, ResolverOutputs}; +use rustc_middle::{bug, span_bug}; use rustc_query_system::ich::StableHashingContext; use rustc_session::cstore::{CrateStore, MetadataLoaderDyn}; use rustc_session::lint; @@ -71,7 +72,7 @@ use smallvec::{smallvec, SmallVec}; use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; -use std::{cmp, fmt, iter, mem, ptr}; +use std::{cmp, fmt, mem, ptr}; use tracing::debug; use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding}; @@ -449,6 +450,19 @@ enum PathResult<'a> { }, } +impl<'a> PathResult<'a> { + fn failed( + span: Span, + is_error_from_last_segment: bool, + finalize: bool, + label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>), + ) -> PathResult<'a> { + let (label, suggestion) = + if finalize { label_and_suggestion() } else { (String::new(), None) }; + PathResult::Failed { span, label, suggestion, is_error_from_last_segment } + } +} + #[derive(Debug)] enum ModuleKind { /// An anonymous module; e.g., just a block. @@ -1936,8 +1950,7 @@ fn resolve_ident_in_lexical_scope( mut ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - record_used_id: Option<NodeId>, - path_span: Span, + finalize_full: Finalize, ribs: &[Rib<'a>], ) -> Option<LexicalScopeBinding<'a>> { assert!(ns == TypeNS || ns == ValueNS); @@ -1959,7 +1972,7 @@ fn resolve_ident_in_lexical_scope( let normalized_ident = Ident { span: normalized_span, ..ident }; // Walk backwards up the ribs in scope. - let record_used = record_used_id.is_some(); + let finalize = finalize_full.path_span(); let mut module = self.graph_root; for i in (0..ribs.len()).rev() { debug!("walk rib\n{:?}", ribs[i].bindings); @@ -1973,8 +1986,7 @@ fn resolve_ident_in_lexical_scope( i, rib_ident, *res, - record_used, - path_span, + finalize, *original_rib_ident_def, ribs, ))); @@ -2001,8 +2013,7 @@ fn resolve_ident_in_lexical_scope( ident, ns, parent_scope, - record_used, - path_span, + finalize, ); if let Ok(binding) = item { // The ident resolves to an item. @@ -2011,11 +2022,10 @@ fn resolve_ident_in_lexical_scope( } self.early_resolve_ident_in_lexical_scope( orig_ident, - ScopeSet::Late(ns, module, record_used_id), + ScopeSet::Late(ns, module, finalize_full.node_id()), parent_scope, - record_used, - record_used, - path_span, + finalize, + finalize.is_some(), ) .ok() .map(LexicalScopeBinding::Item) @@ -2075,10 +2085,9 @@ fn resolve_ident_in_module( ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - record_used: bool, - path_span: Span, + finalize: Option<Span>, ) -> Result<&'a NameBinding<'a>, Determinacy> { - self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, record_used, path_span) + self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, finalize) .map_err(|(determinacy, _)| determinacy) } @@ -2088,8 +2097,7 @@ fn resolve_ident_in_module_ext( mut ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - record_used: bool, - path_span: Span, + finalize: Option<Span>, ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let tmp_parent_scope; let mut adjusted_parent_scope = parent_scope; @@ -2114,8 +2122,7 @@ fn resolve_ident_in_module_ext( ns, adjusted_parent_scope, false, - record_used, - path_span, + finalize, ) } @@ -2206,19 +2213,9 @@ fn resolve_path( path: &[Segment], opt_ns: Option<Namespace>, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, - record_used: bool, - path_span: Span, - crate_lint: CrateLint, + finalize: Finalize, ) -> PathResult<'a> { - self.resolve_path_with_ribs( - path, - opt_ns, - parent_scope, - record_used, - path_span, - crate_lint, - None, - ) + self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None) } fn resolve_path_with_ribs( @@ -2226,25 +2223,20 @@ fn resolve_path_with_ribs( path: &[Segment], opt_ns: Option<Namespace>, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, - record_used: bool, - path_span: Span, - crate_lint: CrateLint, + finalize_full: Finalize, ribs: Option<&PerNS<Vec<Rib<'a>>>>, ) -> PathResult<'a> { + debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize_full); + + let finalize = finalize_full.path_span(); let mut module = None; let mut allow_super = true; let mut second_binding = None; - debug!( - "resolve_path(path={:?}, opt_ns={:?}, record_used={:?}, \ - path_span={:?}, crate_lint={:?})", - path, opt_ns, record_used, path_span, crate_lint, - ); - for (i, &Segment { ident, id, has_generic_args: _ }) in path.iter().enumerate() { debug!("resolve_path ident {} {:?} {:?}", i, ident, id); let record_segment_res = |this: &mut Self, res| { - if record_used { + if finalize.is_some() { if let Some(id) = id { if !this.partial_res_map.contains_key(&id) { assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id"); @@ -2278,13 +2270,9 @@ fn resolve_path_with_ribs( continue; } } - let msg = "there are too many leading `super` keywords".to_string(); - return PathResult::Failed { - span: ident.span, - label: msg, - suggestion: None, - is_error_from_last_segment: false, - }; + return PathResult::failed(ident.span, false, finalize.is_some(), || { + ("there are too many leading `super` keywords".to_string(), None) + }); } if i == 0 { if name == kw::SelfLower { @@ -2313,22 +2301,19 @@ fn resolve_path_with_ribs( // Report special messages for path segment keywords in wrong positions. if ident.is_path_segment_keyword() && i != 0 { - let name_str = if name == kw::PathRoot { - "crate root".to_string() - } else { - format!("`{}`", name) - }; - let label = if i == 1 && path[0].ident.name == kw::PathRoot { - format!("global paths cannot start with {}", name_str) - } else { - format!("{} in paths can only be used in start position", name_str) - }; - return PathResult::Failed { - span: ident.span, - label, - suggestion: None, - is_error_from_last_segment: false, - }; + return PathResult::failed(ident.span, false, finalize.is_some(), || { + let name_str = if name == kw::PathRoot { + "crate root".to_string() + } else { + format!("`{}`", name) + }; + let label = if i == 1 && path[0].ident.name == kw::PathRoot { + format!("global paths cannot start with {}", name_str) + } else { + format!("{} in paths can only be used in start position", name_str) + }; + (label, None) + }); } enum FindBindingResult<'a> { @@ -2337,36 +2322,22 @@ enum FindBindingResult<'a> { } let find_binding_in_ns = |this: &mut Self, ns| { let binding = if let Some(module) = module { - this.resolve_ident_in_module( - module, - ident, - ns, - parent_scope, - record_used, - path_span, - ) + this.resolve_ident_in_module(module, ident, ns, parent_scope, finalize) } else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) { let scopes = ScopeSet::All(ns, opt_ns.is_none()); this.early_resolve_ident_in_lexical_scope( ident, scopes, parent_scope, - record_used, - record_used, - path_span, + finalize, + finalize.is_some(), ) } else { - let record_used_id = if record_used { - crate_lint.node_id().or(Some(CRATE_NODE_ID)) - } else { - None - }; match this.resolve_ident_in_lexical_scope( ident, ns, parent_scope, - record_used_id, - path_span, + finalize_full, &ribs.unwrap()[ns], ) { // we found a locally-imported or available item/module @@ -2380,7 +2351,7 @@ enum FindBindingResult<'a> { PartialRes::with_unresolved_segments(res, path.len() - 1), )); } - _ => Err(Determinacy::determined(record_used)), + _ => Err(Determinacy::determined(finalize.is_some())), } }; FindBindingResult::Binding(binding) @@ -2414,30 +2385,20 @@ enum FindBindingResult<'a> { } else if res == Res::Err { return PathResult::NonModule(PartialRes::new(Res::Err)); } else if opt_ns.is_some() && (is_last || maybe_assoc) { - self.lint_if_path_starts_with_module( - crate_lint, - path, - path_span, - second_binding, - ); + self.lint_if_path_starts_with_module(finalize_full, path, second_binding); return PathResult::NonModule(PartialRes::with_unresolved_segments( res, path.len() - i - 1, )); } else { - let label = format!( - "`{}` is {} {}, not a module", - ident, - res.article(), - res.descr(), - ); - - return PathResult::Failed { - span: ident.span, - label, - suggestion: None, - is_error_from_last_segment: is_last, - }; + return PathResult::failed(ident.span, is_last, finalize.is_some(), || { + let label = format!( + "`{ident}` is {} {}, not a module", + res.article(), + res.descr() + ); + (label, None) + }); } } Err(Undetermined) => return PathResult::Indeterminate, @@ -2450,196 +2411,192 @@ enum FindBindingResult<'a> { )); } } - let module_res = match module { - Some(ModuleOrUniformRoot::Module(module)) => module.res(), - _ => None, - }; - let (label, suggestion) = if module_res == self.graph_root.res() { - let is_mod = |res| matches!(res, Res::Def(DefKind::Mod, _)); - // Don't look up import candidates if this is a speculative resolve - let mut candidates = if record_used { - self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod) - } else { - Vec::new() + + return PathResult::failed(ident.span, is_last, finalize.is_some(), || { + let module_res = match module { + Some(ModuleOrUniformRoot::Module(module)) => module.res(), + _ => None, }; - candidates.sort_by_cached_key(|c| { - (c.path.segments.len(), pprust::path_to_string(&c.path)) - }); - if let Some(candidate) = candidates.get(0) { - ( - String::from("unresolved import"), - Some(( - vec![(ident.span, pprust::path_to_string(&candidate.path))], - String::from("a similar path exists"), - Applicability::MaybeIncorrect, - )), - ) - } else if self.session.edition() == Edition::Edition2015 { - (format!("maybe a missing crate `{}`?", ident), None) - } else { - (format!("could not find `{}` in the crate root", ident), None) - } - } else if i == 0 { - if ident - .name - .as_str() - .chars() - .next() - .map_or(false, |c| c.is_ascii_uppercase()) - { - // Check whether the name refers to an item in the value namespace. - let suggestion = if ribs.is_some() { - let match_span = match self.resolve_ident_in_lexical_scope( - ident, - ValueNS, - parent_scope, - None, - path_span, - &ribs.unwrap()[ValueNS], - ) { - // Name matches a local variable. For example: - // ``` - // fn f() { - // let Foo: &str = ""; - // println!("{}", Foo::Bar); // Name refers to local - // // variable `Foo`. - // } - // ``` - Some(LexicalScopeBinding::Res(Res::Local(id))) => { - Some(*self.pat_span_map.get(&id).unwrap()) - } - - // Name matches item from a local name binding - // created by `use` declaration. For example: - // ``` - // pub Foo: &str = ""; - // - // mod submod { - // use super::Foo; - // println!("{}", Foo::Bar); // Name refers to local - // // binding `Foo`. - // } - // ``` - Some(LexicalScopeBinding::Item(name_binding)) => { - Some(name_binding.span) - } - _ => None, - }; - - if let Some(span) = match_span { + if module_res == self.graph_root.res() { + let is_mod = |res| matches!(res, Res::Def(DefKind::Mod, _)); + let mut candidates = + self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod); + candidates.sort_by_cached_key(|c| { + (c.path.segments.len(), pprust::path_to_string(&c.path)) + }); + if let Some(candidate) = candidates.get(0) { + ( + String::from("unresolved import"), Some(( - vec![(span, String::from(""))], - format!("`{}` is defined here, but is not a type", ident), + vec![(ident.span, pprust::path_to_string(&candidate.path))], + String::from("a similar path exists"), Applicability::MaybeIncorrect, - )) - } else { - None - } + )), + ) + } else if self.session.edition() == Edition::Edition2015 { + (format!("maybe a missing crate `{}`?", ident), None) } else { - None - }; + (format!("could not find `{}` in the crate root", ident), None) + } + } else if i == 0 { + if ident + .name + .as_str() + .chars() + .next() + .map_or(false, |c| c.is_ascii_uppercase()) + { + // Check whether the name refers to an item in the value namespace. + let suggestion = if ribs.is_some() { + let match_span = match self.resolve_ident_in_lexical_scope( + ident, + ValueNS, + parent_scope, + Finalize::No, + &ribs.unwrap()[ValueNS], + ) { + // Name matches a local variable. For example: + // ``` + // fn f() { + // let Foo: &str = ""; + // println!("{}", Foo::Bar); // Name refers to local + // // variable `Foo`. + // } + // ``` + Some(LexicalScopeBinding::Res(Res::Local(id))) => { + Some(*self.pat_span_map.get(&id).unwrap()) + } - (format!("use of undeclared type `{}`", ident), suggestion) - } else { - ( - format!("use of undeclared crate or module `{}`", ident), - if ident.name == sym::alloc { - Some(( - vec![], - String::from( - "add `extern crate alloc` to use the `alloc` crate", - ), - Applicability::MaybeIncorrect, - )) - } else { - self.find_similarly_named_module_or_crate( - ident.name, - &parent_scope.module, - ) - .map(|sugg| { - ( - vec![(ident.span, sugg.to_string())], - String::from( - "there is a crate or module with a similar name", + // Name matches item from a local name binding + // created by `use` declaration. For example: + // ``` + // pub Foo: &str = ""; + // + // mod submod { + // use super::Foo; + // println!("{}", Foo::Bar); // Name refers to local + // // binding `Foo`. + // } + // ``` + Some(LexicalScopeBinding::Item(name_binding)) => { + Some(name_binding.span) + } + _ => None, + }; + + if let Some(span) = match_span { + Some(( + vec![(span, String::from(""))], + format!( + "`{}` is defined here, but is not a type", + ident ), Applicability::MaybeIncorrect, - ) - }) - }, - ) - } - } else { - let parent = path[i - 1].ident.name; - let parent = match parent { - // ::foo is mounted at the crate root for 2015, and is the extern - // prelude for 2018+ - kw::PathRoot if self.session.edition() > Edition::Edition2015 => { - "the list of imported crates".to_owned() - } - kw::PathRoot | kw::Crate => "the crate root".to_owned(), - _ => { - format!("`{}`", parent) - } - }; - - let mut msg = format!("could not find `{}` in {}", ident, parent); - if ns == TypeNS || ns == ValueNS { - let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS }; - if let FindBindingResult::Binding(Ok(binding)) = - find_binding_in_ns(self, ns_to_try) - { - let mut found = |what| { - msg = format!( - "expected {}, found {} `{}` in {}", - ns.descr(), - what, - ident, - parent - ) - }; - if binding.module().is_some() { - found("module") - } else { - match binding.res() { - def::Res::<NodeId>::Def(kind, id) => found(kind.descr(id)), - _ => found(ns_to_try.descr()), + )) + } else { + None } + } else { + None + }; + + (format!("use of undeclared type `{}`", ident), suggestion) + } else { + ( + format!("use of undeclared crate or module `{}`", ident), + if ident.name == sym::alloc { + Some(( + vec![], + String::from( + "add `extern crate alloc` to use the `alloc` crate", + ), + Applicability::MaybeIncorrect, + )) + } else { + self.find_similarly_named_module_or_crate( + ident.name, + &parent_scope.module, + ) + .map(|sugg| { + ( + vec![(ident.span, sugg.to_string())], + String::from( + "there is a crate or module with a similar name", + ), + Applicability::MaybeIncorrect, + ) + }) + }, + ) + } + } else { + let parent = path[i - 1].ident.name; + let parent = match parent { + // ::foo is mounted at the crate root for 2015, and is the extern + // prelude for 2018+ + kw::PathRoot if self.session.edition() > Edition::Edition2015 => { + "the list of imported crates".to_owned() + } + kw::PathRoot | kw::Crate => "the crate root".to_owned(), + _ => { + format!("`{}`", parent) } }; + + let mut msg = format!("could not find `{}` in {}", ident, parent); + if ns == TypeNS || ns == ValueNS { + let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS }; + if let FindBindingResult::Binding(Ok(binding)) = + find_binding_in_ns(self, ns_to_try) + { + let mut found = |what| { + msg = format!( + "expected {}, found {} `{}` in {}", + ns.descr(), + what, + ident, + parent + ) + }; + if binding.module().is_some() { + found("module") + } else { + match binding.res() { + def::Res::<NodeId>::Def(kind, id) => { + found(kind.descr(id)) + } + _ => found(ns_to_try.descr()), + } + } + }; + } + (msg, None) } - (msg, None) - }; - return PathResult::Failed { - span: ident.span, - label, - suggestion, - is_error_from_last_segment: is_last, - }; + }); } } } - self.lint_if_path_starts_with_module(crate_lint, path, path_span, second_binding); + self.lint_if_path_starts_with_module(finalize_full, path, second_binding); PathResult::Module(match module { Some(module) => module, None if path.is_empty() => ModuleOrUniformRoot::CurrentScope, - _ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path), + _ => bug!("resolve_path: non-empty path `{:?}` has no module", path), }) } fn lint_if_path_starts_with_module( &mut self, - crate_lint: CrateLint, + finalize: Finalize, path: &[Segment], - path_span: Span, second_binding: Option<&NameBinding<'_>>, ) { - let (diag_id, diag_span) = match crate_lint { - CrateLint::No => return, - CrateLint::SimplePath(id) => (id, path_span), - CrateLint::UsePath { root_id, root_span } => (root_id, root_span), - CrateLint::QPathTrait { qpath_id, qpath_span } => (qpath_id, qpath_span), + let (diag_id, diag_span) = match finalize { + Finalize::No => return, + Finalize::SimplePath(id, path_span) => (id, path_span), + Finalize::UsePath { root_id, root_span, .. } => (root_id, root_span), + Finalize::QPathTrait { qpath_id, qpath_span, .. } => (qpath_id, qpath_span), }; let first_name = match path.get(0) { @@ -2694,8 +2651,7 @@ fn validate_res_from_ribs( rib_index: usize, rib_ident: Ident, mut res: Res, - record_used: bool, - span: Span, + finalize: Option<Span>, original_rib_ident_def: Ident, all_ribs: &[Rib<'a>], ) -> Res { @@ -2705,7 +2661,7 @@ fn validate_res_from_ribs( // An invalid forward use of a generic parameter from a previous default. if let ForwardGenericParamBanRibKind = all_ribs[rib_index].kind { - if record_used { + if let Some(span) = finalize { let res_error = if rib_ident.name == kw::SelfUpper { ResolutionError::SelfInGenericParamDefault } else { @@ -2735,17 +2691,17 @@ fn validate_res_from_ribs( // This was an attempt to access an upvar inside a // named function item. This is not allowed, so we // report an error. - if record_used { + if let Some(span) = finalize { // We don't immediately trigger a resolve error, because // we want certain other resolution errors (namely those // emitted for `ConstantItemRibKind` below) to take // precedence. - res_err = Some(CannotCaptureDynamicEnvironmentInFnItem); + res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem)); } } ConstantItemRibKind(_, item) => { // Still doesn't deal with upvars - if record_used { + if let Some(span) = finalize { let (span, resolution_error) = if let Some((ident, constant_item_kind)) = item { let kind_str = match constant_item_kind { @@ -2773,14 +2729,14 @@ fn validate_res_from_ribs( return Res::Err; } ConstParamTyRibKind => { - if record_used { + if let Some(span) = finalize { self.report_error(span, ParamInTyOfConstParam(rib_ident.name)); } return Res::Err; } } } - if let Some(res_err) = res_err { + if let Some((span, res_err)) = res_err { self.report_error(span, res_err); return Res::Err; } @@ -2808,7 +2764,7 @@ fn validate_res_from_ribs( if let Res::SelfTy { trait_, alias_to: Some((def, _)) } = res { res = Res::SelfTy { trait_, alias_to: Some((def, true)) } } else { - if record_used { + if let Some(span) = finalize { self.report_error( span, ResolutionError::ParamInNonTrivialAnonConst { @@ -2816,9 +2772,9 @@ fn validate_res_from_ribs( is_type: true, }, ); + self.session.delay_span_bug(span, CG_BUG_STR); } - self.session.delay_span_bug(span, CG_BUG_STR); return Res::Err; } } @@ -2830,7 +2786,7 @@ fn validate_res_from_ribs( ItemRibKind(has_generic_params) => has_generic_params, FnItemRibKind => HasGenericParams::Yes, ConstParamTyRibKind => { - if record_used { + if let Some(span) = finalize { self.report_error( span, ResolutionError::ParamInTyOfConstParam(rib_ident.name), @@ -2840,7 +2796,7 @@ fn validate_res_from_ribs( } }; - if record_used { + if let Some(span) = finalize { self.report_error( span, ResolutionError::GenericParamsFromOuterFunction( @@ -2874,7 +2830,7 @@ fn validate_res_from_ribs( let features = self.session.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. if !(trivial || features.generic_const_exprs) { - if record_used { + if let Some(span) = finalize { self.report_error( span, ResolutionError::ParamInNonTrivialAnonConst { @@ -2882,9 +2838,9 @@ fn validate_res_from_ribs( is_type: false, }, ); + self.session.delay_span_bug(span, CG_BUG_STR); } - self.session.delay_span_bug(span, CG_BUG_STR); return Res::Err; } @@ -2894,7 +2850,7 @@ fn validate_res_from_ribs( ItemRibKind(has_generic_params) => has_generic_params, FnItemRibKind => HasGenericParams::Yes, ConstParamTyRibKind => { - if record_used { + if let Some(span) = finalize { self.report_error( span, ResolutionError::ParamInTyOfConstParam(rib_ident.name), @@ -2905,7 +2861,7 @@ fn validate_res_from_ribs( }; // This was an attempt to use a const parameter outside its scope. - if record_used { + if let Some(span) = finalize { self.report_error( span, ResolutionError::GenericParamsFromOuterFunction( @@ -3293,23 +3249,19 @@ fn add_suggestion_for_duplicate_nested_use( err.span_suggestion(span, message, String::new(), Applicability::MachineApplicable); } - fn extern_prelude_get( - &mut self, - ident: Ident, - speculative: bool, - ) -> Option<&'a NameBinding<'a>> { + fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<&'a NameBinding<'a>> { if ident.is_path_segment_keyword() { // Make sure `self`, `super` etc produce an error when passed to here. return None; } self.extern_prelude.get(&ident.normalize_to_macros_2_0()).cloned().and_then(|entry| { if let Some(binding) = entry.extern_crate_item { - if !speculative && entry.introduced_by_item { + if finalize && entry.introduced_by_item { self.record_use(ident, binding, false); } Some(binding) } else { - let crate_id = if !speculative { + let crate_id = if finalize { let Some(crate_id) = self.crate_loader.process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); }; crate_id @@ -3325,81 +3277,36 @@ fn extern_prelude_get( }) } - /// Rustdoc uses this to resolve things in a recoverable way. `ResolutionError<'a>` + /// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>` /// isn't something that can be returned because it can't be made to live that long, /// and also it's a private type. Fortunately rustdoc doesn't need to know the error, /// just that an error occurred. - // FIXME(Manishearth): intra-doc links won't get warned of epoch changes. - pub fn resolve_str_path_error( + pub fn resolve_rustdoc_path( &mut self, - span: Span, path_str: &str, ns: Namespace, module_id: DefId, - ) -> Result<(ast::Path, Res), ()> { - let path = if path_str.starts_with("::") { - ast::Path { - span, - segments: iter::once(Ident::with_dummy_span(kw::PathRoot)) - .chain(path_str.split("::").skip(1).map(Ident::from_str)) - .map(|i| self.new_ast_path_segment(i)) - .collect(), - tokens: None, - } - } else { - ast::Path { - span, - segments: path_str - .split("::") - .map(Ident::from_str) - .map(|i| self.new_ast_path_segment(i)) - .collect(), - tokens: None, - } - }; - let module = self.expect_module(module_id); - let parent_scope = &ParentScope::module(module, self); - let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?; - Ok((path, res)) - } - - // Resolve a path passed from rustdoc or HIR lowering. - fn resolve_ast_path( - &mut self, - path: &ast::Path, - ns: Namespace, - parent_scope: &ParentScope<'a>, - ) -> Result<Res, (Span, ResolutionError<'a>)> { - match self.resolve_path( - &Segment::from_path(path), - Some(ns), - parent_scope, - false, - path.span, - CrateLint::No, - ) { - PathResult::Module(ModuleOrUniformRoot::Module(module)) => Ok(module.res().unwrap()), - PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => { - Ok(path_res.base_res()) - } - PathResult::NonModule(..) => Err(( - path.span, - ResolutionError::FailedToResolve { - label: String::from("type-relative paths are not supported in this context"), - suggestion: None, - }, - )), - PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), - PathResult::Failed { span, label, suggestion, .. } => { - Err((span, ResolutionError::FailedToResolve { label, suggestion })) - } + ) -> Option<Res> { + let mut segments = + Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident)); + if path_str.starts_with("::") { + segments[0].ident.name = kw::PathRoot; } - } - fn new_ast_path_segment(&mut self, ident: Ident) -> ast::PathSegment { - let mut seg = ast::PathSegment::from_ident(ident); - seg.id = self.next_node_id(); - seg + let module = self.expect_module(module_id); + match self.resolve_path( + &segments, + Some(ns), + &ParentScope::module(module, self), + Finalize::No, + ) { + PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()), + PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => { + Some(path_res.base_res()) + } + PathResult::NonModule(..) | PathResult::Failed { .. } => None, + PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), + } } // For rustdoc. @@ -3485,8 +3392,7 @@ fn resolve_main(&mut self) { ident, ValueNS, parent_scope, - false, - DUMMY_SP, + None ) else { return; }; @@ -3544,35 +3450,43 @@ fn collect_mod(names: &mut Vec<Symbol>, module: Module<'_>) { } #[derive(Copy, Clone, Debug)] -enum CrateLint { +enum Finalize { /// Do not issue the lint. No, /// This lint applies to some arbitrary path; e.g., `impl ::foo::Bar`. /// In this case, we can take the span of that path. - SimplePath(NodeId), + SimplePath(NodeId, Span), /// This lint comes from a `use` statement. In this case, what we /// care about really is the *root* `use` statement; e.g., if we /// have nested things like `use a::{b, c}`, we care about the /// `use a` part. - UsePath { root_id: NodeId, root_span: Span }, + UsePath { root_id: NodeId, root_span: Span, path_span: Span }, /// This is the "trait item" from a fully qualified path. For example, /// we might be resolving `X::Y::Z` from a path like `<T as X::Y>::Z`. /// The `path_span` is the span of the to the trait itself (`X::Y`). - QPathTrait { qpath_id: NodeId, qpath_span: Span }, + QPathTrait { qpath_id: NodeId, qpath_span: Span, path_span: Span }, } -impl CrateLint { - fn node_id(&self) -> Option<NodeId> { +impl Finalize { + fn node_id_and_path_span(&self) -> Option<(NodeId, Span)> { match *self { - CrateLint::No => None, - CrateLint::SimplePath(id) - | CrateLint::UsePath { root_id: id, .. } - | CrateLint::QPathTrait { qpath_id: id, .. } => Some(id), + Finalize::No => None, + Finalize::SimplePath(id, path_span) + | Finalize::UsePath { root_id: id, path_span, .. } + | Finalize::QPathTrait { qpath_id: id, path_span, .. } => Some((id, path_span)), } } + + fn node_id(&self) -> Option<NodeId> { + self.node_id_and_path_span().map(|(id, _)| id) + } + + fn path_span(&self) -> Option<Span> { + self.node_id_and_path_span().map(|(_, path_span)| path_span) + } } pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index e34d3e6..dc94ba4 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs
@@ -4,7 +4,7 @@ use crate::imports::ImportResolver; use crate::Namespace::*; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BuiltinMacroState, Determinacy}; -use crate::{CrateLint, DeriveData, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; +use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc_ast::{self as ast, Inline, ItemKind, ModKind, NodeId}; use rustc_ast_lowering::ResolverAstLowering; @@ -415,7 +415,7 @@ fn cfg_accessible( let mut indeterminate = false; for ns in [TypeNS, ValueNS, MacroNS].iter().copied() { - match self.resolve_path(path, Some(ns), &parent_scope, false, span, CrateLint::No) { + match self.resolve_path(path, Some(ns), &parent_scope, Finalize::No) { PathResult::Module(ModuleOrUniformRoot::Module(_)) => return Ok(true), PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => { return Ok(true); @@ -575,14 +575,7 @@ pub fn resolve_macro_path( } let res = if path.len() > 1 { - let res = match self.resolve_path( - &path, - Some(MacroNS), - parent_scope, - false, - path_span, - CrateLint::No, - ) { + let res = match self.resolve_path(&path, Some(MacroNS), parent_scope, Finalize::No) { PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => { Ok(path_res.base_res()) } @@ -612,9 +605,8 @@ pub fn resolve_macro_path( path[0].ident, scope_set, parent_scope, - false, + None, force, - path_span, ); if let Err(Determinacy::Undetermined) = binding { return Err(Determinacy::Undetermined); @@ -648,9 +640,8 @@ pub fn resolve_macro_path( orig_ident: Ident, scope_set: ScopeSet<'a>, parent_scope: &ParentScope<'a>, - record_used: bool, + finalize: Option<Span>, force: bool, - path_span: Span, ) -> Result<&'a NameBinding<'a>, Determinacy> { bitflags::bitflags! { struct Flags: u8 { @@ -662,7 +653,7 @@ struct Flags: u8 { } } - assert!(force || !record_used); // `record_used` implies `force` + assert!(force || !finalize.is_some()); // `finalize` implies `force` // Make sure `self`, `super` etc produce an error when passed to here. if orig_ident.is_path_segment_keyword() { @@ -769,8 +760,7 @@ struct Flags: u8 { ident, ns, parent_scope, - record_used, - path_span, + finalize, ); match binding { Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)), @@ -791,8 +781,7 @@ struct Flags: u8 { ns, adjusted_parent_scope, !matches!(scope_set, ScopeSet::Late(..)), - record_used, - path_span, + finalize, ); match binding { Ok(binding) => { @@ -856,12 +845,14 @@ struct Flags: u8 { Err(Determinacy::Determined) } } - Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) { - Some(binding) => Ok((binding, Flags::empty())), - None => Err(Determinacy::determined( - this.graph_root.unexpanded_invocations.borrow().is_empty(), - )), - }, + Scope::ExternPrelude => { + match this.extern_prelude_get(ident, finalize.is_some()) { + Some(binding) => Ok((binding, Flags::empty())), + None => Err(Determinacy::determined( + this.graph_root.unexpanded_invocations.borrow().is_empty(), + )), + } + } Scope::ToolPrelude => match this.registered_tools.get(&ident).cloned() { Some(ident) => ok(Res::ToolMod, ident.span, this.arenas), None => Err(Determinacy::Determined), @@ -874,8 +865,7 @@ struct Flags: u8 { ident, ns, parent_scope, - false, - path_span, + None, ) { if use_prelude || this.is_builtin_macro(binding.res()) { result = Ok((binding, Flags::MISC_FROM_PRELUDE)); @@ -894,7 +884,7 @@ struct Flags: u8 { Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => { - if !record_used || matches!(scope_set, ScopeSet::Late(..)) { + if finalize.is_none() || matches!(scope_set, ScopeSet::Late(..)) { return Some(Ok(binding)); } @@ -1033,9 +1023,7 @@ struct Flags: u8 { &path, Some(MacroNS), &parent_scope, - true, - path_span, - CrateLint::No, + Finalize::SimplePath(ast::CRATE_NODE_ID, path_span), ) { PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => { let res = path_res.base_res(); @@ -1069,9 +1057,8 @@ struct Flags: u8 { ident, ScopeSet::Macro(kind), &parent_scope, + Some(ident.span), true, - true, - ident.span, ) { Ok(binding) => { let initial_res = initial_binding.map(|initial_binding| { @@ -1111,9 +1098,8 @@ struct Flags: u8 { ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, + Some(ident.span), true, - true, - ident.span, ); } }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 7eeb6f9..4b2eea5 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs
@@ -19,7 +19,7 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; -use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; +use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; @@ -35,7 +35,6 @@ use std::env; use std::fmt; use std::io::Write; -use std::num::NonZeroU32; use std::ops::{Div, Mul}; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -136,10 +135,6 @@ pub struct Session { /// `None` means that there is no source file. pub local_crate_source_file: Option<PathBuf>, - /// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking - /// (sub)diagnostics that have been set once, but should not be set again, - /// in order to avoid redundantly verbose output (Issue #24690, #44953). - pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>, crate_types: OnceCell<Vec<CrateType>>, /// The `stable_crate_id` is constructed out of the crate name and all the /// `-C metadata` arguments passed to the compiler. Its value forms a unique @@ -209,13 +204,6 @@ pub struct PerfStats { pub normalize_projection_ty: AtomicUsize, } -/// Enum to support dispatch of one-time diagnostics (in `Session.diag_once`). -enum DiagnosticBuilderMethod { - Note, - SpanNote, - // Add more variants as needed to support one-time diagnostics. -} - /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(SessionDiagnostic)]` -- see [rustc_macros::SessionDiagnostic]. pub trait SessionDiagnostic<'a> { @@ -224,21 +212,6 @@ pub trait SessionDiagnostic<'a> { fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a, ErrorGuaranteed>; } -/// Diagnostic message ID, used by `Session.one_time_diagnostics` to avoid -/// emitting the same message more than once. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum DiagnosticMessageId { - ErrorId(u16), // EXXXX error code as integer - LintId(lint::LintId), - StabilityId(Option<NonZeroU32>), // issue number -} - -impl From<&'static lint::Lint> for DiagnosticMessageId { - fn from(lint: &'static lint::Lint) -> Self { - DiagnosticMessageId::LintId(lint::LintId::of(lint)) - } -} - impl Session { pub fn miri_unleashed_feature(&self, span: Span, feature_gate: Option<Symbol>) { self.miri_unleashed_features.lock().push((span, feature_gate)); @@ -497,50 +470,6 @@ pub fn diagnostic(&self) -> &rustc_errors::Handler { &self.parse_sess.span_diagnostic } - /// Analogous to calling methods on the given `DiagnosticBuilder`, but - /// deduplicates on lint ID, span (if any), and message for this `Session` - fn diag_once( - &self, - diag: &mut Diagnostic, - method: DiagnosticBuilderMethod, - msg_id: DiagnosticMessageId, - message: &str, - span_maybe: Option<Span>, - ) { - let id_span_message = (msg_id, span_maybe, message.to_owned()); - let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message); - if fresh { - match method { - DiagnosticBuilderMethod::Note => { - diag.note(message); - } - DiagnosticBuilderMethod::SpanNote => { - let span = span_maybe.expect("`span_note` needs a span"); - diag.span_note(span, message); - } - } - } - } - - pub fn diag_span_note_once( - &self, - diag: &mut Diagnostic, - msg_id: DiagnosticMessageId, - span: Span, - message: &str, - ) { - self.diag_once(diag, DiagnosticBuilderMethod::SpanNote, msg_id, message, Some(span)); - } - - pub fn diag_note_once( - &self, - diag: &mut Diagnostic, - msg_id: DiagnosticMessageId, - message: &str, - ) { - self.diag_once(diag, DiagnosticBuilderMethod::Note, msg_id, message, None); - } - #[inline] pub fn source_map(&self) -> &SourceMap { self.parse_sess.source_map() @@ -1306,7 +1235,6 @@ pub fn build_session( parse_sess, sysroot, local_crate_source_file, - one_time_diagnostics: Default::default(), crate_types: OnceCell::new(), stable_crate_id: OnceCell::new(), features: OnceCell::new(),
diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 46c7466..5b88cff 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs
@@ -5,7 +5,7 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt}; use rustc_middle::ty::{ToPredicate, TypeFoldable}; -use rustc_session::{DiagnosticMessageId, Limit}; +use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::Span; @@ -222,24 +222,19 @@ pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Spa Limit(0) => Limit(2), limit => limit * 2, }; - let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`", ty); - let error_id = (DiagnosticMessageId::ErrorId(55), Some(span), msg); - let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - struct_span_err!( - tcx.sess, - span, - E0055, - "reached the recursion limit while auto-dereferencing `{:?}`", - ty - ) - .span_label(span, "deref recursion limit reached") - .help(&format!( - "consider increasing the recursion limit by adding a \ + struct_span_err!( + tcx.sess, + span, + E0055, + "reached the recursion limit while auto-dereferencing `{:?}`", + ty + ) + .span_label(span, "deref recursion limit reached") + .help(&format!( + "consider increasing the recursion limit by adding a \ `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", - suggested_limit, - tcx.crate_name(LOCAL_CRATE), - )) - .emit(); - } + suggested_limit, + tcx.crate_name(LOCAL_CRATE), + )) + .emit(); }
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 94a4001..ec4f808 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -7,7 +7,7 @@ use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{CombinedSnapshot, InferOk, RegionckMode}; use crate::traits::select::IntercrateAmbiguityCause; -use crate::traits::util::impl_trait_ref_and_oblig; +use crate::traits::util::impl_subject_and_oblig; use crate::traits::SkipLeakCheck; use crate::traits::{ self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation, @@ -23,9 +23,10 @@ use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; +use std::fmt::Debug; use std::iter; /// Whether we do the orphan check relative to this crate or @@ -300,60 +301,62 @@ fn negative_impl<'cx, 'tcx>( debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id); let tcx = selcx.infcx().tcx; - // create a parameter environment corresponding to a (placeholder) instantiation of impl1 - let impl1_env = tcx.param_env(impl1_def_id); - let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap(); - // Create an infcx, taking the predicates of impl1 as assumptions: tcx.infer_ctxt().enter(|infcx| { - // Normalize the trait reference. The WF rules ought to ensure - // that this always succeeds. - let impl1_trait_ref = match traits::fully_normalize( + // create a parameter environment corresponding to a (placeholder) instantiation of impl1 + let impl_env = tcx.param_env(impl1_def_id); + let subject1 = match traits::fully_normalize( &infcx, FulfillmentContext::new(), ObligationCause::dummy(), - impl1_env, - impl1_trait_ref, + impl_env, + tcx.impl_subject(impl1_def_id), ) { - Ok(impl1_trait_ref) => impl1_trait_ref, - Err(err) => { - bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err); - } + Ok(s) => s, + Err(err) => bug!("failed to fully normalize {:?}: {:?}", impl1_def_id, err), }; // Attempt to prove that impl2 applies, given all of the above. let selcx = &mut SelectionContext::new(&infcx); let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id); - let (impl2_trait_ref, obligations) = - impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs); + let (subject2, obligations) = + impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs); - // do the impls unify? If not, not disjoint. - let Ok(InferOk { obligations: more_obligations, .. }) = infcx - .at(&ObligationCause::dummy(), impl1_env) - .eq(impl1_trait_ref, impl2_trait_ref) - else { - debug!( - "explicit_disjoint: {:?} does not unify with {:?}", - impl1_trait_ref, impl2_trait_ref - ); - return false; - }; - - let opt_failing_obligation = obligations - .into_iter() - .chain(more_obligations) - .find(|o| negative_impl_exists(selcx, impl1_env, impl1_def_id, o)); - - if let Some(failing_obligation) = opt_failing_obligation { - debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); - true - } else { - false - } + !equate(&infcx, impl_env, impl1_def_id, subject1, subject2, obligations) }) } -/// Try to prove that a negative impl exist for the given obligation and their super predicates. +fn equate<'cx, 'tcx>( + infcx: &InferCtxt<'cx, 'tcx>, + impl_env: ty::ParamEnv<'tcx>, + impl1_def_id: DefId, + subject1: ImplSubject<'tcx>, + subject2: ImplSubject<'tcx>, + obligations: impl Iterator<Item = PredicateObligation<'tcx>>, +) -> bool { + // do the impls unify? If not, not disjoint. + let Ok(InferOk { obligations: more_obligations, .. }) = + infcx.at(&ObligationCause::dummy(), impl_env).eq(subject1, subject2) + else { + debug!("explicit_disjoint: {:?} does not unify with {:?}", subject1, subject2); + return true; + }; + + let selcx = &mut SelectionContext::new(&infcx); + let opt_failing_obligation = obligations + .into_iter() + .chain(more_obligations) + .find(|o| negative_impl_exists(selcx, impl_env, impl1_def_id, o)); + + if let Some(failing_obligation) = opt_failing_obligation { + debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); + false + } else { + true + } +} + +/// Try to prove that a negative impl exist for the given obligation and its super predicates. #[instrument(level = "debug", skip(selcx))] fn negative_impl_exists<'cx, 'tcx>( selcx: &SelectionContext<'cx, 'tcx>, @@ -367,7 +370,7 @@ fn negative_impl_exists<'cx, 'tcx>( return true; } - // Try to prove a negative obligation exist for super predicates + // Try to prove a negative obligation exists for super predicates for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { if resolve_negative_obligation(infcx, param_env, region_context, &o) { return true;
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 5e22017..1303155 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -28,7 +28,6 @@ use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, }; -use rustc_session::DiagnosticMessageId; use rustc_span::symbol::{kw, sym}; use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP}; use std::fmt; @@ -1406,60 +1405,49 @@ fn report_projection_error( } } - let msg = format!("type mismatch resolving `{}`", predicate); - let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg); - let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - let mut diag = struct_span_err!( - self.tcx.sess, - obligation.cause.span, - E0271, - "type mismatch resolving `{}`", - predicate - ); - let secondary_span = match predicate.kind().skip_binder() { - ty::PredicateKind::Projection(proj) => self - .tcx - .opt_associated_item(proj.projection_ty.item_def_id) - .and_then(|trait_assoc_item| { + let mut diag = struct_span_err!( + self.tcx.sess, + obligation.cause.span, + E0271, + "type mismatch resolving `{}`", + predicate + ); + let secondary_span = match predicate.kind().skip_binder() { + ty::PredicateKind::Projection(proj) => self + .tcx + .opt_associated_item(proj.projection_ty.item_def_id) + .and_then(|trait_assoc_item| { + self.tcx + .trait_of_item(proj.projection_ty.item_def_id) + .map(|id| (trait_assoc_item, id)) + }) + .and_then(|(trait_assoc_item, id)| { + let trait_assoc_ident = trait_assoc_item.ident(self.tcx); + self.tcx.find_map_relevant_impl(id, proj.projection_ty.self_ty(), |did| { self.tcx - .trait_of_item(proj.projection_ty.item_def_id) - .map(|id| (trait_assoc_item, id)) + .associated_items(did) + .in_definition_order() + .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident) }) - .and_then(|(trait_assoc_item, id)| { - let trait_assoc_ident = trait_assoc_item.ident(self.tcx); - self.tcx.find_map_relevant_impl( - id, - proj.projection_ty.self_ty(), - |did| { - self.tcx - .associated_items(did) - .in_definition_order() - .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident) - }, - ) - }) - .and_then(|item| match self.tcx.hir().get_if_local(item.def_id) { - Some( - hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Type(_, Some(ty)), - .. - }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::TyAlias(ty), - .. - }), - ) => { - Some((ty.span, format!("type mismatch resolving `{}`", predicate))) - } - _ => None, - }), - _ => None, - }; - self.note_type_err(&mut diag, &obligation.cause, secondary_span, values, err, true); - self.note_obligation_cause(&mut diag, obligation); - diag.emit(); - } + }) + .and_then(|item| match self.tcx.hir().get_if_local(item.def_id) { + Some( + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(_, Some(ty)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::TyAlias(ty), + .. + }), + ) => Some((ty.span, format!("type mismatch resolving `{}`", predicate))), + _ => None, + }), + _ => None, + }; + self.note_type_err(&mut diag, &obligation.cause, secondary_span, values, err, true); + self.note_obligation_cause(&mut diag, obligation); + diag.emit(); }); }
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 2df0d9f..8997a78 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -5,7 +5,7 @@ use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::{self, Ty, TyCtxt}; -pub use rustc_middle::traits::query::{DropckOutlivesResult, DtorckConstraint}; +pub use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; pub trait AtExt<'tcx> { fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<GenericArg<'tcx>>>;
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 7947106..328e0d2 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -20,12 +20,12 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, ImplSubject, TyCtxt}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::{Span, DUMMY_SP}; -use super::util::impl_trait_ref_and_oblig; +use super::util; use super::{FulfillmentContext, SelectionContext}; /// Information pertinent to an overlapping impl error. @@ -186,18 +186,20 @@ fn fulfill_implication<'a, 'tcx>( param_env, source_trait_ref, target_impl ); + let source_trait = ImplSubject::Trait(source_trait_ref); + let selcx = &mut SelectionContext::new(&infcx); let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); - let (target_trait_ref, obligations) = - impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs); + let (target_trait, obligations) = + util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs); // do the impls unify? If not, no specialization. let Ok(InferOk { obligations: more_obligations, .. }) = - infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) + infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait, target_trait) else { debug!( "fulfill_implication: {:?} does not unify with {:?}", - source_trait_ref, target_trait_ref + source_trait, target_trait ); return Err(()); }; @@ -225,7 +227,7 @@ fn fulfill_implication<'a, 'tcx>( [] => { debug!( "fulfill_implication: an impl for {:?} specializes {:?}", - source_trait_ref, target_trait_ref + source_trait, target_trait ); // Now resolve the *substitution* we built for the target earlier, replacing @@ -237,8 +239,8 @@ fn fulfill_implication<'a, 'tcx>( debug!( "fulfill_implication: for impls on {:?} and {:?}, \ could not fulfill: {:?} given {:?}", - source_trait_ref, - target_trait_ref, + source_trait, + target_trait, errors, param_env.caller_bounds() );
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index f800e7a..7543d1f 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef}; -use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeFoldable}; use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::{self, util::*}; @@ -190,19 +190,19 @@ fn next(&mut self) -> Option<DefId> { // Other /////////////////////////////////////////////////////////////////////////// -/// Instantiate all bound parameters of the impl with the given substs, -/// returning the resulting trait ref and all obligations that arise. +/// Instantiate all bound parameters of the impl subject with the given substs, +/// returning the resulting subject and all obligations that arise. /// The obligations are closed under normalization. -pub fn impl_trait_ref_and_oblig<'a, 'tcx>( +pub fn impl_subject_and_oblig<'a, 'tcx>( selcx: &mut SelectionContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, impl_def_id: DefId, impl_substs: SubstsRef<'tcx>, -) -> (ty::TraitRef<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) { - let impl_trait_ref = selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); - let impl_trait_ref = impl_trait_ref.subst(selcx.tcx(), impl_substs); - let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = - super::normalize(selcx, param_env, ObligationCause::dummy(), impl_trait_ref); +) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) { + let subject = selcx.tcx().impl_subject(impl_def_id); + let subject = subject.subst(selcx.tcx(), impl_substs); + let Normalized { value: subject, obligations: normalization_obligations1 } = + super::normalize(selcx, param_env, ObligationCause::dummy(), subject); let predicates = selcx.tcx().predicates_of(impl_def_id); let predicates = predicates.instantiate(selcx.tcx(), impl_substs); @@ -215,7 +215,7 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( .chain(normalization_obligations1.into_iter()) .chain(normalization_obligations2.into_iter()); - (impl_trait_ref, impl_obligations) + (subject, impl_obligations) } pub fn predicates_for_generics<'tcx>(
diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index df5df17..e4c22a3 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -9,7 +9,7 @@ use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_trait_selection::traits::query::dropck_outlives::trivial_dropck_outlives; use rustc_trait_selection::traits::query::dropck_outlives::{ - DropckOutlivesResult, DtorckConstraint, + DropckConstraint, DropckOutlivesResult, }; use rustc_trait_selection::traits::query::normalize::AtExt; use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; @@ -78,7 +78,7 @@ fn dropck_outlives<'tcx>( let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let cause = ObligationCause::dummy(); - let mut constraints = DtorckConstraint::empty(); + let mut constraints = DropckConstraint::empty(); while let Some((ty, depth)) = ty_stack.pop() { debug!( "{} kinds, {} overflows, {} ty_stack", @@ -159,7 +159,7 @@ fn dtorck_constraint_for_ty<'tcx>( for_ty: Ty<'tcx>, depth: usize, ty: Ty<'tcx>, - constraints: &mut DtorckConstraint<'tcx>, + constraints: &mut DropckConstraint<'tcx>, ) -> Result<(), NoSolution> { debug!("dtorck_constraint_for_ty({:?}, {:?}, {:?}, {:?})", span, for_ty, depth, ty); @@ -267,7 +267,7 @@ fn dtorck_constraint_for_ty<'tcx>( } ty::Adt(def, substs) => { - let DtorckConstraint { dtorck_types, outlives, overflows } = + let DropckConstraint { dtorck_types, outlives, overflows } = tcx.at(span).adt_dtorck_constraint(def.did())?; // FIXME: we can try to recursively `dtorck_constraint_on_ty` // there, but that needs some way to handle cycles. @@ -301,7 +301,7 @@ fn dtorck_constraint_for_ty<'tcx>( crate fn adt_dtorck_constraint( tcx: TyCtxt<'_>, def_id: DefId, -) -> Result<&DtorckConstraint<'_>, NoSolution> { +) -> Result<&DropckConstraint<'_>, NoSolution> { let def = tcx.adt_def(def_id); let span = tcx.def_span(def_id); debug!("dtorck_constraint: {:?}", def); @@ -311,7 +311,7 @@ fn dtorck_constraint_for_ty<'tcx>( // `PhantomData`. let substs = InternalSubsts::identity_for_item(tcx, def_id); assert_eq!(substs.len(), 1); - let result = DtorckConstraint { + let result = DropckConstraint { outlives: vec![], dtorck_types: vec![substs.type_at(0)], overflows: vec![], @@ -320,7 +320,7 @@ fn dtorck_constraint_for_ty<'tcx>( return Ok(tcx.arena.alloc(result)); } - let mut result = DtorckConstraint::empty(); + let mut result = DropckConstraint::empty(); for field in def.all_fields() { let fty = tcx.type_of(field.did); dtorck_constraint_for_ty(tcx, span, fty, 0, fty, &mut result)?; @@ -333,7 +333,7 @@ fn dtorck_constraint_for_ty<'tcx>( Ok(tcx.arena.alloc(result)) } -fn dedup_dtorck_constraint(c: &mut DtorckConstraint<'_>) { +fn dedup_dtorck_constraint(c: &mut DropckConstraint<'_>) { let mut outlives = FxHashSet::default(); let mut dtorck_types = FxHashSet::default();
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 16ffabb..c1cb9a1 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -467,8 +467,8 @@ fn visit_user_provided_tys(&mut self) { if !errors_buffer.is_empty() { errors_buffer.sort_by_key(|diag| diag.span.primary_span()); - for diag in errors_buffer.drain(..) { - self.tcx().sess.diagnostic().emit_diagnostic(&diag); + for mut diag in errors_buffer.drain(..) { + self.tcx().sess.diagnostic().emit_diagnostic(&mut diag); } } }
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index a810a57..6d7ca9a 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs
@@ -568,7 +568,7 @@ fn configure_cmake( // We also do this if the user explicitly requested static libstdc++. if builder.config.llvm_static_stdcpp { if !target.contains("msvc") && !target.contains("netbsd") { - if target.contains("apple") { + if target.contains("apple") || target.contains("windows") { ldflags.push_all("-static-libstdc++"); } else { ldflags.push_all("-Wl,-Bsymbolic -static-libstdc++");
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index fab77af..fcbb537 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@ -0.8.3 \ No newline at end of file +0.8.4 \ No newline at end of file
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3d8a62d..5b14aca 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -487,12 +487,10 @@ fn resolve_macro( module_id: DefId, ) -> Result<Res, ResolutionFailure<'a>> { self.cx.enter_resolver(|resolver| { - // NOTE: this needs 2 separate lookups because `resolve_str_path_error` doesn't take + // NOTE: this needs 2 separate lookups because `resolve_rustdoc_path` doesn't take // lexical scope into account (it ignores all macros not defined at the mod-level) debug!("resolving {} as a macro in the module {:?}", path_str, module_id); - if let Ok((_, res)) = - resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id) - { + if let Some(res) = resolver.resolve_rustdoc_path(path_str, MacroNS, module_id) { // don't resolve builtins like `#[derive]` if let Ok(res) = res.try_into() { return Ok(res); @@ -540,10 +538,10 @@ fn resolve_self_ty(&self, path_str: &str, ns: Namespace, item_id: ItemId) -> Opt }) } - /// Convenience wrapper around `resolve_str_path_error`. + /// Convenience wrapper around `resolve_rustdoc_path`. /// /// This also handles resolving `true` and `false` as booleans. - /// NOTE: `resolve_str_path_error` knows only about paths, not about types. + /// NOTE: `resolve_rustdoc_path` knows only about paths, not about types. /// Associated items will never be resolved by this function. fn resolve_path( &self, @@ -556,18 +554,14 @@ fn resolve_path( return res; } - let result = self.cx.enter_resolver(|resolver| { - resolver - .resolve_str_path_error(DUMMY_SP, path_str, ns, module_id) - .and_then(|(_, res)| res.try_into()) - }); + // Resolver doesn't know about true, false, and types that aren't paths (e.g. `()`). + let result = self + .cx + .enter_resolver(|resolver| resolver.resolve_rustdoc_path(path_str, ns, module_id)) + .and_then(|res| res.try_into().ok()) + .or_else(|| resolve_primitive(path_str, ns)); debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns); - match result { - // resolver doesn't know about true, false, and types that aren't paths (e.g. `()`) - // manually as bool - Err(()) => resolve_primitive(path_str, ns), - Ok(res) => Some(res), - } + result } /// Resolves a string as a path within a particular namespace. Returns an
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index 1d28bbd..30636fa 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -13,7 +13,7 @@ use rustc_middle::ty::{DefIdTree, Visibility}; use rustc_resolve::{ParentScope, Resolver}; use rustc_session::config::Externs; -use rustc_span::{Span, SyntaxContext, DUMMY_SP}; +use rustc_span::SyntaxContext; use std::collections::hash_map::Entry; use std::mem; @@ -39,7 +39,7 @@ // Overridden `visit_item` below doesn't apply to the crate root, // so we have to visit its attributes and reexports separately. - loader.load_links_in_attrs(&krate.attrs, krate.spans.inner_span); + loader.load_links_in_attrs(&krate.attrs); loader.process_module_children_or_reexports(CRATE_DEF_ID.to_def_id()); visit::walk_crate(&mut loader, krate); loader.add_foreign_traits_in_scope(); @@ -49,12 +49,7 @@ // DO NOT REMOVE THIS without first testing on the reproducer in // https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb for (extern_name, _) in externs.iter().filter(|(_, entry)| entry.add_prelude) { - let _ = loader.resolver.resolve_str_path_error( - DUMMY_SP, - extern_name, - TypeNS, - CRATE_DEF_ID.to_def_id(), - ); + loader.resolver.resolve_rustdoc_path(extern_name, TypeNS, CRATE_DEF_ID.to_def_id()); } ResolverCaches { @@ -151,7 +146,7 @@ fn add_foreign_traits_in_scope(&mut self) { } } - fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute], span: Span) { + fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute]) { // FIXME: this needs to consider reexport inlining. let attrs = clean::Attributes::from_ast(attrs, None); for (parent_module, doc) in attrs.collapsed_doc_value_by_module_level() { @@ -165,7 +160,7 @@ fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute], span: Span) { } else { continue; }; - let _ = self.resolver.resolve_str_path_error(span, &path_str, TypeNS, module_id); + self.resolver.resolve_rustdoc_path(&path_str, TypeNS, module_id); } } } @@ -201,7 +196,7 @@ fn visit_item(&mut self, item: &ast::Item) { // loaded, even if the module itself has no doc comments. self.add_traits_in_parent_scope(self.current_mod.to_def_id()); - self.load_links_in_attrs(&item.attrs, item.span); + self.load_links_in_attrs(&item.attrs); self.process_module_children_or_reexports(self.current_mod.to_def_id()); visit::walk_item(self, item); @@ -216,28 +211,28 @@ fn visit_item(&mut self, item: &ast::Item) { } _ => {} } - self.load_links_in_attrs(&item.attrs, item.span); + self.load_links_in_attrs(&item.attrs); visit::walk_item(self, item); } } fn visit_assoc_item(&mut self, item: &ast::AssocItem, ctxt: AssocCtxt) { - self.load_links_in_attrs(&item.attrs, item.span); + self.load_links_in_attrs(&item.attrs); visit::walk_assoc_item(self, item, ctxt) } fn visit_foreign_item(&mut self, item: &ast::ForeignItem) { - self.load_links_in_attrs(&item.attrs, item.span); + self.load_links_in_attrs(&item.attrs); visit::walk_foreign_item(self, item) } fn visit_variant(&mut self, v: &ast::Variant) { - self.load_links_in_attrs(&v.attrs, v.span); + self.load_links_in_attrs(&v.attrs); visit::walk_variant(self, v) } fn visit_field_def(&mut self, field: &ast::FieldDef) { - self.load_links_in_attrs(&field.attrs, field.span); + self.load_links_in_attrs(&field.attrs); visit::walk_field_def(self, field) }
diff --git a/src/test/rustdoc-gui/default-settings.goml b/src/test/rustdoc-gui/default-settings.goml index 68b674a..90f0b08 100644 --- a/src/test/rustdoc-gui/default-settings.goml +++ b/src/test/rustdoc-gui/default-settings.goml
@@ -4,5 +4,5 @@ // check. goto: file://|DOC_PATH|/settings/index.html // Wait a bit to be sure the default theme is applied. -wait-for: 1000 -assert-css: ("body", {"background-color": "rgb(15, 20, 25)"}) +// If the theme isn't applied, the command will time out. +wait-for-css: ("body", {"background-color": "rgb(15, 20, 25)"})
diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml index 3f78d60..aca8390 100644 --- a/src/test/rustdoc-gui/search-filter.goml +++ b/src/test/rustdoc-gui/search-filter.goml
@@ -24,11 +24,9 @@ // Now we check that leaving the search results and putting them back keeps the // crate filtering. press-key: "Escape" -wait-for: 100 -assert-css: ("#main-content", {"display": "block"}) +wait-for-css: ("#main-content", {"display": "block"}) focus: ".search-input" -wait-for: 100 -assert-css: ("#main-content", {"display": "none"}) +wait-for-css: ("#main-content", {"display": "none"}) // We check that there is no more "test_docs" appearing. assert-false: "#results .externcrate" assert-property: ("#crate-search", {"value": "lib2"})
diff --git a/src/test/rustdoc-gui/search-result-go-to-first.goml b/src/test/rustdoc-gui/search-result-go-to-first.goml index cadd7f6..255470a 100644 --- a/src/test/rustdoc-gui/search-result-go-to-first.goml +++ b/src/test/rustdoc-gui/search-result-go-to-first.goml
@@ -16,5 +16,4 @@ // Now we can check that the feature is working as expected! goto: file://|DOC_PATH|/test_docs/index.html?search=struct%3AFoo&go_to_first=true // Waiting for the page to load... -wait-for: 500 -assert-text: (".fqn .in-band", "Struct test_docs::Foo") +wait-for-text: (".fqn .in-band", "Struct test_docs::Foo")
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml index 2722970..377ee9c 100644 --- a/src/test/rustdoc-gui/sidebar-source-code-display.goml +++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -5,8 +5,7 @@ assert-false: "#sidebar-toggle" // For some reason, we need to wait a bit here because it seems like the transition on opacity // is being applied whereas it can't be reproduced in a browser... -wait-for: 500 -assert-css: (".sidebar > *", {"visibility": "hidden", "opacity": 0}) +wait-for-css: (".sidebar > *", {"visibility": "hidden", "opacity": 0}) // Let's retry with javascript enabled. javascript: true @@ -17,6 +16,5 @@ // Let's expand the sidebar now. click: "#sidebar-toggle" // Because of the transition CSS, better wait a second before checking. -wait-for: 1000 -assert-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) +wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "visible", "opacity": 1})
diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index 0cb8e77..8b4a8bd 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml
@@ -7,16 +7,13 @@ assert-css: ("nav.sidebar", {"width": "50px"}) // We now click on the button to expand the sidebar. click: (10, 10) -// We wait for the sidebar to be expanded (there is a 0.5s animation). -wait-for: 600 -assert-css: ("nav.sidebar.expanded", {"width": "300px"}) +// We wait for the sidebar to be expanded. +wait-for-css: ("nav.sidebar.expanded", {"width": "300px"}) assert-css: ("nav.sidebar.expanded a", {"font-size": "14px"}) // We collapse the sidebar. click: (10, 10) -// We wait for the sidebar to be collapsed (there is a 0.5s animation). -wait-for: 600 // We ensure that the class has been removed. -assert-false: "nav.sidebar.expanded" +wait-for: "nav.sidebar:not(.expanded)" assert: "nav.sidebar" // We now switch to mobile mode.
diff --git a/src/test/rustdoc-gui/theme-change.goml b/src/test/rustdoc-gui/theme-change.goml index 73edee6..333391b 100644 --- a/src/test/rustdoc-gui/theme-change.goml +++ b/src/test/rustdoc-gui/theme-change.goml
@@ -2,26 +2,21 @@ goto: file://|DOC_PATH|/test_docs/index.html click: "#theme-picker" click: "#theme-choices > button:first-child" -wait-for: 500 // should be the ayu theme so let's check the color -assert-css: ("body", { "background-color": "rgb(15, 20, 25)" }) +wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" }) click: "#theme-choices > button:last-child" -wait-for: 500 // should be the light theme so let's check the color -assert-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" }) goto: file://|DOC_PATH|/settings.html click: "#theme-light" -wait-for: 500 -assert-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" }) assert-local-storage: { "rustdoc-theme": "light" } click: "#theme-dark" -wait-for: 500 -assert-css: ("body", { "background-color": "rgb(53, 53, 53)" }) +wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" }) assert-local-storage: { "rustdoc-theme": "dark" } click: "#theme-ayu" -wait-for: 500 -assert-css: ("body", { "background-color": "rgb(15, 20, 25)" }) +wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" }) assert-local-storage: { "rustdoc-theme": "ayu" }
diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml index b537991..3b66c85 100644 --- a/src/test/rustdoc-gui/theme-in-history.goml +++ b/src/test/rustdoc-gui/theme-in-history.goml
@@ -12,8 +12,7 @@ wait-for: ".settings" // We change the theme to "light". click: "#theme-light" -wait-for: 250 -assert-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" }) assert-local-storage: { "rustdoc-theme": "light" } // We go back in history.
diff --git a/src/test/rustdoc-gui/toggle-docs.goml b/src/test/rustdoc-gui/toggle-docs.goml index bbc85ec..63962b5 100644 --- a/src/test/rustdoc-gui/toggle-docs.goml +++ b/src/test/rustdoc-gui/toggle-docs.goml
@@ -8,9 +8,8 @@ assert-attribute-false: ("#main-content > details.top-doc", {"open": ""}) assert-text: ("#toggle-all-docs", "[+]") click: "#toggle-all-docs" -wait-for: 50 // Not collapsed anymore so the "open" attribute should be back. -assert-attribute: ("#main-content > details.top-doc", {"open": ""}) +wait-for-attribute: ("#main-content > details.top-doc", {"open": ""}) assert-text: ("#toggle-all-docs", "[−]") // Check that it works on non-module pages as well. @@ -27,8 +26,7 @@ // We collapse them all. click: "#toggle-all-docs" -wait-for: 50 -assert-text: ("#toggle-all-docs", "[+]") +wait-for-text: ("#toggle-all-docs", "[+]") // We check that all <details> are collapsed (except for the impl block ones). assert-attribute-false: ("details.rustdoc-toggle:not(.implementors-toggle)", {"open": ""}, ALL) assert-attribute: ("#implementations-list > details.implementors-toggle", {"open": ""}) @@ -40,6 +38,5 @@ ) // We open them all again. click: "#toggle-all-docs" -wait-for: 50 -assert-text: ("#toggle-all-docs", "[−]") +wait-for-text: ("#toggle-all-docs", "[−]") assert-attribute: ("details.rustdoc-toggle", {"open": ""}, ALL)
diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr index 2758c54..5d46dc7 100644 --- a/src/test/rustdoc-ui/check-fail.stderr +++ b/src/test/rustdoc-ui/check-fail.stderr
@@ -32,11 +32,6 @@ LL | | //! ``` | |_______^ | -note: the lint level is defined here - --> $DIR/check-fail.rs:4:9 - | -LL | #![deny(rustdoc::all)] - | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr index 8c9e70e..06e607f 100644 --- a/src/test/rustdoc-ui/check.stderr +++ b/src/test/rustdoc-ui/check.stderr
@@ -43,11 +43,6 @@ LL | | pub fn foo() {} | |_______________^ | -note: the lint level is defined here - --> $DIR/check.rs:8:9 - | -LL | #![warn(rustdoc::all)] - | ^^^^^^^^^^^^ = note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]` warning: missing code example in this documentation
diff --git a/src/test/rustdoc-ui/display-output.stdout b/src/test/rustdoc-ui/display-output.stdout index 41c1f41..51d638b 100644 --- a/src/test/rustdoc-ui/display-output.stdout +++ b/src/test/rustdoc-ui/display-output.stdout
@@ -30,11 +30,6 @@ LL | fn foo(x: &dyn std::fmt::Display) {} | ^^^ | -note: the lint level is defined here - --> $DIR/display-output.rs:9:9 - | -LL | #![warn(unused)] - | ^^^^^^ = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` warning: 3 warnings emitted
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index cc6f03b..e286001 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -21,11 +21,6 @@ LL | | /// ``` | |_______^ | -note: the lint level is defined here - --> $DIR/lint-group.rs:7:9 - | -LL | #![deny(rustdoc::all)] - | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]` error: missing code example in this documentation @@ -40,11 +35,6 @@ LL | /// what up, let's make an [error] | ^^^^^ no item named `error` in scope | -note: the lint level is defined here - --> $DIR/lint-group.rs:7:9 - | -LL | #![deny(rustdoc::all)] - | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -54,11 +44,6 @@ LL | /// <unknown> | ^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-group.rs:7:9 - | -LL | #![deny(rustdoc::all)] - | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::invalid_html_tags)]` implied by `#[deny(rustdoc::all)]` error: aborting due to 5 previous errors
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.rs b/src/test/ui-fulldeps/hash-stable-is-unstable.rs index 1be0819..11fe688 100644 --- a/src/test/ui-fulldeps/hash-stable-is-unstable.rs +++ b/src/test/ui-fulldeps/hash-stable-is-unstable.rs
@@ -1,5 +1,5 @@ // ignore-stage1 - +// compile-flags: -Zdeduplicate-diagnostics=yes extern crate rustc_data_structures; //~^ use of unstable library feature 'rustc_private' extern crate rustc_macros;
diff --git a/src/test/ui-fulldeps/lint-tool-test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr index 0f76384..513f70d 100644 --- a/src/test/ui-fulldeps/lint-tool-test.stderr +++ b/src/test/ui-fulldeps/lint-tool-test.stderr
@@ -83,11 +83,6 @@ LL | fn lintmetoo() { } | ^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-tool-test.rs:14:9 - | -LL | #![deny(clippy_group)] - | ^^^^^^^^^^^^ = note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]` warning: lint name `test_group` is deprecated and may not have an effect in the future.
diff --git a/src/test/ui/autoref-autoderef/issue-38940.rs b/src/test/ui/autoref-autoderef/issue-38940.rs index 3f10fc0..d2f1c6e 100644 --- a/src/test/ui/autoref-autoderef/issue-38940.rs +++ b/src/test/ui/autoref-autoderef/issue-38940.rs
@@ -2,8 +2,10 @@ // Test that the recursion limit can be changed. In this case, we have // deeply nested types that will fail the `Send` check by overflow // when the recursion limit is set very low. +// compile-flags: -Zdeduplicate-diagnostics=yes + #![allow(dead_code)] -#![recursion_limit="10"] +#![recursion_limit = "10"] macro_rules! link { ($outer:ident, $inner:ident) => { struct $outer($inner); @@ -18,14 +20,17 @@ fn deref(&self) -> &$inner { &self.0 } } - } + }; } + struct Bottom; + impl Bottom { fn new() -> Bottom { Bottom } } + link!(Top, A); link!(A, B); link!(B, C); @@ -38,6 +43,7 @@ fn new() -> Bottom { link!(I, J); link!(J, K); link!(K, Bottom); + fn main() { let t = Top::new(); let x: &Bottom = &t;
diff --git a/src/test/ui/autoref-autoderef/issue-38940.stderr b/src/test/ui/autoref-autoderef/issue-38940.stderr index a560334..f0b8405 100644 --- a/src/test/ui/autoref-autoderef/issue-38940.stderr +++ b/src/test/ui/autoref-autoderef/issue-38940.stderr
@@ -1,5 +1,5 @@ error[E0055]: reached the recursion limit while auto-dereferencing `J` - --> $DIR/issue-38940.rs:43:22 + --> $DIR/issue-38940.rs:49:22 | LL | let x: &Bottom = &t; | ^^ deref recursion limit reached @@ -7,7 +7,7 @@ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`issue_38940`) error[E0308]: mismatched types - --> $DIR/issue-38940.rs:43:22 + --> $DIR/issue-38940.rs:49:22 | LL | let x: &Bottom = &t; | ------- ^^ expected struct `Bottom`, found struct `Top`
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr index 7410977..7e767cb 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
@@ -18,11 +18,6 @@ LL | a += 1; | ^ | -note: the lint level is defined here - --> $DIR/liveness.rs:5:9 - | -LL | #![warn(unused)] - | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` = help: did you mean to capture by reference instead?
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr index 11a4405..2ac801b 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
@@ -18,11 +18,6 @@ LL | a = s; | ^ | -note: the lint level is defined here - --> $DIR/liveness_unintentional_copy.rs:4:9 - | -LL | #![warn(unused)] - | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` = help: did you mean to capture by reference instead?
diff --git a/src/test/ui/coherence/coherence-negative-inherent-where-bounds.rs b/src/test/ui/coherence/coherence-negative-inherent-where-bounds.rs new file mode 100644 index 0000000..39ccaa6 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-inherent-where-bounds.rs
@@ -0,0 +1,25 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +trait Foo {} + +impl !Foo for u32 {} + +#[rustc_strict_coherence] +struct MyStruct<T>(T); + +impl MyStruct<u32> { + fn method(&self) {} +} + +impl<T> MyStruct<T> +where + T: Foo, +{ + fn method(&self) {} +} + +fn main() {}
diff --git a/src/test/ui/coherence/coherence-negative-inherent.rs b/src/test/ui/coherence/coherence-negative-inherent.rs new file mode 100644 index 0000000..a9e1acc --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-inherent.rs
@@ -0,0 +1,22 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +#[rustc_strict_coherence] +trait Foo {} + +impl !Foo for u32 {} + +struct MyStruct<T>(T); + +impl<T: Foo> MyStruct<T> { + fn method(&self) {} +} + +impl MyStruct<u32> { + fn method(&self) {} +} + +fn main() {}
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.rs b/src/test/ui/did_you_mean/recursion_limit_deref.rs index 6138438..41bbca6 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.rs +++ b/src/test/ui/did_you_mean/recursion_limit_deref.rs
@@ -1,6 +1,7 @@ // Test that the recursion limit can be changed and that the compiler // suggests a fix. In this case, we have a long chain of Deref impls // which will cause an overflow during the autoderef loop. +// compile-flags: -Zdeduplicate-diagnostics=yes #![allow(dead_code)] #![recursion_limit="10"]
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr index 658207a..a6b5681 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -1,5 +1,5 @@ error[E0055]: reached the recursion limit while auto-dereferencing `J` - --> $DIR/recursion_limit_deref.rs:50:22 + --> $DIR/recursion_limit_deref.rs:51:22 | LL | let x: &Bottom = &t; | ^^ deref recursion limit reached @@ -7,7 +7,7 @@ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`recursion_limit_deref`) error[E0308]: mismatched types - --> $DIR/recursion_limit_deref.rs:50:22 + --> $DIR/recursion_limit_deref.rs:51:22 | LL | let x: &Bottom = &t; | ------- ^^ expected struct `Bottom`, found struct `Top`
diff --git a/src/test/ui/infinite/infinite-autoderef.rs b/src/test/ui/infinite/infinite-autoderef.rs index ca26252..cbbe1f8 100644 --- a/src/test/ui/infinite/infinite-autoderef.rs +++ b/src/test/ui/infinite/infinite-autoderef.rs
@@ -1,6 +1,5 @@ // error-pattern: reached the recursion limit while auto-dereferencing - - +// compile-flags: -Zdeduplicate-diagnostics=yes use std::ops::Deref;
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr index 2d29f05..2e950db 100644 --- a/src/test/ui/infinite/infinite-autoderef.stderr +++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/infinite-autoderef.rs:20:13 + --> $DIR/infinite-autoderef.rs:19:13 | LL | x = Box::new(x); | ^^^^^^^^^^^ cyclic type of infinite size @@ -10,7 +10,7 @@ | + error[E0055]: reached the recursion limit while auto-dereferencing `Foo` - --> $DIR/infinite-autoderef.rs:25:5 + --> $DIR/infinite-autoderef.rs:24:5 | LL | Foo.foo; | ^^^^^^^ deref recursion limit reached @@ -18,7 +18,7 @@ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`infinite_autoderef`) error[E0055]: reached the recursion limit while auto-dereferencing `Foo` - --> $DIR/infinite-autoderef.rs:25:9 + --> $DIR/infinite-autoderef.rs:24:9 | LL | Foo.foo; | ^^^ deref recursion limit reached @@ -26,13 +26,13 @@ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`infinite_autoderef`) error[E0609]: no field `foo` on type `Foo` - --> $DIR/infinite-autoderef.rs:25:9 + --> $DIR/infinite-autoderef.rs:24:9 | LL | Foo.foo; | ^^^ unknown field error[E0055]: reached the recursion limit while auto-dereferencing `Foo` - --> $DIR/infinite-autoderef.rs:26:9 + --> $DIR/infinite-autoderef.rs:25:9 | LL | Foo.bar(); | ^^^ deref recursion limit reached @@ -40,7 +40,7 @@ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`infinite_autoderef`) error[E0599]: no method named `bar` found for struct `Foo` in the current scope - --> $DIR/infinite-autoderef.rs:26:9 + --> $DIR/infinite-autoderef.rs:25:9 | LL | struct Foo; | ----------- method `bar` not found for this
diff --git a/src/test/ui/issues/issue-33941.rs b/src/test/ui/issues/issue-33941.rs index ccaa633..a121362 100644 --- a/src/test/ui/issues/issue-33941.rs +++ b/src/test/ui/issues/issue-33941.rs
@@ -1,6 +1,9 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes + use std::collections::HashMap; fn main() { for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch //~^ ERROR type mismatch + //~| ERROR type mismatch }
diff --git a/src/test/ui/issues/issue-33941.stderr b/src/test/ui/issues/issue-33941.stderr index c6650d6..e1ce6ee 100644 --- a/src/test/ui/issues/issue-33941.stderr +++ b/src/test/ui/issues/issue-33941.stderr
@@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_` - --> $DIR/issue-33941.rs:4:36 + --> $DIR/issue-33941.rs:6:36 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^ expected reference, found tuple @@ -13,7 +13,7 @@ | ^^^^^^^^^^^^ required by this bound in `cloned` error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_` - --> $DIR/issue-33941.rs:4:14 + --> $DIR/issue-33941.rs:6:14 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference @@ -23,6 +23,16 @@ = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` = note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_` + --> $DIR/issue-33941.rs:6:14 + | +LL | for _ in HashMap::new().iter().cloned() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference + | + = note: expected tuple `(&_, &_)` + found reference `&_` + = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/lint/issue-17718-const-naming.stderr b/src/test/ui/lint/issue-17718-const-naming.stderr index ce4ebcb..a1fc99c 100644 --- a/src/test/ui/lint/issue-17718-const-naming.stderr +++ b/src/test/ui/lint/issue-17718-const-naming.stderr
@@ -17,11 +17,6 @@ LL | const foo: isize = 3; | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO` | -note: the lint level is defined here - --> $DIR/issue-17718-const-naming.rs:2:9 - | -LL | #![deny(warnings)] - | ^^^^^^^^ = note: `#[deny(non_upper_case_globals)]` implied by `#[deny(warnings)]` error: aborting due to 2 previous errors
diff --git a/src/test/ui/lint/lint-group-nonstandard-style.stderr b/src/test/ui/lint/lint-group-nonstandard-style.stderr index 0ce3309..fcd0101 100644 --- a/src/test/ui/lint/lint-group-nonstandard-style.stderr +++ b/src/test/ui/lint/lint-group-nonstandard-style.stderr
@@ -43,11 +43,6 @@ LL | static bad: isize = 1; | ^^^ help: convert the identifier to upper case: `BAD` | -note: the lint level is defined here - --> $DIR/lint-group-nonstandard-style.rs:10:14 - | -LL | #[forbid(nonstandard_style)] - | ^^^^^^^^^^^^^^^^^ = note: `#[forbid(non_upper_case_globals)]` implied by `#[forbid(nonstandard_style)]` warning: function `CamelCase` should have a snake case name @@ -56,11 +51,6 @@ LL | fn CamelCase() {} | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case` | -note: the lint level is defined here - --> $DIR/lint-group-nonstandard-style.rs:18:17 - | -LL | #![warn(nonstandard_style)] - | ^^^^^^^^^^^^^^^^^ = note: `#[warn(non_snake_case)]` implied by `#[warn(nonstandard_style)]` error: aborting due to 3 previous errors; 2 warnings emitted
diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr index 2ef655e..26fa6eb 100644 --- a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -49,11 +49,6 @@ LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 - | -LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) - | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` = help: maybe it is overwritten before being read? @@ -107,11 +102,6 @@ | | | help: remove this `mut` | -note: the lint level is defined here - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 - | -LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) - | ^^^^^^ = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]` warning: variable does not need to be mutable
diff --git a/src/test/ui/liveness/liveness-consts.stderr b/src/test/ui/liveness/liveness-consts.stderr index b1beec9..adaf543 100644 --- a/src/test/ui/liveness/liveness-consts.stderr +++ b/src/test/ui/liveness/liveness-consts.stderr
@@ -18,11 +18,6 @@ LL | b += 1; | ^ | -note: the lint level is defined here - --> $DIR/liveness-consts.rs:2:9 - | -LL | #![warn(unused)] - | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` = help: maybe it is overwritten before being read?
diff --git a/src/test/ui/liveness/liveness-upvars.stderr b/src/test/ui/liveness/liveness-upvars.stderr index d172330..cb104e0 100644 --- a/src/test/ui/liveness/liveness-upvars.stderr +++ b/src/test/ui/liveness/liveness-upvars.stderr
@@ -18,11 +18,6 @@ LL | last = Some(s); | ^^^^ | -note: the lint level is defined here - --> $DIR/liveness-upvars.rs:4:9 - | -LL | #![warn(unused)] - | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` = help: did you mean to capture by reference instead?
diff --git a/src/test/ui/never_type/never-assign-dead-code.stderr b/src/test/ui/never_type/never-assign-dead-code.stderr index 5c5cafa..521b820 100644 --- a/src/test/ui/never_type/never-assign-dead-code.stderr +++ b/src/test/ui/never_type/never-assign-dead-code.stderr
@@ -27,11 +27,6 @@ LL | let x: ! = panic!("aah"); | ^ help: if this is intentional, prefix it with an underscore: `_x` | -note: the lint level is defined here - --> $DIR/never-assign-dead-code.rs:6:9 - | -LL | #![warn(unused)] - | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: 3 warnings emitted
diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index a2c1b82..f1a167e 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr
@@ -101,6 +101,7 @@ LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -112,6 +113,7 @@ LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -123,6 +125,7 @@ LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -150,6 +153,11 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | +note: the lint level is defined here + --> $DIR/generate-mod.rs:30:10 + | +LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr index bd9ba6a..acba357 100644 --- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr +++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
@@ -111,6 +111,7 @@ LL | impl_macros!(Foo); | ----------------- in this macro invocation | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage @@ -128,6 +129,7 @@ LL | arrays!(Foo); | ------------ in this macro invocation | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: older versions of the `js-sys` crate will stop compiling in future versions of Rust; please update to `js-sys` v0.3.40 or above @@ -145,6 +147,7 @@ LL | tuple_from_req!(Foo); | -------------------- in this macro invocation | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage @@ -162,6 +165,7 @@ LL | tuple_from_req!(Foo); | -------------------- in this macro invocation | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage
diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr index 554613b..be42390 100644 --- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
@@ -60,6 +60,7 @@ LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. @@ -71,6 +72,7 @@ LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. @@ -82,6 +84,7 @@ LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed index acb0aa4..5786ed7 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed +++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
@@ -17,28 +17,18 @@ use crate::foo::{bar::{baz::{}}}; //~^ ERROR absolute paths must start with //~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition use crate::foo::{bar::{XX, baz::{}}}; //~^ ERROR absolute paths must start with //~| WARN this is accepted in the current edition //~| ERROR absolute paths must start with //~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition use crate::foo::{bar::{baz::{}, baz1::{}}}; //~^ ERROR absolute paths must start with //~| WARN this is accepted in the current edition //~| ERROR absolute paths must start with //~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition fn main() { }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs index 4825528..b7c8608 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs +++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
@@ -17,28 +17,18 @@ use foo::{bar::{baz::{}}}; //~^ ERROR absolute paths must start with //~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition use foo::{bar::{XX, baz::{}}}; //~^ ERROR absolute paths must start with //~| WARN this is accepted in the current edition //~| ERROR absolute paths must start with //~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition use foo::{bar::{baz::{}, baz1::{}}}; //~^ ERROR absolute paths must start with //~| WARN this is accepted in the current edition //~| ERROR absolute paths must start with //~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| WARN this is accepted in the current edition fn main() { }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr index 8a31137..e47c320 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
@@ -13,16 +13,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:17:5 - | -LL | use foo::{bar::{baz::{}}}; - | ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:23:5 + --> $DIR/edition-lint-nested-empty-paths.rs:21:5 | LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` @@ -31,7 +22,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:23:5 + --> $DIR/edition-lint-nested-empty-paths.rs:21:5 | LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` @@ -40,25 +31,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:23:5 - | -LL | use foo::{bar::{XX, baz::{}}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:23:5 - | -LL | use foo::{bar::{XX, baz::{}}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:33:5 + --> $DIR/edition-lint-nested-empty-paths.rs:27:5 | LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` @@ -67,7 +40,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:33:5 + --> $DIR/edition-lint-nested-empty-paths.rs:27:5 | LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` @@ -75,23 +48,5 @@ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:33:5 - | -LL | use foo::{bar::{baz::{}, baz1::{}}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-empty-paths.rs:33:5 - | -LL | use foo::{bar::{baz::{}, baz1::{}}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: aborting due to 10 previous errors +error: aborting due to 5 previous errors
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.fixed b/src/test/ui/rust-2018/edition-lint-nested-paths.fixed index 4eb1184..c4546f8 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-paths.fixed +++ b/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
@@ -8,10 +8,6 @@ //~| this is accepted in the current edition //~| ERROR absolute paths must start with //~| this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| this is accepted in the current edition mod foo { crate fn a() {} @@ -29,8 +25,6 @@ //~| this is accepted in the current edition //~| ERROR absolute paths must start with //~| this is accepted in the current edition - //~| ERROR absolute paths must start with - //~| this is accepted in the current edition x::a(); c(); }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.rs b/src/test/ui/rust-2018/edition-lint-nested-paths.rs index 2a35822..a7e34e4 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-paths.rs +++ b/src/test/ui/rust-2018/edition-lint-nested-paths.rs
@@ -8,10 +8,6 @@ //~| this is accepted in the current edition //~| ERROR absolute paths must start with //~| this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| this is accepted in the current edition -//~| ERROR absolute paths must start with -//~| this is accepted in the current edition mod foo { crate fn a() {} @@ -29,8 +25,6 @@ fn main() { //~| this is accepted in the current edition //~| ERROR absolute paths must start with //~| this is accepted in the current edition - //~| ERROR absolute paths must start with - //~| this is accepted in the current edition x::a(); c(); }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr index 3d59602..24b17f2 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
@@ -22,25 +22,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-paths.rs:6:5 - | -LL | use foo::{a, b}; - | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-paths.rs:6:5 - | -LL | use foo::{a, b}; - | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-paths.rs:27:13 + --> $DIR/edition-lint-nested-paths.rs:23:13 | LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` @@ -49,7 +31,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-paths.rs:27:13 + --> $DIR/edition-lint-nested-paths.rs:23:13 | LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` @@ -57,14 +39,5 @@ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-nested-paths.rs:27:13 - | -LL | use foo::{self as x, c}; - | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors
diff --git a/src/test/ui/rust-2018/edition-lint-paths.fixed b/src/test/ui/rust-2018/edition-lint-paths.fixed index 46adf02..47f82c5 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.fixed +++ b/src/test/ui/rust-2018/edition-lint-paths.fixed
@@ -12,8 +12,6 @@ use crate::bar::Bar; //~^ ERROR absolute //~| WARN this is accepted in the current edition - //~| ERROR absolute - //~| WARN this is accepted in the current edition use super::bar::Bar2; use crate::bar::Bar3; @@ -42,8 +40,6 @@ use crate::bar::Bar; //~^ ERROR absolute //~| WARN this is accepted in the current edition -//~| ERROR absolute -//~| WARN this is accepted in the current edition pub mod bar { use edition_lint_paths as foo; @@ -61,8 +57,6 @@ impl crate::foo::SomeTrait for u32 {} //~^ ERROR absolute //~| WARN this is accepted in the current edition -//~| ERROR absolute -//~| WARN this is accepted in the current edition fn main() { let x = crate::bar::Bar;
diff --git a/src/test/ui/rust-2018/edition-lint-paths.rs b/src/test/ui/rust-2018/edition-lint-paths.rs index f70bf90..e278983 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.rs +++ b/src/test/ui/rust-2018/edition-lint-paths.rs
@@ -12,8 +12,6 @@ pub mod foo { use bar::Bar; //~^ ERROR absolute //~| WARN this is accepted in the current edition - //~| ERROR absolute - //~| WARN this is accepted in the current edition use super::bar::Bar2; use crate::bar::Bar3; @@ -42,8 +40,6 @@ pub trait SomeTrait {} use bar::Bar; //~^ ERROR absolute //~| WARN this is accepted in the current edition -//~| ERROR absolute -//~| WARN this is accepted in the current edition pub mod bar { use edition_lint_paths as foo; @@ -61,8 +57,6 @@ mod baz { impl ::foo::SomeTrait for u32 {} //~^ ERROR absolute //~| WARN this is accepted in the current edition -//~| ERROR absolute -//~| WARN this is accepted in the current edition fn main() { let x = ::bar::Bar;
diff --git a/src/test/ui/rust-2018/edition-lint-paths.stderr b/src/test/ui/rust-2018/edition-lint-paths.stderr index 481c68e..1ded8cd 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-paths.stderr
@@ -13,16 +13,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:12:9 - | -LL | use bar::Bar; - | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:21:9 + --> $DIR/edition-lint-paths.rs:19:9 | LL | use bar; | ^^^ help: use `crate`: `crate::bar` @@ -31,7 +22,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:27:9 + --> $DIR/edition-lint-paths.rs:25:9 | LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` @@ -40,7 +31,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:27:9 + --> $DIR/edition-lint-paths.rs:25:9 | LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` @@ -49,7 +40,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:27:9 + --> $DIR/edition-lint-paths.rs:25:9 | LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` @@ -58,7 +49,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:42:5 + --> $DIR/edition-lint-paths.rs:40:5 | LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` @@ -67,16 +58,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:42:5 - | -LL | use bar::Bar; - | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:56:9 + --> $DIR/edition-lint-paths.rs:52:9 | LL | use *; | ^ help: use `crate`: `crate::*` @@ -85,7 +67,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:61:6 + --> $DIR/edition-lint-paths.rs:57:6 | LL | impl ::foo::SomeTrait for u32 {} | ^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::SomeTrait` @@ -94,16 +76,7 @@ = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:61:6 - | -LL | impl ::foo::SomeTrait for u32 {} - | ^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::SomeTrait` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:68:13 + --> $DIR/edition-lint-paths.rs:62:13 | LL | let x = ::bar::Bar; | ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar` @@ -111,5 +84,5 @@ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> -error: aborting due to 12 previous errors +error: aborting due to 9 previous errors
diff --git a/src/test/ui/rust-2018/extern-crate-rename.fixed b/src/test/ui/rust-2018/extern-crate-rename.fixed index 05b881a..ea832ef 100644 --- a/src/test/ui/rust-2018/extern-crate-rename.fixed +++ b/src/test/ui/rust-2018/extern-crate-rename.fixed
@@ -12,8 +12,6 @@ use crate::my_crate::foo; //~^ ERROR absolute paths must start //~| WARNING this is accepted in the current edition -//~| ERROR absolute paths must start -//~| WARNING this is accepted in the current edition fn main() { foo();
diff --git a/src/test/ui/rust-2018/extern-crate-rename.rs b/src/test/ui/rust-2018/extern-crate-rename.rs index 6e327be..b1f617d 100644 --- a/src/test/ui/rust-2018/extern-crate-rename.rs +++ b/src/test/ui/rust-2018/extern-crate-rename.rs
@@ -12,8 +12,6 @@ use my_crate::foo; //~^ ERROR absolute paths must start //~| WARNING this is accepted in the current edition -//~| ERROR absolute paths must start -//~| WARNING this is accepted in the current edition fn main() { foo();
diff --git a/src/test/ui/rust-2018/extern-crate-rename.stderr b/src/test/ui/rust-2018/extern-crate-rename.stderr index f2f379c..4bccbc5 100644 --- a/src/test/ui/rust-2018/extern-crate-rename.stderr +++ b/src/test/ui/rust-2018/extern-crate-rename.stderr
@@ -12,14 +12,5 @@ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/extern-crate-rename.rs:12:5 - | -LL | use my_crate::foo; - | ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: aborting due to 2 previous errors +error: aborting due to previous error
diff --git a/src/test/ui/rust-2018/extern-crate-submod.fixed b/src/test/ui/rust-2018/extern-crate-submod.fixed index fdbd893..9b0b0dd 100644 --- a/src/test/ui/rust-2018/extern-crate-submod.fixed +++ b/src/test/ui/rust-2018/extern-crate-submod.fixed
@@ -19,9 +19,6 @@ use crate::m::edition_lint_paths::foo; //~^ ERROR absolute paths must start //~| WARNING this is accepted in the current edition -//~| ERROR absolute paths must start -//~| WARNING this is accepted in the current edition - fn main() { foo();
diff --git a/src/test/ui/rust-2018/extern-crate-submod.rs b/src/test/ui/rust-2018/extern-crate-submod.rs index c2b9158..dfce912 100644 --- a/src/test/ui/rust-2018/extern-crate-submod.rs +++ b/src/test/ui/rust-2018/extern-crate-submod.rs
@@ -19,9 +19,6 @@ mod m { use m::edition_lint_paths::foo; //~^ ERROR absolute paths must start //~| WARNING this is accepted in the current edition -//~| ERROR absolute paths must start -//~| WARNING this is accepted in the current edition - fn main() { foo();
diff --git a/src/test/ui/rust-2018/extern-crate-submod.stderr b/src/test/ui/rust-2018/extern-crate-submod.stderr index c4c3168..3c75319 100644 --- a/src/test/ui/rust-2018/extern-crate-submod.stderr +++ b/src/test/ui/rust-2018/extern-crate-submod.stderr
@@ -12,14 +12,5 @@ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> -error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/extern-crate-submod.rs:19:5 - | -LL | use m::edition_lint_paths::foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> - -error: aborting due to 2 previous errors +error: aborting due to previous error
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 8f8f114..855a6a6 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs
@@ -178,8 +178,8 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // a .span_bug or .bug call has already printed what // it wants to print. if !info.payload().is::<rustc_errors::ExplicitBug>() { - let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); - handler.emit_diagnostic(&d); + let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); + handler.emit_diagnostic(&mut d); } let version_info = rustc_tools_util::get_version_info!();
diff --git a/src/tools/miri b/src/tools/miri index 16c69fd..346f8f2 160000 --- a/src/tools/miri +++ b/src/tools/miri
@@ -1 +1 @@ -Subproject commit 16c69fd2901b49148bff6f24292e7fc98967d7f1 +Subproject commit 346f8f2219562dae3fce5a35cc7eed4df8353b6c
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index a34ceed..412f443 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs
@@ -225,8 +225,10 @@ pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option<Lrc<St // Methods that should be restricted within the parse module. impl ParseSess { pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) { - for diagnostic in diagnostics { - self.parse_sess.span_diagnostic.emit_diagnostic(&diagnostic); + for mut diagnostic in diagnostics { + self.parse_sess + .span_diagnostic + .emit_diagnostic(&mut diagnostic); } }