Skip to content

Commit ae88766

Browse files
authored
Rollup merge of #123703 - estebank:diag-changes-2, r=Nadrieril
Use `fn` ptr signature instead of `{closure@..}` in infer error When suggesting a type on inference error, do not use `{closure@..}`. Instead, replace with an appropriate `fn` ptr. On the error message, use `short_ty_string` and write long types to disk. ``` error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt' = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` instead of ``` error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` Address #123630 (test missing).
2 parents d7d5be0 + 796be88 commit ae88766

29 files changed

+98
-47
lines changed

compiler/rustc_infer/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ infer_fps_items_are_distinct = fn items are distinct from fn pointers
144144
infer_fps_remove_ref = consider removing the reference
145145
infer_fps_use_ref = consider using a reference
146146
infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
147+
148+
infer_full_type_written = the full type name has been written to '{$path}'
149+
147150
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
148151
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
149152
infer_label_bad = {$bad_kind ->

compiler/rustc_infer/src/errors/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use crate::infer::error_reporting::{
1818
ObligationCauseAsDiagArg,
1919
};
2020

21+
use std::path::PathBuf;
22+
2123
pub mod note_and_explain;
2224

2325
#[derive(Diagnostic)]
@@ -47,6 +49,9 @@ pub struct AnnotationRequired<'a> {
4749
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
4850
#[subdiagnostic]
4951
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
52+
#[note(infer_full_type_written)]
53+
pub was_written: Option<()>,
54+
pub path: PathBuf,
5055
}
5156

5257
// Copy of `AnnotationRequired` for E0283
@@ -65,6 +70,9 @@ pub struct AmbiguousImpl<'a> {
6570
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
6671
#[subdiagnostic]
6772
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
73+
#[note(infer_full_type_written)]
74+
pub was_written: Option<()>,
75+
pub path: PathBuf,
6876
}
6977

7078
// Copy of `AnnotationRequired` for E0284
@@ -83,6 +91,9 @@ pub struct AmbiguousReturn<'a> {
8391
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
8492
#[subdiagnostic]
8593
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
94+
#[note(infer_full_type_written)]
95+
pub was_written: Option<()>,
96+
pub path: PathBuf,
8697
}
8798

8899
// Used when a better one isn't available

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

+56-19
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ use rustc_middle::infer::unify_key::{
1818
};
1919
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
2020
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
21-
use rustc_middle::ty::{self, InferConst};
22-
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
23-
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
21+
use rustc_middle::ty::{
22+
self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt,
23+
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
24+
};
2425
use rustc_span::symbol::{kw, sym, Ident};
25-
use rustc_span::{BytePos, Span};
26+
use rustc_span::{BytePos, Span, DUMMY_SP};
2627
use std::borrow::Cow;
2728
use std::iter;
29+
use std::path::PathBuf;
2830

2931
pub enum TypeAnnotationNeeded {
3032
/// ```compile_fail,E0282
@@ -153,6 +155,29 @@ impl UnderspecifiedArgKind {
153155
}
154156
}
155157

158+
struct ClosureEraser<'tcx> {
159+
tcx: TyCtxt<'tcx>,
160+
}
161+
162+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
163+
fn interner(&self) -> TyCtxt<'tcx> {
164+
self.tcx
165+
}
166+
167+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
168+
match ty.kind() {
169+
ty::Closure(_, args) => {
170+
let closure_sig = args.as_closure().sig();
171+
Ty::new_fn_ptr(
172+
self.tcx,
173+
self.tcx.signature_unclosure(closure_sig, hir::Unsafety::Normal),
174+
)
175+
}
176+
_ => ty.super_fold_with(self),
177+
}
178+
}
179+
}
180+
156181
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
157182
let mut printer = FmtPrinter::new(infcx.tcx, ns);
158183
let ty_getter = move |ty_vid| {
@@ -209,6 +234,10 @@ fn ty_to_string<'tcx>(
209234
) -> String {
210235
let mut printer = fmt_printer(infcx, Namespace::TypeNS);
211236
let ty = infcx.resolve_vars_if_possible(ty);
237+
// We use `fn` ptr syntax for closures, but this only works when the closure
238+
// does not capture anything.
239+
let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx });
240+
212241
match (ty.kind(), called_method_def_id) {
213242
// We don't want the regular output for `fn`s because it includes its path in
214243
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
@@ -223,11 +252,6 @@ fn ty_to_string<'tcx>(
223252
"Vec<_>".to_string()
224253
}
225254
_ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
226-
// FIXME: The same thing for closures, but this only works when the closure
227-
// does not capture anything.
228-
//
229-
// We do have to hide the `extern "rust-call"` ABI in that case though,
230-
// which is too much of a bother for now.
231255
_ => {
232256
ty.print(&mut printer).unwrap();
233257
printer.into_buffer()
@@ -387,6 +411,8 @@ impl<'tcx> InferCtxt<'tcx> {
387411
infer_subdiags,
388412
multi_suggestions,
389413
bad_label,
414+
was_written: None,
415+
path: Default::default(),
390416
}),
391417
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
392418
span,
@@ -396,6 +422,8 @@ impl<'tcx> InferCtxt<'tcx> {
396422
infer_subdiags,
397423
multi_suggestions,
398424
bad_label,
425+
was_written: None,
426+
path: Default::default(),
399427
}),
400428
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
401429
span,
@@ -405,6 +433,8 @@ impl<'tcx> InferCtxt<'tcx> {
405433
infer_subdiags,
406434
multi_suggestions,
407435
bad_label,
436+
was_written: None,
437+
path: Default::default(),
408438
}),
409439
}
410440
}
@@ -442,7 +472,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
442472
return self.bad_inference_failure_err(failure_span, arg_data, error_code);
443473
};
444474

445-
let (source_kind, name) = kind.ty_localized_msg(self);
475+
let (source_kind, name, path) = kind.ty_localized_msg(self);
446476
let failure_span = if should_label_span && !failure_span.overlaps(span) {
447477
Some(failure_span)
448478
} else {
@@ -518,15 +548,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
518548
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
519549
GenericArgKind::Type(_) => self
520550
.next_ty_var(TypeVariableOrigin {
521-
span: rustc_span::DUMMY_SP,
551+
span: DUMMY_SP,
522552
kind: TypeVariableOriginKind::MiscVariable,
523553
})
524554
.into(),
525555
GenericArgKind::Const(arg) => self
526556
.next_const_var(
527557
arg.ty(),
528558
ConstVariableOrigin {
529-
span: rustc_span::DUMMY_SP,
559+
span: DUMMY_SP,
530560
kind: ConstVariableOriginKind::MiscVariable,
531561
},
532562
)
@@ -547,7 +577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
547577
}
548578
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
549579
let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
550-
span: rustc_span::DUMMY_SP,
580+
span: DUMMY_SP,
551581
kind: TypeVariableOriginKind::MiscVariable,
552582
}));
553583
if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) {
@@ -584,7 +614,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
584614
}
585615
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
586616
let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
587-
span: rustc_span::DUMMY_SP,
617+
span: DUMMY_SP,
588618
kind: TypeVariableOriginKind::MiscVariable,
589619
}));
590620
if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) {
@@ -606,6 +636,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
606636
infer_subdiags,
607637
multi_suggestions,
608638
bad_label: None,
639+
was_written: path.as_ref().map(|_| ()),
640+
path: path.unwrap_or_default(),
609641
}),
610642
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
611643
span,
@@ -615,6 +647,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
615647
infer_subdiags,
616648
multi_suggestions,
617649
bad_label: None,
650+
was_written: path.as_ref().map(|_| ()),
651+
path: path.unwrap_or_default(),
618652
}),
619653
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
620654
span,
@@ -624,6 +658,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
624658
infer_subdiags,
625659
multi_suggestions,
626660
bad_label: None,
661+
was_written: path.as_ref().map(|_| ()),
662+
path: path.unwrap_or_default(),
627663
}),
628664
}
629665
}
@@ -688,22 +724,23 @@ impl<'tcx> InferSource<'tcx> {
688724
}
689725

690726
impl<'tcx> InferSourceKind<'tcx> {
691-
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String) {
727+
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option<PathBuf>) {
728+
let mut path = None;
692729
match *self {
693730
InferSourceKind::LetBinding { ty, .. }
694731
| InferSourceKind::ClosureArg { ty, .. }
695732
| InferSourceKind::ClosureReturn { ty, .. } => {
696733
if ty.is_closure() {
697-
("closure", closure_as_fn_str(infcx, ty))
734+
("closure", closure_as_fn_str(infcx, ty), path)
698735
} else if !ty.is_ty_or_numeric_infer() {
699-
("normal", ty_to_string(infcx, ty, None))
736+
("normal", infcx.tcx.short_ty_string(ty, &mut path), path)
700737
} else {
701-
("other", String::new())
738+
("other", String::new(), path)
702739
}
703740
}
704741
// FIXME: We should be able to add some additional info here.
705742
InferSourceKind::GenericArg { .. }
706-
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()),
743+
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new(), path),
707744
}
708745
}
709746
}

tests/ui/array-slice-vec/vector-no-ann.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `Vec<T>`
1+
error[E0282]: type annotations needed for `Vec<_>`
22
--> $DIR/vector-no-ann.rs:2:9
33
|
44
LL | let _foo = Vec::new();

tests/ui/const-generics/defaults/doesnt_infer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ impl<const N: u32> Foo<N> {
99
fn main() {
1010
let foo = Foo::<1>::foo();
1111
let foo = Foo::foo();
12-
//~^ error: type annotations needed for `Foo<N>`
12+
//~^ ERROR type annotations needed for `Foo<_>`
1313
}

tests/ui/const-generics/defaults/doesnt_infer.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `Foo<N>`
1+
error[E0282]: type annotations needed for `Foo<_>`
22
--> $DIR/doesnt_infer.rs:11:9
33
|
44
LL | let foo = Foo::foo();

tests/ui/const-generics/generic_arg_infer/issue-91614.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0283]: type annotations needed for `Mask<_, N>`
1+
error[E0283]: type annotations needed for `Mask<_, _>`
22
--> $DIR/issue-91614.rs:6:9
33
|
44
LL | let y = Mask::<_, _>::splat(false);

tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ help: try adding a `where` bound
1818
LL | pub const fn new() -> Self where [(); Self::SIZE]: {
1919
| +++++++++++++++++++++++
2020

21-
error[E0282]: type annotations needed for `ArrayHolder<X>`
21+
error[E0282]: type annotations needed for `ArrayHolder<_>`
2222
--> $DIR/issue-62504.rs:26:9
2323
|
2424
LL | let mut array = ArrayHolder::new();

tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ note: tuple struct defined here
2222
LL | struct ArrayHolder<const X: usize>([u32; X]);
2323
| ^^^^^^^^^^^
2424

25-
error[E0282]: type annotations needed for `ArrayHolder<X>`
25+
error[E0282]: type annotations needed for `ArrayHolder<_>`
2626
--> $DIR/issue-62504.rs:26:9
2727
|
2828
LL | let mut array = ArrayHolder::new();

tests/ui/generic-const-items/inference-failure.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `Option<T>`
1+
error[E0282]: type annotations needed for `Option<_>`
22
--> $DIR/inference-failure.rs:8:9
33
|
44
LL | let _ = NONE;

tests/ui/generic-const-items/parameter-defaults.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
44
LL | const NONE<T = ()>: Option<T> = None::<T>;
55
| ^^^^^^
66

7-
error[E0282]: type annotations needed for `Option<T>`
7+
error[E0282]: type annotations needed for `Option<_>`
88
--> $DIR/parameter-defaults.rs:13:9
99
|
1010
LL | let _ = NONE;

tests/ui/inference/cannot-infer-closure-circular.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn main() {
44
// error handles this gracefully, and in particular doesn't generate an extra
55
// note about the `?` operator in the closure body, which isn't relevant to
66
// the inference.
7-
let x = |r| { //~ ERROR type annotations needed for `Result<(), E>`
7+
let x = |r| { //~ ERROR type annotations needed for `Result<(), _>`
88
let v = r?;
99
Ok(v)
1010
};

tests/ui/inference/cannot-infer-closure-circular.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `Result<(), E>`
1+
error[E0282]: type annotations needed for `Result<(), _>`
22
--> $DIR/cannot-infer-closure-circular.rs:7:14
33
|
44
LL | let x = |r| {

tests/ui/inference/erase-type-params-in-label.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>`
1+
error[E0283]: type annotations needed for `Foo<i32, &str, _, _>`
22
--> $DIR/erase-type-params-in-label.rs:2:9
33
|
44
LL | let foo = foo(1, "");
@@ -15,7 +15,7 @@ help: consider giving `foo` an explicit type, where the type for type parameter
1515
LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
1616
| ++++++++++++++++++++++
1717

18-
error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
18+
error[E0283]: type annotations needed for `Bar<i32, &str, _>`
1919
--> $DIR/erase-type-params-in-label.rs:5:9
2020
|
2121
LL | let bar = bar(1, "");

tests/ui/inference/issue-104649.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>`
1+
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), _>, Error>>`
22
--> $DIR/issue-104649.rs:24:9
33
|
44
LL | let a = A(Result::Ok(Result::Ok(())));

tests/ui/inference/issue-72690.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ help: try using a fully qualified path to specify the expected types
5050
LL | |x| String::from(<str as AsRef<T>>::as_ref("x"));
5151
| ++++++++++++++++++++++++++ ~
5252

53-
error[E0283]: type annotations needed for `&T`
53+
error[E0283]: type annotations needed for `&_`
5454
--> $DIR/issue-72690.rs:17:9
5555
|
5656
LL | let _ = "x".as_ref();

tests/ui/inference/issue-83606.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
66

77
fn main() {
88
let _ = foo("foo");
9-
//~^ ERROR: type annotations needed for `[usize; N]`
9+
//~^ ERROR type annotations needed for `[usize; _]`
1010
}

tests/ui/inference/issue-83606.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `[usize; N]`
1+
error[E0282]: type annotations needed for `[usize; _]`
22
--> $DIR/issue-83606.rs:8:9
33
|
44
LL | let _ = foo("foo");

tests/ui/issues/issue-12187-1.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `&T`
1+
error[E0282]: type annotations needed for `&_`
22
--> $DIR/issue-12187-1.rs:6:9
33
|
44
LL | let &v = new();

tests/ui/issues/issue-12187-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `&T`
1+
error[E0282]: type annotations needed for `&_`
22
--> $DIR/issue-12187-2.rs:6:9
33
|
44
LL | let &v = new();

tests/ui/issues/issue-17551.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `B<T>`
1+
error[E0282]: type annotations needed for `B<_>`
22
--> $DIR/issue-17551.rs:6:9
33
|
44
LL | let foo = B(marker::PhantomData);

tests/ui/issues/issue-23046.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `Expr<'_, VAR>`
1+
error[E0282]: type annotations needed for `Expr<'_, _>`
22
--> $DIR/issue-23046.rs:17:15
33
|
44
LL | let ex = |x| {

tests/ui/issues/issue-98299.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0282]: type annotations needed for `SmallCString<N>`
1+
error[E0282]: type annotations needed for `SmallCString<_>`
22
--> $DIR/issue-98299.rs:4:36
33
|
44
LL | SmallCString::try_from(p).map(|cstr| cstr);

0 commit comments

Comments
 (0)