Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fn ptr signature instead of {closure@..} in infer error #123703

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_infer/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ infer_fps_items_are_distinct = fn items are distinct from fn pointers
infer_fps_remove_ref = consider removing the reference
infer_fps_use_ref = consider using a reference
infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime

infer_full_type_written = the full type name has been written to '{$path}'

infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
infer_label_bad = {$bad_kind ->
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_infer/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use crate::infer::error_reporting::{
ObligationCauseAsDiagArg,
};

use std::path::PathBuf;

pub mod note_and_explain;

#[derive(Diagnostic)]
Expand Down Expand Up @@ -47,6 +49,9 @@ pub struct AnnotationRequired<'a> {
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
}

// Copy of `AnnotationRequired` for E0283
Expand All @@ -65,6 +70,9 @@ pub struct AmbiguousImpl<'a> {
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
}

// Copy of `AnnotationRequired` for E0284
Expand All @@ -83,6 +91,9 @@ pub struct AmbiguousReturn<'a> {
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
}

// Used when a better one isn't available
Expand Down
75 changes: 56 additions & 19 deletions compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ use rustc_middle::infer::unify_key::{
};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
use rustc_middle::ty::{self, InferConst};
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
use rustc_middle::ty::{
self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt,
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span};
use rustc_span::{BytePos, Span, DUMMY_SP};
use std::borrow::Cow;
use std::iter;
use std::path::PathBuf;

pub enum TypeAnnotationNeeded {
/// ```compile_fail,E0282
Expand Down Expand Up @@ -153,6 +155,29 @@ impl UnderspecifiedArgKind {
}
}

struct ClosureEraser<'tcx> {
tcx: TyCtxt<'tcx>,
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match ty.kind() {
ty::Closure(_, args) => {
let closure_sig = args.as_closure().sig();
Ty::new_fn_ptr(
self.tcx,
self.tcx.signature_unclosure(closure_sig, hir::Unsafety::Normal),
)
}
_ => ty.super_fold_with(self),
}
}
}

fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
let mut printer = FmtPrinter::new(infcx.tcx, ns);
let ty_getter = move |ty_vid| {
Expand Down Expand Up @@ -209,6 +234,10 @@ fn ty_to_string<'tcx>(
) -> String {
let mut printer = fmt_printer(infcx, Namespace::TypeNS);
let ty = infcx.resolve_vars_if_possible(ty);
// We use `fn` ptr syntax for closures, but this only works when the closure
// does not capture anything.
let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx });

match (ty.kind(), called_method_def_id) {
// We don't want the regular output for `fn`s because it includes its path in
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
Expand All @@ -223,11 +252,6 @@ fn ty_to_string<'tcx>(
"Vec<_>".to_string()
}
_ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
// FIXME: The same thing for closures, but this only works when the closure
// does not capture anything.
//
// We do have to hide the `extern "rust-call"` ABI in that case though,
// which is too much of a bother for now.
_ => {
ty.print(&mut printer).unwrap();
printer.into_buffer()
Expand Down Expand Up @@ -387,6 +411,8 @@ impl<'tcx> InferCtxt<'tcx> {
infer_subdiags,
multi_suggestions,
bad_label,
was_written: None,
path: Default::default(),
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
Expand All @@ -396,6 +422,8 @@ impl<'tcx> InferCtxt<'tcx> {
infer_subdiags,
multi_suggestions,
bad_label,
was_written: None,
path: Default::default(),
}),
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
span,
Expand All @@ -405,6 +433,8 @@ impl<'tcx> InferCtxt<'tcx> {
infer_subdiags,
multi_suggestions,
bad_label,
was_written: None,
path: Default::default(),
}),
}
}
Expand Down Expand Up @@ -442,7 +472,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return self.bad_inference_failure_err(failure_span, arg_data, error_code);
};

let (source_kind, name) = kind.ty_localized_msg(self);
let (source_kind, name, path) = kind.ty_localized_msg(self);
let failure_span = if should_label_span && !failure_span.overlaps(span) {
Some(failure_span)
} else {
Expand Down Expand Up @@ -518,15 +548,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
GenericArgKind::Type(_) => self
.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP,
span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable,
})
.into(),
GenericArgKind::Const(arg) => self
.next_const_var(
arg.ty(),
ConstVariableOrigin {
span: rustc_span::DUMMY_SP,
span: DUMMY_SP,
kind: ConstVariableOriginKind::MiscVariable,
},
)
Expand All @@ -547,7 +577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP,
span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable,
}));
if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) {
Expand Down Expand Up @@ -584,7 +614,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP,
span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable,
}));
if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) {
Expand All @@ -606,6 +636,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer_subdiags,
multi_suggestions,
bad_label: None,
was_written: path.as_ref().map(|_| ()),
path: path.unwrap_or_default(),
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
Expand All @@ -615,6 +647,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer_subdiags,
multi_suggestions,
bad_label: None,
was_written: path.as_ref().map(|_| ()),
path: path.unwrap_or_default(),
}),
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
span,
Expand All @@ -624,6 +658,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer_subdiags,
multi_suggestions,
bad_label: None,
was_written: path.as_ref().map(|_| ()),
path: path.unwrap_or_default(),
}),
}
}
Expand Down Expand Up @@ -688,22 +724,23 @@ impl<'tcx> InferSource<'tcx> {
}

impl<'tcx> InferSourceKind<'tcx> {
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String) {
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option<PathBuf>) {
let mut path = None;
match *self {
InferSourceKind::LetBinding { ty, .. }
| InferSourceKind::ClosureArg { ty, .. }
| InferSourceKind::ClosureReturn { ty, .. } => {
if ty.is_closure() {
("closure", closure_as_fn_str(infcx, ty))
("closure", closure_as_fn_str(infcx, ty), path)
} else if !ty.is_ty_or_numeric_infer() {
("normal", ty_to_string(infcx, ty, None))
("normal", infcx.tcx.short_ty_string(ty, &mut path), path)
} else {
("other", String::new())
("other", String::new(), path)
}
}
// FIXME: We should be able to add some additional info here.
InferSourceKind::GenericArg { .. }
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()),
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new(), path),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/array-slice-vec/vector-no-ann.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Vec<T>`
error[E0282]: type annotations needed for `Vec<_>`
--> $DIR/vector-no-ann.rs:2:9
|
LL | let _foo = Vec::new();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/const-generics/defaults/doesnt_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ impl<const N: u32> Foo<N> {
fn main() {
let foo = Foo::<1>::foo();
let foo = Foo::foo();
//~^ error: type annotations needed for `Foo<N>`
//~^ ERROR type annotations needed for `Foo<_>`
}
2 changes: 1 addition & 1 deletion tests/ui/const-generics/defaults/doesnt_infer.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Foo<N>`
error[E0282]: type annotations needed for `Foo<_>`
--> $DIR/doesnt_infer.rs:11:9
|
LL | let foo = Foo::foo();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0283]: type annotations needed for `Mask<_, N>`
error[E0283]: type annotations needed for `Mask<_, _>`
--> $DIR/issue-91614.rs:6:9
|
LL | let y = Mask::<_, _>::splat(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ help: try adding a `where` bound
LL | pub const fn new() -> Self where [(); Self::SIZE]: {
| +++++++++++++++++++++++

error[E0282]: type annotations needed for `ArrayHolder<X>`
error[E0282]: type annotations needed for `ArrayHolder<_>`
--> $DIR/issue-62504.rs:26:9
|
LL | let mut array = ArrayHolder::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ note: tuple struct defined here
LL | struct ArrayHolder<const X: usize>([u32; X]);
| ^^^^^^^^^^^

error[E0282]: type annotations needed for `ArrayHolder<X>`
error[E0282]: type annotations needed for `ArrayHolder<_>`
--> $DIR/issue-62504.rs:26:9
|
LL | let mut array = ArrayHolder::new();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/generic-const-items/inference-failure.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Option<T>`
error[E0282]: type annotations needed for `Option<_>`
--> $DIR/inference-failure.rs:8:9
|
LL | let _ = NONE;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/generic-const-items/parameter-defaults.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
LL | const NONE<T = ()>: Option<T> = None::<T>;
| ^^^^^^

error[E0282]: type annotations needed for `Option<T>`
error[E0282]: type annotations needed for `Option<_>`
--> $DIR/parameter-defaults.rs:13:9
|
LL | let _ = NONE;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/inference/cannot-infer-closure-circular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ fn main() {
// error handles this gracefully, and in particular doesn't generate an extra
// note about the `?` operator in the closure body, which isn't relevant to
// the inference.
let x = |r| { //~ ERROR type annotations needed for `Result<(), E>`
let x = |r| { //~ ERROR type annotations needed for `Result<(), _>`
let v = r?;
Ok(v)
};
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/inference/cannot-infer-closure-circular.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Result<(), E>`
error[E0282]: type annotations needed for `Result<(), _>`
--> $DIR/cannot-infer-closure-circular.rs:7:14
|
LL | let x = |r| {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/inference/erase-type-params-in-label.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>`
error[E0283]: type annotations needed for `Foo<i32, &str, _, _>`
--> $DIR/erase-type-params-in-label.rs:2:9
|
LL | let foo = foo(1, "");
Expand All @@ -15,7 +15,7 @@ help: consider giving `foo` an explicit type, where the type for type parameter
LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
| ++++++++++++++++++++++

error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
error[E0283]: type annotations needed for `Bar<i32, &str, _>`
--> $DIR/erase-type-params-in-label.rs:5:9
|
LL | let bar = bar(1, "");
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/inference/issue-104649.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>`
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), _>, Error>>`
--> $DIR/issue-104649.rs:24:9
|
LL | let a = A(Result::Ok(Result::Ok(())));
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/inference/issue-72690.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ help: try using a fully qualified path to specify the expected types
LL | |x| String::from(<str as AsRef<T>>::as_ref("x"));
| ++++++++++++++++++++++++++ ~

error[E0283]: type annotations needed for `&T`
error[E0283]: type annotations needed for `&_`
--> $DIR/issue-72690.rs:17:9
|
LL | let _ = "x".as_ref();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/inference/issue-83606.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {

fn main() {
let _ = foo("foo");
//~^ ERROR: type annotations needed for `[usize; N]`
//~^ ERROR type annotations needed for `[usize; _]`
}
2 changes: 1 addition & 1 deletion tests/ui/inference/issue-83606.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `[usize; N]`
error[E0282]: type annotations needed for `[usize; _]`
--> $DIR/issue-83606.rs:8:9
|
LL | let _ = foo("foo");
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-12187-1.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `&T`
error[E0282]: type annotations needed for `&_`
--> $DIR/issue-12187-1.rs:6:9
|
LL | let &v = new();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-12187-2.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `&T`
error[E0282]: type annotations needed for `&_`
--> $DIR/issue-12187-2.rs:6:9
|
LL | let &v = new();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-17551.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `B<T>`
error[E0282]: type annotations needed for `B<_>`
--> $DIR/issue-17551.rs:6:9
|
LL | let foo = B(marker::PhantomData);
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-23046.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Expr<'_, VAR>`
error[E0282]: type annotations needed for `Expr<'_, _>`
--> $DIR/issue-23046.rs:17:15
|
LL | let ex = |x| {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-98299.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `SmallCString<N>`
error[E0282]: type annotations needed for `SmallCString<_>`
--> $DIR/issue-98299.rs:4:36
|
LL | SmallCString::try_from(p).map(|cstr| cstr);
Expand Down
Loading
Loading