Auto merge of #106215 - matthiaskrgr:rollup-53r89ww, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #106028 (docs/test: add UI test and long-form error docs for `E0461`) - #106172 (Suggest `impl Iterator` when possible for `_` return type) - #106173 (Deduplicate `op` methods) - #106176 (Recover `fn` keyword as `Fn` trait in bounds) - #106194 (rustdoc: combine common sidebar background color CSS rules) - #106199 (Silence knock-down errors on `[type error]` bindings) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
270c94e484
36 changed files with 502 additions and 397 deletions
|
@ -24,6 +24,8 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{GenericParamKind, Node};
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
|
@ -31,7 +33,9 @@ use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyC
|
|||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use std::iter;
|
||||
|
||||
mod generics_of;
|
||||
|
@ -1224,7 +1228,17 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||
// to prevent the user from getting a papercut while trying to use the unique closure
|
||||
// syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
|
||||
diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
|
||||
diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
|
||||
diag.note(
|
||||
"for more information on `Fn` traits and closure types, see \
|
||||
https://doc.rust-lang.org/book/ch13-01-closures.html",
|
||||
);
|
||||
} else if let Some(i_ty) = suggest_impl_iterator(tcx, ret_ty, ty.span, hir_id, def_id) {
|
||||
diag.span_suggestion(
|
||||
ty.span,
|
||||
"replace with an appropriate return type",
|
||||
format!("impl Iterator<Item = {}>", i_ty),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
diag.emit();
|
||||
|
||||
|
@ -1242,6 +1256,51 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_impl_iterator<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ret_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
def_id: LocalDefId,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) else { return None; };
|
||||
let Some(iterator_item) = tcx.get_diagnostic_item(sym::IteratorItem) else { return None; };
|
||||
if !tcx
|
||||
.infer_ctxt()
|
||||
.build()
|
||||
.type_implements_trait(iter_trait, [ret_ty], tcx.param_env(def_id))
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
|
||||
// Find the type of `Iterator::Item`.
|
||||
let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
|
||||
let ty_var = infcx.next_ty_var(origin);
|
||||
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Projection(
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: tcx.mk_alias_ty(iterator_item, tcx.mk_substs([ret_ty.into()].iter())),
|
||||
term: ty_var.into(),
|
||||
},
|
||||
)));
|
||||
// Add `<ret_ty as Iterator>::Item = _` obligation.
|
||||
ocx.register_obligation(crate::traits::Obligation::misc(
|
||||
tcx,
|
||||
span,
|
||||
hir_id,
|
||||
tcx.param_env(def_id),
|
||||
projection,
|
||||
));
|
||||
if ocx.select_where_possible().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(ty_var)
|
||||
&& item_ty.is_suggestable(tcx, false)
|
||||
{
|
||||
return Some(item_ty);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
|
||||
let icx = ItemCtxt::new(tcx, def_id);
|
||||
let item = tcx.hir().expect_item(def_id.expect_local());
|
||||
|
|
|
@ -5,6 +5,7 @@ use rustc_hir::intravisit;
|
|||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{HirId, Node};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
|
||||
|
@ -907,10 +908,10 @@ fn infer_placeholder_type<'a>(
|
|||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.span_note(
|
||||
with_forced_trimmed_paths!(err.span_note(
|
||||
tcx.hir().body(body_id).value.span,
|
||||
&format!("however, the inferred type `{}` cannot be named", ty),
|
||||
);
|
||||
&format!("however, the inferred type `{ty}` cannot be named"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -931,10 +932,10 @@ fn infer_placeholder_type<'a>(
|
|||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
diag.span_note(
|
||||
with_forced_trimmed_paths!(diag.span_note(
|
||||
tcx.hir().body(body_id).value.span,
|
||||
&format!("however, the inferred type `{}` cannot be named", ty),
|
||||
);
|
||||
&format!("however, the inferred type `{ty}` cannot be named"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue