Skip to content

Commit bc1ca6b

Browse files
Fix enforcement of generics for associated items
1 parent 04fafd6 commit bc1ca6b

File tree

3 files changed

+85
-19
lines changed

3 files changed

+85
-19
lines changed

compiler/rustc_ast/src/ast.rs

+22
Original file line numberDiff line numberDiff line change
@@ -2845,6 +2845,28 @@ impl Item {
28452845
pub fn span_with_attributes(&self) -> Span {
28462846
self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
28472847
}
2848+
2849+
pub fn opt_generics(&self) -> Option<&Generics> {
2850+
match &self.kind {
2851+
ItemKind::ExternCrate(_)
2852+
| ItemKind::Use(_)
2853+
| ItemKind::Mod(_, _)
2854+
| ItemKind::ForeignMod(_)
2855+
| ItemKind::GlobalAsm(_)
2856+
| ItemKind::MacCall(_)
2857+
| ItemKind::MacroDef(_) => None,
2858+
ItemKind::Static(_) => None,
2859+
ItemKind::Const(i) => Some(&i.generics),
2860+
ItemKind::Fn(i) => Some(&i.generics),
2861+
ItemKind::TyAlias(i) => Some(&i.generics),
2862+
ItemKind::TraitAlias(generics, _)
2863+
| ItemKind::Enum(_, generics)
2864+
| ItemKind::Struct(_, generics)
2865+
| ItemKind::Union(_, generics) => Some(&generics),
2866+
ItemKind::Trait(i) => Some(&i.generics),
2867+
ItemKind::Impl(i) => Some(&i.generics),
2868+
}
2869+
}
28482870
}
28492871

28502872
/// `extern` qualifier on a function item or function type.

compiler/rustc_hir/src/target.rs

+36
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,42 @@ impl Display for Target {
6767
}
6868

6969
impl Target {
70+
pub fn is_associated_item(self) -> bool {
71+
match self {
72+
Target::AssocConst | Target::AssocTy | Target::Method(_) => true,
73+
Target::ExternCrate
74+
| Target::Use
75+
| Target::Static
76+
| Target::Const
77+
| Target::Fn
78+
| Target::Closure
79+
| Target::Mod
80+
| Target::ForeignMod
81+
| Target::GlobalAsm
82+
| Target::TyAlias
83+
| Target::OpaqueTy
84+
| Target::Enum
85+
| Target::Variant
86+
| Target::Struct
87+
| Target::Field
88+
| Target::Union
89+
| Target::Trait
90+
| Target::TraitAlias
91+
| Target::Impl
92+
| Target::Expression
93+
| Target::Statement
94+
| Target::Arm
95+
| Target::ForeignFn
96+
| Target::ForeignStatic
97+
| Target::ForeignTy
98+
| Target::GenericParam(_)
99+
| Target::MacroDef
100+
| Target::Param
101+
| Target::PatField
102+
| Target::ExprField => false,
103+
}
104+
}
105+
70106
pub fn from_item(item: &Item<'_>) -> Target {
71107
match item.kind {
72108
ItemKind::ExternCrate(..) => Target::ExternCrate,

compiler/rustc_passes/src/lang_items.rs

+27-19
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,15 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
195195
// Some other types like Box and various functions like drop_in_place
196196
// have minimum requirements.
197197

198-
let actual_num = generics.params.len();
198+
// FIXME: This still doesn't count, e.g., elided lifetimes and APITs.
199+
let mut actual_num = generics.params.len();
200+
if target.is_associated_item() {
201+
actual_num += self
202+
.parent_item
203+
.unwrap()
204+
.opt_generics()
205+
.map_or(0, |generics| generics.params.len());
206+
}
199207

200208
let mut at_least = false;
201209
let required = match lang_item.required_generics() {
@@ -258,23 +266,23 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
258266

259267
impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
260268
fn visit_item(&mut self, i: &'ast ast::Item) {
261-
let (target, generics) = match &i.kind {
262-
ast::ItemKind::ExternCrate(_) => (Target::ExternCrate, None),
263-
ast::ItemKind::Use(_) => (Target::Use, None),
264-
ast::ItemKind::Static(_) => (Target::Static, None),
265-
ast::ItemKind::Const(ct) => (Target::Const, Some(&ct.generics)),
266-
ast::ItemKind::Fn(fun) => (Target::Fn, Some(&fun.generics)),
267-
ast::ItemKind::Mod(_, _) => (Target::Mod, None),
268-
ast::ItemKind::ForeignMod(_) => (Target::ForeignFn, None),
269-
ast::ItemKind::GlobalAsm(_) => (Target::GlobalAsm, None),
270-
ast::ItemKind::TyAlias(alias) => (Target::TyAlias, Some(&alias.generics)),
271-
ast::ItemKind::Enum(_, generics) => (Target::Enum, Some(generics)),
272-
ast::ItemKind::Struct(_, generics) => (Target::Struct, Some(generics)),
273-
ast::ItemKind::Union(_, generics) => (Target::Union, Some(generics)),
274-
ast::ItemKind::Trait(tr) => (Target::Trait, Some(&tr.generics)),
275-
ast::ItemKind::TraitAlias(generics, _) => (Target::TraitAlias, Some(generics)),
276-
ast::ItemKind::Impl(_) => (Target::Impl, None),
277-
ast::ItemKind::MacroDef(_) => (Target::MacroDef, None),
269+
let target = match &i.kind {
270+
ast::ItemKind::ExternCrate(_) => Target::ExternCrate,
271+
ast::ItemKind::Use(_) => Target::Use,
272+
ast::ItemKind::Static(_) => Target::Static,
273+
ast::ItemKind::Const(_) => Target::Const,
274+
ast::ItemKind::Fn(_) => Target::Fn,
275+
ast::ItemKind::Mod(_, _) => Target::Mod,
276+
ast::ItemKind::ForeignMod(_) => Target::ForeignFn,
277+
ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm,
278+
ast::ItemKind::TyAlias(_) => Target::TyAlias,
279+
ast::ItemKind::Enum(_, _) => Target::Enum,
280+
ast::ItemKind::Struct(_, _) => Target::Struct,
281+
ast::ItemKind::Union(_, _) => Target::Union,
282+
ast::ItemKind::Trait(_) => Target::Trait,
283+
ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias,
284+
ast::ItemKind::Impl(_) => Target::Impl,
285+
ast::ItemKind::MacroDef(_) => Target::MacroDef,
278286
ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
279287
};
280288

@@ -283,7 +291,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
283291
self.resolver.node_id_to_def_id[&i.id],
284292
&i.attrs,
285293
i.span,
286-
generics,
294+
i.opt_generics(),
287295
);
288296

289297
let parent_item = self.parent_item.replace(i);

0 commit comments

Comments
 (0)