Skip to content

Commit

Permalink
Emit specific message for time<0.3.35 inference failure
Browse files Browse the repository at this point in the history
```
error[E0282]: type annotations needed for `Box<_>`
  --> ~/.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 crate `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.35`
```

Partially address rust-lang#127343.
  • Loading branch information
estebank committed Aug 28, 2024
1 parent 100fde5 commit b013a3d
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 2 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,7 @@ symbols! {
three_way_compare,
thumb2,
thumb_mode: "thumb-mode",
time,
tmm_reg,
to_owned_method,
to_string,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_trait_selection/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ trait_selection_type_annotations_needed = {$source_kind ->
}
.label = type must be known at this point
trait_selection_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
trait_selection_types_declared_different = these two types are declared with different lifetimes...
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_errors::codes::*;
use rustc_errors::{Diag, IntoDiagArg};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
use rustc_middle::bug;
Expand All @@ -18,7 +18,7 @@ use rustc_middle::ty::{
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{BytePos, Span, DUMMY_SP};
use rustc_span::{BytePos, FileName, Span, DUMMY_SP};

use crate::error_reporting::TypeErrCtxt;
use crate::errors::{
Expand Down Expand Up @@ -384,6 +384,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
bad_label,
was_written: false,
path: Default::default(),
time_version: false,
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
Expand Down Expand Up @@ -577,6 +578,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}
}

let time_version =
self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags);

match error_code {
TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
span,
Expand All @@ -588,6 +593,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
bad_label: None,
was_written: path.is_some(),
path: path.unwrap_or_default(),
time_version,
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
Expand All @@ -613,6 +619,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}),
}
}

/// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error.
/// <https://github.com/rust-lang/rust/issues/127343>
// FIXME: we should figure out a more generic version of doing this, ideally in cargo itself.
fn detect_old_time_crate_version(
&self,
span: Option<Span>,
kind: &InferSourceKind<'_>,
// We will clear the non-actionable suggestion from the error to reduce noise.
infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
) -> bool {
// FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing
// compilation once we promote 1.89 to beta, which will happen in 9 months from now.
#[cfg(not(version("1.89")))]
const fn version_check() {}
#[cfg(version("1.89"))]
const fn version_check() {
panic!("remove this check as presumably the ecosystem has moved from needing it");
}
const { version_check() };
// Only relevant when building the `time` crate.
if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time
&& let Some(span) = span
&& let InferSourceKind::LetBinding { pattern_name, .. } = kind
&& let Some(name) = pattern_name
&& name.as_str() == "items"
&& let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span)
{
let path = file.local_path_if_available().to_string_lossy();
if path.contains("format_description") && path.contains("parse") {
infer_subdiags.clear();
return true;
}
}
false
}
}

#[derive(Debug)]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_trait_selection/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ pub struct AnnotationRequired<'a> {
#[note(trait_selection_full_type_written)]
pub was_written: bool,
pub path: PathBuf,
#[note(trait_selection_type_annotations_needed_error_time)]
pub time_version: bool,
}

// Copy of `AnnotationRequired` for E0283
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_trait_selection/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(cfg_version)]
#![feature(control_flow_enum)]
#![feature(extract_if)]
#![feature(if_let_guard)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![crate_name = "time"]

fn main() {
let items = Box::new(vec![]); //~ ERROR E0282
//~^ NOTE type must be known at this point
//~| NOTE this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35`
items.into();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0282]: type annotations needed for `Box<Vec<_>>`
--> $DIR/detect-old-time-version-format_description-parse.rs:4:9
|
LL | let items = Box::new(vec![]);
| ^^^^^ ---------------- type must be known at this point
|
= note: this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0282`.

0 comments on commit b013a3d

Please sign in to comment.