Address review comments.
This commit is contained in:
parent
df247968f2
commit
ec10833609
12 changed files with 104 additions and 99 deletions
|
@ -817,10 +817,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.has_proc_macro_decls = true;
|
self.has_proc_macro_decls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr::contains_name(&item.attrs, sym::no_mangle) {
|
if let Some(ident) = item.kind.ident()
|
||||||
if let Some(ident) = item.kind.ident() {
|
&& attr::contains_name(&item.attrs, sym::no_mangle)
|
||||||
self.check_nomangle_item_asciionly(ident, item.span);
|
{
|
||||||
}
|
self.check_nomangle_item_asciionly(ident, item.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
|
@ -1412,10 +1412,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||||
if attr::contains_name(&item.attrs, sym::no_mangle) {
|
if let Some(ident) = item.kind.ident()
|
||||||
if let Some(ident) = item.kind.ident() {
|
&& attr::contains_name(&item.attrs, sym::no_mangle)
|
||||||
self.check_nomangle_item_asciionly(ident, item.span);
|
{
|
||||||
}
|
self.check_nomangle_item_asciionly(ident, item.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
|
if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
|
||||||
|
|
|
@ -213,10 +213,8 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// First up, make sure we're checking a bare function. If we're not then
|
// Make sure we're checking a bare function. If we're not then we're
|
||||||
// we're just not interested in this item.
|
// just not interested any further in this item.
|
||||||
//
|
|
||||||
// If we find one, try to locate a `#[proc_macro_derive]` attribute on it.
|
|
||||||
let fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
|
let fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
|
||||||
fn_.ident
|
fn_.ident
|
||||||
} else {
|
} else {
|
||||||
|
@ -243,6 +241,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to locate a `#[proc_macro_derive]` attribute.
|
||||||
if attr.has_name(sym::proc_macro_derive) {
|
if attr.has_name(sym::proc_macro_derive) {
|
||||||
self.collect_custom_derive(item, fn_ident, attr);
|
self.collect_custom_derive(item, fn_ident, attr);
|
||||||
} else if attr.has_name(sym::proc_macro_attribute) {
|
} else if attr.has_name(sym::proc_macro_attribute) {
|
||||||
|
|
|
@ -1223,9 +1223,7 @@ impl InvocationCollectorNode for P<ast::Item> {
|
||||||
|
|
||||||
// Work around borrow checker not seeing through `P`'s deref.
|
// Work around borrow checker not seeing through `P`'s deref.
|
||||||
let (span, mut attrs) = (node.span, mem::take(&mut node.attrs));
|
let (span, mut attrs) = (node.span, mem::take(&mut node.attrs));
|
||||||
let ItemKind::Mod(_, ident, mod_kind) = &mut node.kind else { unreachable!() };
|
let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { unreachable!() };
|
||||||
let ident = *ident;
|
|
||||||
|
|
||||||
let ecx = &mut collector.cx;
|
let ecx = &mut collector.cx;
|
||||||
let (file_path, dir_path, dir_ownership) = match mod_kind {
|
let (file_path, dir_path, dir_ownership) = match mod_kind {
|
||||||
ModKind::Loaded(_, inline, _, _) => {
|
ModKind::Loaded(_, inline, _, _) => {
|
||||||
|
|
|
@ -243,8 +243,7 @@ impl<'a> Parser<'a> {
|
||||||
// STATIC ITEM
|
// STATIC ITEM
|
||||||
self.bump(); // `static`
|
self.bump(); // `static`
|
||||||
let mutability = self.parse_mutability();
|
let mutability = self.parse_mutability();
|
||||||
let item = self.parse_static_item(safety, mutability)?;
|
self.parse_static_item(safety, mutability)?
|
||||||
ItemKind::Static(Box::new(item))
|
|
||||||
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
|
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
|
||||||
// CONST ITEM
|
// CONST ITEM
|
||||||
if self.token.is_keyword(kw::Impl) {
|
if self.token.is_keyword(kw::Impl) {
|
||||||
|
@ -681,7 +680,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
None => (None, ty_first), // impl Type
|
None => (None, ty_first), // impl Type
|
||||||
};
|
};
|
||||||
let item_kind = ItemKind::Impl(Box::new(Impl {
|
Ok(ItemKind::Impl(Box::new(Impl {
|
||||||
safety,
|
safety,
|
||||||
polarity,
|
polarity,
|
||||||
defaultness,
|
defaultness,
|
||||||
|
@ -690,9 +689,7 @@ impl<'a> Parser<'a> {
|
||||||
of_trait,
|
of_trait,
|
||||||
self_ty,
|
self_ty,
|
||||||
items: impl_items,
|
items: impl_items,
|
||||||
}));
|
})))
|
||||||
|
|
||||||
Ok(item_kind)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
|
fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
|
||||||
|
@ -1222,13 +1219,12 @@ impl<'a> Parser<'a> {
|
||||||
safety = Safety::Unsafe(self.token.span);
|
safety = Safety::Unsafe(self.token.span);
|
||||||
let _ = self.eat_keyword(exp!(Unsafe));
|
let _ = self.eat_keyword(exp!(Unsafe));
|
||||||
}
|
}
|
||||||
let module = ast::ForeignMod {
|
Ok(ItemKind::ForeignMod(ast::ForeignMod {
|
||||||
extern_span,
|
extern_span,
|
||||||
safety,
|
safety,
|
||||||
abi,
|
abi,
|
||||||
items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
|
items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
|
||||||
};
|
}))
|
||||||
Ok(ItemKind::ForeignMod(module))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a foreign item (one in an `extern { ... }` block).
|
/// Parses a foreign item (one in an `extern { ... }` block).
|
||||||
|
@ -1370,7 +1366,8 @@ impl<'a> Parser<'a> {
|
||||||
Ok(item_kind)
|
Ok(item_kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in `mutability`.
|
/// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in
|
||||||
|
/// `mutability`.
|
||||||
///
|
///
|
||||||
/// ```ebnf
|
/// ```ebnf
|
||||||
/// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
|
/// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
|
||||||
|
@ -1379,7 +1376,7 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
safety: Safety,
|
safety: Safety,
|
||||||
mutability: Mutability,
|
mutability: Mutability,
|
||||||
) -> PResult<'a, StaticItem> {
|
) -> PResult<'a, ItemKind> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
|
|
||||||
if self.token == TokenKind::Lt && self.may_recover() {
|
if self.token == TokenKind::Lt && self.may_recover() {
|
||||||
|
@ -1391,7 +1388,8 @@ impl<'a> Parser<'a> {
|
||||||
// FIXME: This could maybe benefit from `.may_recover()`?
|
// FIXME: This could maybe benefit from `.may_recover()`?
|
||||||
let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
|
let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
|
||||||
(true, false) => self.parse_ty()?,
|
(true, false) => self.parse_ty()?,
|
||||||
// If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing type.
|
// If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing
|
||||||
|
// type.
|
||||||
(colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
|
(colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1399,7 +1397,8 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
self.expect_semi()?;
|
self.expect_semi()?;
|
||||||
|
|
||||||
Ok(StaticItem { ident, ty, safety, mutability, expr, define_opaque: None })
|
let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
|
||||||
|
Ok(ItemKind::Static(Box::new(item)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a constant item with the prefix `"const"` already parsed.
|
/// Parse a constant item with the prefix `"const"` already parsed.
|
||||||
|
@ -1537,7 +1536,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_span = self.prev_token.span;
|
let prev_span = self.prev_token.span;
|
||||||
let id = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
|
|
||||||
|
@ -1548,10 +1547,10 @@ impl<'a> Parser<'a> {
|
||||||
(thin_vec![], Trailing::No)
|
(thin_vec![], Trailing::No)
|
||||||
} else {
|
} else {
|
||||||
self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
|
self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
|
||||||
p.parse_enum_variant(id.span)
|
p.parse_enum_variant(ident.span)
|
||||||
})
|
})
|
||||||
.map_err(|mut err| {
|
.map_err(|mut err| {
|
||||||
err.span_label(id.span, "while parsing this enum");
|
err.span_label(ident.span, "while parsing this enum");
|
||||||
if self.token == token::Colon {
|
if self.token == token::Colon {
|
||||||
let snapshot = self.create_snapshot_for_diagnostic();
|
let snapshot = self.create_snapshot_for_diagnostic();
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -1577,7 +1576,7 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
|
let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
|
||||||
Ok(ItemKind::Enum(id, enum_definition, generics))
|
Ok(ItemKind::Enum(ident, enum_definition, generics))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
|
fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
|
||||||
|
|
|
@ -10,8 +10,8 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
|
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, ForeignItem,
|
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
|
||||||
ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind,
|
ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind, TyAlias,
|
||||||
};
|
};
|
||||||
use rustc_attr_parsing as attr;
|
use rustc_attr_parsing as attr;
|
||||||
use rustc_expand::base::ResolverExpand;
|
use rustc_expand::base::ResolverExpand;
|
||||||
|
@ -764,8 +764,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
ItemKind::ExternCrate(orig_name, ident) => {
|
ItemKind::ExternCrate(orig_name, ident) => {
|
||||||
self.build_reduced_graph_for_extern_crate(
|
self.build_reduced_graph_for_extern_crate(
|
||||||
orig_name,
|
orig_name,
|
||||||
ident,
|
|
||||||
item,
|
item,
|
||||||
|
ident,
|
||||||
local_def_id,
|
local_def_id,
|
||||||
vis,
|
vis,
|
||||||
parent,
|
parent,
|
||||||
|
@ -797,7 +797,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
| ItemKind::Static(box StaticItem { ident, .. }) => {
|
| ItemKind::Static(box StaticItem { ident, .. }) => {
|
||||||
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
||||||
}
|
}
|
||||||
ItemKind::Fn(box ast::Fn { ident, .. }) => {
|
ItemKind::Fn(box Fn { ident, .. }) => {
|
||||||
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
||||||
|
|
||||||
// Functions introducing procedural macros reserve a slot
|
// Functions introducing procedural macros reserve a slot
|
||||||
|
@ -806,7 +806,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// These items live in the type namespace.
|
// These items live in the type namespace.
|
||||||
ItemKind::TyAlias(box ast::TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => {
|
ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => {
|
||||||
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,8 +900,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
fn build_reduced_graph_for_extern_crate(
|
fn build_reduced_graph_for_extern_crate(
|
||||||
&mut self,
|
&mut self,
|
||||||
orig_name: Option<Symbol>,
|
orig_name: Option<Symbol>,
|
||||||
ident: Ident,
|
|
||||||
item: &Item,
|
item: &Item,
|
||||||
|
ident: Ident,
|
||||||
local_def_id: LocalDefId,
|
local_def_id: LocalDefId,
|
||||||
vis: ty::Visibility,
|
vis: ty::Visibility,
|
||||||
parent: Module<'ra>,
|
parent: Module<'ra>,
|
||||||
|
@ -1362,14 +1362,16 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
|
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
|
||||||
if let ForeignItemKind::MacCall(_) = foreign_item.kind {
|
let ident = match foreign_item.kind {
|
||||||
self.visit_invoc_in_module(foreign_item.id);
|
ForeignItemKind::Static(box StaticItem { ident, .. })
|
||||||
return;
|
| ForeignItemKind::Fn(box Fn { ident, .. })
|
||||||
}
|
| ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => ident,
|
||||||
|
ForeignItemKind::MacCall(_) => {
|
||||||
|
self.visit_invoc_in_module(foreign_item.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// `unwrap` is safe because `MacCall` has been excluded, and other foreign item kinds have
|
|
||||||
// an ident.
|
|
||||||
let ident = foreign_item.kind.ident().unwrap();
|
|
||||||
self.build_reduced_graph_for_foreign_item(foreign_item, ident);
|
self.build_reduced_graph_for_foreign_item(foreign_item, ident);
|
||||||
visit::walk_item(self, foreign_item);
|
visit::walk_item(self, foreign_item);
|
||||||
}
|
}
|
||||||
|
@ -1384,26 +1386,35 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||||
if let AssocItemKind::MacCall(_) = item.kind {
|
let (ident, ns) = match item.kind {
|
||||||
match ctxt {
|
AssocItemKind::Const(box ConstItem { ident, .. })
|
||||||
AssocCtxt::Trait => {
|
| AssocItemKind::Fn(box Fn { ident, .. })
|
||||||
self.visit_invoc_in_module(item.id);
|
| AssocItemKind::Delegation(box Delegation { ident, .. }) => (ident, ValueNS),
|
||||||
}
|
|
||||||
AssocCtxt::Impl { .. } => {
|
|
||||||
let invoc_id = item.id.placeholder_to_expn_id();
|
|
||||||
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
|
|
||||||
self.r
|
|
||||||
.impl_unexpanded_invocations
|
|
||||||
.entry(self.r.invocation_parent(invoc_id))
|
|
||||||
.or_default()
|
|
||||||
.insert(invoc_id);
|
|
||||||
}
|
|
||||||
self.visit_invoc(item.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
AssocItemKind::Type(box TyAlias { ident, .. }) => (ident, TypeNS),
|
||||||
|
|
||||||
|
AssocItemKind::MacCall(_) => {
|
||||||
|
match ctxt {
|
||||||
|
AssocCtxt::Trait => {
|
||||||
|
self.visit_invoc_in_module(item.id);
|
||||||
|
}
|
||||||
|
AssocCtxt::Impl { .. } => {
|
||||||
|
let invoc_id = item.id.placeholder_to_expn_id();
|
||||||
|
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
|
||||||
|
self.r
|
||||||
|
.impl_unexpanded_invocations
|
||||||
|
.entry(self.r.invocation_parent(invoc_id))
|
||||||
|
.or_default()
|
||||||
|
.insert(invoc_id);
|
||||||
|
}
|
||||||
|
self.visit_invoc(item.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssocItemKind::DelegationMac(..) => bug!(),
|
||||||
|
};
|
||||||
let vis = self.resolve_visibility(&item.vis);
|
let vis = self.resolve_visibility(&item.vis);
|
||||||
let feed = self.r.feed(item.id);
|
let feed = self.r.feed(item.id);
|
||||||
let local_def_id = feed.key();
|
let local_def_id = feed.key();
|
||||||
|
@ -1418,16 +1429,6 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
self.r.feed_visibility(feed, vis);
|
self.r.feed_visibility(feed, vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ns = match item.kind {
|
|
||||||
AssocItemKind::Const(..) | AssocItemKind::Delegation(..) | AssocItemKind::Fn(..) => {
|
|
||||||
ValueNS
|
|
||||||
}
|
|
||||||
AssocItemKind::Type(..) => TypeNS,
|
|
||||||
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => bug!(), // handled above
|
|
||||||
};
|
|
||||||
// `unwrap` is safe because `MacCall`/`DelegationMac` have been excluded, and other foreign
|
|
||||||
// item kinds have an ident.
|
|
||||||
let ident = item.kind.ident().unwrap();
|
|
||||||
if ctxt == AssocCtxt::Trait {
|
if ctxt == AssocCtxt::Trait {
|
||||||
let parent = self.parent_scope.module;
|
let parent = self.parent_scope.module;
|
||||||
let expansion = self.parent_scope.expansion;
|
let expansion = self.parent_scope.expansion;
|
||||||
|
|
|
@ -186,8 +186,11 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
||||||
FnKind::Fn(
|
FnKind::Fn(
|
||||||
_ctxt,
|
_ctxt,
|
||||||
_vis,
|
_vis,
|
||||||
Fn { sig: FnSig { header, decl, span: _ }, generics, contract, body, .. },
|
Fn {
|
||||||
|
sig: FnSig { header, decl, span: _ }, ident, generics, contract, body, ..
|
||||||
|
},
|
||||||
) if let Some(coroutine_kind) = header.coroutine_kind => {
|
) if let Some(coroutine_kind) = header.coroutine_kind => {
|
||||||
|
self.visit_ident(ident);
|
||||||
self.visit_fn_header(header);
|
self.visit_fn_header(header);
|
||||||
self.visit_generics(generics);
|
self.visit_generics(generics);
|
||||||
if let Some(contract) = contract {
|
if let Some(contract) = contract {
|
||||||
|
|
|
@ -1025,9 +1025,10 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
|
||||||
match fn_kind {
|
match fn_kind {
|
||||||
// Bail if the function is foreign, and thus cannot validly have
|
// Bail if the function is foreign, and thus cannot validly have
|
||||||
// a body, or if there's no body for some other reason.
|
// a body, or if there's no body for some other reason.
|
||||||
FnKind::Fn(FnCtxt::Foreign, _, Fn { sig, generics, .. })
|
FnKind::Fn(FnCtxt::Foreign, _, Fn { sig, ident, generics, .. })
|
||||||
| FnKind::Fn(_, _, Fn { sig, generics, body: None, .. }) => {
|
| FnKind::Fn(_, _, Fn { sig, ident, generics, body: None, .. }) => {
|
||||||
self.visit_fn_header(&sig.header);
|
self.visit_fn_header(&sig.header);
|
||||||
|
self.visit_ident(ident);
|
||||||
self.visit_generics(generics);
|
self.visit_generics(generics);
|
||||||
self.with_lifetime_rib(
|
self.with_lifetime_rib(
|
||||||
LifetimeRibKind::AnonymousCreateParameter {
|
LifetimeRibKind::AnonymousCreateParameter {
|
||||||
|
|
|
@ -227,14 +227,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
&& let FnKind::Fn(_, _, ast::Fn { sig, .. }) = fn_kind
|
&& let FnKind::Fn(_, _, ast::Fn { sig, .. }) = fn_kind
|
||||||
&& let Some(items) = self.diag_metadata.current_impl_items
|
&& let Some(items) = self.diag_metadata.current_impl_items
|
||||||
&& let Some(item) = items.iter().find(|i| {
|
&& let Some(item) = items.iter().find(|i| {
|
||||||
if let Some(ident) = i.kind.ident()
|
i.kind.ident().is_some_and(|ident| {
|
||||||
&& ident.name == item_str.name
|
|
||||||
{
|
|
||||||
// Don't suggest if the item is in Fn signature arguments (#112590).
|
// Don't suggest if the item is in Fn signature arguments (#112590).
|
||||||
!sig.span.contains(item_span)
|
ident.name == item_str.name && !sig.span.contains(item_span)
|
||||||
} else {
|
})
|
||||||
false
|
|
||||||
}
|
|
||||||
}) {
|
}) {
|
||||||
let sp = item_span.shrink_to_lo();
|
let sp = item_span.shrink_to_lo();
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@ use rustc_errors::{Applicability, Diag, SuggestionStyle};
|
||||||
use rustc_lexer::TokenKind;
|
use rustc_lexer::TokenKind;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol, kw};
|
||||||
use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol, sym};
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
|
@ -375,14 +374,16 @@ impl EmptyLineAfter {
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &EarlyContext<'_>,
|
cx: &EarlyContext<'_>,
|
||||||
kind: &ItemKind,
|
kind: &ItemKind,
|
||||||
ident: &Option<Ident>,
|
ident: Option<Ident>,
|
||||||
span: Span,
|
span: Span,
|
||||||
attrs: &[Attribute],
|
attrs: &[Attribute],
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
) {
|
) {
|
||||||
self.items.push(ItemInfo {
|
self.items.push(ItemInfo {
|
||||||
kind: kind.descr(),
|
kind: kind.descr(),
|
||||||
name: if let Some(ident) = ident { ident.name } else { sym::dummy },
|
// FIXME: this `sym::empty` can be leaked, see
|
||||||
|
// https://github.com/rust-lang/rust/pull/138740#discussion_r2021979899
|
||||||
|
name: if let Some(ident) = ident { ident.name } else { kw::Empty },
|
||||||
span: if let Some(ident) = ident {
|
span: if let Some(ident) = ident {
|
||||||
span.with_hi(ident.span.hi())
|
span.with_hi(ident.span.hi())
|
||||||
} else {
|
} else {
|
||||||
|
@ -471,7 +472,7 @@ impl EarlyLintPass for EmptyLineAfter {
|
||||||
self.check_item_kind(
|
self.check_item_kind(
|
||||||
cx,
|
cx,
|
||||||
&item.kind.clone().into(),
|
&item.kind.clone().into(),
|
||||||
&item.kind.ident(),
|
item.kind.ident(),
|
||||||
item.span,
|
item.span,
|
||||||
&item.attrs,
|
&item.attrs,
|
||||||
item.id,
|
item.id,
|
||||||
|
@ -482,7 +483,7 @@ impl EarlyLintPass for EmptyLineAfter {
|
||||||
self.check_item_kind(
|
self.check_item_kind(
|
||||||
cx,
|
cx,
|
||||||
&item.kind.clone().into(),
|
&item.kind.clone().into(),
|
||||||
&item.kind.ident(),
|
item.kind.ident(),
|
||||||
item.span,
|
item.span,
|
||||||
&item.attrs,
|
&item.attrs,
|
||||||
item.id,
|
item.id,
|
||||||
|
@ -490,6 +491,6 @@ impl EarlyLintPass for EmptyLineAfter {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||||
self.check_item_kind(cx, &item.kind, &item.kind.ident(), item.span, &item.attrs, item.id);
|
self.check_item_kind(cx, &item.kind, item.kind.ident(), item.span, &item.attrs, item.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -567,20 +567,23 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
|
||||||
(
|
(
|
||||||
TyAlias(box ast::TyAlias {
|
TyAlias(box ast::TyAlias {
|
||||||
defaultness: ld,
|
defaultness: ld,
|
||||||
|
ident: li,
|
||||||
generics: lg,
|
generics: lg,
|
||||||
|
where_clauses: _,
|
||||||
bounds: lb,
|
bounds: lb,
|
||||||
ty: lt,
|
ty: lt,
|
||||||
..
|
|
||||||
}),
|
}),
|
||||||
TyAlias(box ast::TyAlias {
|
TyAlias(box ast::TyAlias {
|
||||||
defaultness: rd,
|
defaultness: rd,
|
||||||
|
ident: ri,
|
||||||
generics: rg,
|
generics: rg,
|
||||||
|
where_clauses: _,
|
||||||
bounds: rb,
|
bounds: rb,
|
||||||
ty: rt,
|
ty: rt,
|
||||||
..
|
|
||||||
}),
|
}),
|
||||||
) => {
|
) => {
|
||||||
eq_defaultness(*ld, *rd)
|
eq_defaultness(*ld, *rd)
|
||||||
|
&& eq_id(*li, *ri)
|
||||||
&& eq_generics(lg, rg)
|
&& eq_generics(lg, rg)
|
||||||
&& over(lb, rb, eq_generic_bound)
|
&& over(lb, rb, eq_generic_bound)
|
||||||
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
|
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
|
||||||
|
@ -647,20 +650,23 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
|
||||||
(
|
(
|
||||||
Type(box TyAlias {
|
Type(box TyAlias {
|
||||||
defaultness: ld,
|
defaultness: ld,
|
||||||
|
ident: li,
|
||||||
generics: lg,
|
generics: lg,
|
||||||
|
where_clauses: _,
|
||||||
bounds: lb,
|
bounds: lb,
|
||||||
ty: lt,
|
ty: lt,
|
||||||
..
|
|
||||||
}),
|
}),
|
||||||
Type(box TyAlias {
|
Type(box TyAlias {
|
||||||
defaultness: rd,
|
defaultness: rd,
|
||||||
|
ident: ri,
|
||||||
generics: rg,
|
generics: rg,
|
||||||
|
where_clauses: _,
|
||||||
bounds: rb,
|
bounds: rb,
|
||||||
ty: rt,
|
ty: rt,
|
||||||
..
|
|
||||||
}),
|
}),
|
||||||
) => {
|
) => {
|
||||||
eq_defaultness(*ld, *rd)
|
eq_defaultness(*ld, *rd)
|
||||||
|
&& eq_id(*li, *ri)
|
||||||
&& eq_generics(lg, rg)
|
&& eq_generics(lg, rg)
|
||||||
&& over(lb, rb, eq_generic_bound)
|
&& over(lb, rb, eq_generic_bound)
|
||||||
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
|
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
|
||||||
|
|
|
@ -623,13 +623,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
||||||
|
|
||||||
fn visit_assoc_item(&mut self, ai: &ast::AssocItem, visitor_kind: ItemVisitorKind) {
|
fn visit_assoc_item(&mut self, ai: &ast::AssocItem, visitor_kind: ItemVisitorKind) {
|
||||||
use ItemVisitorKind::*;
|
use ItemVisitorKind::*;
|
||||||
// TODO(calebcartwright): Not sure the skip spans are correct
|
|
||||||
let assoc_ctxt = match visitor_kind {
|
let assoc_ctxt = match visitor_kind {
|
||||||
AssocTraitItem => visit::AssocCtxt::Trait,
|
AssocTraitItem => visit::AssocCtxt::Trait,
|
||||||
// There is no difference between trait and inherent assoc item formatting
|
// There is no difference between trait and inherent assoc item formatting
|
||||||
AssocImplItem => visit::AssocCtxt::Impl { of_trait: false },
|
AssocImplItem => visit::AssocCtxt::Impl { of_trait: false },
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
// TODO(calebcartwright): Not sure the skip spans are correct
|
||||||
let skip_span = ai.span;
|
let skip_span = ai.span;
|
||||||
skip_out_of_file_lines_range_visitor!(self, ai.span);
|
skip_out_of_file_lines_range_visitor!(self, ai.span);
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,13 @@ const TEST_1: IsFoo = IsFoo("hello");
|
||||||
static TEST_2: IsFoo = IsFoo("foo");
|
static TEST_2: IsFoo = IsFoo("foo");
|
||||||
|
|
||||||
// FIXME: `test_case` is currently ignored on anything other than
|
// FIXME: `test_case` is currently ignored on anything other than
|
||||||
// fn/const/static. Should this be a warning/error?
|
// fn/const/static. This should be an error. Compare this with `#[test]` and
|
||||||
|
// #[bench] whose expanders emit "error: expected a non-associated function,
|
||||||
|
// found […]" if applied to invalid items.
|
||||||
#[test_case]
|
#[test_case]
|
||||||
struct _S;
|
struct _S;
|
||||||
|
|
||||||
// FIXME: `test_case` is currently ignored on anything other than
|
// FIXME: as above.
|
||||||
// fn/const/static. Should this be a warning/error?
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
impl _S {
|
impl _S {
|
||||||
fn _f() {}
|
fn _f() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue