Skip to content

Commit b4414a1

Browse files
committed
Emit specific message for time<=0.3.35
``` error[E0282]: type annotations needed for `Box<_>` --> /home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9 | 83 | let items = format_items | ^^^^^ ... 86 | Ok(items.into()) | ---- type must be known at this point | = note: this is an inference error on `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.36` ```
1 parent 4d5b3b1 commit b4414a1

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,7 @@ symbols! {
18931893
three_way_compare,
18941894
thumb2,
18951895
thumb_mode: "thumb-mode",
1896+
time,
18961897
tmm_reg,
18971898
to_owned_method,
18981899
to_string,

compiler/rustc_trait_selection/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ trait_selection_type_annotations_needed = {$source_kind ->
446446
}
447447
.label = type must be known at this point
448448
449+
trait_selection_type_annotations_needed_error_time = this is an inference error on `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.36`
450+
449451
trait_selection_types_declared_different = these two types are declared with different lifetimes...
450452
451453
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}

compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs

+58-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_errors::codes::*;
66
use rustc_errors::{Diag, IntoDiagArg};
77
use rustc_hir as hir;
88
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
9-
use rustc_hir::def_id::{DefId, LocalDefId};
9+
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
1010
use rustc_hir::intravisit::{self, Visitor};
1111
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
1212
use rustc_middle::bug;
@@ -18,7 +18,7 @@ use rustc_middle::ty::{
1818
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
1919
};
2020
use rustc_span::symbol::{sym, Ident};
21-
use rustc_span::{BytePos, Span, DUMMY_SP};
21+
use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
2222

2323
use crate::error_reporting::TypeErrCtxt;
2424
use crate::errors::{
@@ -384,6 +384,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
384384
bad_label,
385385
was_written: None,
386386
path: Default::default(),
387+
time_version: None,
387388
}),
388389
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
389390
span,
@@ -577,6 +578,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
577578
}
578579
}
579580
}
581+
582+
let time_version = self.detect_old_time_crate_version(failure_span, &mut infer_subdiags);
583+
580584
match error_code {
581585
TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
582586
span,
@@ -588,6 +592,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
588592
bad_label: None,
589593
was_written: path.as_ref().map(|_| ()),
590594
path: path.unwrap_or_default(),
595+
time_version,
591596
}),
592597
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
593598
span,
@@ -613,6 +618,57 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
613618
}),
614619
}
615620
}
621+
622+
/// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error.
623+
/// <https://github.com/rust-lang/rust/issues/127343>
624+
// FIXME: we should figure out a more generic version of doing this, ideally in cargo itself.
625+
fn detect_old_time_crate_version(
626+
&self,
627+
span: Option<Span>,
628+
/// We will clear the non-actionable suggestion from the error to reduce noise.
629+
infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
630+
) -> Option<()> {
631+
if self.infcx.tcx.crate_name(LOCAL_CRATE) != sym::time {
632+
// Only relevant when building the `time` crate.
633+
return None;
634+
}
635+
let Some(span) = span else { return None };
636+
let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span) else {
637+
return None;
638+
};
639+
let path = file.local_path_if_available();
640+
let mut components = path.components();
641+
// We will take the filename of the error and see if it is of the form
642+
// `.../registry/src/index.crates.io-.../time-0...`, in order to detect the specific case
643+
// we care about.
644+
while let Some(component) = components.next() {
645+
let std::path::Component::Normal(component) = component else {
646+
continue;
647+
};
648+
if component == "registry"
649+
&& let Some(next) = components.next()
650+
&& let std::path::Component::Normal(next) = next
651+
&& next == "src"
652+
&& let Some(next) = components.next()
653+
&& let std::path::Component::Normal(next) = next
654+
&& next.to_string_lossy().starts_with("index.")
655+
&& let Some(next) = components.next()
656+
&& let std::path::Component::Normal(next) = next
657+
&& let next = next.to_string_lossy()
658+
&& next.starts_with("time-0.")
659+
&& let Some(version) = next.split('-').skip(1).next()
660+
&& let mut segments = version.split('.')
661+
&& let Some(major) = segments.next()
662+
&& major == "0"
663+
&& let Some(minor) = segments.next()
664+
&& minor == "3"
665+
{
666+
infer_subdiags.clear();
667+
return Some(());
668+
}
669+
}
670+
None
671+
}
616672
}
617673

618674
#[derive(Debug)]

compiler/rustc_trait_selection/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ pub struct AnnotationRequired<'a> {
205205
#[note(trait_selection_full_type_written)]
206206
pub was_written: Option<()>,
207207
pub path: PathBuf,
208+
#[note(trait_selection_type_annotations_needed_error_time)]
209+
pub time_version: Option<()>,
208210
}
209211

210212
// Copy of `AnnotationRequired` for E0283

0 commit comments

Comments
 (0)