1
Fork 0

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,3 +1,4 @@
use intravisit::InferKind;
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap}; use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
@ -265,14 +266,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}); });
} }
fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir>) {
self.insert(const_arg.span(), const_arg.hir_id, Node::ConstArg(const_arg));
self.with_parent(const_arg.hir_id, |this| {
intravisit::walk_const_arg(this, const_arg);
});
}
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) { fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
self.insert(expr.span, expr.hir_id, Node::Expr(expr)); self.insert(expr.span, expr.hir_id, Node::Expr(expr));
@ -302,22 +295,41 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
intravisit::walk_path_segment(self, path_segment); intravisit::walk_path_segment(self, path_segment);
} }
fn visit_ty(&mut self, ty: &'hir Ty<'hir>) { fn visit_ty(&mut self, ty: &'hir Ty<'hir, AmbigArg>) {
self.insert(ty.span, ty.hir_id, Node::Ty(ty)); self.insert(ty.span, ty.hir_id, Node::Ty(ty.as_unambig_ty()));
self.with_parent(ty.hir_id, |this| { self.with_parent(ty.hir_id, |this| {
intravisit::walk_ty(this, ty); intravisit::walk_ty(this, ty);
}); });
} }
fn visit_infer(&mut self, inf: &'hir InferArg) { fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir, AmbigArg>) {
self.insert(inf.span, inf.hir_id, Node::Infer(inf)); self.insert(
const_arg.as_unambig_ct().span(),
const_arg.hir_id,
Node::ConstArg(const_arg.as_unambig_ct()),
);
self.with_parent(inf.hir_id, |this| { self.with_parent(const_arg.hir_id, |this| {
intravisit::walk_inf(this, inf); intravisit::walk_ambig_const_arg(this, const_arg);
}); });
} }
fn visit_infer(
&mut self,
inf_id: HirId,
inf_span: Span,
kind: InferKind<'hir>,
) -> Self::Result {
match kind {
InferKind::Ty(ty) => self.insert(inf_span, inf_id, Node::Ty(ty)),
InferKind::Const(ct) => self.insert(inf_span, inf_id, Node::ConstArg(ct)),
InferKind::Ambig(inf) => self.insert(inf_span, inf_id, Node::Infer(inf)),
}
self.visit_id(inf_id);
}
fn visit_trait_ref(&mut self, tr: &'hir TraitRef<'hir>) { fn visit_trait_ref(&mut self, tr: &'hir TraitRef<'hir>) {
self.insert(tr.path.span, tr.hir_ref_id, Node::TraitRef(tr)); self.insert(tr.path.span, tr.hir_ref_id, Node::TraitRef(tr));

View file

@ -1111,15 +1111,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ct = let ct =
self.lower_const_path_to_const_arg(path, res, ty.id, ty.span); self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
return GenericArg::Const(ct); return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
} }
} }
} }
_ => {} _ => {}
} }
GenericArg::Type(self.lower_ty(ty, itctx)) GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
}
ast::GenericArg::Const(ct) => {
GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
} }
ast::GenericArg::Const(ct) => GenericArg::Const(self.lower_anon_const_to_const_arg(ct)),
} }
} }
@ -1189,7 +1191,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> { fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
let kind = match &t.kind { let kind = match &t.kind {
TyKind::Infer => hir::TyKind::Infer, TyKind::Infer => hir::TyKind::Infer(()),
TyKind::Err(guar) => hir::TyKind::Err(*guar), TyKind::Err(guar) => hir::TyKind::Err(*guar),
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
@ -2045,7 +2047,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) )
.stash(c.value.span, StashKey::UnderscoreForArrayLengths); .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
} }
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span)); let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
} }
_ => self.lower_anon_const_to_const_arg(c), _ => self.lower_anon_const_to_const_arg(c),

View file

@ -525,7 +525,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])), FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
}; };
let args = smallvec![GenericArg::Type(self.arena.alloc(self.ty_tup(*inputs_span, inputs)))]; let args = smallvec![GenericArg::Type(
self.arena.alloc(self.ty_tup(*inputs_span, inputs)).try_as_ambig_ty().unwrap()
)];
// If we have a bound like `async Fn() -> T`, make sure that we mark the // If we have a bound like `async Fn() -> T`, make sure that we mark the
// `Output = T` associated type bound with the right feature gates. // `Output = T` associated type bound with the right feature gates.

View file

@ -8,7 +8,7 @@ use rustc_hir::QPath::Resolved;
use rustc_hir::WherePredicateKind::BoundPredicate; use rustc_hir::WherePredicateKind::BoundPredicate;
use rustc_hir::def::Res::Def; use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate}; use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate};
use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound}; use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
use rustc_middle::bug; use rustc_middle::bug;
@ -987,7 +987,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
for found_did in found_dids { for found_did in found_dids {
let mut traits = vec![]; let mut traits = vec![];
let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did); let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
hir_v.visit_ty(self_ty); hir_v.visit_unambig_ty(self_ty);
debug!("trait spans found: {:?}", traits); debug!("trait spans found: {:?}", traits);
for span in &traits { for span in &traits {
let mut multi_span: MultiSpan = vec![*span].into(); let mut multi_span: MultiSpan = vec![*span].into();

View file

@ -432,7 +432,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
// must highlight the variable. // must highlight the variable.
// NOTE(eddyb) this is handled in/by the sole caller // NOTE(eddyb) this is handled in/by the sole caller
// (`give_name_if_anonymous_region_appears_in_arguments`). // (`give_name_if_anonymous_region_appears_in_arguments`).
hir::TyKind::Infer => None, hir::TyKind::Infer(()) => None,
_ => Some(argument_hir_ty), _ => Some(argument_hir_ty),
} }
@ -615,7 +615,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
} }
(GenericArgKind::Type(ty), hir::GenericArg::Type(hir_ty)) => { (GenericArgKind::Type(ty), hir::GenericArg::Type(hir_ty)) => {
search_stack.push((ty, hir_ty)); search_stack.push((ty, hir_ty.as_unambig_ty()));
} }
(GenericArgKind::Const(_ct), hir::GenericArg::Const(_hir_ct)) => { (GenericArgKind::Const(_ct), hir::GenericArg::Const(_hir_ct)) => {

View file

@ -31,7 +31,7 @@ use crate::LangItem;
use crate::def::{CtorKind, DefKind, Res}; use crate::def::{CtorKind, DefKind, Res};
use crate::def_id::{DefId, LocalDefIdMap}; use crate::def_id::{DefId, LocalDefIdMap};
pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId}; pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
use crate::intravisit::FnKind; use crate::intravisit::{FnKind, VisitorExt};
#[derive(Debug, Copy, Clone, HashStable_Generic)] #[derive(Debug, Copy, Clone, HashStable_Generic)]
pub struct Lifetime { pub struct Lifetime {
@ -264,11 +264,55 @@ impl<'hir> PathSegment<'hir> {
/// So, `ConstArg` (specifically, [`ConstArgKind`]) distinguishes between const args /// So, `ConstArg` (specifically, [`ConstArgKind`]) distinguishes between const args
/// that are [just paths](ConstArgKind::Path) (currently just bare const params) /// that are [just paths](ConstArgKind::Path) (currently just bare const params)
/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`). /// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
///
/// The `Unambig` generic parameter represents whether the position this const is from is
/// unambiguously a const or ambiguous as to whether it is a type or a const. When in an
/// ambiguous context the parameter is instantiated with an uninhabited type making the
/// [`ConstArgKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
#[derive(Clone, Copy, Debug, HashStable_Generic)] #[derive(Clone, Copy, Debug, HashStable_Generic)]
pub struct ConstArg<'hir> { #[repr(C)]
pub struct ConstArg<'hir, Unambig = ()> {
#[stable_hasher(ignore)] #[stable_hasher(ignore)]
pub hir_id: HirId, pub hir_id: HirId,
pub kind: ConstArgKind<'hir>, pub kind: ConstArgKind<'hir, Unambig>,
}
impl<'hir> ConstArg<'hir, AmbigArg> {
/// Converts a `ConstArg` in an ambiguous position to one in an unambiguous position.
///
/// Functions accepting an unambiguous consts may expect the [`ConstArgKind::Infer`] variant
/// to be used. Care should be taken to separately handle infer consts when calling this
/// function as it cannot be handled by downstream code making use of the returned const.
///
/// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
/// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
///
/// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
// SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the
// layout is the same across different ZST type arguments.
let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
unsafe { &*ptr }
}
}
impl<'hir> ConstArg<'hir> {
/// Converts a `ConstArg` in an unambigous position to one in an ambiguous position. This is
/// fallible as the [`ConstArgKind::Infer`] variant is not present in ambiguous positions.
///
/// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
/// infer consts are relevant to you then care should be taken to handle them separately.
pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
if let ConstArgKind::Infer(_, ()) = self.kind {
return None;
}
// SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
// the same across different ZST type arguments. We also asserted that the `self` is
// not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
Some(unsafe { &*ptr })
}
} }
impl<'hir> ConstArg<'hir> { impl<'hir> ConstArg<'hir> {
@ -283,14 +327,15 @@ impl<'hir> ConstArg<'hir> {
match self.kind { match self.kind {
ConstArgKind::Path(path) => path.span(), ConstArgKind::Path(path) => path.span(),
ConstArgKind::Anon(anon) => anon.span, ConstArgKind::Anon(anon) => anon.span,
ConstArgKind::Infer(span) => span, ConstArgKind::Infer(span, _) => span,
} }
} }
} }
/// See [`ConstArg`]. /// See [`ConstArg`].
#[derive(Clone, Copy, Debug, HashStable_Generic)] #[derive(Clone, Copy, Debug, HashStable_Generic)]
pub enum ConstArgKind<'hir> { #[repr(u8, C)]
pub enum ConstArgKind<'hir, Unambig = ()> {
/// **Note:** Currently this is only used for bare const params /// **Note:** Currently this is only used for bare const params
/// (`N` where `fn foo<const N: usize>(...)`), /// (`N` where `fn foo<const N: usize>(...)`),
/// not paths to any const (`N` where `const N: usize = ...`). /// not paths to any const (`N` where `const N: usize = ...`).
@ -298,11 +343,9 @@ pub enum ConstArgKind<'hir> {
/// However, in the future, we'll be using it for all of those. /// However, in the future, we'll be using it for all of those.
Path(QPath<'hir>), Path(QPath<'hir>),
Anon(&'hir AnonConst), Anon(&'hir AnonConst),
/// **Note:** Not all inferred consts are represented as /// This variant is not always used to represent inference consts, sometimes
/// `ConstArgKind::Infer`. In cases where it is ambiguous whether /// [`GenericArg::Infer`] is used instead.
/// a generic arg is a type or a const, inference variables are Infer(Span, Unambig),
/// represented as `GenericArg::Infer` instead.
Infer(Span),
} }
#[derive(Clone, Copy, Debug, HashStable_Generic)] #[derive(Clone, Copy, Debug, HashStable_Generic)]
@ -314,19 +357,24 @@ pub struct InferArg {
impl InferArg { impl InferArg {
pub fn to_ty(&self) -> Ty<'static> { pub fn to_ty(&self) -> Ty<'static> {
Ty { kind: TyKind::Infer, span: self.span, hir_id: self.hir_id } Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
} }
} }
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum GenericArg<'hir> { pub enum GenericArg<'hir> {
Lifetime(&'hir Lifetime), Lifetime(&'hir Lifetime),
Type(&'hir Ty<'hir>), Type(&'hir Ty<'hir, AmbigArg>),
Const(&'hir ConstArg<'hir>), Const(&'hir ConstArg<'hir, AmbigArg>),
/// **Note:** Inference variables are only represented as /// Inference variables in [`GenericArg`] are always represnted by
/// `GenericArg::Infer` in cases where it is ambiguous whether /// `GenericArg::Infer` instead of the `Infer` variants on [`TyKind`] and
/// a generic arg is a type or a const. Otherwise, inference variables /// [`ConstArgKind`] as it is not clear until hir ty lowering whether a
/// are represented as `TyKind::Infer` or `ConstArgKind::Infer`. /// `_` argument is a type or const argument.
///
/// However, some builtin types' generic arguments are represented by [`TyKind`]
/// without a [`GenericArg`], instead directly storing a [`Ty`] or [`ConstArg`]. In
/// such cases they *are* represented by the `Infer` variants on [`TyKind`] and
/// [`ConstArgKind`] as it is not ambiguous whether the argument is a type or const.
Infer(InferArg), Infer(InferArg),
} }
@ -335,7 +383,7 @@ impl GenericArg<'_> {
match self { match self {
GenericArg::Lifetime(l) => l.ident.span, GenericArg::Lifetime(l) => l.ident.span,
GenericArg::Type(t) => t.span, GenericArg::Type(t) => t.span,
GenericArg::Const(c) => c.span(), GenericArg::Const(c) => c.as_unambig_ct().span(),
GenericArg::Infer(i) => i.span, GenericArg::Infer(i) => i.span,
} }
} }
@ -354,7 +402,7 @@ impl GenericArg<'_> {
GenericArg::Lifetime(_) => "lifetime", GenericArg::Lifetime(_) => "lifetime",
GenericArg::Type(_) => "type", GenericArg::Type(_) => "type",
GenericArg::Const(_) => "constant", GenericArg::Const(_) => "constant",
GenericArg::Infer(_) => "inferred", GenericArg::Infer(_) => "placeholder",
} }
} }
@ -2915,12 +2963,63 @@ impl<'hir> AssocItemConstraintKind<'hir> {
} }
} }
/// An uninhabited enum used to make `Infer` variants on [`Ty`] and [`ConstArg`] be
/// unreachable. Zero-Variant enums are guaranteed to have the same layout as the never
/// type.
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Ty<'hir> { pub enum AmbigArg {}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
#[repr(C)]
/// Represents a type in the `HIR`.
///
/// The `Unambig` generic parameter represents whether the position this type is from is
/// unambiguously a type or ambiguous as to whether it is a type or a const. When in an
/// ambiguous context the parameter is instantiated with an uninhabited type making the
/// [`TyKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
pub struct Ty<'hir, Unambig = ()> {
#[stable_hasher(ignore)] #[stable_hasher(ignore)]
pub hir_id: HirId, pub hir_id: HirId,
pub kind: TyKind<'hir>,
pub span: Span, pub span: Span,
pub kind: TyKind<'hir, Unambig>,
}
impl<'hir> Ty<'hir, AmbigArg> {
/// Converts a `Ty` in an ambiguous position to one in an unambiguous position.
///
/// Functions accepting an unambiguous types may expect the [`TyKind::Infer`] variant
/// to be used. Care should be taken to separately handle infer types when calling this
/// function as it cannot be handled by downstream code making use of the returned ty.
///
/// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
/// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
///
/// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
pub fn as_unambig_ty(&self) -> &Ty<'hir> {
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
// the same across different ZST type arguments.
let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
unsafe { &*ptr }
}
}
impl<'hir> Ty<'hir> {
/// Converts a `Ty` in an unambigous position to one in an ambiguous position. This is
/// fallible as the [`TyKind::Infer`] variant is not present in ambiguous positions.
///
/// Functions accepting ambiguous types will not handle the [`TyKind::Infer`] variant, if
/// infer types are relevant to you then care should be taken to handle them separately.
pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
if let TyKind::Infer(()) = self.kind {
return None;
}
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
// the same across different ZST type arguments. We also asserted that the `self` is
// not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
Some(unsafe { &*ptr })
}
} }
impl<'hir> Ty<'hir> { impl<'hir> Ty<'hir> {
@ -2952,7 +3051,7 @@ impl<'hir> Ty<'hir> {
use crate::intravisit::Visitor; use crate::intravisit::Visitor;
struct MyVisitor(Vec<Span>); struct MyVisitor(Vec<Span>);
impl<'v> Visitor<'v> for MyVisitor { impl<'v> Visitor<'v> for MyVisitor {
fn visit_ty(&mut self, t: &'v Ty<'v>) { fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
if matches!( if matches!(
&t.kind, &t.kind,
TyKind::Path(QPath::Resolved(_, Path { TyKind::Path(QPath::Resolved(_, Path {
@ -2968,7 +3067,7 @@ impl<'hir> Ty<'hir> {
} }
let mut my_visitor = MyVisitor(vec![]); let mut my_visitor = MyVisitor(vec![]);
my_visitor.visit_ty(self); my_visitor.visit_unambig_ty(self);
my_visitor.0 my_visitor.0
} }
@ -2977,14 +3076,14 @@ impl<'hir> Ty<'hir> {
pub fn is_suggestable_infer_ty(&self) -> bool { pub fn is_suggestable_infer_ty(&self) -> bool {
fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool { fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
generic_args.iter().any(|arg| match arg { generic_args.iter().any(|arg| match arg {
GenericArg::Type(ty) => ty.is_suggestable_infer_ty(), GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
GenericArg::Infer(_) => true, GenericArg::Infer(_) => true,
_ => false, _ => false,
}) })
} }
debug!(?self); debug!(?self);
match &self.kind { match &self.kind {
TyKind::Infer => true, TyKind::Infer(()) => true,
TyKind::Slice(ty) => ty.is_suggestable_infer_ty(), TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
TyKind::Array(ty, length) => { TyKind::Array(ty, length) => {
ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..)) ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
@ -3198,7 +3297,9 @@ pub enum InferDelegationKind {
/// The various kinds of types recognized by the compiler. /// The various kinds of types recognized by the compiler.
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum TyKind<'hir> { // SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
#[repr(u8, C)]
pub enum TyKind<'hir, Unambig = ()> {
/// Actual type should be inherited from `DefId` signature /// Actual type should be inherited from `DefId` signature
InferDelegation(DefId, InferDelegationKind), InferDelegation(DefId, InferDelegationKind),
/// A variable length slice (i.e., `[T]`). /// A variable length slice (i.e., `[T]`).
@ -3234,18 +3335,16 @@ pub enum TyKind<'hir> {
TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>), TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
/// Unused for now. /// Unused for now.
Typeof(&'hir AnonConst), Typeof(&'hir AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
///
/// **Note:** Not all inferred types are represented as
/// `TyKind::Infer`. In cases where it is ambiguous whether
/// a generic arg is a type or a const, inference variables are
/// represented as `GenericArg::Infer` instead.
Infer,
/// Placeholder for a type that has failed to be defined. /// Placeholder for a type that has failed to be defined.
Err(rustc_span::ErrorGuaranteed), Err(rustc_span::ErrorGuaranteed),
/// Pattern types (`pattern_type!(u32 is 1..)`) /// Pattern types (`pattern_type!(u32 is 1..)`)
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>), Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
/// `TyKind::Infer` means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
///
/// This variant is not always used to represent inference types, sometimes
/// [`GenericArg::Infer`] is used instead.
Infer(Unambig),
} }
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]

View file

@ -351,18 +351,42 @@ pub trait Visitor<'v>: Sized {
fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result { fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result {
walk_inline_const(self, c) walk_inline_const(self, c)
} }
fn visit_const_arg(&mut self, c: &'v ConstArg<'v>) -> Self::Result {
walk_const_arg(self, c) fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) -> Self::Result {
walk_generic_arg(self, generic_arg)
} }
/// All types are treated as ambiguous types for the purposes of hir visiting in
/// order to ensure that visitors can handle infer vars without it being too error-prone.
///
/// The [`Visitor::visit_infer`] method should be overriden in order to handle infer vars.
fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) -> Self::Result {
walk_ty(self, t)
}
/// All consts are treated as ambiguous consts for the purposes of hir visiting in
/// order to ensure that visitors can handle infer vars without it being too error-prone.
///
/// The [`Visitor::visit_infer`] method should be overriden in order to handle infer vars.
fn visit_const_arg(&mut self, c: &'v ConstArg<'v, AmbigArg>) -> Self::Result {
walk_ambig_const_arg(self, c)
}
#[allow(unused_variables)]
fn visit_infer(&mut self, inf_id: HirId, inf_span: Span, kind: InferKind<'v>) -> Self::Result {
self.visit_id(inf_id)
}
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) -> Self::Result {
walk_lifetime(self, lifetime)
}
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result { fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
walk_expr(self, ex) walk_expr(self, ex)
} }
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result { fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
walk_expr_field(self, field) walk_expr_field(self, field)
} }
fn visit_ty(&mut self, t: &'v Ty<'v>) -> Self::Result {
walk_ty(self, t)
}
fn visit_pattern_type_pattern(&mut self, _p: &'v Pat<'v>) { fn visit_pattern_type_pattern(&mut self, _p: &'v Pat<'v>) {
// Do nothing. Only a few visitors need to know the details of the pattern type, // Do nothing. Only a few visitors need to know the details of the pattern type,
// and they opt into it. All other visitors will just choke on our fake patterns // and they opt into it. All other visitors will just choke on our fake patterns
@ -444,15 +468,6 @@ pub trait Visitor<'v>: Sized {
fn visit_label(&mut self, label: &'v Label) -> Self::Result { fn visit_label(&mut self, label: &'v Label) -> Self::Result {
walk_label(self, label) walk_label(self, label)
} }
fn visit_infer(&mut self, inf: &'v InferArg) -> Self::Result {
walk_inf(self, inf)
}
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) -> Self::Result {
walk_generic_arg(self, generic_arg)
}
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) -> Self::Result {
walk_lifetime(self, lifetime)
}
// The span is that of the surrounding type/pattern/expr/whatever. // The span is that of the surrounding type/pattern/expr/whatever.
fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) -> Self::Result { fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) -> Self::Result {
walk_qpath(self, qpath, id) walk_qpath(self, qpath, id)
@ -486,6 +501,20 @@ pub trait Visitor<'v>: Sized {
} }
} }
pub trait VisitorExt<'v>: Visitor<'v> {
/// Extension trait method to visit types in unambiguous positions, this is not
/// directly on the [`Visitor`] trait as this method should never be overridden.
fn visit_unambig_ty(&mut self, t: &'v Ty<'v>) -> Self::Result {
walk_unambig_ty(self, t)
}
/// Extension trait method to visit consts in unambiguous positions, this is not
/// directly on the [`Visitor`] trait as this method should never be overridden.
fn visit_unambig_const_arg(&mut self, c: &'v ConstArg<'v>) -> Self::Result {
walk_const_arg(self, c)
}
}
impl<'v, V: Visitor<'v>> VisitorExt<'v> for V {}
pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) -> V::Result { pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) -> V::Result {
try_visit!(visitor.visit_id(param.hir_id)); try_visit!(visitor.visit_id(param.hir_id));
visitor.visit_pat(param.pat) visitor.visit_pat(param.pat)
@ -503,12 +532,12 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
} }
ItemKind::Static(ref typ, _, body) => { ItemKind::Static(ref typ, _, body) => {
try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(visitor.visit_ty(typ)); try_visit!(visitor.visit_unambig_ty(typ));
try_visit!(visitor.visit_nested_body(body)); try_visit!(visitor.visit_nested_body(body));
} }
ItemKind::Const(ref typ, ref generics, body) => { ItemKind::Const(ref typ, ref generics, body) => {
try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(visitor.visit_ty(typ)); try_visit!(visitor.visit_unambig_ty(typ));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_nested_body(body)); try_visit!(visitor.visit_nested_body(body));
} }
@ -539,7 +568,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
} }
ItemKind::TyAlias(ref ty, ref generics) => { ItemKind::TyAlias(ref ty, ref generics) => {
try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_unambig_ty(ty));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
} }
ItemKind::Enum(ref enum_definition, ref generics) => { ItemKind::Enum(ref enum_definition, ref generics) => {
@ -561,7 +590,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
visit_opt!(visitor, visit_trait_ref, of_trait); visit_opt!(visitor, visit_trait_ref, of_trait);
try_visit!(visitor.visit_ty(self_ty)); try_visit!(visitor.visit_unambig_ty(self_ty));
walk_list!(visitor, visit_impl_item_ref, *items); walk_list!(visitor, visit_impl_item_ref, *items);
} }
ItemKind::Struct(ref struct_definition, ref generics) ItemKind::Struct(ref struct_definition, ref generics)
@ -618,7 +647,7 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
walk_list!(visitor, visit_ident, param_names.iter().copied()); walk_list!(visitor, visit_ident, param_names.iter().copied());
} }
ForeignItemKind::Static(ref typ, _, _) => { ForeignItemKind::Static(ref typ, _, _) => {
try_visit!(visitor.visit_ty(typ)); try_visit!(visitor.visit_unambig_ty(typ));
} }
ForeignItemKind::Type => (), ForeignItemKind::Type => (),
} }
@ -632,7 +661,7 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v LetStmt<'v>) -
try_visit!(visitor.visit_id(local.hir_id)); try_visit!(visitor.visit_id(local.hir_id));
try_visit!(visitor.visit_pat(local.pat)); try_visit!(visitor.visit_pat(local.pat));
visit_opt!(visitor, visit_block, local.els); visit_opt!(visitor, visit_block, local.els);
visit_opt!(visitor, visit_ty, local.ty); visit_opt!(visitor, visit_unambig_ty, local.ty);
V::Result::output() V::Result::output()
} }
@ -735,18 +764,6 @@ pub fn walk_inline_const<'v, V: Visitor<'v>>(
visitor.visit_nested_body(constant.body) visitor.visit_nested_body(constant.body)
} }
pub fn walk_const_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
const_arg: &'v ConstArg<'v>,
) -> V::Result {
try_visit!(visitor.visit_id(const_arg.hir_id));
match &const_arg.kind {
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, const_arg.hir_id, qpath.span()),
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
ConstArgKind::Infer(..) => V::Result::output(),
}
}
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result { pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
try_visit!(visitor.visit_id(expression.hir_id)); try_visit!(visitor.visit_id(expression.hir_id));
match expression.kind { match expression.kind {
@ -758,7 +775,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
} }
ExprKind::Repeat(ref element, ref count) => { ExprKind::Repeat(ref element, ref count) => {
try_visit!(visitor.visit_expr(element)); try_visit!(visitor.visit_expr(element));
try_visit!(visitor.visit_const_arg(count)); try_visit!(visitor.visit_unambig_const_arg(count));
} }
ExprKind::Struct(ref qpath, fields, ref optional_base) => { ExprKind::Struct(ref qpath, fields, ref optional_base) => {
try_visit!(visitor.visit_qpath(qpath, expression.hir_id, expression.span)); try_visit!(visitor.visit_qpath(qpath, expression.hir_id, expression.span));
@ -789,7 +806,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
} }
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
try_visit!(visitor.visit_expr(subexpression)); try_visit!(visitor.visit_expr(subexpression));
try_visit!(visitor.visit_ty(typ)); try_visit!(visitor.visit_unambig_ty(typ));
} }
ExprKind::DropTemps(ref subexpression) => { ExprKind::DropTemps(ref subexpression) => {
try_visit!(visitor.visit_expr(subexpression)); try_visit!(visitor.visit_expr(subexpression));
@ -798,7 +815,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
// match the visit order in walk_local // match the visit order in walk_local
try_visit!(visitor.visit_expr(init)); try_visit!(visitor.visit_expr(init));
try_visit!(visitor.visit_pat(pat)); try_visit!(visitor.visit_pat(pat));
visit_opt!(visitor, visit_ty, ty); visit_opt!(visitor, visit_unambig_ty, ty);
} }
ExprKind::If(ref cond, ref then, ref else_opt) => { ExprKind::If(ref cond, ref then, ref else_opt) => {
try_visit!(visitor.visit_expr(cond)); try_visit!(visitor.visit_expr(cond));
@ -866,7 +883,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
try_visit!(visitor.visit_inline_asm(asm, expression.hir_id)); try_visit!(visitor.visit_inline_asm(asm, expression.hir_id));
} }
ExprKind::OffsetOf(ref container, ref fields) => { ExprKind::OffsetOf(ref container, ref fields) => {
try_visit!(visitor.visit_ty(container)); try_visit!(visitor.visit_unambig_ty(container));
walk_list!(visitor, visit_ident, fields.iter().copied()); walk_list!(visitor, visit_ident, fields.iter().copied());
} }
ExprKind::Yield(ref subexpression, _) => { ExprKind::Yield(ref subexpression, _) => {
@ -874,7 +891,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
} }
ExprKind::UnsafeBinderCast(_kind, expr, ty) => { ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
try_visit!(visitor.visit_expr(expr)); try_visit!(visitor.visit_expr(expr));
visit_opt!(visitor, visit_ty, ty); visit_opt!(visitor, visit_unambig_ty, ty);
} }
ExprKind::Lit(_) | ExprKind::Err(_) => {} ExprKind::Lit(_) | ExprKind::Err(_) => {}
} }
@ -887,19 +904,47 @@ pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField
visitor.visit_expr(field.expr) visitor.visit_expr(field.expr)
} }
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Result { pub enum InferKind<'hir> {
Ty(&'hir Ty<'hir>),
Const(&'hir ConstArg<'hir>),
Ambig(&'hir InferArg),
}
pub fn walk_generic_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
generic_arg: &'v GenericArg<'v>,
) -> V::Result {
match generic_arg {
GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt),
GenericArg::Type(ty) => visitor.visit_ty(ty),
GenericArg::Const(ct) => visitor.visit_const_arg(ct),
GenericArg::Infer(inf) => visitor.visit_infer(inf.hir_id, inf.span, InferKind::Ambig(inf)),
}
}
pub fn walk_unambig_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Result {
match typ.try_as_ambig_ty() {
Some(ambig_ty) => visitor.visit_ty(ambig_ty),
None => {
try_visit!(visitor.visit_id(typ.hir_id));
visitor.visit_infer(typ.hir_id, typ.span, InferKind::Ty(typ))
}
}
}
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -> V::Result {
try_visit!(visitor.visit_id(typ.hir_id)); try_visit!(visitor.visit_id(typ.hir_id));
match typ.kind { match typ.kind {
TyKind::Slice(ref ty) => try_visit!(visitor.visit_ty(ty)), TyKind::Slice(ref ty) => try_visit!(visitor.visit_unambig_ty(ty)),
TyKind::Ptr(ref mutable_type) => try_visit!(visitor.visit_ty(mutable_type.ty)), TyKind::Ptr(ref mutable_type) => try_visit!(visitor.visit_unambig_ty(mutable_type.ty)),
TyKind::Ref(ref lifetime, ref mutable_type) => { TyKind::Ref(ref lifetime, ref mutable_type) => {
try_visit!(visitor.visit_lifetime(lifetime)); try_visit!(visitor.visit_lifetime(lifetime));
try_visit!(visitor.visit_ty(mutable_type.ty)); try_visit!(visitor.visit_unambig_ty(mutable_type.ty));
} }
TyKind::Never => {} TyKind::Never => {}
TyKind::Tup(tuple_element_types) => { TyKind::Tup(tuple_element_types) => {
walk_list!(visitor, visit_ty, tuple_element_types); walk_list!(visitor, visit_unambig_ty, tuple_element_types);
} }
TyKind::BareFn(ref function_declaration) => { TyKind::BareFn(ref function_declaration) => {
walk_list!(visitor, visit_generic_param, function_declaration.generic_params); walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
@ -907,7 +952,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
} }
TyKind::UnsafeBinder(ref unsafe_binder) => { TyKind::UnsafeBinder(ref unsafe_binder) => {
walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params); walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params);
try_visit!(visitor.visit_ty(unsafe_binder.inner_ty)); try_visit!(visitor.visit_unambig_ty(unsafe_binder.inner_ty));
} }
TyKind::Path(ref qpath) => { TyKind::Path(ref qpath) => {
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span)); try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
@ -919,8 +964,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
} }
TyKind::Array(ref ty, ref length) => { TyKind::Array(ref ty, ref length) => {
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_unambig_ty(ty));
try_visit!(visitor.visit_const_arg(length)); try_visit!(visitor.visit_unambig_const_arg(length));
} }
TyKind::TraitObject(bounds, ref lifetime) => { TyKind::TraitObject(bounds, ref lifetime) => {
for bound in bounds { for bound in bounds {
@ -929,15 +974,39 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
try_visit!(visitor.visit_lifetime(lifetime)); try_visit!(visitor.visit_lifetime(lifetime));
} }
TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)), TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)),
TyKind::Infer | TyKind::InferDelegation(..) | TyKind::Err(_) => {} TyKind::InferDelegation(..) | TyKind::Err(_) => {}
TyKind::Pat(ty, pat) => { TyKind::Pat(ty, pat) => {
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_unambig_ty(ty));
try_visit!(visitor.visit_pattern_type_pattern(pat)); try_visit!(visitor.visit_pattern_type_pattern(pat));
} }
} }
V::Result::output() V::Result::output()
} }
pub fn walk_const_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
const_arg: &'v ConstArg<'v>,
) -> V::Result {
match const_arg.try_as_ambig_ct() {
Some(ambig_ct) => visitor.visit_const_arg(ambig_ct),
None => {
try_visit!(visitor.visit_id(const_arg.hir_id));
visitor.visit_infer(const_arg.hir_id, const_arg.span(), InferKind::Const(const_arg))
}
}
}
pub fn walk_ambig_const_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
const_arg: &'v ConstArg<'v, AmbigArg>,
) -> V::Result {
try_visit!(visitor.visit_id(const_arg.hir_id));
match &const_arg.kind {
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, const_arg.hir_id, qpath.span()),
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
}
}
pub fn walk_generic_param<'v, V: Visitor<'v>>( pub fn walk_generic_param<'v, V: Visitor<'v>>(
visitor: &mut V, visitor: &mut V,
param: &'v GenericParam<'v>, param: &'v GenericParam<'v>,
@ -949,9 +1018,11 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(
} }
match param.kind { match param.kind {
GenericParamKind::Lifetime { .. } => {} GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { ref default, .. } => visit_opt!(visitor, visit_ty, default), GenericParamKind::Type { ref default, .. } => {
visit_opt!(visitor, visit_unambig_ty, default)
}
GenericParamKind::Const { ref ty, ref default, synthetic: _ } => { GenericParamKind::Const { ref ty, ref default, synthetic: _ } => {
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_unambig_ty(ty));
if let Some(ref default) = default { if let Some(ref default) = default {
try_visit!(visitor.visit_const_param_default(param.hir_id, default)); try_visit!(visitor.visit_const_param_default(param.hir_id, default));
} }
@ -964,7 +1035,7 @@ pub fn walk_const_param_default<'v, V: Visitor<'v>>(
visitor: &mut V, visitor: &mut V,
ct: &'v ConstArg<'v>, ct: &'v ConstArg<'v>,
) -> V::Result { ) -> V::Result {
visitor.visit_const_arg(ct) visitor.visit_unambig_const_arg(ct)
} }
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) -> V::Result { pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) -> V::Result {
@ -986,7 +1057,7 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
bound_generic_params, bound_generic_params,
origin: _, origin: _,
}) => { }) => {
try_visit!(visitor.visit_ty(bounded_ty)); try_visit!(visitor.visit_unambig_ty(bounded_ty));
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_generic_param, bound_generic_params); walk_list!(visitor, visit_generic_param, bound_generic_params);
} }
@ -999,8 +1070,8 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
} }
WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => { WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => {
try_visit!(visitor.visit_ty(lhs_ty)); try_visit!(visitor.visit_unambig_ty(lhs_ty));
try_visit!(visitor.visit_ty(rhs_ty)); try_visit!(visitor.visit_unambig_ty(rhs_ty));
} }
} }
V::Result::output() V::Result::output()
@ -1010,13 +1081,13 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(
visitor: &mut V, visitor: &mut V,
function_declaration: &'v FnDecl<'v>, function_declaration: &'v FnDecl<'v>,
) -> V::Result { ) -> V::Result {
walk_list!(visitor, visit_ty, function_declaration.inputs); walk_list!(visitor, visit_unambig_ty, function_declaration.inputs);
visitor.visit_fn_ret_ty(&function_declaration.output) visitor.visit_fn_ret_ty(&function_declaration.output)
} }
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) -> V::Result { pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) -> V::Result {
if let FnRetTy::Return(output_ty) = *ret_ty { if let FnRetTy::Return(output_ty) = *ret_ty {
try_visit!(visitor.visit_ty(output_ty)); try_visit!(visitor.visit_unambig_ty(output_ty));
} }
V::Result::output() V::Result::output()
} }
@ -1069,7 +1140,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_id(hir_id)); try_visit!(visitor.visit_id(hir_id));
match *kind { match *kind {
TraitItemKind::Const(ref ty, default) => { TraitItemKind::Const(ref ty, default) => {
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_unambig_ty(ty));
visit_opt!(visitor, visit_nested_body, default); visit_opt!(visitor, visit_nested_body, default);
} }
TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => { TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
@ -1087,7 +1158,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
} }
TraitItemKind::Type(bounds, ref default) => { TraitItemKind::Type(bounds, ref default) => {
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
visit_opt!(visitor, visit_ty, default); visit_opt!(visitor, visit_unambig_ty, default);
} }
} }
V::Result::output() V::Result::output()
@ -1125,7 +1196,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_id(impl_item.hir_id())); try_visit!(visitor.visit_id(impl_item.hir_id()));
match *kind { match *kind {
ImplItemKind::Const(ref ty, body) => { ImplItemKind::Const(ref ty, body) => {
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_unambig_ty(ty));
visitor.visit_nested_body(body) visitor.visit_nested_body(body)
} }
ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn( ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn(
@ -1135,7 +1206,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
impl_item.span, impl_item.span,
impl_item.owner_id.def_id, impl_item.owner_id.def_id,
), ),
ImplItemKind::Type(ref ty) => visitor.visit_ty(ty), ImplItemKind::Type(ref ty) => visitor.visit_unambig_ty(ty),
} }
} }
@ -1223,7 +1294,7 @@ pub fn walk_field_def<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_id(*hir_id)); try_visit!(visitor.visit_id(*hir_id));
try_visit!(visitor.visit_ident(*ident)); try_visit!(visitor.visit_ident(*ident));
visit_opt!(visitor, visit_anon_const, default); visit_opt!(visitor, visit_anon_const, default);
visitor.visit_ty(*ty) visitor.visit_unambig_ty(*ty)
} }
pub fn walk_enum_def<'v, V: Visitor<'v>>( pub fn walk_enum_def<'v, V: Visitor<'v>>(
@ -1252,18 +1323,6 @@ pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) -> V::Re
visitor.visit_id(inf.hir_id) visitor.visit_id(inf.hir_id)
} }
pub fn walk_generic_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
generic_arg: &'v GenericArg<'v>,
) -> V::Result {
match generic_arg {
GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt),
GenericArg::Type(ty) => visitor.visit_ty(ty),
GenericArg::Const(ct) => visitor.visit_const_arg(ct),
GenericArg::Infer(inf) => visitor.visit_infer(inf),
}
}
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) -> V::Result { pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) -> V::Result {
try_visit!(visitor.visit_id(lifetime.hir_id)); try_visit!(visitor.visit_id(lifetime.hir_id));
visitor.visit_ident(lifetime.ident) visitor.visit_ident(lifetime.ident)
@ -1276,11 +1335,11 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(
) -> V::Result { ) -> V::Result {
match *qpath { match *qpath {
QPath::Resolved(ref maybe_qself, ref path) => { QPath::Resolved(ref maybe_qself, ref path) => {
visit_opt!(visitor, visit_ty, maybe_qself); visit_opt!(visitor, visit_unambig_ty, maybe_qself);
visitor.visit_path(path, id) visitor.visit_path(path, id)
} }
QPath::TypeRelative(ref qself, ref segment) => { QPath::TypeRelative(ref qself, ref segment) => {
try_visit!(visitor.visit_ty(qself)); try_visit!(visitor.visit_unambig_ty(qself));
visitor.visit_path_segment(segment) visitor.visit_path_segment(segment)
} }
QPath::LangItem(..) => V::Result::output(), QPath::LangItem(..) => V::Result::output(),
@ -1320,8 +1379,8 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_generic_args(constraint.gen_args)); try_visit!(visitor.visit_generic_args(constraint.gen_args));
match constraint.kind { match constraint.kind {
AssocItemConstraintKind::Equality { ref term } => match term { AssocItemConstraintKind::Equality { ref term } => match term {
Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)), Term::Ty(ref ty) => try_visit!(visitor.visit_unambig_ty(ty)),
Term::Const(ref c) => try_visit!(visitor.visit_const_arg(c)), Term::Const(ref c) => try_visit!(visitor.visit_unambig_const_arg(c)),
}, },
AssocItemConstraintKind::Bound { bounds } => { AssocItemConstraintKind::Bound { bounds } => {
walk_list!(visitor, visit_param_bound, bounds) walk_list!(visitor, visit_param_bound, bounds)

View file

@ -6,6 +6,7 @@
#![allow(internal_features)] #![allow(internal_features)]
#![feature(associated_type_defaults)] #![feature(associated_type_defaults)]
#![feature(closure_track_caller)] #![feature(closure_track_caller)]
#![feature(exhaustive_patterns)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(never_type)] #![feature(never_type)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]

View file

@ -6,9 +6,9 @@ use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*; use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::{GenericParamKind, ImplItemKind, intravisit}; use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::util; use rustc_infer::traits::util;
@ -1610,7 +1610,7 @@ fn compare_synthetic_generics<'tcx>(
struct Visitor(hir::def_id::LocalDefId); struct Visitor(hir::def_id::LocalDefId);
impl<'v> intravisit::Visitor<'v> for Visitor { impl<'v> intravisit::Visitor<'v> for Visitor {
type Result = ControlFlow<Span>; type Result = ControlFlow<Span>;
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) -> Self::Result { fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) -> Self::Result {
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
&& let Res::Def(DefKind::TyParam, def_id) = path.res && let Res::Def(DefKind::TyParam, def_id) = path.res
&& def_id == self.0.to_def_id() && def_id == self.0.to_def_id()
@ -1622,9 +1622,9 @@ fn compare_synthetic_generics<'tcx>(
} }
} }
let span = input_tys.iter().find_map(|ty| { let span = input_tys
intravisit::Visitor::visit_ty(&mut Visitor(impl_def_id), ty).break_value() .iter()
})?; .find_map(|ty| Visitor(impl_def_id).visit_unambig_ty(ty).break_value())?;
let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds; let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
let bounds = bounds.first()?.span().to(bounds.last()?.span()); let bounds = bounds.first()?.span().to(bounds.last()?.span());

View file

@ -6,10 +6,10 @@ use rustc_abi::ExternAbi;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*; use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_hir::ItemKind;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{AmbigArg, ItemKind};
use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_macros::LintDiagnostic; use rustc_macros::LintDiagnostic;
@ -2196,7 +2196,7 @@ impl<'tcx> Visitor<'tcx> for CollectUsageSpans<'_> {
// Skip the generics. We only care about fields, not where clause/param bounds. // Skip the generics. We only care about fields, not where clause/param bounds.
} }
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result { fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
if let hir::TyKind::Path(hir::QPath::Resolved(None, qpath)) = t.kind { if let hir::TyKind::Path(hir::QPath::Resolved(None, qpath)) = t.kind {
if let Res::Def(DefKind::TyParam, def_id) = qpath.res if let Res::Def(DefKind::TyParam, def_id) = qpath.res
&& def_id == self.param_def_id && def_id == self.param_def_id

View file

@ -28,7 +28,7 @@ use rustc_errors::{
}; };
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor, walk_generics}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
use rustc_hir::{self as hir, GenericParamKind, HirId, Node}; use rustc_hir::{self as hir, GenericParamKind, HirId, Node};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
@ -583,7 +583,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, a)| { .map(|(i, a)| {
if let hir::TyKind::Infer = a.kind { if let hir::TyKind::Infer(()) = a.kind {
if let Some(suggested_ty) = if let Some(suggested_ty) =
self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i)) self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
{ {
@ -593,21 +593,21 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
} }
// Only visit the type looking for `_` if we didn't fix the type above // Only visit the type looking for `_` if we didn't fix the type above
visitor.visit_ty(a); visitor.visit_unambig_ty(a);
self.lowerer().lower_arg_ty(a, None) self.lowerer().lower_arg_ty(a, None)
}) })
.collect(); .collect();
let output_ty = match decl.output { let output_ty = match decl.output {
hir::FnRetTy::Return(output) => { hir::FnRetTy::Return(output) => {
if let hir::TyKind::Infer = output.kind if let hir::TyKind::Infer(()) = output.kind
&& let Some(suggested_ty) = && let Some(suggested_ty) =
self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None) self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
{ {
infer_replacements.push((output.span, suggested_ty.to_string())); infer_replacements.push((output.span, suggested_ty.to_string()));
Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string()) Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string())
} else { } else {
visitor.visit_ty(output); visitor.visit_unambig_ty(output);
self.lower_ty(output) self.lower_ty(output)
} }
} }
@ -1453,7 +1453,7 @@ fn recover_infer_ret_ty<'tcx>(
}); });
let mut visitor = HirPlaceholderCollector::default(); let mut visitor = HirPlaceholderCollector::default();
visitor.visit_ty(infer_ret_ty); visitor.visit_unambig_ty(infer_ret_ty);
let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type"); let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type");
let ret_ty = fn_sig.output(); let ret_ty = fn_sig.output();

View file

@ -3,9 +3,10 @@ use std::ops::ControlFlow;
use hir::intravisit::{self, Visitor}; use hir::intravisit::{self, Visitor};
use hir::{GenericParamKind, HirId, Node}; use hir::{GenericParamKind, HirId, Node};
use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg};
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::{Span, Symbol, kw}; use rustc_span::{Span, Symbol, kw};
@ -461,7 +462,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> { impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> {
type Result = ControlFlow<Span>; type Result = ControlFlow<Span>;
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) -> ControlFlow<Span> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) -> ControlFlow<Span> {
match ty.kind { match ty.kind {
hir::TyKind::BareFn(..) => { hir::TyKind::BareFn(..) => {
self.outer_index.shift_in(1); self.outer_index.shift_in(1);
@ -539,7 +540,7 @@ impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
if let GenericParamKind::Const { ty, default: _, synthetic: _ } = p.kind { if let GenericParamKind::Const { ty, default: _, synthetic: _ } = p.kind {
let prev = self.in_param_ty; let prev = self.in_param_ty;
self.in_param_ty = true; self.in_param_ty = true;
let res = self.visit_ty(ty); let res = self.visit_unambig_ty(ty);
self.in_param_ty = prev; self.in_param_ty = prev;
res res
} else { } else {

View file

@ -14,11 +14,11 @@ use rustc_ast::visit::walk_list;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
use rustc_hir::{ use rustc_hir::{
GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap, LifetimeName, Node, self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap,
LifetimeName, Node,
}; };
use rustc_macros::extension; use rustc_macros::extension;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
@ -749,7 +749,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
match ty.kind { match ty.kind {
hir::TyKind::BareFn(c) => { hir::TyKind::BareFn(c) => {
let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c let (mut bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c
@ -851,7 +851,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(), lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
s: self.scope, s: self.scope,
}; };
self.with(scope, |this| this.visit_ty(mt.ty)); self.with(scope, |this| this.visit_unambig_ty(mt.ty));
} }
hir::TyKind::TraitAscription(bounds) => { hir::TyKind::TraitAscription(bounds) => {
let scope = Scope::TraitRefBoundary { s: self.scope }; let scope = Scope::TraitRefBoundary { s: self.scope };
@ -893,7 +893,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
this.visit_param_bound(bound); this.visit_param_bound(bound);
} }
if let Some(ty) = ty { if let Some(ty) = ty {
this.visit_ty(ty); this.visit_unambig_ty(ty);
} }
}) })
} }
@ -912,7 +912,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}), }),
Type(ty) => self.visit_early(impl_item.hir_id(), impl_item.generics, |this| { Type(ty) => self.visit_early(impl_item.hir_id(), impl_item.generics, |this| {
this.visit_generics(impl_item.generics); this.visit_generics(impl_item.generics);
this.visit_ty(ty); this.visit_unambig_ty(ty);
}), }),
Const(_, _) => self.visit_early(impl_item.hir_id(), impl_item.generics, |this| { Const(_, _) => self.visit_early(impl_item.hir_id(), impl_item.generics, |this| {
intravisit::walk_impl_item(this, impl_item) intravisit::walk_impl_item(this, impl_item)
@ -1021,7 +1021,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}; };
self.with(scope, |this| { self.with(scope, |this| {
walk_list!(this, visit_generic_param, bound_generic_params); walk_list!(this, visit_generic_param, bound_generic_params);
this.visit_ty(bounded_ty); this.visit_unambig_ty(bounded_ty);
walk_list!(this, visit_param_bound, bounds); walk_list!(this, visit_param_bound, bounds);
}) })
} }
@ -1036,8 +1036,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
&hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { &hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
lhs_ty, rhs_ty, .. lhs_ty, rhs_ty, ..
}) => { }) => {
self.visit_ty(lhs_ty); self.visit_unambig_ty(lhs_ty);
self.visit_ty(rhs_ty); self.visit_unambig_ty(rhs_ty);
} }
} }
} }
@ -1070,13 +1070,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
GenericParamKind::Lifetime { .. } => {} GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { default, .. } => { GenericParamKind::Type { default, .. } => {
if let Some(ty) = default { if let Some(ty) = default {
self.visit_ty(ty); self.visit_unambig_ty(ty);
} }
} }
GenericParamKind::Const { ty, default, .. } => { GenericParamKind::Const { ty, default, .. } => {
self.visit_ty(ty); self.visit_unambig_ty(ty);
if let Some(default) = default { if let Some(default) = default {
self.visit_const_arg(default); self.visit_unambig_const_arg(default);
} }
} }
} }
@ -1985,15 +1985,15 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}, },
|this| { |this| {
for input in inputs { for input in inputs {
this.visit_ty(input); this.visit_unambig_ty(input);
} }
if !in_closure && let Some(output) = output { if !in_closure && let Some(output) = output {
this.visit_ty(output); this.visit_unambig_ty(output);
} }
}, },
); );
if in_closure && let Some(output) = output { if in_closure && let Some(output) = output {
self.visit_ty(output); self.visit_unambig_ty(output);
} }
} }
@ -2311,7 +2311,7 @@ fn is_late_bound_map(
let mut constrained_by_input = ConstrainedCollector { regions: Default::default(), tcx }; let mut constrained_by_input = ConstrainedCollector { regions: Default::default(), tcx };
for arg_ty in sig.decl.inputs { for arg_ty in sig.decl.inputs {
constrained_by_input.visit_ty(arg_ty); constrained_by_input.visit_unambig_ty(arg_ty);
} }
let mut appears_in_output = let mut appears_in_output =
@ -2419,7 +2419,7 @@ fn is_late_bound_map(
} }
impl<'v> Visitor<'v> for ConstrainedCollector<'_> { impl<'v> Visitor<'v> for ConstrainedCollector<'_> {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
match ty.kind { match ty.kind {
hir::TyKind::Path( hir::TyKind::Path(
hir::QPath::Resolved(Some(_), _) | hir::QPath::TypeRelative(..), hir::QPath::Resolved(Some(_), _) | hir::QPath::TypeRelative(..),

View file

@ -1,10 +1,9 @@
use core::ops::ControlFlow; use core::ops::ControlFlow;
use rustc_errors::{Applicability, StashKey, Suggestions}; use rustc_errors::{Applicability, StashKey, Suggestions};
use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::print::with_forced_trimmed_paths;
@ -451,7 +450,7 @@ fn infer_placeholder_type<'tcx>(
let mut visitor = HirPlaceholderCollector::default(); let mut visitor = HirPlaceholderCollector::default();
let node = tcx.hir_node_by_def_id(def_id); let node = tcx.hir_node_by_def_id(def_id);
if let Some(ty) = node.ty() { if let Some(ty) = node.ty() {
visitor.visit_ty(ty); visitor.visit_unambig_ty(ty);
} }
// If we have just one span, let's try to steal a const `_` feature error. // If we have just one span, let's try to steal a const `_` feature error.
let try_steal_span = if !tcx.features().generic_arg_infer() && visitor.spans.len() == 1 let try_steal_span = if !tcx.features().generic_arg_infer() && visitor.spans.len() == 1
@ -525,7 +524,7 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) ->
struct HasTait; struct HasTait;
impl<'tcx> Visitor<'tcx> for HasTait { impl<'tcx> Visitor<'tcx> for HasTait {
type Result = ControlFlow<()>; type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result { fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
if let hir::TyKind::OpaqueDef(..) = t.kind { if let hir::TyKind::OpaqueDef(..) = t.kind {
ControlFlow::Break(()) ControlFlow::Break(())
} else { } else {
@ -533,5 +532,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) ->
} }
} }
} }
HasTait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break() HasTait.visit_unambig_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break()
} }

View file

@ -1,10 +1,9 @@
use rustc_ast::ast::ParamKindOrd; use rustc_ast::ast::ParamKindOrd;
use rustc_errors::codes::*; use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, struct_span_code_err}; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::GenericArg;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, GenericArg};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty,
}; };

View file

@ -517,14 +517,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into() self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
} }
(&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => { (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
handle_ty_args(has_default, ty) // We handle the other parts of `Ty` in the match arm below
handle_ty_args(has_default, ty.as_unambig_ty())
} }
(&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => { (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
handle_ty_args(has_default, &inf.to_ty()) handle_ty_args(has_default, &inf.to_ty())
} }
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
self.lowerer.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into() .lowerer
} // Ambig portions of `ConstArg` are handled in the match arm below
.lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
.into(),
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
self.lowerer.ct_infer(Some(param), inf.span).into() self.lowerer.ct_infer(Some(param), inf.span).into()
} }
@ -2115,7 +2118,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
format!("Const::lower_const_arg: invalid qpath {qpath:?}"), format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
), ),
hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon), hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
hir::ConstArgKind::Infer(span) => self.ct_infer(None, span), hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
} }
} }
@ -2423,7 +2426,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length) Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
} }
hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(), hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
hir::TyKind::Infer => { hir::TyKind::Infer(()) => {
// Infer also appears as the type of arguments or return // Infer also appears as the type of arguments or return
// values in an ExprKind::Closure, or as // values in an ExprKind::Closure, or as
// the type of local variables. Both of these cases are // the type of local variables. Both of these cases are
@ -2556,7 +2559,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> { pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
match ty.kind { match ty.kind {
hir::TyKind::Infer if let Some(expected_ty) = expected_ty => { hir::TyKind::Infer(()) if let Some(expected_ty) = expected_ty => {
self.record_ty(ty.hir_id, expected_ty, ty.span); self.record_ty(ty.hir_id, expected_ty, ty.span);
expected_ty expected_ty
} }

View file

@ -1,6 +1,5 @@
use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, AmbigArg, ForeignItem, ForeignItemKind};
use rustc_hir::{ForeignItem, ForeignItemKind};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::bug; use rustc_middle::bug;
@ -68,11 +67,13 @@ fn diagnostic_hir_wf_check<'tcx>(
} }
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> { impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
let infcx = self.tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let infcx = self.tcx.infer_ctxt().build(TypingMode::non_body_analysis());
let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let tcx_ty = self.icx.lower_ty(ty); // We don't handle infer vars but we wouldn't handle them anyway as we're creating a
// fresh `InferCtxt` in this function.
let tcx_ty = self.icx.lower_ty(ty.as_unambig_ty());
// This visitor can walk into binders, resulting in the `tcx_ty` to // This visitor can walk into binders, resulting in the `tcx_ty` to
// potentially reference escaping bound variables. We simply erase // potentially reference escaping bound variables. We simply erase
// those here. // those here.
@ -149,7 +150,11 @@ fn diagnostic_hir_wf_check<'tcx>(
.iter() .iter()
.flat_map(|seg| seg.args().args) .flat_map(|seg| seg.args().args)
.filter_map(|arg| { .filter_map(|arg| {
if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None } if let hir::GenericArg::Type(ty) = arg {
Some(ty.as_unambig_ty())
} else {
None
}
}) })
.chain([impl_.self_ty]) .chain([impl_.self_ty])
.collect(), .collect(),
@ -196,7 +201,7 @@ fn diagnostic_hir_wf_check<'tcx>(
} }
}; };
for ty in tys { for ty in tys {
visitor.visit_ty(ty); visitor.visit_unambig_ty(ty);
} }
visitor.cause visitor.cause
} }

View file

@ -442,7 +442,7 @@ impl<'a> State<'a> {
self.word("/*ERROR*/"); self.word("/*ERROR*/");
self.pclose(); self.pclose();
} }
hir::TyKind::Infer | hir::TyKind::InferDelegation(..) => { hir::TyKind::Infer(()) | hir::TyKind::InferDelegation(..) => {
self.word("_"); self.word("_");
} }
hir::TyKind::Pat(ty, pat) => { hir::TyKind::Pat(ty, pat) => {
@ -1800,8 +1800,8 @@ impl<'a> State<'a> {
match generic_arg { match generic_arg {
GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
GenericArg::Lifetime(_) => {} GenericArg::Lifetime(_) => {}
GenericArg::Type(ty) => s.print_type(ty), GenericArg::Type(ty) => s.print_type(ty.as_unambig_ty()),
GenericArg::Const(ct) => s.print_const_arg(ct), GenericArg::Const(ct) => s.print_const_arg(ct.as_unambig_ct()),
GenericArg::Infer(_inf) => s.word("_"), GenericArg::Infer(_inf) => s.word("_"),
} }
}); });
@ -2151,7 +2151,7 @@ impl<'a> State<'a> {
s.ann.nested(s, Nested::BodyParamPat(body_id, i)); s.ann.nested(s, Nested::BodyParamPat(body_id, i));
i += 1; i += 1;
if let hir::TyKind::Infer = ty.kind { if let hir::TyKind::Infer(()) = ty.kind {
// Print nothing. // Print nothing.
} else { } else {
s.word(":"); s.word(":");

View file

@ -6,9 +6,9 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan}; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan};
use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::VisitorExt;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{self as hir, ExprKind, GenericArg, HirId, Node, QPath, intravisit}; use rustc_hir::{self as hir, AmbigArg, ExprKind, GenericArg, HirId, Node, QPath, intravisit};
use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend; use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend;
use rustc_hir_analysis::hir_ty_lowering::generics::{ use rustc_hir_analysis::hir_ty_lowering::generics::{
check_generic_arg_count_for_call, lower_generic_args, check_generic_arg_count_for_call, lower_generic_args,
@ -470,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
impl<'tcx> intravisit::Visitor<'tcx> for CollectClauses<'_, 'tcx> { impl<'tcx> intravisit::Visitor<'tcx> for CollectClauses<'_, 'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
if let Some(clauses) = self.fcx.trait_ascriptions.borrow().get(&ty.hir_id.local_id) if let Some(clauses) = self.fcx.trait_ascriptions.borrow().get(&ty.hir_id.local_id)
{ {
self.clauses.extend(clauses.iter().cloned()); self.clauses.extend(clauses.iter().cloned());
@ -480,7 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
let mut clauses = CollectClauses { clauses: vec![], fcx: self }; let mut clauses = CollectClauses { clauses: vec![], fcx: self };
clauses.visit_ty(hir_ty); clauses.visit_unambig_ty(hir_ty);
self.tcx.mk_clauses(&clauses.clauses) self.tcx.mk_clauses(&clauses.clauses)
} }
@ -1272,11 +1272,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.lower_lifetime(lt, RegionInferReason::Param(param)) .lower_lifetime(lt, RegionInferReason::Param(param))
.into(), .into(),
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.fcx.lower_ty(ty).raw.into() // We handle the ambig portions of `Ty` in match arms below
} self.fcx.lower_ty(ty.as_unambig_ty()).raw.into()
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
self.fcx.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into()
} }
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
.fcx
// Ambiguous parts of `ConstArg` are handled in the match arms below
.lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
.into(),
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
self.fcx.ty_infer(Some(param), inf.span).into() self.fcx.ty_infer(Some(param), inf.span).into()
} }

View file

@ -251,7 +251,8 @@ fn typeck_with_inspect<'tcx>(
fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Option<Ty<'tcx>> { fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Option<Ty<'tcx>> {
let tcx = fcx.tcx; let tcx = fcx.tcx;
let def_id = fcx.body_id; let def_id = fcx.body_id;
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = node.ty() { let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer(()), span, .. }) = node.ty()
{
if let Some(item) = tcx.opt_associated_item(def_id.into()) if let Some(item) = tcx.opt_associated_item(def_id.into())
&& let ty::AssocKind::Const = item.kind && let ty::AssocKind::Const = item.kind
&& let ty::AssocItemContainer::Impl = item.container && let ty::AssocItemContainer::Impl = item.container

View file

@ -425,11 +425,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
.lower_lifetime(lt, RegionInferReason::Param(param)) .lower_lifetime(lt, RegionInferReason::Param(param))
.into(), .into(),
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.cfcx.lower_ty(ty).raw.into() // We handle the ambig portions of `Ty` in the match arms below
} self.cfcx.lower_ty(ty.as_unambig_ty()).raw.into()
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
self.cfcx.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into()
} }
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
.cfcx
// We handle the ambig portions of `ConstArg` in the match arms below
.lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
.into(),
(GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
self.cfcx.ty_infer(Some(param), inf.span).into() self.cfcx.ty_infer(Some(param), inf.span).into()
} }

View file

@ -6,9 +6,8 @@ use std::mem;
use rustc_data_structures::unord::ExtendUnord; use rustc_data_structures::unord::ExtendUnord;
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir; use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::HirId; use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@ -354,7 +353,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
self.write_ty_to_typeck_results(l.hir_id, var_ty); self.write_ty_to_typeck_results(l.hir_id, var_ty);
} }
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
intravisit::walk_ty(self, hir_ty); intravisit::walk_ty(self, hir_ty);
// If there are type checking errors, Type privacy pass will stop, // If there are type checking errors, Type privacy pass will stop,
// so we may not get the type from hid_id, see #104513 // so we may not get the type from hid_id, see #104513
@ -364,12 +363,18 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
} }
} }
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { fn visit_infer(
intravisit::walk_inf(self, inf); &mut self,
inf_id: HirId,
inf_span: Span,
_kind: InferKind<'cx>,
) -> Self::Result {
self.visit_id(inf_id);
// Ignore cases where the inference is a const. // Ignore cases where the inference is a const.
if let Some(ty) = self.fcx.node_ty_opt(inf.hir_id) { if let Some(ty) = self.fcx.node_ty_opt(inf_id) {
let ty = self.resolve(ty, &inf.span); let ty = self.resolve(ty, &inf_span);
self.write_ty_to_typeck_results(inf.hir_id, ty); self.write_ty_to_typeck_results(inf_id, ty);
} }
} }
} }

View file

@ -5,8 +5,8 @@ use rustc_ast as ast;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{ use rustc_hir::{
BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat, PatKind, AmbigArg, BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat,
Path, PathSegment, QPath, Ty, TyKind, PatKind, Path, PathSegment, QPath, Ty, TyKind,
}; };
use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy}; use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -159,7 +159,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
} }
} }
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx>) { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx, AmbigArg>) {
match &ty.kind { match &ty.kind {
TyKind::Path(QPath::Resolved(_, path)) => { TyKind::Path(QPath::Resolved(_, path)) => {
if lint_ty_kind_usage(cx, &path.res) { if lint_ty_kind_usage(cx, &path.res) {

View file

@ -8,9 +8,8 @@ use std::cell::Cell;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::join; use rustc_data_structures::sync::join;
use rustc_hir as hir;
use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::def_id::{LocalDefId, LocalModDefId};
use rustc_hir::{HirId, intravisit as hir_visit}; use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_session::Session; use rustc_session::Session;
@ -214,15 +213,11 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}) })
} }
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) {
lint_callback!(self, check_ty, t); lint_callback!(self, check_ty, t);
hir_visit::walk_ty(self, t); hir_visit::walk_ty(self, t);
} }
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
hir_visit::walk_inf(self, inf);
}
fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: HirId) { fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: HirId) {
if !self.context.only_module { if !self.context.only_module {
self.process_mod(m, n); self.process_mod(m, n);

View file

@ -9,6 +9,7 @@ use rustc_errors::{
}; };
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, MissingLifetimeKind}; use rustc_hir::{self as hir, MissingLifetimeKind};
use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::inhabitedness::InhabitedPredicate;
@ -293,7 +294,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
// avoid doing throwaway work in case the lint ends up getting suppressed. // avoid doing throwaway work in case the lint ends up getting suppressed.
let mut collector = ShorthandAssocTyCollector { qselves: Vec::new() }; let mut collector = ShorthandAssocTyCollector { qselves: Vec::new() };
if let Some(ty) = self.ty { if let Some(ty) = self.ty {
hir::intravisit::Visitor::visit_ty(&mut collector, ty); collector.visit_unambig_ty(ty);
} }
let affect_object_lifetime_defaults = self let affect_object_lifetime_defaults = self

View file

@ -1,6 +1,6 @@
use rustc_errors::MultiSpan; use rustc_errors::MultiSpan;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind}; use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::{declare_lint, impl_lint_pass}; use rustc_session::{declare_lint, impl_lint_pass};
@ -126,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
// 1. We collect all the `hir::Path` from the `Self` type and `Trait` ref // 1. We collect all the `hir::Path` from the `Self` type and `Trait` ref
// of the `impl` definition // of the `impl` definition
let mut collector = PathCollector { paths: Vec::new() }; let mut collector = PathCollector { paths: Vec::new() };
collector.visit_ty(&impl_.self_ty); collector.visit_unambig_ty(&impl_.self_ty);
if let Some(of_trait) = &impl_.of_trait { if let Some(of_trait) = &impl_.of_trait {
collector.visit_trait_ref(of_trait); collector.visit_trait_ref(of_trait);
} }

View file

@ -1,4 +1,4 @@
use rustc_hir as hir; use rustc_hir::{self as hir, AmbigArg};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::fold::BottomUpFolder;
@ -67,7 +67,7 @@ declare_lint! {
declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]); declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx>) { fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
let hir::TyKind::OpaqueDef(opaque) = &ty.kind else { let hir::TyKind::OpaqueDef(opaque) = &ty.kind else {
return; return;
}; };

View file

@ -1,6 +1,5 @@
use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::{GenericArg, PathSegment, QPath, TyKind}; use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
@ -22,7 +21,7 @@ declare_tool_lint! {
declare_lint_pass!(PassByValue => [PASS_BY_VALUE]); declare_lint_pass!(PassByValue => [PASS_BY_VALUE]);
impl<'tcx> LateLintPass<'tcx> for PassByValue { impl<'tcx> LateLintPass<'tcx> for PassByValue {
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
match &ty.kind { match &ty.kind {
TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => { TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => {
if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner.to_def_id()) { if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner.to_def_id()) {
@ -78,7 +77,7 @@ fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String {
.tcx .tcx
.sess .sess
.source_map() .source_map()
.span_to_snippet(c.span()) .span_to_snippet(c.as_unambig_ct().span())
.unwrap_or_else(|_| "_".into()), .unwrap_or_else(|_| "_".into()),
GenericArg::Infer(_) => String::from("_"), GenericArg::Infer(_) => String::from("_"),
}) })

View file

@ -25,7 +25,7 @@ macro_rules! late_lint_methods {
fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>); fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>);
fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>); fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>);
fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>); fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>);
fn check_ty(a: &'tcx rustc_hir::Ty<'tcx>); fn check_ty(a: &'tcx rustc_hir::Ty<'tcx, rustc_hir::AmbigArg>);
fn check_generic_param(a: &'tcx rustc_hir::GenericParam<'tcx>); fn check_generic_param(a: &'tcx rustc_hir::GenericParam<'tcx>);
fn check_generics(a: &'tcx rustc_hir::Generics<'tcx>); fn check_generics(a: &'tcx rustc_hir::Generics<'tcx>);
fn check_poly_trait_ref(a: &'tcx rustc_hir::PolyTraitRef<'tcx>); fn check_poly_trait_ref(a: &'tcx rustc_hir::PolyTraitRef<'tcx>);

View file

@ -1,4 +1,4 @@
use rustc_hir::{self as hir, LangItem}; use rustc_hir::{self as hir, AmbigArg, LangItem};
use rustc_session::{declare_lint, declare_lint_pass}; use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym; use rustc_span::sym;
@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
} }
} }
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
let hir::TyKind::TraitObject(bounds, _lifetime_and_syntax_pointer) = &ty.kind else { let hir::TyKind::TraitObject(bounds, _lifetime_and_syntax_pointer) = &ty.kind else {
return; return;
}; };

View file

@ -4,7 +4,8 @@ use std::ops::ControlFlow;
use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, Variants, WrappingRange}; use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, Variants, WrappingRange};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagMessage; use rustc_errors::DiagMessage;
use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{AmbigArg, Expr, ExprKind, LangItem};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
use rustc_middle::ty::{ use rustc_middle::ty::{
@ -1472,7 +1473,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
} }
impl<'a, 'b, 'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'a, 'b, 'tcx> {
fn visit_ty(&mut self, ty: &'_ hir::Ty<'_>) { fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) {
debug!(?ty); debug!(?ty);
if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind
&& !self.visitor.is_internal_abi(*abi) && !self.visitor.is_internal_abi(*abi)
@ -1500,7 +1501,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let mut visitor = FnPtrFinder { visitor: self, spans: Vec::new(), tys: Vec::new() }; let mut visitor = FnPtrFinder { visitor: self, spans: Vec::new(), tys: Vec::new() };
ty.visit_with(&mut visitor); ty.visit_with(&mut visitor);
hir::intravisit::Visitor::visit_ty(&mut visitor, hir_ty); visitor.visit_unambig_ty(hir_ty);
iter::zip(visitor.tys.drain(..), visitor.spans.drain(..)).collect() iter::zip(visitor.tys.drain(..), visitor.spans.drain(..)).collect()
} }

View file

@ -33,7 +33,7 @@ use rustc_errors::{
use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::definitions::Definitions; use rustc_hir::definitions::Definitions;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::VisitorExt;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate}; use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
use rustc_index::IndexVec; use rustc_index::IndexVec;
@ -2028,7 +2028,7 @@ impl<'tcx> TyCtxt<'tcx> {
}; };
let mut v = TraitObjectVisitor(vec![], self.hir()); let mut v = TraitObjectVisitor(vec![], self.hir());
v.visit_ty(hir_output); v.visit_unambig_ty(hir_output);
v.0 v.0
} }
@ -2050,7 +2050,7 @@ impl<'tcx> TyCtxt<'tcx> {
&& let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
&& let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics() && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
{ {
v.visit_ty(alias_ty); v.visit_unambig_ty(alias_ty);
if !v.0.is_empty() { if !v.0.is_empty() {
return Some(( return Some((
v.0, v.0,

View file

@ -9,7 +9,7 @@ use rustc_errors::{
}; };
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicateKind}; use rustc_hir::{self as hir, AmbigArg, LangItem, PredicateOrigin, WherePredicateKind};
use rustc_span::{BytePos, Span}; use rustc_span::{BytePos, Span};
use rustc_type_ir::TyKind::*; use rustc_type_ir::TyKind::*;
@ -570,7 +570,7 @@ pub fn suggest_constraining_type_params<'a>(
pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>, pub crate::hir::map::Map<'tcx>); pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>, pub crate::hir::map::Map<'tcx>);
impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
match ty.kind { match ty.kind {
hir::TyKind::TraitObject(_, tagged_ptr) hir::TyKind::TraitObject(_, tagged_ptr)
if let hir::Lifetime { if let hir::Lifetime {
@ -579,9 +579,9 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
.. ..
} = tagged_ptr.pointer() => } = tagged_ptr.pointer() =>
{ {
self.0.push(ty) self.0.push(ty.as_unambig_ty())
} }
hir::TyKind::OpaqueDef(..) => self.0.push(ty), hir::TyKind::OpaqueDef(..) => self.0.push(ty.as_unambig_ty()),
_ => {} _ => {}
} }
hir::intravisit::walk_ty(self, ty); hir::intravisit::walk_ty(self, ty);

View file

@ -374,7 +374,13 @@ fn find_item_ty_spans(
if let hir::GenericArg::Type(ty) = arg if let hir::GenericArg::Type(ty) = arg
&& params_in_repr.contains(i as u32) && params_in_repr.contains(i as u32)
{ {
find_item_ty_spans(tcx, ty, needle, spans, seen_representable); find_item_ty_spans(
tcx,
ty.as_unambig_ty(),
needle,
spans,
seen_representable,
);
} }
} }
} }

View file

@ -2808,7 +2808,7 @@ fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool {
&& let Some(&[hir::GenericArg::Type(ty)]) = && let Some(&[hir::GenericArg::Type(ty)]) =
path.segments.last().map(|last| last.args().args) path.segments.last().map(|last| last.args().args)
{ {
doc_fake_variadic_is_allowed_self_ty(ty) doc_fake_variadic_is_allowed_self_ty(ty.as_unambig_ty())
} else { } else {
false false
}) })

View file

@ -460,7 +460,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
} }
// mark self_ty live // mark self_ty live
intravisit::walk_ty(self, impl_ref.self_ty); intravisit::walk_unambig_ty(self, impl_ref.self_ty);
if let Some(&impl_item_id) = if let Some(&impl_item_id) =
self.tcx.impl_item_implementor_ids(impl_id).get(&trait_item_id) self.tcx.impl_item_implementor_ids(impl_id).get(&trait_item_id)
{ {

View file

@ -5,8 +5,7 @@
use rustc_ast::visit::BoundKind; use rustc_ast::visit::BoundKind;
use rustc_ast::{self as ast, NodeId, visit as ast_visit}; use rustc_ast::{self as ast, NodeId, visit as ast_visit};
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir; use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit};
use rustc_hir::{HirId, intravisit as hir_visit};
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_middle::util::common::to_readable_str; use rustc_middle::util::common::to_readable_str;
@ -363,7 +362,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_expr_field(self, f) hir_visit::walk_expr_field(self, f)
} }
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) { fn visit_ty(&mut self, t: &'v hir::Ty<'v, AmbigArg>) {
record_variants!((self, t, t.kind, Some(t.hir_id), hir, Ty, TyKind), [ record_variants!((self, t, t.kind, Some(t.hir_id), hir, Ty, TyKind), [
InferDelegation, InferDelegation,
Slice, Slice,
@ -476,7 +475,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir::GenericArg::Lifetime(lt) => self.visit_lifetime(lt), hir::GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
hir::GenericArg::Type(ty) => self.visit_ty(ty), hir::GenericArg::Type(ty) => self.visit_ty(ty),
hir::GenericArg::Const(ct) => self.visit_const_arg(ct), hir::GenericArg::Const(ct) => self.visit_const_arg(ct),
hir::GenericArg::Infer(inf) => self.visit_infer(inf), hir::GenericArg::Infer(inf) => self.visit_id(inf.hir_id),
} }
} }

View file

@ -11,12 +11,11 @@ use rustc_attr_parsing::{
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
use rustc_feature::{ACCEPTED_LANG_FEATURES, EnabledLangFeature, EnabledLibFeature}; use rustc_feature::{ACCEPTED_LANG_FEATURES, EnabledLangFeature, EnabledLibFeature};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
use rustc_hir::hir_id::CRATE_HIR_ID; use rustc_hir::hir_id::CRATE_HIR_ID;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant}; use rustc_hir::{self as hir, AmbigArg, FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures}; use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::privacy::EffectiveVisibilities;
@ -802,7 +801,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
)) = stab )) = stab
{ {
let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true }; let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
c.visit_ty(self_ty); c.visit_unambig_ty(self_ty);
c.visit_trait_ref(t); c.visit_trait_ref(t);
// do not lint when the trait isn't resolved, since resolution error should // do not lint when the trait isn't resolved, since resolution error should
@ -1028,7 +1027,7 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
intravisit::walk_trait_ref(self, t) intravisit::walk_trait_ref(self, t)
} }
fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) { fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) {
if let TyKind::Never = t.kind { if let TyKind::Never = t.kind {
self.fully_stable = false; self.fully_stable = false;
} }
@ -1042,12 +1041,12 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) { fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
for ty in fd.inputs { for ty in fd.inputs {
self.visit_ty(ty) self.visit_unambig_ty(ty)
} }
if let hir::FnRetTy::Return(output_ty) = fd.output { if let hir::FnRetTy::Return(output_ty) = fd.output {
match output_ty.kind { match output_ty.kind {
TyKind::Never => {} // `-> !` is stable TyKind::Never => {} // `-> !` is stable
_ => self.visit_ty(output_ty), _ => self.visit_unambig_ty(output_ty),
} }
} }
} }

View file

@ -27,8 +27,8 @@ use rustc_data_structures::intern::Interned;
use rustc_errors::MultiSpan; use rustc_errors::MultiSpan;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind}; use rustc_hir::{AmbigArg, AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::print::PrintTraitRefExt as _;
@ -1179,7 +1179,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
self.maybe_typeck_results = old_maybe_typeck_results; self.maybe_typeck_results = old_maybe_typeck_results;
} }
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
self.span = hir_ty.span; self.span = hir_ty.span;
if self if self
.visit( .visit(
@ -1195,12 +1195,17 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
intravisit::walk_ty(self, hir_ty); intravisit::walk_ty(self, hir_ty);
} }
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { fn visit_infer(
self.span = inf.span; &mut self,
inf_id: rustc_hir::HirId,
inf_span: Span,
_kind: InferKind<'tcx>,
) -> Self::Result {
self.span = inf_span;
if let Some(ty) = self if let Some(ty) = self
.maybe_typeck_results .maybe_typeck_results
.unwrap_or_else(|| span_bug!(inf.span, "`hir::InferArg` outside of a body")) .unwrap_or_else(|| span_bug!(inf_span, "Inference variable outside of a body"))
.node_type_opt(inf.hir_id) .node_type_opt(inf_id)
{ {
if self.visit(ty).is_break() { if self.visit(ty).is_break() {
return; return;
@ -1208,7 +1213,8 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
} else { } else {
// FIXME: check types of const infers here. // FIXME: check types of const infers here.
} }
intravisit::walk_inf(self, inf);
self.visit_id(inf_id)
} }
// Check types of expressions // Check types of expressions

View file

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

View file

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

View file

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

View file

@ -1,10 +1,10 @@
//! Error Reporting for `impl` items that do not match the obligations from their `trait`. //! Error Reporting for `impl` items that do not match the obligations from their `trait`.
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{Namespace, Res}; use rustc_hir::def::{Namespace, Res};
use rustc_hir::def_id::DefId; 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::hir::nested_filter;
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::error::ExpectedFound;
@ -137,11 +137,13 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
self.tcx.hir() 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 { match arg.kind {
hir::TyKind::Ref(_, ref mut_ty) => { hir::TyKind::Ref(_, ref mut_ty) => {
// We don't want to suggest looking into borrowing `&T` or `&Self`. // 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; return;
} }
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments { 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() && let ty::Ref(found_region, _, _) = found.kind()
&& expected_region.is_bound() && expected_region.is_bound()
&& !found_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 // 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 `: &_`. // 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_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, LangItem}; use rustc_hir::{self as hir, AmbigArg, LangItem};
use rustc_infer::traits::{ use rustc_infer::traits::{
DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode, DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode,
PredicateObligation, SelectionError, 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 { if self.span == ty.span {
self.ty_result = Some(ty); self.ty_result = Some(ty.as_unambig_ty());
} else { } else {
hir::intravisit::walk_ty(self, ty); hir::intravisit::walk_ty(self, ty);
} }

View file

@ -14,14 +14,13 @@ use rustc_errors::{
Applicability, Diag, EmissionGuarantee, MultiSpan, Style, SuggestionStyle, pluralize, Applicability, Diag, EmissionGuarantee, MultiSpan, Style, SuggestionStyle, pluralize,
struct_span_code_err, struct_span_code_err,
}; };
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId; 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::lang_items::LangItem;
use rustc_hir::{ use rustc_hir::{
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node, expr_needs_parens, self as hir, AmbigArg, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node,
is_range_literal, expr_needs_parens, is_range_literal,
}; };
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_middle::hir::map; use rustc_middle::hir::map;
@ -179,7 +178,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
let mut ty_spans = vec![]; let mut ty_spans = vec![];
for input in fn_sig.decl.inputs { for input in fn_sig.decl.inputs {
ReplaceImplTraitVisitor { ty_spans: &mut ty_spans, param_did: param.def_id } 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. // The type param `T: Trait` we will suggest to introduce.
let type_param = format!("{type_param_name}: {bound_str}"); let type_param = format!("{type_param_name}: {bound_str}");
@ -5065,7 +5064,7 @@ pub struct SelfVisitor<'v> {
} }
impl<'v> Visitor<'v> for 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 if let hir::TyKind::Path(path) = ty.kind
&& let hir::QPath::TypeRelative(inner_ty, segment) = path && let hir::QPath::TypeRelative(inner_ty, segment) = path
&& (Some(segment.ident.name) == self.name || self.name.is_none()) && (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 hir::QPath::Resolved(None, inner_path) = inner_path
&& let Res::SelfTyAlias { .. } = inner_path.res && let Res::SelfTyAlias { .. } = inner_path.res
{ {
self.paths.push(ty); self.paths.push(ty.as_unambig_ty());
} }
hir::intravisit::walk_ty(self, ty); hir::intravisit::walk_ty(self, ty);
} }
@ -5187,7 +5186,7 @@ struct ReplaceImplTraitVisitor<'a> {
} }
impl<'a, 'hir> hir::intravisit::Visitor<'hir> for 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( if let hir::TyKind::Path(hir::QPath::Resolved(
None, None,
hir::Path { res: Res::Def(_, segment_did), .. }, 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. // 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 // 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 // `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` // 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, Applicability, Diag, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic,
EmissionGuarantee, IntoDiagArg, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic, EmissionGuarantee, IntoDiagArg, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic,
}; };
use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{Visitor, walk_ty}; use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
use rustc_hir::{FnRetTy, GenericParamKind, Node}; use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node};
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath}; use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt}; 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 { 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| { let make_suggestion = |ident: Ident| {
if ident.name == kw::Empty && ident.span.is_empty() { if ident.name == kw::Empty && ident.span.is_empty() {
format!("{}, ", self.suggestion_param_name) format!("{}, ", self.suggestion_param_name)
@ -642,16 +641,16 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
if let Some(fn_decl) = node.fn_decl() if let Some(fn_decl) = node.fn_decl()
&& let hir::FnRetTy::Return(ty) = fn_decl.output && let hir::FnRetTy::Return(ty) = fn_decl.output
{ {
visitor.visit_ty(ty); visitor.visit_unambig_ty(ty);
} }
if visitor.suggestions.is_empty() { if visitor.suggestions.is_empty() {
// Do not suggest constraining the `&self` param, but rather the return type. // 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 // 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 // user to fix it. This way we lower the chances of *over* constraining, but still
// get the cake of "correctly" contrained in two steps. // 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() { if visitor.suggestions.is_empty() {
return false; return false;
} }

View file

@ -1,8 +1,8 @@
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self as hir, AmbigArg};
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
@ -187,7 +187,7 @@ fn associated_types_for_impl_traits_in_associated_fn(
} }
impl<'tcx> Visitor<'tcx> for RPITVisitor { impl<'tcx> Visitor<'tcx> for RPITVisitor {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
if let hir::TyKind::OpaqueDef(opaq) = ty.kind if let hir::TyKind::OpaqueDef(opaq) = ty.kind
&& self.rpits.insert(opaq.def_id) && self.rpits.insert(opaq.def_id)
{ {