From: Mazdak Farrokhzad Date: Thu, 13 Feb 2020 17:03:38 +0000 (+0100) Subject: ast: move Generics into AssocItemKinds X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=2fd15442f2f1c798718242eaa9817531a53c2134;p=rust.git ast: move Generics into AssocItemKinds --- diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 426659fd924..073f0c6bc47 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -760,31 +760,25 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> { let (generics, kind) = match i.kind { AssocItemKind::Const(ref ty, ref default) => { - let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed()); let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); - ( - generics, - hir::TraitItemKind::Const( - ty, - default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))), - ), - ) + let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); + (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body)) } - AssocItemKind::Fn(ref sig, None) => { + AssocItemKind::Fn(ref sig, ref generics, None) => { let names = self.lower_fn_params_to_names(&sig.decl); let (generics, sig) = - self.lower_method_sig(&i.generics, sig, trait_item_def_id, false, None); + self.lower_method_sig(generics, sig, trait_item_def_id, false, None); (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names))) } - AssocItemKind::Fn(ref sig, Some(ref body)) => { + AssocItemKind::Fn(ref sig, ref generics, Some(ref body)) => { let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body)); let (generics, sig) = - self.lower_method_sig(&i.generics, sig, trait_item_def_id, false, None); + self.lower_method_sig(generics, sig, trait_item_def_id, false, None); (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id))) } - AssocItemKind::TyAlias(ref bounds, ref default) => { + AssocItemKind::TyAlias(ref generics, ref bounds, ref default) => { let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed())); - let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed()); + let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); let kind = hir::TraitItemKind::Type( self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), ty, @@ -806,10 +800,10 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> { } fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { - let (kind, has_default) = match i.kind { - AssocItemKind::Const(_, ref default) => (hir::AssocItemKind::Const, default.is_some()), - AssocItemKind::TyAlias(_, ref default) => (hir::AssocItemKind::Type, default.is_some()), - AssocItemKind::Fn(ref sig, ref default) => { + let (kind, has_default) = match &i.kind { + AssocItemKind::Const(_, default) => (hir::AssocItemKind::Const, default.is_some()), + AssocItemKind::TyAlias(_, _, default) => (hir::AssocItemKind::Type, default.is_some()), + AssocItemKind::Fn(sig, _, default) => { (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some()) } AssocItemKind::Macro(..) => unimplemented!(), @@ -833,21 +827,20 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> { let (generics, kind) = match i.kind { AssocItemKind::Const(ref ty, ref expr) => { - let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed()); let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); ( - generics, + hir::Generics::empty(), hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())), ) } - AssocItemKind::Fn(ref sig, ref body) => { + AssocItemKind::Fn(ref sig, ref generics, ref body) => { self.current_item = Some(i.span); let asyncness = sig.header.asyncness; let body_id = self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref()); let impl_trait_return_allow = !self.is_in_trait_impl; let (generics, sig) = self.lower_method_sig( - &i.generics, + generics, sig, impl_item_def_id, impl_trait_return_allow, @@ -856,8 +849,8 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> { (generics, hir::ImplItemKind::Method(sig, body_id)) } - AssocItemKind::TyAlias(_, ref ty) => { - let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed()); + AssocItemKind::TyAlias(ref generics, _, ref ty) => { + let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); let kind = match ty { None => { let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err)); @@ -902,13 +895,13 @@ fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef<'hir> { defaultness: self.lower_defaultness(i.defaultness, true /* [1] */), kind: match &i.kind { AssocItemKind::Const(..) => hir::AssocItemKind::Const, - AssocItemKind::TyAlias(_, ty) => { + AssocItemKind::TyAlias(_, _, ty) => { match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { None => hir::AssocItemKind::Type, Some(_) => hir::AssocItemKind::OpaqueTy, } } - AssocItemKind::Fn(sig, _) => { + AssocItemKind::Fn(sig, _, _) => { hir::AssocItemKind::Method { has_self: sig.decl.has_self() } } AssocItemKind::Macro(..) => unimplemented!(), diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 99de4b88fd3..56d789b7a6a 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -490,7 +490,7 @@ fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) { self.lctx.allocate_hir_id_counter(item.id); let owner = match (&item.kind, ctxt) { // Ignore patterns in trait methods without bodies. - (AssocItemKind::Fn(_, None), AssocCtxt::Trait) => None, + (AssocItemKind::Fn(_, _, None), AssocCtxt::Trait) => None, _ => Some(item.id), }; self.with_hir_id_owner(owner, |this| visit::walk_assoc_item(this, item, ctxt)); diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 2f0495b8b5a..206cdefecc9 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -1154,10 +1154,10 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { AssocItemKind::Const(_, body) => { self.check_impl_item_provided(item.span, body, "constant", " = ;"); } - AssocItemKind::Fn(_, body) => { + AssocItemKind::Fn(_, _, body) => { self.check_impl_item_provided(item.span, body, "function", " { }"); } - AssocItemKind::TyAlias(bounds, body) => { + AssocItemKind::TyAlias(_, bounds, body) => { self.check_impl_item_provided(item.span, body, "type", " = ;"); self.check_impl_assoc_type_no_bounds(bounds); } @@ -1167,7 +1167,7 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { if ctxt == AssocCtxt::Trait || self.in_trait_impl { self.invalid_visibility(&item.vis, None); - if let AssocItemKind::Fn(sig, _) = &item.kind { + if let AssocItemKind::Fn(sig, _, _) = &item.kind { self.check_trait_fn_not_const(sig.header.constness); self.check_trait_fn_not_async(item.span, sig.header.asyncness); } diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 0b21de4d78b..32c91f4a634 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -548,12 +548,12 @@ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { } match i.kind { - ast::AssocItemKind::Fn(ref sig, _) => { + ast::AssocItemKind::Fn(ref sig, _, _) => { if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) { gate_feature_post!(&self, const_fn, i.span, "const fn is unstable"); } } - ast::AssocItemKind::TyAlias(_, ref ty) => { + ast::AssocItemKind::TyAlias(ref generics, _, ref ty) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate_feature_post!( &self, @@ -565,7 +565,7 @@ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { if let Some(ty) = ty { self.check_impl_trait(ty); } - self.check_gat(&i.generics, i.span); + self.check_gat(generics, i.span); } _ => {} } diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 75938470b6f..0fcda7f763e 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1473,12 +1473,12 @@ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) { ast::AssocItemKind::Const(ty, expr) => { self.print_associated_const(item.ident, ty, expr.as_deref(), &item.vis); } - ast::AssocItemKind::Fn(sig, body) => { + ast::AssocItemKind::Fn(sig, generics, body) => { let body = body.as_deref(); - self.print_fn_full(sig, item.ident, &item.generics, &item.vis, body, &item.attrs); + self.print_fn_full(sig, item.ident, generics, &item.vis, body, &item.attrs); } - ast::AssocItemKind::TyAlias(bounds, ty) => { - self.print_associated_type(item.ident, &item.generics, bounds, ty.as_deref()); + ast::AssocItemKind::TyAlias(generics, bounds, ty) => { + self.print_associated_type(item.ident, generics, bounds, ty.as_deref()); } ast::AssocItemKind::Macro(mac) => { self.print_mac(mac); diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 5cf233e222e..2e4cbd708a9 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -544,8 +544,8 @@ fn create_derived_impl( vis: respan(self.span.shrink_to_lo(), ast::VisibilityKind::Inherited), defaultness: ast::Defaultness::Final, attrs: Vec::new(), - generics: Generics::default(), kind: ast::AssocItemKind::TyAlias( + Generics::default(), Vec::new(), Some(type_def.to_ty(cx, self.span, type_ident, generics)), ), @@ -973,12 +973,11 @@ fn create_method( P(ast::AssocItem { id: ast::DUMMY_NODE_ID, attrs: self.attributes.clone(), - generics: fn_generics, span: trait_.span, vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited), defaultness: ast::Defaultness::Final, ident: method_ident, - kind: ast::AssocItemKind::Fn(sig, Some(body_block)), + kind: ast::AssocItemKind::Fn(sig, fn_generics, Some(body_block)), tokens: None, }) } diff --git a/src/librustc_expand/placeholders.rs b/src/librustc_expand/placeholders.rs index 6bcb8f45f00..c96b394c7b5 100644 --- a/src/librustc_expand/placeholders.rs +++ b/src/librustc_expand/placeholders.rs @@ -25,7 +25,6 @@ fn mac_placeholder() -> ast::Mac { let ident = ast::Ident::invalid(); let attrs = Vec::new(); - let generics = ast::Generics::default(); let vis = vis.unwrap_or_else(|| dummy_spanned(ast::VisibilityKind::Inherited)); let span = DUMMY_SP; let expr_placeholder = || { @@ -57,7 +56,6 @@ fn mac_placeholder() -> ast::Mac { ident, vis, attrs, - generics, kind: ast::AssocItemKind::Macro(mac_placeholder()), defaultness: ast::Defaultness::Final, tokens: None, @@ -68,7 +66,6 @@ fn mac_placeholder() -> ast::Mac { ident, vis, attrs, - generics, kind: ast::AssocItemKind::Macro(mac_placeholder()), defaultness: ast::Defaultness::Final, tokens: None, diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 659323d1c25..df50fc5d3ed 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -686,7 +686,7 @@ fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> { let is_const = match i.kind { ast::AssocItemKind::Const(..) => true, - ast::AssocItemKind::Fn(ref sig, _) => Self::is_sig_const(sig), + ast::AssocItemKind::Fn(ref sig, _, _) => Self::is_sig_const(sig), _ => false, }; self.run(is_const, |s| noop_flat_map_assoc_item(i, s)) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 93fca43d67c..207defa96a3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -640,7 +640,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item<'_>) { impl EarlyLintPass for AnonymousParameters { fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) { match it.kind { - ast::AssocItemKind::Fn(ref sig, _) => { + ast::AssocItemKind::Fn(ref sig, _, _) => { for arg in sig.decl.inputs.iter() { match arg.pat.kind { ast::PatKind::Ident(_, ident, None) => { diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 500aaaf43b9..96b3cf79720 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -665,11 +665,11 @@ fn parse_assoc_item_( let vis = self.parse_visibility(FollowedByType::No)?; let defaultness = self.parse_defaultness(); - let (ident, kind, generics) = if self.eat_keyword(kw::Type) { + let (ident, kind) = if self.eat_keyword(kw::Type) { self.parse_assoc_ty()? } else if self.check_fn_front_matter() { let (ident, sig, generics, body) = self.parse_fn(at_end, &mut attrs, req_name)?; - (ident, AssocItemKind::Fn(sig, body), generics) + (ident, AssocItemKind::Fn(sig, generics, body)) } else if self.check_keyword(kw::Const) { self.parse_assoc_const()? } else if self.isnt_macro_invocation() { @@ -677,7 +677,7 @@ fn parse_assoc_item_( } else if self.token.is_path_start() { let mac = self.parse_item_macro(&vis)?; *at_end = true; - (Ident::invalid(), AssocItemKind::Macro(mac), Generics::default()) + (Ident::invalid(), AssocItemKind::Macro(mac)) } else { self.recover_attrs_no_item(&attrs)?; self.unexpected()? @@ -685,26 +685,26 @@ fn parse_assoc_item_( let span = lo.to(self.prev_span); let id = DUMMY_NODE_ID; - Ok(AssocItem { id, span, ident, attrs, vis, defaultness, generics, kind, tokens: None }) + Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None }) } /// This parses the grammar: /// /// AssocConst = "const" Ident ":" Ty "=" Expr ";" - fn parse_assoc_const(&mut self) -> PResult<'a, (Ident, AssocItemKind, Generics)> { + fn parse_assoc_const(&mut self) -> PResult<'a, (Ident, AssocItemKind)> { self.expect_keyword(kw::Const)?; let ident = self.parse_ident()?; self.expect(&token::Colon)?; let ty = self.parse_ty()?; let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None }; self.expect_semi()?; - Ok((ident, AssocItemKind::Const(ty, expr), Generics::default())) + Ok((ident, AssocItemKind::Const(ty, expr))) } /// Parses the following grammar: /// /// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty] - fn parse_assoc_ty(&mut self) -> PResult<'a, (Ident, AssocItemKind, Generics)> { + fn parse_assoc_ty(&mut self) -> PResult<'a, (Ident, AssocItemKind)> { let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; @@ -716,7 +716,7 @@ fn parse_assoc_ty(&mut self) -> PResult<'a, (Ident, AssocItemKind, Generics)> { let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None }; self.expect_semi()?; - Ok((ident, AssocItemKind::TyAlias(bounds, default), generics)) + Ok((ident, AssocItemKind::TyAlias(generics, bounds, default))) } /// Parses a `UseTree`. diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index d6ea737385c..280a7a8fdba 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1252,7 +1252,7 @@ fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) { let item_def_id = self.r.definitions.local_def_id(item.id); let (res, ns) = match item.kind { AssocItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), - AssocItemKind::Fn(ref sig, _) => { + AssocItemKind::Fn(ref sig, _, _) => { if sig.decl.has_self() { self.r.has_self.insert(item_def_id); } diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index fe80dec513c..256b5ff4b9a 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -215,13 +215,15 @@ fn visit_generic_param(&mut self, param: &'a GenericParam) { fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { let def_data = match &i.kind { - AssocItemKind::Fn(FnSig { header, decl }, body) if header.asyncness.is_async() => { + AssocItemKind::Fn(FnSig { header, decl }, generics, body) + if header.asyncness.is_async() => + { return self.visit_async_fn( i.id, i.ident.name, i.span, header, - &i.generics, + generics, decl, body.as_deref(), ); diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index bcf558d1563..0e4e9c15286 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -826,41 +826,33 @@ fn resolve_item(&mut self, item: &'ast Item) { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds); - for trait_item in trait_items { + let walk_assoc_item = |this: &mut Self, generics, item| { + this.with_generic_param_rib(generics, AssocItemRibKind, |this| { + visit::walk_assoc_item(this, item, AssocCtxt::Trait) + }); + }; + + for item in trait_items { this.with_trait_items(trait_items, |this| { - this.with_generic_param_rib( - &trait_item.generics, - AssocItemRibKind, - |this| { - match trait_item.kind { - AssocItemKind::Const(ref ty, ref default) => { - this.visit_ty(ty); - - // Only impose the restrictions of - // ConstRibKind for an actual constant - // expression in a provided default. - if let Some(ref expr) = *default { - this.with_constant_rib(|this| { - this.visit_expr(expr); - }); - } - } - AssocItemKind::Fn(_, _) => visit::walk_assoc_item( - this, - trait_item, - AssocCtxt::Trait, - ), - AssocItemKind::TyAlias(..) => visit::walk_assoc_item( - this, - trait_item, - AssocCtxt::Trait, - ), - AssocItemKind::Macro(_) => { - panic!("unexpanded macro in resolve!") - } - }; - }, - ); + match &item.kind { + AssocItemKind::Const(ty, default) => { + this.visit_ty(ty); + // Only impose the restrictions of `ConstRibKind` for an + // actual constant expression in a provided default. + if let Some(expr) = default { + this.with_constant_rib(|this| this.visit_expr(expr)); + } + } + AssocItemKind::Fn(_, generics, _) => { + walk_assoc_item(this, generics, item); + } + AssocItemKind::TyAlias(generics, _, _) => { + walk_assoc_item(this, generics, item); + } + AssocItemKind::Macro(_) => { + panic!("unexpanded macro in resolve!") + } + }; }); } }); @@ -1021,7 +1013,7 @@ fn with_trait_items( trait_items .iter() .filter_map(|item| match &item.kind { - AssocItemKind::TyAlias(bounds, _) if bounds.len() == 0 => Some(item.ident), + AssocItemKind::TyAlias(_, bounds, _) if bounds.len() == 0 => Some(item.ident), _ => None, }) .collect(), @@ -1113,66 +1105,74 @@ fn resolve_implementation( this.with_current_self_type(self_type, |this| { this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| { debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)"); - for impl_item in impl_items { - // We also need a new scope for the impl item type parameters. - this.with_generic_param_rib(&impl_item.generics, - AssocItemRibKind, - |this| { - use crate::ResolutionError::*; - match impl_item.kind { - AssocItemKind::Const(..) => { - debug!( - "resolve_implementation AssocItemKind::Const", - ); - // If this is a trait impl, ensure the const - // exists in trait - this.check_trait_item( - impl_item.ident, - ValueNS, - impl_item.span, - |n, s| ConstNotMemberOfTrait(n, s), - ); - - this.with_constant_rib(|this| { + for item in impl_items { + use crate::ResolutionError::*; + match &item.kind { + AssocItemKind::Const(..) => { + debug!("resolve_implementation AssocItemKind::Const",); + // If this is a trait impl, ensure the const + // exists in trait + this.check_trait_item( + item.ident, + ValueNS, + item.span, + |n, s| ConstNotMemberOfTrait(n, s), + ); + + this.with_constant_rib(|this| { + visit::walk_assoc_item(this, item, AssocCtxt::Impl) + }); + } + AssocItemKind::Fn(_, generics, _) => { + // We also need a new scope for the impl item type parameters. + this.with_generic_param_rib( + generics, + AssocItemRibKind, + |this| { + // If this is a trait impl, ensure the method + // exists in trait + this.check_trait_item( + item.ident, + ValueNS, + item.span, + |n, s| MethodNotMemberOfTrait(n, s), + ); + visit::walk_assoc_item( this, - impl_item, + item, AssocCtxt::Impl, ) - }); - } - AssocItemKind::Fn(..) => { - // If this is a trait impl, ensure the method - // exists in trait - this.check_trait_item(impl_item.ident, - ValueNS, - impl_item.span, - |n, s| MethodNotMemberOfTrait(n, s)); - - visit::walk_assoc_item( - this, - impl_item, - AssocCtxt::Impl, - ) - } - AssocItemKind::TyAlias(_, _) => { - // If this is a trait impl, ensure the type - // exists in trait - this.check_trait_item(impl_item.ident, - TypeNS, - impl_item.span, - |n, s| TypeNotMemberOfTrait(n, s)); - - visit::walk_assoc_item( - this, - impl_item, - AssocCtxt::Impl, - ) - } - AssocItemKind::Macro(_) => - panic!("unexpanded macro in resolve!"), + }, + ); + } + AssocItemKind::TyAlias(generics, _, _) => { + // We also need a new scope for the impl item type parameters. + this.with_generic_param_rib( + generics, + AssocItemRibKind, + |this| { + // If this is a trait impl, ensure the type + // exists in trait + this.check_trait_item( + item.ident, + TypeNS, + item.span, + |n, s| TypeNotMemberOfTrait(n, s), + ); + + visit::walk_assoc_item( + this, + item, + AssocCtxt::Impl, + ) + }, + ); + } + AssocItemKind::Macro(_) => { + panic!("unexpanded macro in resolve!") } - }); + } } }); }); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 01e3e3f3685..561a4a83d28 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1015,18 +1015,18 @@ fn process_trait_item(&mut self, trait_item: &'l ast::AssocItem, trait_id: DefId &trait_item.attrs, ); } - ast::AssocItemKind::Fn(ref sig, ref body) => { + ast::AssocItemKind::Fn(ref sig, ref generics, ref body) => { self.process_method( sig, body.as_ref().map(|x| &**x), trait_item.id, trait_item.ident, - &trait_item.generics, + generics, respan(vis_span, ast::VisibilityKind::Public), trait_item.span, ); } - ast::AssocItemKind::TyAlias(ref bounds, ref default_ty) => { + ast::AssocItemKind::TyAlias(_, ref bounds, ref default_ty) => { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); let qualname = format!( @@ -1085,19 +1085,19 @@ fn process_impl_item(&mut self, impl_item: &'l ast::AssocItem, impl_id: DefId) { &impl_item.attrs, ); } - ast::AssocItemKind::Fn(ref sig, ref body) => { + ast::AssocItemKind::Fn(ref sig, ref generics, ref body) => { self.process_method( sig, body.as_deref(), impl_item.id, impl_item.ident, - &impl_item.generics, + generics, impl_item.vis.clone(), impl_item.span, ); } - ast::AssocItemKind::TyAlias(_, None) => {} - ast::AssocItemKind::TyAlias(_, Some(ref ty)) => { + ast::AssocItemKind::TyAlias(_, _, None) => {} + ast::AssocItemKind::TyAlias(_, _, Some(ref ty)) => { // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 72430fa9c17..7f6e405fec6 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1616,7 +1616,6 @@ pub struct AssocItem { pub ident: Ident, pub defaultness: Defaultness, - pub generics: Generics, pub kind: AssocItemKind, /// See `Item::tokens` for what this is. pub tokens: Option, @@ -1636,10 +1635,10 @@ pub enum AssocItemKind { Const(P, Option>), /// An associated function. - Fn(FnSig, Option>), + Fn(FnSig, Generics, Option>), /// An associated type. - TyAlias(GenericBounds, Option>), + TyAlias(Generics, GenericBounds, Option>), /// A macro expanding to an associated item. Macro(Mac), diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index e0180d45193..f3857b3a414 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -951,23 +951,24 @@ pub fn noop_flat_map_assoc_item( mut item: P, visitor: &mut T, ) -> SmallVec<[P; 1]> { - let AssocItem { id, ident, vis, defaultness: _, attrs, generics, kind, span, tokens: _ } = + let AssocItem { id, ident, vis, defaultness: _, attrs, kind, span, tokens: _ } = item.deref_mut(); visitor.visit_id(id); visitor.visit_ident(ident); visitor.visit_vis(vis); visit_attrs(attrs, visitor); - visitor.visit_generics(generics); match kind { AssocItemKind::Const(ty, expr) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } - AssocItemKind::Fn(sig, body) => { + AssocItemKind::Fn(sig, generics, body) => { + visitor.visit_generics(generics); visit_fn_sig(sig, visitor); visit_opt(body, |body| visitor.visit_block(body)); } - AssocItemKind::TyAlias(bounds, ty) => { + AssocItemKind::TyAlias(generics, bounds, ty) => { + visitor.visit_generics(generics); visit_bounds(bounds, visitor); visit_opt(ty, |ty| visitor.visit_ty(ty)); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 73e731397c3..edcfd7f4e78 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -625,17 +625,18 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); walk_list!(visitor, visit_attribute, &item.attrs); - visitor.visit_generics(&item.generics); match item.kind { AssocItemKind::Const(ref ty, ref expr) => { visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(ref sig, ref body) => { + AssocItemKind::Fn(ref sig, ref generics, ref body) => { + visitor.visit_generics(generics); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), item.ident, sig, &item.vis, body.as_deref()); visitor.visit_fn(kind, item.span, item.id); } - AssocItemKind::TyAlias(ref bounds, ref ty) => { + AssocItemKind::TyAlias(ref generics, ref bounds, ref ty) => { + visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_ty, ty); }