Auto merge of #124428 - matthiaskrgr:rollup-sk5z4z8, r=matthiaskrgr

Rollup of 3 pull requests

Successful merges:

 - #124382 (ast: Generalize item kind visiting)
 - #124387 (thread_local: be excruciatingly explicit in dtor code)
 - #124427 (Add missing tests for an ICE)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-04-27 07:28:53 +00:00
commit 35194e76b7
22 changed files with 501 additions and 394 deletions

View File

@ -34,6 +34,10 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
}
}
pub trait NoopVisitItemKind {
fn noop_visit(&mut self, visitor: &mut impl MutVisitor);
}
pub trait MutVisitor: Sized {
/// Mutable token visiting only exists for the `macro_rules` token marker and should not be
/// used otherwise. Token visitor would be entirely separate from the regular visitor if
@ -90,7 +94,7 @@ pub trait MutVisitor: Sized {
}
fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
noop_flat_map_foreign_item(ni, self)
noop_flat_map_item(ni, self)
}
fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
@ -105,16 +109,12 @@ pub trait MutVisitor: Sized {
noop_flat_map_field_def(fd, self)
}
fn visit_item_kind(&mut self, i: &mut ItemKind) {
noop_visit_item_kind(i, self);
}
fn flat_map_trait_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
noop_flat_map_assoc_item(i, self)
noop_flat_map_item(i, self)
}
fn flat_map_impl_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
noop_flat_map_assoc_item(i, self)
noop_flat_map_item(i, self)
}
fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
@ -1068,149 +1068,151 @@ pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
visit_lazy_tts(tokens, vis);
}
pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
match kind {
ItemKind::ExternCrate(_orig_name) => {}
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
}
ItemKind::Const(item) => {
visit_const_item(item, vis);
}
ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, vis);
visit_fn_sig(sig, vis);
vis.visit_generics(generics);
visit_opt(body, |body| vis.visit_block(body));
}
ItemKind::Mod(unsafety, mod_kind) => {
visit_unsafety(unsafety, vis);
match mod_kind {
ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => {
vis.visit_span(inner_span);
vis.visit_span(inject_use_span);
items.flat_map_in_place(|item| vis.flat_map_item(item));
pub fn noop_visit_item_kind(kind: &mut impl NoopVisitItemKind, vis: &mut impl MutVisitor) {
kind.noop_visit(vis)
}
impl NoopVisitItemKind for ItemKind {
fn noop_visit(&mut self, vis: &mut impl MutVisitor) {
match self {
ItemKind::ExternCrate(_orig_name) => {}
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
}
ItemKind::Const(item) => {
visit_const_item(item, vis);
}
ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, vis);
visit_fn_sig(sig, vis);
vis.visit_generics(generics);
visit_opt(body, |body| vis.visit_block(body));
}
ItemKind::Mod(unsafety, mod_kind) => {
visit_unsafety(unsafety, vis);
match mod_kind {
ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => {
vis.visit_span(inner_span);
vis.visit_span(inject_use_span);
items.flat_map_in_place(|item| vis.flat_map_item(item));
}
ModKind::Unloaded => {}
}
ModKind::Unloaded => {}
}
}
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias {
defaultness, generics, where_clauses, bounds, ty, ..
}) => {
visit_defaultness(defaultness, vis);
vis.visit_generics(generics);
vis.visit_span(&mut where_clauses.before.span);
vis.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, vis);
visit_opt(ty, |ty| vis.visit_ty(ty));
}
ItemKind::Enum(EnumDef { variants }, generics) => {
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
vis.visit_generics(generics);
}
ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
vis.visit_variant_data(variant_data);
vis.visit_generics(generics);
}
ItemKind::Impl(box Impl {
defaultness,
unsafety,
generics,
constness,
polarity,
of_trait,
self_ty,
items,
}) => {
visit_defaultness(defaultness, vis);
visit_unsafety(unsafety, vis);
vis.visit_generics(generics);
visit_constness(constness, vis);
visit_polarity(polarity, vis);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
}
ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => {
visit_unsafety(unsafety, vis);
vis.visit_generics(generics);
visit_bounds(bounds, vis);
items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
}
ItemKind::TraitAlias(generics, bounds) => {
vis.visit_generics(generics);
visit_bounds(bounds, vis);
}
ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
vis.visit_id(id);
vis.visit_qself(qself);
vis.visit_path(path);
if let Some(rename) = rename {
vis.visit_ident(rename);
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias {
defaultness,
generics,
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, vis);
vis.visit_generics(generics);
vis.visit_span(&mut where_clauses.before.span);
vis.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, vis);
visit_opt(ty, |ty| vis.visit_ty(ty));
}
if let Some(body) = body {
vis.visit_block(body);
ItemKind::Enum(EnumDef { variants }, generics) => {
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
vis.visit_generics(generics);
}
ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
vis.visit_variant_data(variant_data);
vis.visit_generics(generics);
}
ItemKind::Impl(box Impl {
defaultness,
unsafety,
generics,
constness,
polarity,
of_trait,
self_ty,
items,
}) => {
visit_defaultness(defaultness, vis);
visit_unsafety(unsafety, vis);
vis.visit_generics(generics);
visit_constness(constness, vis);
visit_polarity(polarity, vis);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
}
ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => {
visit_unsafety(unsafety, vis);
vis.visit_generics(generics);
visit_bounds(bounds, vis);
items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
}
ItemKind::TraitAlias(generics, bounds) => {
vis.visit_generics(generics);
visit_bounds(bounds, vis);
}
ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
vis.visit_id(id);
vis.visit_qself(qself);
vis.visit_path(path);
if let Some(rename) = rename {
vis.visit_ident(rename);
}
if let Some(body) = body {
vis.visit_block(body);
}
}
}
}
}
pub fn noop_flat_map_assoc_item<T: MutVisitor>(
mut item: P<AssocItem>,
visitor: &mut T,
) -> SmallVec<[P<AssocItem>; 1]> {
let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut();
visitor.visit_id(id);
visitor.visit_ident(ident);
visitor.visit_vis(vis);
visit_attrs(attrs, visitor);
match kind {
AssocItemKind::Const(item) => {
visit_const_item(item, visitor);
}
AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
AssocItemKind::Type(box TyAlias {
defaultness,
generics,
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visitor.visit_span(&mut where_clauses.before.span);
visitor.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
}
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
visitor.visit_id(id);
visitor.visit_qself(qself);
visitor.visit_path(path);
if let Some(rename) = rename {
visitor.visit_ident(rename);
impl NoopVisitItemKind for AssocItemKind {
fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
match self {
AssocItemKind::Const(item) => {
visit_const_item(item, visitor);
}
if let Some(body) = body {
visitor.visit_block(body);
AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
AssocItemKind::Type(box TyAlias {
defaultness,
generics,
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visitor.visit_span(&mut where_clauses.before.span);
visitor.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
}
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
visitor.visit_id(id);
visitor.visit_qself(qself);
visitor.visit_path(path);
if let Some(rename) = rename {
visitor.visit_ident(rename);
}
if let Some(body) = body {
visitor.visit_block(body);
}
}
}
}
visitor.visit_span(span);
visit_lazy_tts(tokens, visitor);
smallvec![item]
}
fn visit_const_item<T: MutVisitor>(
@ -1241,62 +1243,52 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
}
// Mutates one item into possibly many items.
pub fn noop_flat_map_item<T: MutVisitor>(
mut item: P<Item>,
visitor: &mut T,
) -> SmallVec<[P<Item>; 1]> {
pub fn noop_flat_map_item<K: NoopVisitItemKind>(
mut item: P<Item<K>>,
visitor: &mut impl MutVisitor,
) -> SmallVec<[P<Item<K>>; 1]> {
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
visitor.visit_ident(ident);
visit_attrs(attrs, visitor);
visitor.visit_id(id);
visitor.visit_item_kind(kind);
visit_attrs(attrs, visitor);
visitor.visit_vis(vis);
visitor.visit_ident(ident);
kind.noop_visit(visitor);
visitor.visit_span(span);
visit_lazy_tts(tokens, visitor);
smallvec![item]
}
pub fn noop_flat_map_foreign_item<T: MutVisitor>(
mut item: P<ForeignItem>,
visitor: &mut T,
) -> SmallVec<[P<ForeignItem>; 1]> {
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
visitor.visit_id(id);
visitor.visit_ident(ident);
visitor.visit_vis(vis);
visit_attrs(attrs, visitor);
match kind {
ForeignItemKind::Static(ty, _, expr) => {
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
impl NoopVisitItemKind for ForeignItemKind {
fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
match self {
ForeignItemKind::Static(ty, _, expr) => {
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
}
ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
ForeignItemKind::TyAlias(box TyAlias {
defaultness,
generics,
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visitor.visit_span(&mut where_clauses.before.span);
visitor.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
}
ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
}
ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
ForeignItemKind::TyAlias(box TyAlias {
defaultness,
generics,
where_clauses,
bounds,
ty,
..
}) => {
visit_defaultness(defaultness, visitor);
visitor.visit_generics(generics);
visitor.visit_span(&mut where_clauses.before.span);
visitor.visit_span(&mut where_clauses.after.span);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
}
ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
}
visitor.visit_span(span);
visit_lazy_tts(tokens, visitor);
smallvec![item]
}
pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {

View File

@ -102,6 +102,15 @@ pub enum LifetimeCtxt {
GenericArg,
}
pub trait WalkItemKind: Sized {
fn walk<'a, V: Visitor<'a>>(
&'a self,
item: &'a Item<Self>,
ctxt: AssocCtxt,
visitor: &mut V,
) -> V::Result;
}
/// Each method of the `Visitor` trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
@ -120,7 +129,7 @@ pub trait Visitor<'ast>: Sized {
Self::Result::output()
}
fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result {
walk_foreign_item(self, i)
walk_item(self, i)
}
fn visit_item(&mut self, i: &'ast Item) -> Self::Result {
walk_item(self, i)
@ -312,87 +321,98 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR
visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
}
pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) -> V::Result {
try_visit!(visitor.visit_vis(&item.vis));
try_visit!(visitor.visit_ident(item.ident));
match &item.kind {
ItemKind::ExternCrate(_) => {}
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind =
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, item.span, item.id));
}
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
ModKind::Loaded(items, _inline, _inner_span) => {
walk_list!(visitor, visit_item, items);
impl WalkItemKind for ItemKind {
fn walk<'a, V: Visitor<'a>>(
&'a self,
item: &'a Item<Self>,
_ctxt: AssocCtxt,
visitor: &mut V,
) -> V::Result {
match self {
ItemKind::ExternCrate(_) => {}
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(foreign_module) => {
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
ItemKind::Enum(enum_definition, generics) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_enum_def(enum_definition));
}
ItemKind::Impl(box Impl {
defaultness: _,
unsafety: _,
generics,
constness: _,
polarity: _,
of_trait,
self_ty,
items,
}) => {
try_visit!(visitor.visit_generics(generics));
visit_opt!(visitor, visit_trait_ref, of_trait);
try_visit!(visitor.visit_ty(self_ty));
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
}
ItemKind::Struct(struct_definition, generics)
| ItemKind::Union(struct_definition, generics) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_variant_data(struct_definition));
}
ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
}
ItemKind::TraitAlias(generics, bounds) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind =
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, item.span, item.id));
}
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
ModKind::Loaded(items, _inline, _inner_span) => {
walk_list!(visitor, visit_item, items);
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(foreign_module) => {
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
ItemKind::Enum(enum_definition, generics) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_enum_def(enum_definition));
}
ItemKind::Impl(box Impl {
defaultness: _,
unsafety: _,
generics,
constness: _,
polarity: _,
of_trait,
self_ty,
items,
}) => {
try_visit!(visitor.visit_generics(generics));
visit_opt!(visitor, visit_trait_ref, of_trait);
try_visit!(visitor.visit_ty(self_ty));
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
}
ItemKind::Struct(struct_definition, generics)
| ItemKind::Union(struct_definition, generics) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_variant_data(struct_definition));
}
ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
}
ItemKind::TraitAlias(generics, bounds) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, *id));
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
try_visit!(visitor.visit_path(path, *id));
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
V::Result::output()
}
walk_list!(visitor, visit_attribute, &item.attrs);
V::Result::output()
}
pub fn walk_item<'a, V: Visitor<'a>>(
visitor: &mut V,
item: &'a Item<impl WalkItemKind>,
) -> V::Result {
walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/)
}
pub fn walk_enum_def<'a, V: Visitor<'a>>(
@ -613,30 +633,34 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
V::Result::output()
}
pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) -> V::Result {
let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(ident));
walk_list!(visitor, visit_attribute, attrs);
match kind {
ForeignItemKind::Static(ty, _, expr) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, span, id));
}
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
ForeignItemKind::MacCall(mac) => {
try_visit!(visitor.visit_mac_call(mac));
impl WalkItemKind for ForeignItemKind {
fn walk<'a, V: Visitor<'a>>(
&'a self,
item: &'a Item<Self>,
_ctxt: AssocCtxt,
visitor: &mut V,
) -> V::Result {
let &Item { id, span, ident, ref vis, .. } = item;
match self {
ForeignItemKind::Static(ty, _, expr) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, span, id));
}
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
ForeignItemKind::MacCall(mac) => {
try_visit!(visitor.visit_mac_call(mac));
}
}
V::Result::output()
}
V::Result::output()
}
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
@ -756,42 +780,56 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
V::Result::output()
}
impl WalkItemKind for AssocItemKind {
fn walk<'a, V: Visitor<'a>>(
&'a self,
item: &'a Item<Self>,
ctxt: AssocCtxt,
visitor: &mut V,
) -> V::Result {
let &Item { id, span, ident, ref vis, .. } = item;
match self {
AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind =
FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, span, id));
}
AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
AssocItemKind::MacCall(mac) => {
try_visit!(visitor.visit_mac_call(mac));
}
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, *id));
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
}
V::Result::output()
}
}
pub fn walk_assoc_item<'a, V: Visitor<'a>>(
visitor: &mut V,
item: &'a AssocItem,
item: &'a Item<impl WalkItemKind>,
ctxt: AssocCtxt,
) -> V::Result {
let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(ident));
walk_list!(visitor, visit_attribute, attrs);
match kind {
AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
try_visit!(visitor.visit_fn(kind, span, id));
}
AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => {
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
AssocItemKind::MacCall(mac) => {
try_visit!(visitor.visit_mac_call(mac));
}
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, *id));
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
}
try_visit!(kind.walk(item, ctxt, visitor));
V::Result::output()
}

View File

@ -394,7 +394,7 @@ fn index_crate<'a>(
let def_id = self.node_id_to_def_id[&item.id];
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
AstOwner::ForeignItem(item);
visit::walk_foreign_item(self, item);
visit::walk_item(self, item);
}
}
}

View File

@ -1192,7 +1192,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ForeignItemKind::MacCall(..) => {}
}
visit::walk_foreign_item(self, fi)
visit::walk_item(self, fi)
}
// Mirrors `visit::walk_generic_args`, but tracks relevant state.

View File

@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::ForeignItemKind::MacCall(..) => {}
}
visit::walk_foreign_item(self, i)
visit::walk_item(self, i)
}
fn visit_ty(&mut self, ty: &'a ast::Ty) {

View File

@ -21,7 +21,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
}
fn visit_foreign_item(&mut self, i: &ForeignItem) {
self.count += 1;
walk_foreign_item(self, i)
walk_item(self, i)
}
fn visit_item(&mut self, i: &Item) {
self.count += 1;

View File

@ -246,18 +246,18 @@ impl MutVisitor for CfgEval<'_, '_> {
}
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
mut_visit::noop_flat_map_assoc_item(configure!(self, item), self)
mut_visit::noop_flat_map_item(configure!(self, item), self)
}
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
mut_visit::noop_flat_map_assoc_item(configure!(self, item), self)
mut_visit::noop_flat_map_item(configure!(self, item), self)
}
fn flat_map_foreign_item(
&mut self,
foreign_item: P<ast::ForeignItem>,
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
mut_visit::noop_flat_map_foreign_item(configure!(self, foreign_item), self)
mut_visit::noop_flat_map_item(configure!(self, foreign_item), self)
}
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {

View File

@ -1218,7 +1218,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
fragment.make_trait_items()
}
fn noop_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
noop_flat_map_assoc_item(self.wrapped, visitor)
noop_flat_map_item(self.wrapped, visitor)
}
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@ -1243,7 +1243,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
fragment.make_impl_items()
}
fn noop_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
noop_flat_map_assoc_item(self.wrapped, visitor)
noop_flat_map_item(self.wrapped, visitor)
}
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@ -1266,7 +1266,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
fragment.make_foreign_items()
}
fn noop_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
noop_flat_map_foreign_item(self, visitor)
noop_flat_map_item(self, visitor)
}
fn is_mac_call(&self) -> bool {
matches!(self.kind, ForeignItemKind::MacCall(..))

View File

@ -271,14 +271,14 @@ impl MutVisitor for PlaceholderExpander {
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
match item.kind {
ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_trait_items(),
_ => noop_flat_map_assoc_item(item, self),
_ => noop_flat_map_item(item, self),
}
}
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
match item.kind {
ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_impl_items(),
_ => noop_flat_map_assoc_item(item, self),
_ => noop_flat_map_item(item, self),
}
}
@ -288,7 +288,7 @@ impl MutVisitor for PlaceholderExpander {
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
match item.kind {
ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(),
_ => noop_flat_map_foreign_item(item, self),
_ => noop_flat_map_item(item, self),
}
}

View File

@ -99,7 +99,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) {
self.with_lint_attrs(it.id, &it.attrs, |cx| {
ast_visit::walk_foreign_item(cx, it);
ast_visit::walk_item(cx, it);
})
}

View File

@ -498,7 +498,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
(self, i, i.kind, Id::None, ast, ForeignItem, ForeignItemKind),
[Static, Fn, TyAlias, MacCall]
);
ast_visit::walk_foreign_item(self, i)
ast_visit::walk_item(self, i)
}
fn visit_item(&mut self, i: &'v ast::Item) {

View File

@ -1335,7 +1335,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
self.build_reduced_graph_for_foreign_item(foreign_item);
visit::walk_foreign_item(self, foreign_item);
visit::walk_item(self, foreign_item);
}
fn visit_block(&mut self, block: &'b Block) {

View File

@ -219,7 +219,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
let def = self.create_def(fi.id, fi.ident.name, def_kind, fi.span);
self.with_parent(def, |this| visit::walk_foreign_item(this, fi));
self.with_parent(def, |this| visit::walk_item(this, fi));
}
fn visit_variant(&mut self, v: &'a Variant) {

View File

@ -886,7 +886,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
kind: LifetimeBinderKind::Item,
span: generics.span,
},
|this| visit::walk_foreign_item(this, foreign_item),
|this| visit::walk_item(this, foreign_item),
);
}
ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
@ -898,13 +898,11 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
kind: LifetimeBinderKind::Function,
span: generics.span,
},
|this| visit::walk_foreign_item(this, foreign_item),
|this| visit::walk_item(this, foreign_item),
);
}
ForeignItemKind::Static(..) => {
self.with_static_rib(def_kind, |this| {
visit::walk_foreign_item(this, foreign_item);
});
self.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item))
}
ForeignItemKind::MacCall(..) => {
panic!("unexpanded macro in resolve!")

View File

@ -1,7 +1,7 @@
use super::lazy::LazyKeyInner;
use crate::cell::Cell;
use crate::sys::thread_local_dtor::register_dtor;
use crate::{fmt, mem, panic};
use crate::{fmt, mem, panic, ptr};
#[doc(hidden)]
#[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
@ -237,8 +237,9 @@ unsafe extern "C" fn destroy_value<T>(ptr: *mut u8) {
// Wrap the call in a catch to ensure unwinding is caught in the event
// a panic takes place in a destructor.
if let Err(_) = panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe {
let value = (*ptr).inner.take();
(*ptr).dtor_state.set(DtorState::RunningOrHasRun);
let Key { inner, dtor_state } = &*ptr;
let value = inner.take();
dtor_state.set(DtorState::RunningOrHasRun);
drop(value);
})) {
rtabort!("thread local panicked on drop");

View File

@ -91,13 +91,15 @@ mod lazy {
}
}
/// The other methods hand out references while taking &self.
/// As such, callers of this method must ensure no `&` and `&mut` are
/// available and used at the same time.
/// Watch out: unsynchronized internal mutability!
///
/// # Safety
/// Causes UB if any reference to the value is used after this.
#[allow(unused)]
pub unsafe fn take(&mut self) -> Option<T> {
// SAFETY: See doc comment for this method.
unsafe { (*self.inner.get()).take() }
pub(crate) unsafe fn take(&self) -> Option<T> {
let mutable: *mut _ = UnsafeCell::get(&self.inner);
// SAFETY: That's the caller's problem.
unsafe { mutable.replace(None) }
}
}
}

View File

@ -1,35 +1,11 @@
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:10:9
|
LL | /// - First String:
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:11:9
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:14:9
|
LL | /// - Second String:
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:15:9
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
LL | /// - first one
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:13
@ -49,5 +25,29 @@ error: using tabs in doc comments is not recommended
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:10:9
|
LL | /// - First String:
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:11:9
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:14:9
|
LL | /// - Second String:
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:15:9
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: aborting due to 8 previous errors

View File

@ -0,0 +1,18 @@
type Foo = impl Send;
//~^ ERROR `impl Trait` in type aliases is unstable
struct A;
const VALUE: Foo = value();
//~^ ERROR cannot find function `value` in this scope
fn test() {
match VALUE {
0 | 0 => {}
//~^ ERROR mismatched types
//~| ERROR mismatched types
_ => (),
}
}
fn main() {}

View File

@ -0,0 +1,58 @@
error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/ice-unhandled-type-122191.rs:1:12
|
LL | type Foo = impl Send;
| ^^^^^^^^^
|
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0425]: cannot find function `value` in this scope
--> $DIR/ice-unhandled-type-122191.rs:6:20
|
LL | const VALUE: Foo = value();
| ^^^^^ not found in this scope
error[E0308]: mismatched types
--> $DIR/ice-unhandled-type-122191.rs:11:9
|
LL | type Foo = impl Send;
| --------- the expected opaque type
...
LL | match VALUE {
| ----- this expression has type `Foo`
LL | 0 | 0 => {}
| ^ expected opaque type, found integer
|
= note: expected opaque type `Foo`
found type `{integer}`
note: this item must have the opaque type in its signature in order to be able to register hidden types
--> $DIR/ice-unhandled-type-122191.rs:9:4
|
LL | fn test() {
| ^^^^
error[E0308]: mismatched types
--> $DIR/ice-unhandled-type-122191.rs:11:13
|
LL | type Foo = impl Send;
| --------- the expected opaque type
...
LL | match VALUE {
| ----- this expression has type `Foo`
LL | 0 | 0 => {}
| ^ expected opaque type, found integer
|
= note: expected opaque type `Foo`
found type `{integer}`
note: this item must have the opaque type in its signature in order to be able to register hidden types
--> $DIR/ice-unhandled-type-122191.rs:9:4
|
LL | fn test() {
| ^^^^
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0308, E0425, E0658.
For more information about an error, try `rustc --explain E0308`.

View File

@ -1,3 +1,13 @@
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:4:1
|
LL | #[optimize(size)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:7:1
|
@ -28,16 +38,6 @@ LL | #[optimize(banana)]
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:4:1
|
LL | #[optimize(size)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:2:1
|

View File

@ -1,3 +1,9 @@
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:10:1
|
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:14:9
|
@ -28,12 +34,6 @@ error[E0734]: stability attributes may not be used outside of the standard libra
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:10:1
|
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:7:1
|

View File

@ -1,3 +1,9 @@
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:10:1
|
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:14:9
|
@ -28,12 +34,6 @@ error[E0734]: stability attributes may not be used outside of the standard libra
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:10:1
|
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:7:1
|