Skip to content

Commit 6a2a59d

Browse files
Don't give APITs names with macro expansion placeholder fragments in it
1 parent 100199c commit 6a2a59d

File tree

9 files changed

+76
-13
lines changed

9 files changed

+76
-13
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,10 @@ pub trait ResolverExpand {
11161116
trait_def_id: DefId,
11171117
impl_def_id: LocalDefId,
11181118
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1119+
1120+
/// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used
1121+
/// to generate an item name later that does not reference placeholder macros.
1122+
fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
11191123
}
11201124

11211125
pub trait LintStoreExpand {

compiler/rustc_expand/src/expand.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
2626
use rustc_session::parse::feature_err;
2727
use rustc_session::{Limit, Session};
2828
use rustc_span::hygiene::SyntaxContext;
29-
use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, sym};
29+
use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym};
3030
use smallvec::SmallVec;
3131

3232
use crate::base::*;
@@ -2315,7 +2315,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
23152315
}
23162316

23172317
fn visit_ty(&mut self, node: &mut P<ast::Ty>) {
2318-
self.visit_node(node)
2318+
// Save the pre-expanded name of this `ImplTrait`, so that later when defining
2319+
// an APIT we use a name that doesn't have any placeholder fragments in it.
2320+
if let ast::TyKind::ImplTrait(id, _) = &mut node.kind {
2321+
// HACK: Assign an ID to this node out-of-order.
2322+
self.visit_id(id);
2323+
let id = *id;
2324+
let name = Symbol::intern(&pprust::ty_to_string(node).replace('\n', " "));
2325+
self.cx.resolver.insert_impl_trait_name(id, name);
2326+
}
2327+
2328+
self.visit_node(node);
23192329
}
23202330

23212331
fn visit_pat(&mut self, node: &mut P<ast::Pat>) {

compiler/rustc_resolve/src/def_collector.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ use std::mem;
22

33
use rustc_ast::visit::FnKind;
44
use rustc_ast::*;
5-
use rustc_ast_pretty::pprust;
65
use rustc_attr_parsing::{AttributeParser, OmitDoc};
76
use rustc_expand::expand::AstFragment;
87
use rustc_hir as hir;
98
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
109
use rustc_hir::def_id::LocalDefId;
10+
use rustc_middle::span_bug;
1111
use rustc_span::hygiene::LocalExpnId;
1212
use rustc_span::{Span, Symbol, sym};
1313
use tracing::debug;
@@ -381,7 +381,11 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
381381
// gets too long. We don't want these to show up in compiler
382382
// output or built artifacts, so replace them here...
383383
// Perhaps we should instead format APITs more robustly.
384-
let name = Symbol::intern(&pprust::ty_to_string(ty).replace('\n', " "));
384+
let name = *self
385+
.resolver
386+
.impl_trait_names
387+
.get(id)
388+
.unwrap_or_else(|| span_bug!(ty.span, "expected this opaque to be named"));
385389
let kind = match self.invocation_parent.impl_trait_context {
386390
ImplTraitContext::Universal => DefKind::TyParam,
387391
ImplTraitContext::Existential => DefKind::OpaqueTy,

compiler/rustc_resolve/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,11 @@ pub struct Resolver<'ra, 'tcx> {
12241224
current_crate_outer_attr_insert_span: Span,
12251225

12261226
mods_with_parse_errors: FxHashSet<DefId>,
1227+
1228+
// Stores pre-expansion and pre-placeholder-fragment-insertion names for `impl Trait` types
1229+
// that were encountered during resolution. These names are used to generate item names
1230+
// for APITs, so we don't want to leak details of resolution into these names.
1231+
impl_trait_names: FxHashMap<NodeId, Symbol>,
12271232
}
12281233

12291234
/// This provides memory for the rest of the crate. The `'ra` lifetime that is
@@ -1579,6 +1584,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15791584
impl_binding_keys: Default::default(),
15801585
current_crate_outer_attr_insert_span,
15811586
mods_with_parse_errors: Default::default(),
1587+
impl_trait_names: Default::default(),
15821588
};
15831589

15841590
let root_parent_scope = ParentScope::module(graph_root, &resolver);

compiler/rustc_resolve/src/macros.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
511511
});
512512
Ok(idents)
513513
}
514+
515+
fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol) {
516+
self.impl_trait_names.insert(id, name);
517+
}
514518
}
515519

516520
impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

tests/crashes/140333.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
trait Foo<T> {}
2+
3+
macro_rules! bar {
4+
() => { () }
5+
}
6+
7+
fn foo(x: impl Foo<bar!()>) {
8+
let () = x;
9+
//~^ ERROR mismatched types
10+
}
11+
12+
fn main() {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/name-mentioning-macro.rs:8:9
3+
|
4+
LL | fn foo(x: impl Foo<bar!()>) {
5+
| ---------------- expected this type parameter
6+
LL | let () = x;
7+
| ^^ - this expression has type `impl Foo<bar!()>`
8+
| |
9+
| expected type parameter `impl Foo<bar!()>`, found `()`
10+
|
11+
= note: expected type parameter `impl Foo<bar!()>`
12+
found unit type `()`
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ check-pass
2+
3+
trait Trait<T> {}
4+
5+
fn a(_: impl Trait<
6+
[(); {
7+
struct D {
8+
#[rustfmt::skip]
9+
bar: (),
10+
}
11+
0
12+
}],
13+
>) {
14+
}
15+
16+
fn main() {}

0 commit comments

Comments
 (0)