Auto merge of #129244 - cjgillot:opaque-hir, r=compiler-errors
Make opaque types regular HIR nodes Having opaque types as HIR owner introduces all sorts of complications. This PR proposes to make them regular HIR nodes instead. I haven't gone through all the test changes yet, so there may be a few surprises. Many thanks to `@camelid` for the first draft. Fixes https://github.com/rust-lang/rust/issues/129023 Fixes #129099 Fixes #125843 Fixes #119716 Fixes #121422
This commit is contained in:
commit
a1beaa1992
|
@ -6,7 +6,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
|
||||
use rustc_hir::{
|
||||
BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
|
||||
PredicateOrigin, Ty, TyKind, WherePredicate,
|
||||
PredicateOrigin, Ty, WherePredicate,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
@ -199,12 +199,6 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
|
|||
fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
|
||||
if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
|
||||
self.ty_params.remove(&def_id);
|
||||
} else if let TyKind::OpaqueDef(id, _) = t.kind {
|
||||
// Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls
|
||||
// `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're
|
||||
// using `OnlyBodies`, so the check ends up failing and the type isn't fully walked.
|
||||
let item = self.nested_visit_map().item(id);
|
||||
walk_item(self, item);
|
||||
} else {
|
||||
walk_ty(self, t);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
|
|||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{
|
||||
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier,
|
||||
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier,
|
||||
TyKind, WherePredicate,
|
||||
};
|
||||
use rustc_hir_analysis::lower_ty;
|
||||
|
@ -342,11 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &rustc_hir::Ty<'_>) {
|
||||
if let TyKind::OpaqueDef(item_id, ..) = ty.kind
|
||||
&& let item = cx.tcx.hir().item(item_id)
|
||||
&& let ItemKind::OpaqueTy(opaque_ty) = item.kind
|
||||
{
|
||||
fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx>) {
|
||||
if let TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {
|
||||
check(cx, opaque_ty.bounds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,11 +308,7 @@ enum LenOutput {
|
|||
|
||||
fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {
|
||||
if let ty::Alias(_, alias_ty) = ty.kind()
|
||||
&& let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
|
||||
&& let Item {
|
||||
kind: ItemKind::OpaqueTy(opaque),
|
||||
..
|
||||
} = item
|
||||
&& let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
|
||||
&& let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
|
||||
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
|
||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::FnRetTy::Return;
|
||||
use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
|
||||
use rustc_hir::intravisit::{
|
||||
Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
|
||||
Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound,
|
||||
walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_where_predicate,
|
||||
};
|
||||
use rustc_hir::{
|
||||
|
@ -420,11 +420,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
|
|||
|
||||
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
|
||||
match ty.kind {
|
||||
TyKind::OpaqueDef(item, bounds) => {
|
||||
let map = self.cx.tcx.hir();
|
||||
let item = map.item(item);
|
||||
TyKind::OpaqueDef(opaque, bounds) => {
|
||||
let len = self.lts.len();
|
||||
walk_item(self, item);
|
||||
self.visit_opaque_ty(opaque);
|
||||
self.lts.truncate(len);
|
||||
self.lts.extend(bounds.iter().filter_map(|bound| match bound {
|
||||
GenericArg::Lifetime(&l) => Some(l),
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
|
||||
FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind,
|
||||
FnRetTy, GenericArg, GenericBound, ImplItem, Item, LifetimeName, Node, TraitRef, Ty, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
@ -105,9 +105,7 @@ fn future_trait_ref<'tcx>(
|
|||
cx: &LateContext<'tcx>,
|
||||
ty: &'tcx Ty<'tcx>,
|
||||
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
|
||||
if let TyKind::OpaqueDef(item_id, bounds) = ty.kind
|
||||
&& let item = cx.tcx.hir().item(item_id)
|
||||
&& let ItemKind::OpaqueTy(opaque) = &item.kind
|
||||
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
|
||||
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
|
||||
if let GenericBound::Trait(poly, _) = bound {
|
||||
Some(&poly.trait_ref)
|
||||
|
|
|
@ -193,8 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
| hir::ItemKind::Trait(..)
|
||||
| hir::ItemKind::TraitAlias(..)
|
||||
| hir::ItemKind::TyAlias(..)
|
||||
| hir::ItemKind::Union(..)
|
||||
| hir::ItemKind::OpaqueTy(..) => {},
|
||||
| hir::ItemKind::Union(..) => {}
|
||||
hir::ItemKind::ExternCrate(..)
|
||||
| hir::ItemKind::ForeignMod { .. }
|
||||
| hir::ItemKind::GlobalAsm(..)
|
||||
|
|
|
@ -130,7 +130,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
|||
| hir::ItemKind::GlobalAsm(..)
|
||||
| hir::ItemKind::TyAlias(..)
|
||||
| hir::ItemKind::Union(..)
|
||||
| hir::ItemKind::OpaqueTy(..)
|
||||
| hir::ItemKind::ExternCrate(..)
|
||||
| hir::ItemKind::ForeignMod { .. }
|
||||
| hir::ItemKind::Impl { .. }
|
||||
|
|
|
@ -85,10 +85,6 @@ const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
|
||||
if matches!(item.kind, ItemKind::OpaqueTy(_)) {
|
||||
// skip over `ItemKind::OpaqueTy` in order to lint `foo() -> impl <..>`
|
||||
return;
|
||||
}
|
||||
// We push the self types of `impl`s on a stack here. Only the top type on the stack is
|
||||
// relevant for linting, since this is the self type of the `impl` we're currently in. To
|
||||
// avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
|
||||
|
@ -130,10 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
|
|||
self.stack.push(stack_item);
|
||||
}
|
||||
|
||||
fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
|
||||
if !matches!(item.kind, ItemKind::OpaqueTy(_)) {
|
||||
self.stack.pop();
|
||||
}
|
||||
fn check_item_post(&mut self, _: &LateContext<'_>, _: &Item<'_>) {
|
||||
self.stack.pop();
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
|
||||
|
|
|
@ -220,7 +220,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
|
|||
ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
|
||||
ItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
|
||||
ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
|
||||
ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
|
||||
ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
|
||||
ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
|
||||
ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
|
||||
ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
|
||||
|
|
Loading…
Reference in New Issue