Skip to content

Commit 4cb986b

Browse files
committed
Auto merge of rust-lang#122041 - matthiaskrgr:rollup-imsmdke, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#121202 (Limit the number of names and values in check-cfg diagnostics) - rust-lang#121301 (errors: share `SilentEmitter` between rustc and rustfmt) - rust-lang#121658 (Hint user to update nightly on ICEs produced from outdated nightly) - rust-lang#121846 (only compare ambiguity item that have hard error) - rust-lang#121961 (add test for rust-lang#78894 rust-lang#71450) - rust-lang#121975 (hir_analysis: enums return `None` in `find_field`) - rust-lang#121978 (Fix duplicated path in the "not found dylib" error) - rust-lang#121991 (Merge impl_trait_in_assoc_types_defined_by query back into `opaque_types_defined_by`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3c02972 + 3d6b3d0 commit 4cb986b

37 files changed

+584
-220
lines changed

compiler/rustc_driver_impl/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
5050
rustc_ty_utils = { path = "../rustc_ty_utils" }
5151
serde_json = "1.0.59"
5252
shlex = "1.0"
53-
time = { version = "0.3", default-features = false, features = ["alloc", "formatting"] }
53+
time = { version = "0.3", default-features = false, features = ["alloc", "formatting", "parsing", "macros"] }
5454
tracing = { version = "0.1.35" }
5555
# tidy-alphabetical-end
5656

compiler/rustc_driver_impl/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
22
driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
33
driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly
4+
driver_impl_ice_bug_report_outdated =
5+
it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the mean time
6+
.update = please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
7+
.url = if the problem still persists, we would appreciate a bug report: {$bug_report_url}
48
driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden
59
610
driver_impl_ice_flags = compiler flags: {$flags}

compiler/rustc_driver_impl/src/lib.rs

+31-4
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use std::str;
5858
use std::sync::atomic::{AtomicBool, Ordering};
5959
use std::sync::{Arc, OnceLock};
6060
use std::time::{Instant, SystemTime};
61-
use time::OffsetDateTime;
61+
use time::{Date, OffsetDateTime, Time};
6262

6363
#[allow(unused_macros)]
6464
macro do_not_use_print($($t:tt)*) {
@@ -1369,6 +1369,9 @@ pub fn install_ice_hook(
13691369
using_internal_features
13701370
}
13711371

1372+
const DATE_FORMAT: &[time::format_description::FormatItem<'static>] =
1373+
&time::macros::format_description!("[year]-[month]-[day]");
1374+
13721375
/// Prints the ICE message, including query stack, but without backtrace.
13731376
///
13741377
/// The message will point the user at `bug_report_url` to report the ICE.
@@ -1397,10 +1400,34 @@ fn report_ice(
13971400
dcx.emit_err(session_diagnostics::Ice);
13981401
}
13991402

1400-
if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
1401-
dcx.emit_note(session_diagnostics::IceBugReportInternalFeature);
1403+
use time::ext::NumericalDuration;
1404+
1405+
// Try to hint user to update nightly if applicable when reporting an ICE.
1406+
// Attempt to calculate when current version was released, and add 12 hours
1407+
// as buffer. If the current version's release timestamp is older than
1408+
// the system's current time + 24 hours + 12 hours buffer if we're on
1409+
// nightly.
1410+
if let Some("nightly") = option_env!("CFG_RELEASE_CHANNEL")
1411+
&& let Some(version) = option_env!("CFG_VERSION")
1412+
&& let Some(ver_date_str) = option_env!("CFG_VER_DATE")
1413+
&& let Ok(ver_date) = Date::parse(&ver_date_str, DATE_FORMAT)
1414+
&& let ver_datetime = OffsetDateTime::new_utc(ver_date, Time::MIDNIGHT)
1415+
&& let system_datetime = OffsetDateTime::from(SystemTime::now())
1416+
&& system_datetime.checked_sub(36.hours()).is_some_and(|d| d > ver_datetime)
1417+
&& !using_internal_features.load(std::sync::atomic::Ordering::Relaxed)
1418+
{
1419+
dcx.emit_note(session_diagnostics::IceBugReportOutdated {
1420+
version,
1421+
bug_report_url,
1422+
note_update: (),
1423+
note_url: (),
1424+
});
14021425
} else {
1403-
dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1426+
if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
1427+
dcx.emit_note(session_diagnostics::IceBugReportInternalFeature);
1428+
} else {
1429+
dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1430+
}
14041431
}
14051432

14061433
let version = util::version_str!().unwrap_or("unknown_version");

compiler/rustc_driver_impl/src/session_diagnostics.rs

+11
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ pub(crate) struct IceBugReport<'a> {
4646
#[diag(driver_impl_ice_bug_report_internal_feature)]
4747
pub(crate) struct IceBugReportInternalFeature;
4848

49+
#[derive(Diagnostic)]
50+
#[diag(driver_impl_ice_bug_report_outdated)]
51+
pub(crate) struct IceBugReportOutdated<'a> {
52+
pub version: &'a str,
53+
pub bug_report_url: &'a str,
54+
#[note(driver_impl_update)]
55+
pub note_update: (),
56+
#[note(driver_impl_url)]
57+
pub note_url: (),
58+
}
59+
4960
#[derive(Diagnostic)]
5061
#[diag(driver_impl_ice_version)]
5162
pub(crate) struct IceVersion<'a> {

compiler/rustc_errors/src/emitter.rs

+8-24
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use rustc_span::source_map::SourceMap;
1111
use rustc_span::{FileLines, FileName, SourceFile, Span};
1212

13-
use crate::error::TranslateError;
1413
use crate::snippet::{
1514
Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
1615
};
@@ -539,18 +538,9 @@ impl Emitter for HumanEmitter {
539538
/// Fatal diagnostics are forwarded to `fatal_dcx` to avoid silent
540539
/// failures of rustc, as witnessed e.g. in issue #89358.
541540
pub struct SilentEmitter {
541+
pub fallback_bundle: LazyFallbackBundle,
542542
pub fatal_dcx: DiagCtxt,
543-
pub fatal_note: String,
544-
}
545-
546-
pub fn silent_translate<'a>(message: &'a DiagMessage) -> Result<Cow<'_, str>, TranslateError<'_>> {
547-
match message {
548-
DiagMessage::Str(msg) | DiagMessage::Translated(msg) => Ok(Cow::Borrowed(msg)),
549-
DiagMessage::FluentIdentifier(identifier, _) => {
550-
// Any value works here.
551-
Ok(identifier.clone())
552-
}
553-
}
543+
pub fatal_note: Option<String>,
554544
}
555545

556546
impl Translate for SilentEmitter {
@@ -559,17 +549,9 @@ impl Translate for SilentEmitter {
559549
}
560550

561551
fn fallback_fluent_bundle(&self) -> &FluentBundle {
562-
panic!("silent emitter attempted to translate message")
563-
}
564-
565-
// Override `translate_message` for the silent emitter because eager translation of
566-
// subdiagnostics result in a call to this.
567-
fn translate_message<'a>(
568-
&'a self,
569-
message: &'a DiagMessage,
570-
_: &'a FluentArgs<'_>,
571-
) -> Result<Cow<'_, str>, TranslateError<'_>> {
572-
silent_translate(message)
552+
// Ideally this field wouldn't be necessary and the fallback bundle in `fatal_dcx` would be
553+
// used but the lock prevents this.
554+
&self.fallback_bundle
573555
}
574556
}
575557

@@ -580,7 +562,9 @@ impl Emitter for SilentEmitter {
580562

581563
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
582564
if diag.level == Level::Fatal {
583-
diag.sub(Level::Note, self.fatal_note.clone(), MultiSpan::new());
565+
if let Some(fatal_note) = &self.fatal_note {
566+
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
567+
}
584568
self.fatal_dcx.emit_diagnostic(diag);
585569
}
586570
}

compiler/rustc_errors/src/lib.rs

+72-23
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use emitter::{is_case_difference, DynEmitter, Emitter};
6363
use registry::Registry;
6464
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
6565
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
66-
use rustc_data_structures::sync::Lock;
66+
use rustc_data_structures::sync::{Lock, Lrc};
6767
use rustc_data_structures::AtomicRef;
6868
use rustc_lint_defs::LintExpectationId;
6969
use rustc_span::source_map::SourceMap;
@@ -606,29 +606,54 @@ impl DiagCtxt {
606606
}
607607

608608
pub fn new(emitter: Box<DynEmitter>) -> Self {
609-
Self {
610-
inner: Lock::new(DiagCtxtInner {
611-
flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
612-
err_guars: Vec::new(),
613-
lint_err_guars: Vec::new(),
614-
delayed_bugs: Vec::new(),
615-
deduplicated_err_count: 0,
616-
deduplicated_warn_count: 0,
617-
emitter,
618-
must_produce_diag: false,
619-
has_printed: false,
620-
suppressed_expected_diag: false,
621-
taught_diagnostics: Default::default(),
622-
emitted_diagnostic_codes: Default::default(),
623-
emitted_diagnostics: Default::default(),
624-
stashed_diagnostics: Default::default(),
625-
future_breakage_diagnostics: Vec::new(),
626-
check_unstable_expect_diagnostics: false,
627-
unstable_expect_diagnostics: Vec::new(),
628-
fulfilled_expectations: Default::default(),
629-
ice_file: None,
630-
}),
609+
Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
610+
}
611+
612+
pub fn make_silent(&mut self, fallback_bundle: LazyFallbackBundle, fatal_note: Option<String>) {
613+
self.wrap_emitter(|old_dcx| {
614+
Box::new(emitter::SilentEmitter {
615+
fallback_bundle,
616+
fatal_dcx: DiagCtxt { inner: Lock::new(old_dcx) },
617+
fatal_note,
618+
})
619+
});
620+
}
621+
622+
fn wrap_emitter<F>(&mut self, f: F)
623+
where
624+
F: FnOnce(DiagCtxtInner) -> Box<DynEmitter>,
625+
{
626+
// A empty type that implements `Emitter` so that a `DiagCtxtInner` can be constructed
627+
// to temporarily swap in place of the real one, which will be used in constructing
628+
// its replacement.
629+
struct FalseEmitter;
630+
631+
impl Emitter for FalseEmitter {
632+
fn emit_diagnostic(&mut self, _: DiagInner) {
633+
unimplemented!("false emitter must only used during `wrap_emitter`")
634+
}
635+
636+
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
637+
unimplemented!("false emitter must only used during `wrap_emitter`")
638+
}
631639
}
640+
641+
impl translation::Translate for FalseEmitter {
642+
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
643+
unimplemented!("false emitter must only used during `wrap_emitter`")
644+
}
645+
646+
fn fallback_fluent_bundle(&self) -> &FluentBundle {
647+
unimplemented!("false emitter must only used during `wrap_emitter`")
648+
}
649+
}
650+
651+
let mut inner = self.inner.borrow_mut();
652+
let mut prev_dcx = DiagCtxtInner::new(Box::new(FalseEmitter));
653+
std::mem::swap(&mut *inner, &mut prev_dcx);
654+
let new_emitter = f(prev_dcx);
655+
let mut new_dcx = DiagCtxtInner::new(new_emitter);
656+
std::mem::swap(&mut *inner, &mut new_dcx);
632657
}
633658

634659
/// Translate `message` eagerly with `args` to `SubdiagMessage::Eager`.
@@ -1345,6 +1370,30 @@ impl DiagCtxt {
13451370
// `DiagCtxt::foo()` just borrows `inner` and forwards a call to
13461371
// `DiagCtxtInner::foo`.
13471372
impl DiagCtxtInner {
1373+
fn new(emitter: Box<DynEmitter>) -> Self {
1374+
Self {
1375+
flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
1376+
err_guars: Vec::new(),
1377+
lint_err_guars: Vec::new(),
1378+
delayed_bugs: Vec::new(),
1379+
deduplicated_err_count: 0,
1380+
deduplicated_warn_count: 0,
1381+
emitter,
1382+
must_produce_diag: false,
1383+
has_printed: false,
1384+
suppressed_expected_diag: false,
1385+
taught_diagnostics: Default::default(),
1386+
emitted_diagnostic_codes: Default::default(),
1387+
emitted_diagnostics: Default::default(),
1388+
stashed_diagnostics: Default::default(),
1389+
future_breakage_diagnostics: Vec::new(),
1390+
check_unstable_expect_diagnostics: false,
1391+
unstable_expect_diagnostics: Vec::new(),
1392+
fulfilled_expectations: Default::default(),
1393+
ice_file: None,
1394+
}
1395+
}
1396+
13481397
/// Emit all stashed diagnostics.
13491398
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
13501399
let mut guar = None;

compiler/rustc_hir_analysis/src/collect.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,12 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
791791
}
792792

793793
fn find_field(tcx: TyCtxt<'_>, (def_id, ident): (DefId, Ident)) -> Option<FieldIdx> {
794-
tcx.adt_def(def_id).non_enum_variant().fields.iter_enumerated().find_map(|(idx, field)| {
794+
let adt = tcx.adt_def(def_id);
795+
if adt.is_enum() {
796+
return None;
797+
}
798+
799+
adt.non_enum_variant().fields.iter_enumerated().find_map(|(idx, field)| {
795800
if field.is_unnamed() {
796801
let field_ty = tcx.type_of(field.did).instantiate_identity();
797802
let adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field");

compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs

+8-20
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
4646
for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
4747
let assoc = tcx.associated_item(assoc_id);
4848
match assoc.kind {
49-
ty::AssocKind::Const | ty::AssocKind::Fn => {
50-
locator.check(assoc_id.expect_local(), ImplTraitSource::AssocTy)
51-
}
49+
ty::AssocKind::Const | ty::AssocKind::Fn => locator.check(assoc_id.expect_local()),
5250
// Associated types don't have bodies, so they can't constrain hidden types
5351
ty::AssocKind::Type => {}
5452
}
@@ -182,15 +180,9 @@ struct TaitConstraintLocator<'tcx> {
182180
typeck_types: Vec<ty::OpaqueHiddenType<'tcx>>,
183181
}
184182

185-
#[derive(Debug)]
186-
enum ImplTraitSource {
187-
AssocTy,
188-
TyAlias,
189-
}
190-
191183
impl TaitConstraintLocator<'_> {
192184
#[instrument(skip(self), level = "debug")]
193-
fn check(&mut self, item_def_id: LocalDefId, source: ImplTraitSource) {
185+
fn check(&mut self, item_def_id: LocalDefId) {
194186
// Don't try to check items that cannot possibly constrain the type.
195187
if !self.tcx.has_typeck_results(item_def_id) {
196188
debug!("no constraint: no typeck results");
@@ -242,12 +234,8 @@ impl TaitConstraintLocator<'_> {
242234
continue;
243235
}
244236
constrained = true;
245-
let opaque_types_defined_by = match source {
246-
ImplTraitSource::AssocTy => {
247-
self.tcx.impl_trait_in_assoc_types_defined_by(item_def_id)
248-
}
249-
ImplTraitSource::TyAlias => self.tcx.opaque_types_defined_by(item_def_id),
250-
};
237+
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
238+
251239
if !opaque_types_defined_by.contains(&self.def_id) {
252240
self.tcx.dcx().emit_err(TaitForwardCompat {
253241
span: hidden_type.span,
@@ -308,29 +296,29 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
308296
}
309297
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
310298
if let hir::ExprKind::Closure(closure) = ex.kind {
311-
self.check(closure.def_id, ImplTraitSource::TyAlias);
299+
self.check(closure.def_id);
312300
}
313301
intravisit::walk_expr(self, ex);
314302
}
315303
fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
316304
trace!(?it.owner_id);
317305
// The opaque type itself or its children are not within its reveal scope.
318306
if it.owner_id.def_id != self.def_id {
319-
self.check(it.owner_id.def_id, ImplTraitSource::TyAlias);
307+
self.check(it.owner_id.def_id);
320308
intravisit::walk_item(self, it);
321309
}
322310
}
323311
fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
324312
trace!(?it.owner_id);
325313
// The opaque type itself or its children are not within its reveal scope.
326314
if it.owner_id.def_id != self.def_id {
327-
self.check(it.owner_id.def_id, ImplTraitSource::TyAlias);
315+
self.check(it.owner_id.def_id);
328316
intravisit::walk_impl_item(self, it);
329317
}
330318
}
331319
fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
332320
trace!(?it.owner_id);
333-
self.check(it.owner_id.def_id, ImplTraitSource::TyAlias);
321+
self.check(it.owner_id.def_id);
334322
intravisit::walk_trait_item(self, it);
335323
}
336324
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {

compiler/rustc_interface/src/interface.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ pub struct Compiler {
4545
pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
4646
cfgs.into_iter()
4747
.map(|s| {
48-
let psess = ParseSess::with_silent_emitter(format!(
49-
"this error occurred on the command line: `--cfg={s}`"
50-
));
48+
let psess = ParseSess::with_silent_emitter(
49+
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
50+
format!("this error occurred on the command line: `--cfg={s}`"),
51+
);
5152
let filename = FileName::cfg_spec_source_code(&s);
5253

5354
macro_rules! error {
@@ -107,9 +108,10 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
107108
let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() };
108109

109110
for s in specs {
110-
let psess = ParseSess::with_silent_emitter(format!(
111-
"this error occurred on the command line: `--check-cfg={s}`"
112-
));
111+
let psess = ParseSess::with_silent_emitter(
112+
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
113+
format!("this error occurred on the command line: `--check-cfg={s}`"),
114+
);
113115
let filename = FileName::cfg_spec_source_code(&s);
114116

115117
macro_rules! error {

0 commit comments

Comments
 (0)