diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-06-26 15:47:20 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-26 15:47:20 +0200 |
| commit | a05f2cc44db687e6be19d84119cf7f8c9e52c510 (patch) | |
| tree | 93619423e6c9144e12e077c56db4a40cab9d720c /compiler/rustc_resolve/src | |
| parent | d73bf103b9040a417ab5dacc3e93cb487b49f397 (diff) | |
| parent | 8cd3fa04e2e023967cf2cfe3e4170b636fd25019 (diff) | |
| download | rust-a05f2cc44db687e6be19d84119cf7f8c9e52c510.tar.gz rust-a05f2cc44db687e6be19d84119cf7f8c9e52c510.zip | |
Rollup merge of #142393 - compiler-errors:nofield, r=petrochenkov
Don't give APITs names with macro expansion placeholder fragments in it The `DefCollector` previously called `pprust::ty_to_string` to construct a name for APITs (arg-position impl traits). The `ast::Ty` that was being formatted however has already had its macro calls replaced with "placeholder fragments", which end up rendering like `!()` (or ICEing, in the case of rust-lang/rust#140333, since it led to a placeholder struct field with no name). Instead, collect the name of the APIT *before* we visit its macros and replace them with placeholders in the macro expander. This makes the implementation a bit more involved, but AFAICT there's no better way to do this since we can't do a reverse mapping from placeholder fragment -> original macro call AST. Fixes rust-lang/rust#140333
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/def_collector.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 4 |
3 files changed, 19 insertions, 9 deletions
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 16852d1661e..1e345b11c14 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -2,12 +2,12 @@ use std::mem; use rustc_ast::visit::FnKind; use rustc_ast::*; -use rustc_ast_pretty::pprust; use rustc_attr_parsing::{AttributeParser, Early, OmitDoc}; use rustc_expand::expand::AstFragment; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::LocalDefId; +use rustc_middle::span_bug; use rustc_span::hygiene::LocalExpnId; use rustc_span::{Span, Symbol, sym}; use tracing::debug; @@ -380,20 +380,20 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_ty(&mut self, ty: &'a Ty) { - match &ty.kind { + match ty.kind { TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), - TyKind::ImplTrait(id, _) => { - // HACK: pprust breaks strings with newlines when the type - // gets too long. We don't want these to show up in compiler - // output or built artifacts, so replace them here... - // Perhaps we should instead format APITs more robustly. - let name = Symbol::intern(&pprust::ty_to_string(ty).replace('\n', " ")); + TyKind::ImplTrait(opaque_id, _) => { + let name = *self + .resolver + .impl_trait_names + .get(&ty.id) + .unwrap_or_else(|| span_bug!(ty.span, "expected this opaque to be named")); let kind = match self.invocation_parent.impl_trait_context { ImplTraitContext::Universal => DefKind::TyParam, ImplTraitContext::Existential => DefKind::OpaqueTy, ImplTraitContext::InBinding => return visit::walk_ty(self, ty), }; - let id = self.create_def(*id, Some(name), kind, ty.span); + let id = self.create_def(opaque_id, Some(name), kind, ty.span); match self.invocation_parent.impl_trait_context { // Do not nest APIT, as we desugar them as `impl_trait: bounds`, // so the `impl_trait` node is not a parent to `bounds`. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f0540725416..05bc3611dd8 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1224,6 +1224,11 @@ pub struct Resolver<'ra, 'tcx> { current_crate_outer_attr_insert_span: Span, mods_with_parse_errors: FxHashSet<DefId>, + + // Stores pre-expansion and pre-placeholder-fragment-insertion names for `impl Trait` types + // that were encountered during resolution. These names are used to generate item names + // for APITs, so we don't want to leak details of resolution into these names. + impl_trait_names: FxHashMap<NodeId, Symbol>, } /// This provides memory for the rest of the crate. The `'ra` lifetime that is @@ -1579,6 +1584,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { impl_binding_keys: Default::default(), current_crate_outer_attr_insert_span, mods_with_parse_errors: Default::default(), + impl_trait_names: Default::default(), }; let root_parent_scope = ParentScope::module(graph_root, &resolver); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 1b82e9c9799..3d33a02a9c6 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -522,6 +522,10 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { }); Ok(idents) } + + fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol) { + self.impl_trait_names.insert(id, name); + } } impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
