From c98399f5eba594925cc136ac890c322326895fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 22 Jul 2022 02:28:03 +0200 Subject: [PATCH 1/4] Don't suggest unnameable generic arguments --- .../infer/error_reporting/need_type_info.rs | 41 ++++++++++++++++--- compiler/rustc_middle/src/ty/diagnostics.rs | 18 +++++--- .../src/traits/error_reporting/suggestions.rs | 6 +-- compiler/rustc_typeck/src/astconv/generics.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- .../src/check/fn_ctxt/suggestions.rs | 7 +++- compiler/rustc_typeck/src/collect.rs | 9 +++- src/test/ui/closures/issue-99565.rs | 7 ++++ src/test/ui/closures/issue-99565.stderr | 14 +++++++ src/test/ui/issues/issue-23041.stderr | 2 +- src/test/ui/issues/issue-24013.stderr | 2 +- 12 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/closures/issue-99565.rs create mode 100644 src/test/ui/closures/issue-99565.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index b267140daa971..561d1354edd21 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1,4 +1,4 @@ -use crate::infer::type_variable::TypeVariableOriginKind; +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::InferCtxt; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; @@ -8,12 +8,12 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource}; use rustc_middle::hir::nested_filter; -use rustc_middle::infer::unify_key::ConstVariableOriginKind; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, InferConst}; -use rustc_middle::ty::{Ty, TyCtxt, TypeckResults}; +use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; use rustc_span::symbol::{kw, Ident}; use rustc_span::{BytePos, Span}; use std::borrow::Cow; @@ -407,11 +407,40 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_label(span, cannot_infer_msg); - let printer = fmt_printer(self, Namespace::TypeNS); - let args = printer.comma_sep(generic_args.iter().copied()).unwrap().into_buffer(); + let args = fmt_printer(self, Namespace::TypeNS) + .comma_sep(generic_args.iter().copied().map(|arg| { + if arg.is_suggestable(self.tcx, true) { + return arg; + } + + match arg.unpack() { + GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), + GenericArgKind::Type(_) => self + .next_ty_var(TypeVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: TypeVariableOriginKind::MiscVariable, + }) + .into(), + GenericArgKind::Const(arg) => self + .next_const_var( + arg.ty(), + ConstVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: ConstVariableOriginKind::MiscVariable, + }, + ) + .into(), + } + })) + .unwrap() + .into_buffer(); + err.span_suggestion_verbose( insert_span, - &format!("consider specifying the generic argument{}", pluralize!(args.len()),), + &format!( + "consider specifying the generic argument{}", + pluralize!(generic_args.len()), + ), format!("::<{}>", args), Applicability::HasPlaceholders, ); diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 25bc6dc616784..dd2f43210603a 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -3,7 +3,7 @@ use std::ops::ControlFlow; use crate::ty::{ - visit::TypeVisitable, Const, ConstKind, DefIdTree, ExistentialPredicate, InferTy, + visit::TypeVisitable, Const, ConstKind, DefIdTree, ExistentialPredicate, InferConst, InferTy, PolyTraitPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, }; @@ -82,15 +82,18 @@ pub trait IsSuggestable<'tcx> { /// meaningful rendered suggestions when pretty-printed. We leave some /// nonsense, such as region vars, since those render as `'_` and are /// usually okay to reinterpret as elided lifetimes. - fn is_suggestable(self, tcx: TyCtxt<'tcx>) -> bool; + /// + /// Only if `infer_suggestable` is true, we consider type and const + /// inference variables to be suggestable. + fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool; } impl<'tcx, T> IsSuggestable<'tcx> for T where T: TypeVisitable<'tcx>, { - fn is_suggestable(self, tcx: TyCtxt<'tcx>) -> bool { - self.visit_with(&mut IsSuggestableVisitor { tcx }).is_continue() + fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool { + self.visit_with(&mut IsSuggestableVisitor { tcx, infer_suggestable }).is_continue() } } @@ -100,7 +103,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>( err: &mut Diagnostic, trait_pred: PolyTraitPredicate<'tcx>, ) -> bool { - if !trait_pred.is_suggestable(tcx) { + if !trait_pred.is_suggestable(tcx, false) { return false; } @@ -419,6 +422,7 @@ impl<'v> hir::intravisit::Visitor<'v> for StaticLifetimeVisitor<'v> { pub struct IsSuggestableVisitor<'tcx> { tcx: TyCtxt<'tcx>, + infer_suggestable: bool, } impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> { @@ -426,6 +430,8 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { + Infer(InferTy::TyVar(_)) if self.infer_suggestable => {} + FnDef(..) | Closure(..) | Infer(..) @@ -479,6 +485,8 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> { fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow { match c.kind() { + ConstKind::Infer(InferConst::Var(_)) if self.infer_suggestable => {} + ConstKind::Infer(..) | ConstKind::Bound(..) | ConstKind::Placeholder(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5636c74452ccf..7ab85e7fa663e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -378,7 +378,7 @@ fn suggest_restriction<'tcx>( replace_ty: ty::ParamTy::new(generics.count() as u32, Symbol::intern(&type_param_name)) .to_ty(tcx), }); - if !trait_pred.is_suggestable(tcx) { + if !trait_pred.is_suggestable(tcx, false) { return; } // We know we have an `impl Trait` that doesn't satisfy a required projection. @@ -417,7 +417,7 @@ fn suggest_restriction<'tcx>( Applicability::MaybeIncorrect, ); } else { - if !trait_pred.is_suggestable(tcx) { + if !trait_pred.is_suggestable(tcx, false) { return; } // Trivial case: `T` needs an extra bound: `T: Bound`. @@ -586,7 +586,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // else in the predicate. if !trait_pred.skip_binder().trait_ref.substs[1..] .iter() - .all(|g| g.is_suggestable(self.tcx)) + .all(|g| g.is_suggestable(self.tcx, false)) { return; } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 612dc38452188..40aa27a29e957 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -86,7 +86,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let param_type = tcx.infer_ctxt().enter(|infcx| { infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id)) }); - if param_type.is_suggestable(tcx) { + if param_type.is_suggestable(tcx, false) { err.span_suggestion( tcx.def_span(src_def_id), "consider changing this type parameter to be a `const` generic", diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 9e4da0580522b..7111812f0b090 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2676,7 +2676,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, ty, opt_sugg: Some((span, Applicability::MachineApplicable)) - .filter(|_| ty.is_suggestable(tcx)), + .filter(|_| ty.is_suggestable(tcx, false)), }); ty diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 1555f4f3fd6a6..84d2878308a10 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1070,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (_, expected_ty) = formal_and_expected_inputs[expected_idx]; if expected_ty.is_unit() { "()".to_string() - } else if expected_ty.is_suggestable(tcx) { + } else if expected_ty.is_suggestable(tcx, false) { format!("/* {} */", expected_ty) } else { "/* value */".to_string() diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 871fc4a21f2a7..b8311832b8470 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -507,7 +507,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found)); // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()` or an impl). - match (&fn_decl.output, found.is_suggestable(self.tcx), can_suggest, expected.is_unit()) { + match ( + &fn_decl.output, + found.is_suggestable(self.tcx, false), + can_suggest, + expected.is_unit(), + ) { (&hir::FnRetTy::DefaultReturn(span), true, true, true) => { err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found }); true diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 24e6a5d304789..c303905652d52 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1929,7 +1929,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( visitor.visit_ty(ty); let mut diag = bad_placeholder(tcx, visitor.0, "return type"); let ret_ty = fn_sig.skip_binder().output(); - if ret_ty.is_suggestable(tcx) { + if ret_ty.is_suggestable(tcx, false) { diag.span_suggestion( ty.span, "replace with the correct return type", @@ -1938,7 +1938,12 @@ fn infer_return_ty_for_fn_sig<'tcx>( ); } else if matches!(ret_ty.kind(), ty::FnDef(..)) { let fn_sig = ret_ty.fn_sig(tcx); - if fn_sig.skip_binder().inputs_and_output.iter().all(|t| t.is_suggestable(tcx)) { + if fn_sig + .skip_binder() + .inputs_and_output + .iter() + .all(|t| t.is_suggestable(tcx, false)) + { diag.span_suggestion( ty.span, "replace with the correct return type", diff --git a/src/test/ui/closures/issue-99565.rs b/src/test/ui/closures/issue-99565.rs new file mode 100644 index 0000000000000..3a30d2ee03499 --- /dev/null +++ b/src/test/ui/closures/issue-99565.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +fn foo(_: U) {} + +fn bar() { + foo(|| {}); //~ ERROR type annotations needed +} diff --git a/src/test/ui/closures/issue-99565.stderr b/src/test/ui/closures/issue-99565.stderr new file mode 100644 index 0000000000000..0d940aa9a2f5f --- /dev/null +++ b/src/test/ui/closures/issue-99565.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/issue-99565.rs:6:5 + | +LL | foo(|| {}); + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | +help: consider specifying the generic arguments + | +LL | foo::(|| {}); + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-23041.stderr b/src/test/ui/issues/issue-23041.stderr index 7b9a1634a0d4c..6592b76a39f7a 100644 --- a/src/test/ui/issues/issue-23041.stderr +++ b/src/test/ui/issues/issue-23041.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | b.downcast_ref::_>(); | ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `downcast_ref` | -help: consider specifying the generic arguments +help: consider specifying the generic argument | LL | b.downcast_ref:: _>(); | ~~~~~~~~~~~~~~ diff --git a/src/test/ui/issues/issue-24013.stderr b/src/test/ui/issues/issue-24013.stderr index 863993f450904..995dce552e37f 100644 --- a/src/test/ui/issues/issue-24013.stderr +++ b/src/test/ui/issues/issue-24013.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap` | -help: consider specifying the generic arguments +help: consider specifying the generic argument | LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; | ~~~~~~~~~~ From 31dd1f685961f52a56d230528d8de4220f51fdcf Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 22 Jul 2022 11:59:20 -0700 Subject: [PATCH 2/4] Update mdbook --- Cargo.lock | 4 ++-- src/tools/rustbook/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff73b45634fd6..9deda378cbb18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2361,9 +2361,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13cdad8057b09a519c6c63e6d7c93ea854f5d7fbfe284df864d5e1140d215a2d" +checksum = "23f3e133c6d515528745ffd3b9f0c7d975ae039f0b6abb099f2168daa2afb4f9" dependencies = [ "ammonia", "anyhow", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index bd08e0ede0bfa..33c051804081c 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -9,6 +9,6 @@ clap = "3.1.1" env_logger = "0.7.1" [dependencies.mdbook] -version = "0.4.18" +version = "0.4.21" default-features = false features = ["search"] From e0c9be539a2129478b4d6246cda6a398738290a0 Mon Sep 17 00:00:00 2001 From: Jordan McQueen Date: Sat, 23 Jul 2022 13:26:45 +0900 Subject: [PATCH 3/4] Use span_bug in case of unexpected rib kind Extremely minor QOL change to improve the ICE output in case this default match case is encountered (an unexpected rib kind). --- compiler/rustc_resolve/src/late.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 49761023ec333..e739ed678d8be 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2111,7 +2111,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let res = match kind { ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()), NormalRibKind => Res::Err, - _ => bug!("Unexpected rib kind {:?}", kind), + _ => span_bug!(param.ident.span, "Unexpected rib kind {:?}", kind), }; self.r.record_partial_res(param.id, PartialRes::new(res)); rib.bindings.insert(ident, res); From db977ca37ed2adff2d3b04e2af10d0776f2e5aef Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Sat, 23 Jul 2022 07:31:20 +0200 Subject: [PATCH 4/4] Fix typo/grammar in locator.rs doc comment --- compiler/rustc_metadata/src/locator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index a72bcb9a2dbd1..2c1c84b0be26a 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -67,7 +67,7 @@ //! //! ## What criterion to select on? //! -//! This a pretty tricky area of loading crates. Given a file, how do we know +//! This is a pretty tricky area of loading crates. Given a file, how do we know //! whether it's the right crate? Currently, the rules look along these lines: //! //! 1. Does the filename match an rlib/dylib pattern? That is to say, does the