Split hir TyKind and ConstArgKind in two and update hir::Visitor

This commit is contained in:
Boxy 2025-01-11 19:12:36 +00:00
parent 0f10ba60ff
commit 98d80e22d0
48 changed files with 513 additions and 313 deletions

View file

@ -1,8 +1,8 @@
use core::ops::ControlFlow;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::{self as hir, AmbigArg};
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars as rbv;
@ -48,7 +48,7 @@ fn find_component_for_bound_region<'tcx>(
region_def_id: DefId,
) -> Option<&'tcx hir::Ty<'tcx>> {
FindNestedTypeVisitor { tcx, region_def_id, current_index: ty::INNERMOST }
.visit_ty(arg)
.visit_unambig_ty(arg)
.break_value()
}
@ -74,7 +74,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
self.tcx.hir()
}
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) -> Self::Result {
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
match arg.kind {
hir::TyKind::BareFn(_) => {
self.current_index.shift_in(1);
@ -101,7 +101,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
Some(rbv::ResolvedArg::EarlyBound(id)) => {
debug!("EarlyBound id={:?}", id);
if id.to_def_id() == self.region_def_id {
return ControlFlow::Break(arg);
return ControlFlow::Break(arg.as_unambig_ty());
}
}
@ -117,7 +117,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
if debruijn_index == self.current_index
&& id.to_def_id() == self.region_def_id
{
return ControlFlow::Break(arg);
return ControlFlow::Break(arg.as_unambig_ty());
}
}
@ -147,7 +147,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
)
.is_break()
{
ControlFlow::Break(arg)
ControlFlow::Break(arg.as_unambig_ty())
} else {
ControlFlow::Continue(())
};
@ -210,7 +210,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
ControlFlow::Continue(())
}
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) -> Self::Result {
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
// ignore nested types
//
// If you have a type like `Foo<'a, &Ty>` we

View file

@ -4,7 +4,7 @@
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
use rustc_hir::intravisit::VisitorExt;
use rustc_middle::bug;
use rustc_middle::ty::TypeVisitor;
use tracing::debug;
@ -87,7 +87,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
for matching_def_id in v.0 {
let mut hir_v =
super::static_impl_trait::HirTraitObjectVisitor(&mut traits, matching_def_id);
hir_v.visit_ty(impl_self_ty);
hir_v.visit_unambig_ty(impl_self_ty);
}
if traits.is_empty() {

View file

@ -3,9 +3,9 @@
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, Subdiagnostic};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{Visitor, walk_ty};
use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
use rustc_hir::{
self as hir, GenericBound, GenericParam, GenericParamKind, Item, ItemKind, Lifetime,
self as hir, AmbigArg, GenericBound, GenericParam, GenericParamKind, Item, ItemKind, Lifetime,
LifetimeName, LifetimeParamKind, MissingLifetimeKind, Node, TyKind,
};
use rustc_middle::ty::{
@ -153,7 +153,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let mut add_label = true;
if let hir::FnRetTy::Return(ty) = fn_decl.output {
let mut v = StaticLifetimeVisitor(vec![], tcx.hir());
v.visit_ty(ty);
v.visit_unambig_ty(ty);
if !v.0.is_empty() {
span = v.0.clone().into();
spans = v.0;
@ -500,7 +500,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// In that case, only the first one will get suggestions.
let mut traits = vec![];
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
hir_v.visit_ty(self_ty);
hir_v.visit_unambig_ty(self_ty);
!traits.is_empty()
})
{
@ -560,7 +560,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
for found_did in found_dids {
let mut traits = vec![];
let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
hir_v.visit_ty(self_ty);
hir_v.visit_unambig_ty(self_ty);
for &span in &traits {
let subdiag = DynTraitConstraintSuggestion { span, ident };
subdiag.add_to_diag(err);
@ -591,7 +591,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for TraitObjectVisitor {
pub struct HirTraitObjectVisitor<'a>(pub &'a mut Vec<Span>, pub DefId);
impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) {
if let TyKind::TraitObject(poly_trait_refs, lifetime_ptr) = t.kind
&& let Lifetime { res: LifetimeName::ImplicitObjectLifetimeDefault, .. } =
lifetime_ptr.pointer()

View file

@ -1,10 +1,10 @@
//! Error Reporting for `impl` items that do not match the obligations from their `trait`.
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{Namespace, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::intravisit::{Visitor, walk_ty};
use rustc_hir::{self as hir, AmbigArg};
use rustc_middle::hir::nested_filter;
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::ExpectedFound;
@ -137,11 +137,13 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
self.tcx.hir()
}
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx, AmbigArg>) {
match arg.kind {
hir::TyKind::Ref(_, ref mut_ty) => {
// We don't want to suggest looking into borrowing `&T` or `&Self`.
hir::intravisit::walk_ty(self, mut_ty.ty);
if let Some(ambig_ty) = mut_ty.ty.try_as_ambig_ty() {
walk_ty(self, ambig_ty);
}
return;
}
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {

View file

@ -643,7 +643,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& let ty::Ref(found_region, _, _) = found.kind()
&& expected_region.is_bound()
&& !found_region.is_bound()
&& let hir::TyKind::Infer = arg_hir.kind
&& let hir::TyKind::Infer(()) = arg_hir.kind
{
// If the expected region is late bound, the found region is not, and users are asking compiler
// to infer the type, we can suggest adding `: &_`.

View file

@ -11,7 +11,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, LangItem};
use rustc_hir::{self as hir, AmbigArg, LangItem};
use rustc_infer::traits::{
DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode,
PredicateObligation, SelectionError,
@ -87,9 +87,9 @@ impl<'v> Visitor<'v> for FindExprBySpan<'v> {
}
}
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
if self.span == ty.span {
self.ty_result = Some(ty);
self.ty_result = Some(ty.as_unambig_ty());
} else {
hir::intravisit::walk_ty(self, ty);
}

View file

@ -14,14 +14,13 @@ use rustc_errors::{
Applicability, Diag, EmissionGuarantee, MultiSpan, Style, SuggestionStyle, pluralize,
struct_span_code_err,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::intravisit::{Visitor, VisitorExt};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node, expr_needs_parens,
is_range_literal,
self as hir, AmbigArg, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node,
expr_needs_parens, is_range_literal,
};
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_middle::hir::map;
@ -179,7 +178,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
let mut ty_spans = vec![];
for input in fn_sig.decl.inputs {
ReplaceImplTraitVisitor { ty_spans: &mut ty_spans, param_did: param.def_id }
.visit_ty(input);
.visit_unambig_ty(input);
}
// The type param `T: Trait` we will suggest to introduce.
let type_param = format!("{type_param_name}: {bound_str}");
@ -5065,7 +5064,7 @@ pub struct SelfVisitor<'v> {
}
impl<'v> Visitor<'v> for SelfVisitor<'v> {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
if let hir::TyKind::Path(path) = ty.kind
&& let hir::QPath::TypeRelative(inner_ty, segment) = path
&& (Some(segment.ident.name) == self.name || self.name.is_none())
@ -5073,7 +5072,7 @@ impl<'v> Visitor<'v> for SelfVisitor<'v> {
&& let hir::QPath::Resolved(None, inner_path) = inner_path
&& let Res::SelfTyAlias { .. } = inner_path.res
{
self.paths.push(ty);
self.paths.push(ty.as_unambig_ty());
}
hir::intravisit::walk_ty(self, ty);
}
@ -5187,7 +5186,7 @@ struct ReplaceImplTraitVisitor<'a> {
}
impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
fn visit_ty(&mut self, t: &'hir hir::Ty<'hir>) {
fn visit_ty(&mut self, t: &'hir hir::Ty<'hir, AmbigArg>) {
if let hir::TyKind::Path(hir::QPath::Resolved(
None,
hir::Path { res: Res::Def(_, segment_did), .. },
@ -5480,7 +5479,7 @@ impl<'v> Visitor<'v> for FindTypeParam {
// Skip where-clauses, to avoid suggesting indirection for type parameters found there.
}
fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
fn visit_ty(&mut self, ty: &hir::Ty<'_, AmbigArg>) {
// We collect the spans of all uses of the "bare" type param, like in `field: T` or
// `field: (T, T)` where we could make `T: ?Sized` while skipping cases that are known to be
// valid like `field: &'a T` or `field: *mut T` and cases that *might* have further `Sized`

View file

@ -6,11 +6,10 @@ use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic,
EmissionGuarantee, IntoDiagArg, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic,
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{Visitor, walk_ty};
use rustc_hir::{FnRetTy, GenericParamKind, Node};
use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt};
@ -579,7 +578,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
}
impl<'v> Visitor<'v> for ImplicitLifetimeFinder {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
let make_suggestion = |ident: Ident| {
if ident.name == kw::Empty && ident.span.is_empty() {
format!("{}, ", self.suggestion_param_name)
@ -642,16 +641,16 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
if let Some(fn_decl) = node.fn_decl()
&& let hir::FnRetTy::Return(ty) = fn_decl.output
{
visitor.visit_ty(ty);
visitor.visit_unambig_ty(ty);
}
if visitor.suggestions.is_empty() {
// Do not suggest constraining the `&self` param, but rather the return type.
// If that is wrong (because it is not sufficient), a follow up error will tell the
// user to fix it. This way we lower the chances of *over* constraining, but still
// get the cake of "correctly" contrained in two steps.
visitor.visit_ty(self.ty_sup);
visitor.visit_unambig_ty(self.ty_sup);
}
visitor.visit_ty(self.ty_sub);
visitor.visit_unambig_ty(self.ty_sub);
if visitor.suggestions.is_empty() {
return false;
}