From 9072c8d274307c08ad0a7afb16681d43181c4033 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jan 2022 15:34:06 -0800 Subject: [PATCH 01/11] skip pointing out ambuguous impls in alloc/std crates too --- .../src/traits/error_reporting/mod.rs | 2 +- src/test/ui/impl-trait/equality.rs | 2 +- src/test/ui/impl-trait/equality.stderr | 19 +--------- src/test/ui/issues/issue-72690.rs | 1 - src/test/ui/issues/issue-72690.stderr | 38 +++++++------------ 5 files changed, 18 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f22b4e8d072a8..67b44f0a34881 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1973,7 +1973,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { if self.is_tainted_by_errors() && crate_names.len() == 1 - && crate_names[0] == "`core`" + && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str()) && spans.len() == 0 { // Avoid complaining about other inference issues for expressions like diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 9610618ca11f6..828b5aac896be 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -17,7 +17,7 @@ fn two(x: bool) -> impl Foo { //~| expected `i32`, found `u32` } -fn sum_to(n: u32) -> impl Foo { //~ ERROR type annotations needed +fn sum_to(n: u32) -> impl Foo { if n == 0 { 0 } else { diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index d9819484a9612..536a4726c6de2 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -34,22 +34,7 @@ LL | n + sum_to(n - 1) | = help: the trait `Add` is not implemented for `u32` -error[E0283]: type annotations needed - --> $DIR/equality.rs:20:22 - | -LL | fn sum_to(n: u32) -> impl Foo { - | ^^^^^^^^ cannot infer type for type `{integer}` - | - = note: multiple `impl`s satisfying `{integer}: ToString` found in the `alloc` crate: - - impl ToString for i8; - - impl ToString for u8; -note: required because of the requirements on the impl of `Foo` for `{integer}` - --> $DIR/equality.rs:5:26 - | -LL | impl Foo for T {} - | ^^^ ^ - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0283, E0308. +Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-72690.rs b/src/test/ui/issues/issue-72690.rs index 916a7832c6886..8c0a0f51a2157 100644 --- a/src/test/ui/issues/issue-72690.rs +++ b/src/test/ui/issues/issue-72690.rs @@ -10,7 +10,6 @@ fn err() { fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed //~| ERROR type annotations needed } diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/issues/issue-72690.stderr index 629ccea2577bd..f1ec678b20193 100644 --- a/src/test/ui/issues/issue-72690.stderr +++ b/src/test/ui/issues/issue-72690.stderr @@ -29,16 +29,6 @@ error[E0282]: type annotations needed LL | |x| String::from("x".as_ref()); | ^ consider giving this closure parameter a type -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:12:9 - | -LL | |x| String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; - error[E0283]: type annotations needed --> $DIR/issue-72690.rs:12:26 | @@ -55,7 +45,7 @@ LL | |x| String::from("x".as_ref()); - impl AsRef for str; error[E0283]: type annotations needed for `&T` - --> $DIR/issue-72690.rs:18:17 + --> $DIR/issue-72690.rs:17:17 | LL | let _ = "x".as_ref(); | - ^^^^^^ cannot infer type for type parameter `T` declared on the trait `AsRef` @@ -69,7 +59,7 @@ LL | let _ = "x".as_ref(); - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:22:5 + --> $DIR/issue-72690.rs:21:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` @@ -79,7 +69,7 @@ LL | String::from("x".as_ref()); - impl<> From<&str> for String; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:22:22 + --> $DIR/issue-72690.rs:21:22 | LL | String::from("x".as_ref()); | ----^^^^^^-- @@ -94,7 +84,7 @@ LL | String::from("x".as_ref()); - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:29:5 + --> $DIR/issue-72690.rs:28:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` @@ -104,7 +94,7 @@ LL | String::from("x".as_ref()); - impl<> From<&str> for String; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:29:22 + --> $DIR/issue-72690.rs:28:22 | LL | String::from("x".as_ref()); | ----^^^^^^-- @@ -119,7 +109,7 @@ LL | String::from("x".as_ref()); - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:38:5 + --> $DIR/issue-72690.rs:37:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` @@ -129,7 +119,7 @@ LL | String::from("x".as_ref()); - impl<> From<&str> for String; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:38:22 + --> $DIR/issue-72690.rs:37:22 | LL | String::from("x".as_ref()); | ----^^^^^^-- @@ -144,7 +134,7 @@ LL | String::from("x".as_ref()); - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:47:5 + --> $DIR/issue-72690.rs:46:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` @@ -154,7 +144,7 @@ LL | String::from("x".as_ref()); - impl<> From<&str> for String; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:47:22 + --> $DIR/issue-72690.rs:46:22 | LL | String::from("x".as_ref()); | ----^^^^^^-- @@ -169,7 +159,7 @@ LL | String::from("x".as_ref()); - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:54:5 + --> $DIR/issue-72690.rs:53:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` @@ -179,7 +169,7 @@ LL | String::from("x".as_ref()); - impl<> From<&str> for String; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:54:22 + --> $DIR/issue-72690.rs:53:22 | LL | String::from("x".as_ref()); | ----^^^^^^-- @@ -194,7 +184,7 @@ LL | String::from("x".as_ref()); - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:63:5 + --> $DIR/issue-72690.rs:62:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` @@ -204,7 +194,7 @@ LL | String::from("x".as_ref()); - impl<> From<&str> for String; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:63:22 + --> $DIR/issue-72690.rs:62:22 | LL | String::from("x".as_ref()); | ----^^^^^^-- @@ -218,7 +208,7 @@ LL | String::from("x".as_ref()); - impl AsRef<[u8]> for str; - impl AsRef for str; -error: aborting due to 18 previous errors +error: aborting due to 17 previous errors Some errors have detailed explanations: E0282, E0283. For more information about an error, try `rustc --explain E0282`. From 78294371c4a6272e4b36bd36f0317b697b18138e Mon Sep 17 00:00:00 2001 From: Ian Chamberlain Date: Fri, 18 Feb 2022 17:25:40 -0500 Subject: [PATCH 02/11] Enable #[thread_local] on armv6k-nintendo-3ds --- compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs index 3e3a6ac82a439..84105fbad47cc 100644 --- a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs +++ b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs @@ -37,6 +37,7 @@ pub fn target() -> Target { pre_link_args, exe_suffix: ".elf".to_string(), no_default_libraries: false, + has_thread_local: true, ..Default::default() }, } From ea26d72710c100bf41bf5b672f1a218f24166574 Mon Sep 17 00:00:00 2001 From: Badel2 <2badel2@gmail.com> Date: Sat, 26 Mar 2022 16:47:13 +0100 Subject: [PATCH 03/11] Move resolve_path to rustc_builtin_macros and make it private --- .../rustc_builtin_macros/src/source_util.rs | 47 +++++++++++++++++-- compiler/rustc_expand/src/base.rs | 39 +-------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index bbc8e62d68ff0..be628c9202cbd 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -3,15 +3,17 @@ use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; +use rustc_errors::PResult; use rustc_expand::base::{self, *}; use rustc_expand::module::DirOwnership; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_parse::{self, new_parser_from_file}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; use rustc_span::symbol::Symbol; -use rustc_span::{self, Pos, Span}; +use rustc_span::{self, FileName, Pos, Span}; use smallvec::SmallVec; +use std::path::PathBuf; use std::rc::Rc; // These macros all relate to the file system; they either return @@ -102,7 +104,7 @@ pub fn expand_include<'cx>( return DummyResult::any(sp); }; // The file will be added to the code map by the parser - let file = match cx.resolve_path(file, sp) { + let file = match resolve_path(cx, file, sp) { Ok(f) => f, Err(mut err) => { err.emit(); @@ -171,7 +173,7 @@ pub fn expand_include_str( let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else { return DummyResult::any(sp); }; - let file = match cx.resolve_path(file, sp) { + let file = match resolve_path(cx, file, sp) { Ok(f) => f, Err(mut err) => { err.emit(); @@ -205,7 +207,7 @@ pub fn expand_include_bytes( let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else { return DummyResult::any(sp); }; - let file = match cx.resolve_path(file, sp) { + let file = match resolve_path(cx, file, sp) { Ok(f) => f, Err(mut err) => { err.emit(); @@ -220,3 +222,40 @@ pub fn expand_include_bytes( } } } + +/// Resolves a `path` mentioned inside Rust code, returning an absolute path. +/// +/// This unifies the logic used for resolving `include_X!`. +fn resolve_path<'a>( + cx: &mut ExtCtxt<'a>, + path: impl Into, + span: Span, +) -> PResult<'a, PathBuf> { + let path = path.into(); + + // Relative paths are resolved relative to the file in which they are found + // after macro expansion (that is, they are unhygienic). + if !path.is_absolute() { + let callsite = span.source_callsite(); + let mut result = match cx.source_map().span_to_filename(callsite) { + FileName::Real(name) => name + .into_local_path() + .expect("attempting to resolve a file path in an external file"), + FileName::DocTest(path, _) => path, + other => { + return Err(cx.struct_span_err( + span, + &format!( + "cannot resolve relative path in non-file source `{}`", + cx.source_map().filename_for_diagnostics(&other) + ), + )); + } + }; + result.pop(); + result.push(path); + Ok(result) + } else { + Ok(path) + } +} diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d6b308cdf85d5..7f569af4abd65 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -10,7 +10,7 @@ use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{self, Lrc}; -use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; +use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::BuiltinLintDiagnostics; use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS}; @@ -20,7 +20,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{FileName, MultiSpan, Span, DUMMY_SP}; +use rustc_span::{MultiSpan, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::default::Default; @@ -1128,41 +1128,6 @@ impl<'a> ExtCtxt<'a> { pub fn check_unused_macros(&mut self) { self.resolver.check_unused_macros(); } - - /// Resolves a `path` mentioned inside Rust code, returning an absolute path. - /// - /// This unifies the logic used for resolving `include_X!`. - /// - /// FIXME: move this to `rustc_builtin_macros` and make it private. - pub fn resolve_path(&self, path: impl Into, span: Span) -> PResult<'a, PathBuf> { - let path = path.into(); - - // Relative paths are resolved relative to the file in which they are found - // after macro expansion (that is, they are unhygienic). - if !path.is_absolute() { - let callsite = span.source_callsite(); - let mut result = match self.source_map().span_to_filename(callsite) { - FileName::Real(name) => name - .into_local_path() - .expect("attempting to resolve a file path in an external file"), - FileName::DocTest(path, _) => path, - other => { - return Err(self.struct_span_err( - span, - &format!( - "cannot resolve relative path in non-file source `{}`", - self.source_map().filename_for_diagnostics(&other) - ), - )); - } - }; - result.pop(); - result.push(path); - Ok(result) - } else { - Ok(path) - } - } } /// Extracts a string literal from the macro expanded version of `expr`, From 78b680e14a287a98ec0501116607bb49b31c9f28 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 26 Mar 2022 13:03:49 -0400 Subject: [PATCH 04/11] interpret: mark a dead match arm as dead --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d78c7a9fad983..abd7094440e57 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -444,6 +444,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match scalar.try_to_int() { Ok(int) => int.is_null(), Err(_) => { + // Can only happen during CTFE. let ptr = self.scalar_to_ptr(scalar); match self.memory.ptr_try_get_alloc(ptr) { Ok((alloc_id, offset, _)) => { @@ -455,7 +456,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Note that one-past-the-end (offset == size) is still inbounds, and never null. offset > size } - Err(offset) => offset == 0, + Err(_offset) => bug!("a non-int scalar is always a pointer"), } } } From 3bbcf64fb33e701084c664d9b691ac3c1736bd14 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 26 Mar 2022 13:17:49 -0400 Subject: [PATCH 05/11] interpret: with enforce_number_validity, ensure integers are truly Scalar::Int (i.e., no pointers) --- compiler/rustc_const_eval/src/interpret/validity.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 8bdafa8762386..9da7f5e30cb9e 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -21,7 +21,7 @@ use std::hash::Hash; use super::{ alloc_range, CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine, - MemPlaceMeta, OpTy, ScalarMaybeUninit, ValueVisitor, + MemPlaceMeta, OpTy, Scalar, ScalarMaybeUninit, ValueVisitor, }; macro_rules! throw_validation_failure { @@ -521,8 +521,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // NOTE: Keep this in sync with the array optimization for int/float // types below! if M::enforce_number_validity(self.ecx) { - // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous - let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok()); + // Integers/floats with number validity: Must be scalar bits, pointers are dangerous. + // As a special exception we *do* match on a `Scalar` here, since we truly want + // to know its underlying representation (and *not* cast it to an integer). + let is_bits = + value.check_init().map_or(false, |v| matches!(v, Scalar::Int(..))); if !is_bits { throw_validation_failure!(self.path, { "{:x}", value } expected { "initialized plain (non-pointer) bytes" } From 474626af50ae9836b56a351edf59c1ca9b104b5c Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 15 Dec 2021 22:59:32 +0000 Subject: [PATCH 06/11] Eagerly replace `{integer}`/`{float}` with `i32`/`f64` for suggestion --- compiler/rustc_infer/src/infer/mod.rs | 31 +++++++++++++++++++ .../src/check/fn_ctxt/suggestions.rs | 2 ++ src/test/ui/issues/issue-66706.stderr | 6 ++-- .../ui/proc-macro/span-preservation.stderr | 8 ++--- src/test/ui/return/return-type.stderr | 14 ++++++--- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 2886d921c705d..5878cfdf0b7fc 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1434,6 +1434,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { value.fold_with(&mut r) } + pub fn resolve_numeric_literals_with_default(&self, value: T) -> T + where + T: TypeFoldable<'tcx>, + { + if !value.needs_infer() { + return value; // Avoid duplicated subst-folding. + } + let mut r = InferenceLiteralEraser { infcx: self }; + value.fold_with(&mut r) + } + /// Returns the first unresolved variable contained in `T`. In the /// process of visiting `T`, this will resolve (where possible) /// type variables in `T`, but it never constructs the final, @@ -1785,6 +1796,26 @@ impl<'tcx> TyOrConstInferVar<'tcx> { } } +/// Replace `{integer}` with `i32` and `{float}` with `f64`. +/// Used only for diagnostics. +struct InferenceLiteralEraser<'a, 'tcx> { + infcx: &'a InferCtxt<'a, 'tcx>, +} + +impl<'a, 'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'a, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.kind() { + ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => self.tcx().types.i32, + ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => self.tcx().types.f64, + _ => ty.super_fold_with(self), + } + } +} + struct ShallowResolver<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 67d61668b6d85..37014b5eea5c1 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -521,6 +521,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { can_suggest: bool, fn_id: hir::HirId, ) -> bool { + let found = + 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(), can_suggest, expected.is_unit()) { diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr index 3e933a0f01b75..e8cb18f5c1e62 100644 --- a/src/test/ui/issues/issue-66706.stderr +++ b/src/test/ui/issues/issue-66706.stderr @@ -36,7 +36,7 @@ error[E0308]: mismatched types --> $DIR/issue-66706.rs:2:5 | LL | fn a() { - | - possibly return type missing here? + | - help: try adding a return type: `-> [i32; _]` LL | [0; [|_: _ &_| ()].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` @@ -44,7 +44,7 @@ error[E0308]: mismatched types --> $DIR/issue-66706.rs:14:5 | LL | fn c() { - | - possibly return type missing here? + | - help: try adding a return type: `-> [i32; _]` LL | [0; [|&_: _ &_| {}; 0 ].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` @@ -52,7 +52,7 @@ error[E0308]: mismatched types --> $DIR/issue-66706.rs:20:5 | LL | fn d() { - | - possibly return type missing here? + | - help: try adding a return type: `-> [i32; _]` LL | [0; match [|f @ &ref _| () ] {} ] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` diff --git a/src/test/ui/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr index e9a44ccb12e74..66c68be2f09de 100644 --- a/src/test/ui/proc-macro/span-preservation.stderr +++ b/src/test/ui/proc-macro/span-preservation.stderr @@ -38,7 +38,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:39:5 | LL | extern "C" fn bar() { - | - possibly return type missing here? + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer @@ -46,7 +46,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:44:5 | LL | extern "C" fn baz() { - | - possibly return type missing here? + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer @@ -54,7 +54,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:49:5 | LL | extern "Rust" fn rust_abi() { - | - possibly return type missing here? + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer @@ -62,7 +62,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:54:5 | LL | extern "\x43" fn c_abi_escaped() { - | - possibly return type missing here? + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer diff --git a/src/test/ui/return/return-type.stderr b/src/test/ui/return/return-type.stderr index f86209a651d13..5af136e601123 100644 --- a/src/test/ui/return/return-type.stderr +++ b/src/test/ui/return/return-type.stderr @@ -1,15 +1,19 @@ error[E0308]: mismatched types --> $DIR/return-type.rs:10:5 | -LL | fn bar() { - | - possibly return type missing here? LL | foo(4 as usize) - | ^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` - | | - | expected `()`, found struct `S` + | ^^^^^^^^^^^^^^^ expected `()`, found struct `S` | = note: expected unit type `()` found struct `S` +help: consider using a semicolon here + | +LL | foo(4 as usize); + | + +help: try adding a return type + | +LL | fn bar() -> S { + | +++++++++++ error: aborting due to previous error From c4d741fa16fb1048830db7566e0b7d1a6d61be1b Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 15 Dec 2021 23:11:26 +0000 Subject: [PATCH 07/11] Also resolve `const` param suggestion --- compiler/rustc_typeck/src/astconv/generics.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 754172b115819..451e1e05d1458 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -11,6 +11,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::GenericArg; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::ty::{ self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt, }; @@ -83,7 +84,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(param_local_id) = param.def_id.as_local() { let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id); let param_name = tcx.hir().ty_param_name(param_hir_id); - let param_type = tcx.type_of(param.def_id); + let param_type = tcx.infer_ctxt().enter(|infcx| { + infcx.resolve_numeric_literals_with_default( + infcx.resolve_vars_if_possible(tcx.type_of(param.def_id)), + ) + }); if param_type.is_suggestable() { err.span_suggestion( tcx.def_span(src_def_id), From 1c85987274d46cd08d74decec0ee1c754597d271 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 15 Dec 2021 23:16:21 +0000 Subject: [PATCH 08/11] Point (again) to more expressions with their type, even if not fully resolved --- .../src/infer/error_reporting/mod.rs | 3 +- src/test/ui/async-await/issue-61076.rs | 1 + src/test/ui/async-await/issue-61076.stderr | 5 ++- .../async-await/suggest-missing-await.stderr | 8 ++++ .../ui/blind/blind-item-block-middle.stderr | 2 +- .../default-match-bindings-forbidden.stderr | 4 +- .../tuple_destructure_fail.stderr | 8 +++- ...sive_range_pattern_syntax_collision.stderr | 2 + ...ive_range_pattern_syntax_collision2.stderr | 2 + ...ive_range_pattern_syntax_collision3.stderr | 6 +++ .../pat-tuple-5.stderr | 2 + src/test/ui/issues/issue-11844.stderr | 2 + src/test/ui/issues/issue-12552.stderr | 5 +++ src/test/ui/issues/issue-13466.stderr | 5 +++ src/test/ui/issues/issue-33504.stderr | 2 +- src/test/ui/issues/issue-3680.stderr | 2 + src/test/ui/issues/issue-4968.stderr | 11 +++--- src/test/ui/issues/issue-72574-1.stderr | 2 + .../keyword-false-as-identifier.stderr | 4 +- .../keyword/keyword-true-as-identifier.stderr | 4 +- src/test/ui/match/match-range-fail.stderr | 2 + src/test/ui/mismatched_types/E0409.stderr | 2 + src/test/ui/mut/mut-pattern-mismatched.stderr | 6 +++ .../ui/or-patterns/already-bound-name.stderr | 5 ++- .../ui/or-patterns/inconsistent-modes.stderr | 5 ++- src/test/ui/parser/recover-range-pats.stderr | 39 +++++++++++++------ src/test/ui/pattern/issue-74702.stderr | 4 +- .../ui/pattern/pat-tuple-overfield.stderr | 5 +++ ...ghtly-nice-generic-literal-messages.stderr | 2 + ...structure-constructor-type-mismatch.stderr | 6 +++ 30 files changed, 125 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index abc25d51776f3..f1c21f5923926 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -602,7 +602,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match *cause.code() { ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => { let ty = self.resolve_vars_if_possible(root_ty); - if ty.is_suggestable() { + if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_))) + { // don't show type `_` err.span_label(span, format!("this expression has type `{}`", ty)); } diff --git a/src/test/ui/async-await/issue-61076.rs b/src/test/ui/async-await/issue-61076.rs index a94136cfea1fc..750fad8393bbf 100644 --- a/src/test/ui/async-await/issue-61076.rs +++ b/src/test/ui/async-await/issue-61076.rs @@ -87,6 +87,7 @@ async fn baz() -> Result<(), ()> { async fn match_() { match tuple() { //~ HELP consider `await`ing on the `Future` + //~^ NOTE this expression has type `impl Future` Tuple(_) => {} //~ ERROR mismatched types //~^ NOTE expected opaque type, found struct `Tuple` //~| NOTE expected opaque type `impl Future` diff --git a/src/test/ui/async-await/issue-61076.stderr b/src/test/ui/async-await/issue-61076.stderr index 65c0bc695bfbc..33839ea59392d 100644 --- a/src/test/ui/async-await/issue-61076.stderr +++ b/src/test/ui/async-await/issue-61076.stderr @@ -56,8 +56,11 @@ LL | struct_().await.method(); | ++++++ error[E0308]: mismatched types - --> $DIR/issue-61076.rs:90:9 + --> $DIR/issue-61076.rs:91:9 | +LL | match tuple() { + | ------- this expression has type `impl Future` +LL | LL | Tuple(_) => {} | ^^^^^^^^ expected opaque type, found struct `Tuple` | diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 3cca9616a358a..76073c4c87996 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -91,6 +91,8 @@ LL ~ 1 => dummy().await, error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:53:9 | +LL | let _x = match dummy() { + | ------- this expression has type `impl Future` LL | () => {} | ^^ expected opaque type, found `()` | @@ -109,6 +111,9 @@ LL | let _x = match dummy().await { error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:67:9 | +LL | match dummy_result() { + | -------------- this expression has type `impl Future>` +... LL | Ok(_) => {} | ^^^^^ expected opaque type, found enum `Result` | @@ -127,6 +132,9 @@ LL | match dummy_result().await { error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:69:9 | +LL | match dummy_result() { + | -------------- this expression has type `impl Future>` +... LL | Err(_) => {} | ^^^^^^ expected opaque type, found enum `Result` | diff --git a/src/test/ui/blind/blind-item-block-middle.stderr b/src/test/ui/blind/blind-item-block-middle.stderr index 9db11cf1590e8..dd83f6edf62a4 100644 --- a/src/test/ui/blind/blind-item-block-middle.stderr +++ b/src/test/ui/blind/blind-item-block-middle.stderr @@ -5,7 +5,7 @@ LL | mod foo { pub struct bar; } | --------------- unit struct defined here ... LL | let bar = 5; - | ^^^ + | ^^^ - this expression has type `{integer}` | | | expected integer, found struct `bar` | `bar` is interpreted as a unit struct, not a new binding diff --git a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr index 2250f561b54a5..3d472bf63094d 100644 --- a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr +++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/default-match-bindings-forbidden.rs:4:5 | LL | (x, y) = &(1, 2); - | ^^^^^^ expected reference, found tuple + | ^^^^^^ ------- this expression has type `&({integer}, {integer})` + | | + | expected reference, found tuple | = note: expected type `&({integer}, {integer})` found tuple `(_, _)` diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr index 184b3ea6da82b..55b08b74af062 100644 --- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr @@ -10,7 +10,9 @@ error[E0308]: mismatched types --> $DIR/tuple_destructure_fail.rs:6:5 | LL | (a, a, b) = (1, 2); - | ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements + | ^^^^^^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 3 elements | = note: expected type `({integer}, {integer})` found tuple `(_, _, _)` @@ -27,7 +29,9 @@ error[E0308]: mismatched types --> $DIR/tuple_destructure_fail.rs:8:5 | LL | (_,) = (1, 2); - | ^^^^ expected a tuple with 2 elements, found one with 1 element + | ^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 1 element | = note: expected type `({integer}, {integer})` found tuple `(_,)` diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr index 241485db49bc9..a6f8563a04785 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [_, 99.., _] => {}, | ^^ expected struct `std::ops::Range`, found integer | diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr index 777d029d7dd7b..4e0102c930da8 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr @@ -7,6 +7,8 @@ LL | [_, 99..] => {}, error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [_, 99..] => {}, | ^^ expected struct `std::ops::Range`, found integer | diff --git a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr index 6119733a7d84b..665eef2fcb96c 100644 --- a/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:12 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [..9, 99..100, _] => {}, | ^ expected struct `std::ops::Range`, found integer | @@ -10,6 +12,8 @@ LL | [..9, 99..100, _] => {}, error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [..9, 99..100, _] => {}, | ^^ --- this is of type `{integer}` | | @@ -21,6 +25,8 @@ LL | [..9, 99..100, _] => {}, error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [..9, 99..100, _] => {}, | -- ^^^ expected struct `std::ops::Range`, found integer | | diff --git a/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr b/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr index 31ea3a17871a5..307ad711b74d9 100644 --- a/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr +++ b/src/test/ui/half-open-range-patterns/pat-tuple-5.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/pat-tuple-5.rs:8:10 | +LL | match (0, 1) { + | ------ this expression has type `({integer}, {integer})` LL | (PAT ..) => {} | ^^^ expected tuple, found `u8` | diff --git a/src/test/ui/issues/issue-11844.stderr b/src/test/ui/issues/issue-11844.stderr index ecab1074a295f..9d7470e7af9aa 100644 --- a/src/test/ui/issues/issue-11844.stderr +++ b/src/test/ui/issues/issue-11844.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-11844.rs:6:9 | +LL | match a { + | - this expression has type `Option>` LL | Ok(a) => | ^^^^^ expected enum `Option`, found enum `Result` | diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/issues/issue-12552.stderr index 1ba6852b17c06..3d8852ca748af 100644 --- a/src/test/ui/issues/issue-12552.stderr +++ b/src/test/ui/issues/issue-12552.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-12552.rs:6:5 | +LL | match t { + | - this expression has type `Result<_, {integer}>` LL | Some(k) => match k { | ^^^^^^^ expected enum `Result`, found enum `Option` | @@ -10,6 +12,9 @@ LL | Some(k) => match k { error[E0308]: mismatched types --> $DIR/issue-12552.rs:9:5 | +LL | match t { + | - this expression has type `Result<_, {integer}>` +... LL | None => () | ^^^^ expected enum `Result`, found enum `Option` | diff --git a/src/test/ui/issues/issue-13466.stderr b/src/test/ui/issues/issue-13466.stderr index 15ee49a5fdd25..c78466f4e8ce1 100644 --- a/src/test/ui/issues/issue-13466.stderr +++ b/src/test/ui/issues/issue-13466.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-13466.rs:8:9 | +LL | let _x: usize = match Some(1) { + | ------- this expression has type `Option<{integer}>` LL | Ok(u) => u, | ^^^^^ expected enum `Option`, found enum `Result` | @@ -10,6 +12,9 @@ LL | Ok(u) => u, error[E0308]: mismatched types --> $DIR/issue-13466.rs:14:9 | +LL | let _x: usize = match Some(1) { + | ------- this expression has type `Option<{integer}>` +... LL | Err(e) => panic!(e) | ^^^^^^ expected enum `Option`, found enum `Result` | diff --git a/src/test/ui/issues/issue-33504.stderr b/src/test/ui/issues/issue-33504.stderr index 1e61178f42edb..ec15525ed0601 100644 --- a/src/test/ui/issues/issue-33504.stderr +++ b/src/test/ui/issues/issue-33504.stderr @@ -5,7 +5,7 @@ LL | struct Test; | ------------ unit struct defined here ... LL | let Test = 1; - | ^^^^ + | ^^^^ - this expression has type `{integer}` | | | expected integer, found struct `Test` | `Test` is interpreted as a unit struct, not a new binding diff --git a/src/test/ui/issues/issue-3680.stderr b/src/test/ui/issues/issue-3680.stderr index 8dc0dfa2356f4..e8fafa76b919b 100644 --- a/src/test/ui/issues/issue-3680.stderr +++ b/src/test/ui/issues/issue-3680.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-3680.rs:3:9 | +LL | match None { + | ---- this expression has type `Option<_>` LL | Err(_) => () | ^^^^^^ expected enum `Option`, found enum `Result` | diff --git a/src/test/ui/issues/issue-4968.stderr b/src/test/ui/issues/issue-4968.stderr index 5451cf423559e..57ff7fe09e5b9 100644 --- a/src/test/ui/issues/issue-4968.stderr +++ b/src/test/ui/issues/issue-4968.stderr @@ -5,11 +5,12 @@ LL | const A: (isize,isize) = (4,2); | ------------------------------- constant defined here LL | fn main() { LL | match 42 { A => () } - | ^ - | | - | expected integer, found tuple - | `A` is interpreted as a constant, not a new binding - | help: introduce a new binding instead: `other_a` + | -- ^ + | | | + | | expected integer, found tuple + | | `A` is interpreted as a constant, not a new binding + | | help: introduce a new binding instead: `other_a` + | this expression has type `{integer}` | = note: expected type `{integer}` found tuple `(isize, isize)` diff --git a/src/test/ui/issues/issue-72574-1.stderr b/src/test/ui/issues/issue-72574-1.stderr index 5d3d390a95ded..653869a237d88 100644 --- a/src/test/ui/issues/issue-72574-1.stderr +++ b/src/test/ui/issues/issue-72574-1.stderr @@ -21,6 +21,8 @@ LL | (_a, _x @ ..) => {} error[E0308]: mismatched types --> $DIR/issue-72574-1.rs:4:9 | +LL | match x { + | - this expression has type `({integer}, {integer}, {integer})` LL | (_a, _x @ ..) => {} | ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements | diff --git a/src/test/ui/keyword/keyword-false-as-identifier.stderr b/src/test/ui/keyword/keyword-false-as-identifier.stderr index fcc3006401816..6dcfa3a481161 100644 --- a/src/test/ui/keyword/keyword-false-as-identifier.stderr +++ b/src/test/ui/keyword/keyword-false-as-identifier.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/keyword-false-as-identifier.rs:2:9 | LL | let false = 22; - | ^^^^^ expected integer, found `bool` + | ^^^^^ -- this expression has type `{integer}` + | | + | expected integer, found `bool` error: aborting due to previous error diff --git a/src/test/ui/keyword/keyword-true-as-identifier.stderr b/src/test/ui/keyword/keyword-true-as-identifier.stderr index b8cc2ffd2a826..86f6e00064f7d 100644 --- a/src/test/ui/keyword/keyword-true-as-identifier.stderr +++ b/src/test/ui/keyword/keyword-true-as-identifier.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/keyword-true-as-identifier.rs:2:9 | LL | let true = 22; - | ^^^^ expected integer, found `bool` + | ^^^^ -- this expression has type `{integer}` + | | + | expected integer, found `bool` error: aborting due to previous error diff --git a/src/test/ui/match/match-range-fail.stderr b/src/test/ui/match/match-range-fail.stderr index 938c05ac7324c..65db92df19f79 100644 --- a/src/test/ui/match/match-range-fail.stderr +++ b/src/test/ui/match/match-range-fail.stderr @@ -27,6 +27,8 @@ LL | true ..= "what" => {} error[E0308]: mismatched types --> $DIR/match-range-fail.rs:18:9 | +LL | match 5 { + | - this expression has type `{integer}` LL | 'c' ..= 100 => { } | ^^^ --- this is of type `{integer}` | | diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr index eb884bcc6226f..ef03b67b1b0b1 100644 --- a/src/test/ui/mismatched_types/E0409.stderr +++ b/src/test/ui/mismatched_types/E0409.stderr @@ -9,6 +9,8 @@ LL | (0, ref y) | (y, 0) => {} error[E0308]: mismatched types --> $DIR/E0409.rs:5:23 | +LL | match x { + | - this expression has type `({integer}, {integer})` LL | (0, ref y) | (y, 0) => {} | ----- ^ expected `&{integer}`, found integer | | diff --git a/src/test/ui/mut/mut-pattern-mismatched.stderr b/src/test/ui/mut/mut-pattern-mismatched.stderr index ccc8ac1278c63..cad1cef5155d5 100644 --- a/src/test/ui/mut/mut-pattern-mismatched.stderr +++ b/src/test/ui/mut/mut-pattern-mismatched.stderr @@ -3,6 +3,9 @@ error[E0308]: mismatched types | LL | let &_ | ^^ types differ in mutability +... +LL | = foo; + | --- this expression has type `&mut {integer}` | = note: expected mutable reference `&mut {integer}` found reference `&_` @@ -12,6 +15,9 @@ error[E0308]: mismatched types | LL | let &mut _ | ^^^^^^ types differ in mutability +... +LL | = bar; + | --- this expression has type `&{integer}` | = note: expected reference `&{integer}` found mutable reference `&mut _` diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr index 92416a0d5cbf0..66112165622b9 100644 --- a/src/test/ui/or-patterns/already-bound-name.stderr +++ b/src/test/ui/or-patterns/already-bound-name.stderr @@ -86,8 +86,9 @@ error[E0308]: mismatched types --> $DIR/already-bound-name.rs:30:32 | LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1)); - | - ^ expected integer, found enum `E` - | | + | - ^ ------- this expression has type `E>` + | | | + | | expected integer, found enum `E` | first introduced with type `{integer}` here | = note: expected type `{integer}` diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr index 95e8618808c08..dae6bb41e74e2 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.stderr +++ b/src/test/ui/or-patterns/inconsistent-modes.stderr @@ -65,8 +65,9 @@ error[E0308]: mismatched types --> $DIR/inconsistent-modes.rs:13:32 | LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0)); - | ----- ^^^^^^^^^ types differ in mutability - | | + | ----- ^^^^^^^^^ ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>` + | | | + | | types differ in mutability | first introduced with type `&{integer}` here | = note: expected type `&{integer}` diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index 9296ad2e335f1..8063ba8e9f7bd 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -303,8 +303,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:22:12 | LL | if let .0..Y = 0 {} - | ^^ - this is of type `u8` - | | + | ^^ - - this expression has type `{integer}` + | | | + | | this is of type `u8` | expected integer, found floating-point number error[E0308]: mismatched types @@ -336,8 +337,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:35:12 | LL | if let .0..=Y = 0 {} - | ^^ - this is of type `u8` - | | + | ^^ - - this expression has type `{integer}` + | | | + | | this is of type `u8` | expected integer, found floating-point number error[E0308]: mismatched types @@ -369,8 +371,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:60:12 | LL | if let .0...Y = 0 {} - | ^^ - this is of type `u8` - | | + | ^^ - - this expression has type `{integer}` + | | | + | | this is of type `u8` | expected integer, found floating-point number error[E0308]: mismatched types @@ -392,7 +395,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:75:12 | LL | if let .0.. = 0 {} - | ^^ expected integer, found floating-point number + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:83:12 @@ -404,7 +409,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:85:12 | LL | if let .0..= = 0 {} - | ^^ expected integer, found floating-point number + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:93:12 @@ -416,7 +423,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:95:12 | LL | if let .0... = 0 {} - | ^^ expected integer, found floating-point number + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:103:14 @@ -428,7 +437,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:105:15 | LL | if let .. .0 = 0 {} - | ^^ expected integer, found floating-point number + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:113:15 @@ -440,7 +451,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:115:15 | LL | if let ..=.0 = 0 {} - | ^^ expected integer, found floating-point number + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:125:15 @@ -452,7 +465,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:128:15 | LL | if let ....3 = 0 {} - | ^^ expected integer, found floating-point number + | ^^ - this expression has type `{integer}` + | | + | expected integer, found floating-point number error: aborting due to 60 previous errors diff --git a/src/test/ui/pattern/issue-74702.stderr b/src/test/ui/pattern/issue-74702.stderr index 53dcf97f81c6a..f2e2c8f021bad 100644 --- a/src/test/ui/pattern/issue-74702.stderr +++ b/src/test/ui/pattern/issue-74702.stderr @@ -22,7 +22,9 @@ error[E0308]: mismatched types --> $DIR/issue-74702.rs:2:9 | LL | let (foo @ ..,) = (0, 0); - | ^^^^^^^^^^^ expected a tuple with 2 elements, found one with 1 element + | ^^^^^^^^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 1 element | = note: expected tuple `({integer}, {integer})` found tuple `(_,)` diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index 64b6e5eec5562..1c44f7e5f6f1f 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -150,6 +150,8 @@ LL | E1::Z0 => {} error[E0308]: mismatched types --> $DIR/pat-tuple-overfield.rs:19:9 | +LL | match (1, 2, 3) { + | --------- this expression has type `({integer}, {integer}, {integer})` LL | (1, 2, 3, 4) => {} | ^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements | @@ -159,6 +161,9 @@ LL | (1, 2, 3, 4) => {} error[E0308]: mismatched types --> $DIR/pat-tuple-overfield.rs:20:9 | +LL | match (1, 2, 3) { + | --------- this expression has type `({integer}, {integer}, {integer})` +LL | (1, 2, 3, 4) => {} LL | (1, 2, .., 3, 4) => {} | ^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements | diff --git a/src/test/ui/slightly-nice-generic-literal-messages.stderr b/src/test/ui/slightly-nice-generic-literal-messages.stderr index 61eabed950423..14f01f0ebdf73 100644 --- a/src/test/ui/slightly-nice-generic-literal-messages.stderr +++ b/src/test/ui/slightly-nice-generic-literal-messages.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/slightly-nice-generic-literal-messages.rs:7:9 | +LL | match Foo(1.1, marker::PhantomData) { + | ----------------------------- this expression has type `Foo<{float}, _>` LL | 1 => {} | ^ expected struct `Foo`, found integer | diff --git a/src/test/ui/structs/structure-constructor-type-mismatch.stderr b/src/test/ui/structs/structure-constructor-type-mismatch.stderr index 98972a1215996..3d64fc601df98 100644 --- a/src/test/ui/structs/structure-constructor-type-mismatch.stderr +++ b/src/test/ui/structs/structure-constructor-type-mismatch.stderr @@ -101,6 +101,8 @@ LL | type PointF = Point; error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:54:9 | +LL | match (Point { x: 1, y: 2 }) { + | ---------------------- this expression has type `Point<{integer}>` LL | PointF:: { .. } => {} | ^^^^^^^^^^^^^^^^^^^^ expected integer, found `f32` | @@ -110,6 +112,8 @@ LL | PointF:: { .. } => {} error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:59:9 | +LL | match (Point { x: 1, y: 2 }) { + | ---------------------- this expression has type `Point<{integer}>` LL | PointF { .. } => {} | ^^^^^^^^^^^^^ expected integer, found `f32` | @@ -119,6 +123,8 @@ LL | PointF { .. } => {} error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:67:9 | +LL | match (Pair { x: 1, y: 2 }) { + | --------------------- this expression has type `Pair<{integer}, {integer}>` LL | PairF:: { .. } => {} | ^^^^^^^^^^^^^^^^^^^ expected integer, found `f32` | From b09420f95a719c85e60b501955d356b1c34abf16 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 15 Dec 2021 23:25:03 +0000 Subject: [PATCH 09/11] Drive by: handle references in `same_type_modulo_infer` --- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f1c21f5923926..78b21a235cb8e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -333,6 +333,9 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { ) | (&ty::Infer(ty::InferTy::TyVar(_)), _) | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true, + (&ty::Ref(reg_a, ty_a, mut_a), &ty::Ref(reg_b, ty_b, mut_b)) => { + reg_a == reg_b && mut_a == mut_b && same_type_modulo_infer(ty_a, ty_b) + } _ => a == b, } } From 1db02b8a438aa3b0d6dcbf3628a5142eda0a8589 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 15 Dec 2021 23:49:03 +0000 Subject: [PATCH 10/11] Change wording of missing return type suggestion --- .../src/check/fn_ctxt/suggestions.rs | 11 +++++++++-- src/test/ui/block-result/issue-20862.stderr | 2 +- .../diverging-tuple-parts-39485.stderr | 6 ++++-- src/test/ui/typeck/issue-91334.stderr | 2 +- .../typeck/return_type_containing_closure.rs | 4 ++-- .../return_type_containing_closure.stderr | 19 +++++++++++-------- 6 files changed, 28 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 37014b5eea5c1..e6a98ad6dc051 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -530,13 +530,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( span, "try adding a return type", - format!("-> {} ", self.resolve_vars_with_obligations(found)), + format!("-> {} ", found), Applicability::MachineApplicable, ); true } (&hir::FnRetTy::DefaultReturn(span), false, true, true) => { - err.span_label(span, "possibly return type missing here?"); + // FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest + // that. + err.span_suggestion( + span, + "a return type might be missing here", + "-> _ ".to_string(), + Applicability::HasPlaceholders, + ); true } (&hir::FnRetTy::DefaultReturn(span), _, false, true) => { diff --git a/src/test/ui/block-result/issue-20862.stderr b/src/test/ui/block-result/issue-20862.stderr index 09c06e8428d20..e9ca0ad9029e6 100644 --- a/src/test/ui/block-result/issue-20862.stderr +++ b/src/test/ui/block-result/issue-20862.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-20862.rs:2:5 | LL | fn foo(x: i32) { - | - possibly return type missing here? + | - help: a return type might be missing here: `-> _` LL | |y| x + y | ^^^^^^^^^ expected `()`, found closure | diff --git a/src/test/ui/never_type/diverging-tuple-parts-39485.stderr b/src/test/ui/never_type/diverging-tuple-parts-39485.stderr index e99a38aaaee95..4b5b8c45d5939 100644 --- a/src/test/ui/never_type/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/never_type/diverging-tuple-parts-39485.stderr @@ -1,13 +1,15 @@ error[E0308]: mismatched types --> $DIR/diverging-tuple-parts-39485.rs:8:5 | -LL | fn g() { - | - possibly return type missing here? LL | &panic!() | ^^^^^^^^^ expected `()`, found reference | = note: expected unit type `()` found reference `&_` +help: a return type might be missing here + | +LL | fn g() -> _ { + | ++++ help: consider removing the borrow | LL - &panic!() diff --git a/src/test/ui/typeck/issue-91334.stderr b/src/test/ui/typeck/issue-91334.stderr index 0872e83ea2e7e..633c7b11aa2f8 100644 --- a/src/test/ui/typeck/issue-91334.stderr +++ b/src/test/ui/typeck/issue-91334.stderr @@ -40,7 +40,7 @@ error[E0308]: mismatched types LL | fn f(){||yield(((){), | -^^^^^^^^^^^^^^^ expected `()`, found generator | | - | possibly return type missing here? + | help: a return type might be missing here: `-> _` | = note: expected unit type `()` found generator `[generator@$DIR/issue-91334.rs:10:8: 10:23]` diff --git a/src/test/ui/typeck/return_type_containing_closure.rs b/src/test/ui/typeck/return_type_containing_closure.rs index aee9769b28038..29624e08a2e80 100644 --- a/src/test/ui/typeck/return_type_containing_closure.rs +++ b/src/test/ui/typeck/return_type_containing_closure.rs @@ -1,10 +1,10 @@ #[allow(unused)] -fn foo() { - //~^ NOTE possibly return type missing here? +fn foo() { //~ HELP a return type might be missing here vec!['a'].iter().map(|c| c) //~^ ERROR mismatched types [E0308] //~| NOTE expected `()`, found struct `Map` //~| NOTE expected unit type `()` + //~| HELP consider using a semicolon here } fn main() {} diff --git a/src/test/ui/typeck/return_type_containing_closure.stderr b/src/test/ui/typeck/return_type_containing_closure.stderr index b08152d63318e..ae72b1477c885 100644 --- a/src/test/ui/typeck/return_type_containing_closure.stderr +++ b/src/test/ui/typeck/return_type_containing_closure.stderr @@ -1,16 +1,19 @@ error[E0308]: mismatched types - --> $DIR/return_type_containing_closure.rs:4:5 + --> $DIR/return_type_containing_closure.rs:3:5 | -LL | fn foo() { - | - possibly return type missing here? -LL | LL | vec!['a'].iter().map(|c| c) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` - | | - | expected `()`, found struct `Map` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Map` | = note: expected unit type `()` - found struct `Map, [closure@$DIR/return_type_containing_closure.rs:4:26: 4:31]>` + found struct `Map, [closure@$DIR/return_type_containing_closure.rs:3:26: 3:31]>` +help: consider using a semicolon here + | +LL | vec!['a'].iter().map(|c| c); + | + +help: a return type might be missing here + | +LL | fn foo() -> _ { + | ++++ error: aborting due to previous error From f479e262d68271c1190dba6560923aff026d32fe Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Sun, 27 Mar 2022 02:40:07 +0000 Subject: [PATCH 11/11] review comments and rebase --- .../rustc_infer/src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 16 ++++++++-------- compiler/rustc_typeck/src/astconv/generics.rs | 4 +--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 78b21a235cb8e..238145c5c6ee4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -334,7 +334,7 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { | (&ty::Infer(ty::InferTy::TyVar(_)), _) | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true, (&ty::Ref(reg_a, ty_a, mut_a), &ty::Ref(reg_b, ty_b, mut_b)) => { - reg_a == reg_b && mut_a == mut_b && same_type_modulo_infer(ty_a, ty_b) + reg_a == reg_b && mut_a == mut_b && same_type_modulo_infer(*ty_a, *ty_b) } _ => a == b, } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 5878cfdf0b7fc..83ba9c96978d0 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1441,7 +1441,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if !value.needs_infer() { return value; // Avoid duplicated subst-folding. } - let mut r = InferenceLiteralEraser { infcx: self }; + let mut r = InferenceLiteralEraser { tcx: self.tcx }; value.fold_with(&mut r) } @@ -1798,19 +1798,19 @@ impl<'tcx> TyOrConstInferVar<'tcx> { /// Replace `{integer}` with `i32` and `{float}` with `f64`. /// Used only for diagnostics. -struct InferenceLiteralEraser<'a, 'tcx> { - infcx: &'a InferCtxt<'a, 'tcx>, +struct InferenceLiteralEraser<'tcx> { + tcx: TyCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { - self.infcx.tcx +impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { match ty.kind() { - ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => self.tcx().types.i32, - ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => self.tcx().types.f64, + ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => self.tcx.types.i32, + ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => self.tcx.types.f64, _ => ty.super_fold_with(self), } } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 451e1e05d1458..a07700aa9f5b9 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -85,9 +85,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id); let param_name = tcx.hir().ty_param_name(param_hir_id); let param_type = tcx.infer_ctxt().enter(|infcx| { - infcx.resolve_numeric_literals_with_default( - infcx.resolve_vars_if_possible(tcx.type_of(param.def_id)), - ) + infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id)) }); if param_type.is_suggestable() { err.span_suggestion(