Rollup merge of #91981 - estebank:tweakaroo, r=lcnr
Recover suggestions and useful information lost in previous PR Follow up to #91898.
This commit is contained in:
commit
4435bb0704
41 changed files with 209 additions and 60 deletions
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -602,7 +605,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));
|
||||
}
|
||||
|
|
|
@ -1434,6 +1434,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
value.fold_with(&mut r)
|
||||
}
|
||||
|
||||
pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
if !value.needs_infer() {
|
||||
return value; // Avoid duplicated subst-folding.
|
||||
}
|
||||
let mut r = InferenceLiteralEraser { tcx: self.tcx };
|
||||
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<'tcx> {
|
||||
tcx: TyCtxt<'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.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ShallowResolver<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
|
|
@ -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,9 @@ 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(tcx.type_of(param.def_id))
|
||||
});
|
||||
if param_type.is_suggestable() {
|
||||
err.span_suggestion(
|
||||
tcx.def_span(src_def_id),
|
||||
|
|
|
@ -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()) {
|
||||
|
@ -528,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) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue