提交 a8ff647d 编写于 作者: J Joshua Nelson

Separate out a `hir::Impl` struct

This makes it possible to pass the `Impl` directly to functions, instead
of having to pass each of the many fields one at a time. It also
simplifies matches in many cases.
上级 fd34606d
......@@ -134,7 +134,7 @@ fn with_parent_item_lifetime_defs<T>(
let old_len = self.in_scope_lifetimes.len();
let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
hir::ItemKind::Impl { ref generics, .. }
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
| hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
_ => &[],
};
......@@ -431,7 +431,7 @@ fn lower_item_kind(
// to not cause an assertion failure inside the `lower_defaultness` function.
let has_val = true;
let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
hir::ItemKind::Impl {
hir::ItemKind::Impl(hir::Impl {
unsafety: self.lower_unsafety(unsafety),
polarity,
defaultness,
......@@ -441,7 +441,7 @@ fn lower_item_kind(
of_trait: trait_ref,
self_ty: lowered_ty,
items: new_impl_items,
}
})
}
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
......
......@@ -2562,22 +2562,25 @@ pub enum ItemKind<'hir> {
TraitAlias(Generics<'hir>, GenericBounds<'hir>),
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
Impl {
unsafety: Unsafety,
polarity: ImplPolarity,
defaultness: Defaultness,
// We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
// decoding as `Span`s cannot be decoded when a `Session` is not available.
defaultness_span: Option<Span>,
constness: Constness,
generics: Generics<'hir>,
/// The trait being implemented, if any.
of_trait: Option<TraitRef<'hir>>,
self_ty: &'hir Ty<'hir>,
items: &'hir [ImplItemRef<'hir>],
},
Impl(Impl<'hir>),
}
#[derive(Debug, HashStable_Generic)]
pub struct Impl<'hir> {
pub unsafety: Unsafety,
pub polarity: ImplPolarity,
pub defaultness: Defaultness,
// We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
// decoding as `Span`s cannot be decoded when a `Session` is not available.
pub defaultness_span: Option<Span>,
pub constness: Constness,
pub generics: Generics<'hir>,
/// The trait being implemented, if any.
pub of_trait: Option<TraitRef<'hir>>,
pub self_ty: &'hir Ty<'hir>,
pub items: &'hir [ImplItemRef<'hir>],
}
impl ItemKind<'_> {
......@@ -2590,7 +2593,7 @@ pub fn generics(&self) -> Option<&Generics<'_>> {
| ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
| ItemKind::Trait(_, _, ref generics, _, _)
| ItemKind::Impl { ref generics, .. } => generics,
| ItemKind::Impl(Impl { ref generics, .. }) => generics,
_ => return None,
})
}
......
......@@ -611,7 +611,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span)
}
ItemKind::Impl {
ItemKind::Impl(Impl {
unsafety: _,
defaultness: _,
polarity: _,
......@@ -621,7 +621,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
ref of_trait,
ref self_ty,
items,
} => {
}) => {
visitor.visit_id(item.hir_id);
visitor.visit_generics(generics);
walk_list!(visitor, visit_trait_ref, of_trait);
......
......@@ -684,7 +684,7 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
self.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident.name, item.span, true);
}
hir::ItemKind::Impl {
hir::ItemKind::Impl(hir::Impl {
unsafety,
polarity,
defaultness,
......@@ -694,7 +694,7 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
ref of_trait,
ref self_ty,
items,
} => {
}) => {
self.head("");
self.print_visibility(&item.vis);
self.print_defaultness(defaultness);
......
......@@ -345,9 +345,10 @@ fn get_impl_ident_and_self_ty_from_trait(
match tcx.hir().get_if_local(def_id) {
Some(Node::ImplItem(ImplItem { ident, hir_id, .. })) => {
match tcx.hir().find(tcx.hir().get_parent_item(*hir_id)) {
Some(Node::Item(Item { kind: ItemKind::Impl { self_ty, .. }, .. })) => {
Some((*ident, self_ty))
}
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) => Some((*ident, self_ty)),
_ => None,
}
}
......@@ -367,7 +368,7 @@ fn get_impl_ident_and_self_ty_from_trait(
let impl_did = tcx.hir().local_def_id(*impl_node);
match tcx.hir().get_if_local(impl_did.to_def_id()) {
Some(Node::Item(Item {
kind: ItemKind::Impl { self_ty, .. },
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) if trait_objects.iter().all(|did| {
// FIXME: we should check `self_ty` against the receiver
......
......@@ -541,7 +541,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
return;
}
}
hir::ItemKind::Impl { of_trait: Some(ref trait_ref), items, .. } => {
hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), items, .. }) => {
// If the trait is private, add the impl items to `private_traits` so they don't get
// reported for missing docs.
let real_trait = trait_ref.path.res.def_id();
......
......@@ -1259,7 +1259,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}), adt_def.repr)
}
hir::ItemKind::Impl { defaultness, .. } => {
hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
let trait_ref = self.tcx.impl_trait_ref(def_id);
let polarity = self.tcx.impl_polarity(def_id);
let parent = if let Some(trait_ref) = trait_ref {
......
......@@ -505,7 +505,7 @@ pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> {
| ItemKind::Union(_, generics)
| ItemKind::Trait(_, _, generics, ..)
| ItemKind::TraitAlias(generics, _)
| ItemKind::Impl { generics, .. },
| ItemKind::Impl(Impl { generics, .. }),
..
}) => Some(generics),
_ => None,
......
......@@ -829,7 +829,8 @@ trait defining them",
}
}
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl { items, .. }, ..
kind: hir::ItemKind::Impl(hir::Impl { items, .. }),
..
})) => {
for item in &items[..] {
if let hir::AssocItemKind::Type = item.kind {
......
......@@ -126,7 +126,7 @@ fn is_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
matches!(
node,
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl { constness: hir::Constness::Const, .. },
kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
..
})
)
......
......@@ -1146,8 +1146,8 @@ fn create_mono_items_for_default_impls<'tcx>(
output: &mut Vec<Spanned<MonoItem<'tcx>>>,
) {
match item.kind {
hir::ItemKind::Impl { ref generics, ref items, .. } => {
for param in generics.params {
hir::ItemKind::Impl(ref impl_) => {
for param in impl_.generics.params {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}
hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
......@@ -1167,7 +1167,7 @@ fn create_mono_items_for_default_impls<'tcx>(
let param_env = ty::ParamEnv::reveal_all();
let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
let overridden_methods: FxHashSet<_> =
items.iter().map(|iiref| iiref.ident.normalize_to_macros_2_0()).collect();
impl_.items.iter().map(|iiref| iiref.ident.normalize_to_macros_2_0()).collect();
for method in tcx.provided_trait_methods(trait_ref.def_id) {
if overridden_methods.contains(&method.ident.normalize_to_macros_2_0()) {
continue;
......
......@@ -32,7 +32,7 @@ pub(crate) fn target_from_impl_item<'tcx>(
let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id);
let containing_item = tcx.hir().expect_item(parent_hir_id);
let containing_impl_is_for_trait = match &containing_item.kind {
hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(),
hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(),
_ => bug!("parent of an ImplItem must be an Impl"),
};
if containing_impl_is_for_trait {
......@@ -343,7 +343,7 @@ fn check_doc_alias(&self, meta: &NestedMetaItem, hir_id: HirId, target: Target)
// We can't link to trait impl's consts.
let err = "associated constant in trait implementation block";
match containing_item.kind {
ItemKind::Impl { of_trait: Some(_), .. } => Some(err),
ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => Some(err),
_ => None,
}
}
......
......@@ -396,7 +396,7 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
}
}
}
hir::ItemKind::Impl { ref of_trait, items, .. } => {
hir::ItemKind::Impl(hir::Impl { ref of_trait, items, .. }) => {
if of_trait.is_some() {
self.worklist.push(item.hir_id);
}
......
......@@ -349,7 +349,9 @@ fn visit_item(&mut self, item: &hir::Item<'_>) {
}
// We need only trait impls here, not inherent impls, and only non-exported ones
if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
item.kind
{
if !self.access_levels.is_reachable(item.hir_id) {
// FIXME(#53488) remove `let`
let tcx = self.tcx;
......
......@@ -330,11 +330,12 @@ fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
// they don't have their own stability. They still can be annotated as unstable
// and propagate this unstability to children, but this annotation is completely
// optional. They inherit stability from their parents when unannotated.
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod { .. } => {
hir::ItemKind::Impl(hir::Impl { of_trait: None, .. })
| hir::ItemKind::ForeignMod { .. } => {
self.in_trait_impl = false;
kind = AnnotationKind::Container;
}
hir::ItemKind::Impl { of_trait: Some(_), .. } => {
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
self.in_trait_impl = true;
kind = AnnotationKind::DeprecationProhibited;
}
......@@ -503,7 +504,7 @@ fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
// optional. They inherit stability from their parents when unannotated.
if !matches!(
i.kind,
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod { .. }
hir::ItemKind::Impl(hir::Impl { of_trait: None, .. }) | hir::ItemKind::ForeignMod { .. }
) {
self.check_missing_stability(i.hir_id, i.span);
}
......@@ -672,7 +673,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
// For implementations of traits, check the stability of each item
// individually as it's possible to have a stable trait with unstable
// items.
hir::ItemKind::Impl { of_trait: Some(ref t), self_ty, items, .. } => {
hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
if self.tcx.features().staged_api {
// If this impl block has an #[unstable] attribute, give an
// error if all involved types and traits are stable, because
......
......@@ -632,9 +632,9 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
}
hir::ItemKind::Impl { ref of_trait, items, .. } => {
for impl_item_ref in items {
if of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
hir::ItemKind::Impl(ref impl_) => {
for impl_item_ref in impl_.items {
if impl_.of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
self.update(impl_item_ref.id.hir_id, item_level);
}
}
......@@ -736,11 +736,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
// Visit everything except for private impl items.
hir::ItemKind::Impl { items, .. } => {
hir::ItemKind::Impl(ref impl_) => {
if item_level.is_some() {
self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref();
for impl_item_ref in items {
for impl_item_ref in impl_.items {
let impl_item_level = self.get(impl_item_ref.id.hir_id);
if impl_item_level.is_some() {
self.reach(impl_item_ref.id.hir_id, impl_item_level)
......@@ -1450,7 +1450,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
// (i.e., we could just return here to not check them at
// all, or some worse estimation of whether an impl is
// publicly visible).
hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => {
hir::ItemKind::Impl(ref impl_) => {
// `impl [... for] Private` is never visible.
let self_contains_private;
// `impl [... for] Public<...>`, but not `impl [... for]
......@@ -1465,7 +1465,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
at_outer_type: true,
outer_type_is_public_path: false,
};
visitor.visit_ty(&self_ty);
visitor.visit_ty(&impl_.self_ty);
self_contains_private = visitor.contains_private;
self_is_public_path = visitor.outer_type_is_public_path;
}
......@@ -1473,7 +1473,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
// Miscellaneous info about the impl:
// `true` iff this is `impl Private for ...`.
let not_private_trait = of_trait.as_ref().map_or(
let not_private_trait = impl_.of_trait.as_ref().map_or(
true, // no trait counts as public trait
|tr| {
let did = tr.path.res.def_id();
......@@ -1494,8 +1494,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
// directly because we might have `impl<T: Foo<Private>> ...`,
// and we shouldn't warn about the generics if all the methods
// are private (because `T` won't be visible externally).
let trait_or_some_public_method = of_trait.is_some()
|| items.iter().any(|impl_item_ref| {
let trait_or_some_public_method = impl_.of_trait.is_some()
|| impl_.items.iter().any(|impl_item_ref| {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item.kind {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => {
......@@ -1506,11 +1506,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
});
if !self_contains_private && not_private_trait && trait_or_some_public_method {
intravisit::walk_generics(self, g);
intravisit::walk_generics(self, &impl_.generics);
match of_trait {
match impl_.of_trait {
None => {
for impl_item_ref in items {
for impl_item_ref in impl_.items {
// This is where we choose whether to walk down
// further into the impl to check its items. We
// should only walk into public items so that we
......@@ -1531,7 +1531,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
}
Some(tr) => {
Some(ref tr) => {
// Any private types in a trait impl fall into three
// categories.
// 1. mentioned in the trait definition
......@@ -1548,7 +1548,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
intravisit::walk_path(self, &tr.path);
// Those in 3. are warned with this call.
for impl_item_ref in items {
for impl_item_ref in impl_.items {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.kind {
self.visit_ty(ty);
......@@ -1556,11 +1556,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
}
} else if of_trait.is_none() && self_is_public_path {
} else if impl_.of_trait.is_none() && self_is_public_path {
// `impl Public<Private> { ... }`. Any public static
// methods will be visible as `Public::foo`.
let mut found_pub_static = false;
for impl_item_ref in items {
for impl_item_ref in impl_.items {
if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item_ref.kind {
......@@ -1577,7 +1577,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}
}
if found_pub_static {
intravisit::walk_generics(self, g)
intravisit::walk_generics(self, &impl_.generics)
}
}
return;
......@@ -1970,11 +1970,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
// Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity.
hir::ItemKind::Impl { ref of_trait, items, .. } => {
hir::ItemKind::Impl(ref impl_) => {
let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default());
self.check(item.hir_id, impl_vis).generics().predicates();
for impl_item_ref in items {
let impl_item_vis = if of_trait.is_none() {
for impl_item_ref in impl_.items {
let impl_item_vis = if impl_.of_trait.is_none() {
min(
tcx.visibility(tcx.hir().local_def_id(impl_item_ref.id.hir_id)),
impl_vis,
......@@ -2032,7 +2032,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
Node::ImplItem(impl_item) => {
match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) {
Node::Item(hir::Item {
kind: hir::ItemKind::Impl { of_trait: Some(tr), .. },
kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }),
..
}) => tr.path.res.opt_def_id().map_or_else(
|| {
......
......@@ -409,11 +409,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
| hir::ItemKind::Union(_, ref generics)
| hir::ItemKind::Trait(_, _, ref generics, ..)
| hir::ItemKind::TraitAlias(ref generics, ..)
| hir::ItemKind::Impl { ref generics, .. } => {
| hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
self.missing_named_lifetime_spots.push(generics.into());
// Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
// This is not true for other kinds of items.x
// This is not true for other kinds of items.
let track_lifetime_uses = matches!(item.kind, hir::ItemKind::Impl { .. });
// These kinds of items have only early-bound lifetime parameters.
let mut index = if sub_items_have_self_param(&item.kind) {
......@@ -1677,7 +1677,7 @@ fn visit_early_late<F>(
}
match parent.kind {
hir::ItemKind::Trait(_, _, ref generics, ..)
| hir::ItemKind::Impl { ref generics, .. } => {
| hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
index += generics.params.len() as u32;
}
_ => {}
......@@ -2102,7 +2102,7 @@ fn visit_fn_like_elision(
}
Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body), .. }) => {
if let hir::ItemKind::Impl { ref self_ty, ref items, .. } =
if let hir::ItemKind::Impl(hir::Impl { ref self_ty, ref items, .. }) =
self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind
{
impl_self = Some(self_ty);
......
......@@ -631,14 +631,7 @@ fn process_enum(
self.dumper.dump_def(&access, enum_data);
}
fn process_impl(
&mut self,
item: &'tcx hir::Item<'tcx>,
generics: &'tcx hir::Generics<'tcx>,
trait_ref: &'tcx Option<hir::TraitRef<'tcx>>,
typ: &'tcx hir::Ty<'tcx>,
impl_items: &'tcx [hir::ImplItemRef<'tcx>],
) {
fn process_impl(&mut self, item: &'tcx hir::Item<'tcx>, impl_: &'tcx hir::Impl<'tcx>) {
if let Some(impl_data) = self.save_ctxt.get_item_data(item) {
if !self.span.filter_generated(item.span) {
if let super::Data::RelationData(rel, imp) = impl_data {
......@@ -652,12 +645,12 @@ fn process_impl(
let map = &self.tcx.hir();
self.nest_typeck_results(map.local_def_id(item.hir_id), |v| {
v.visit_ty(&typ);
if let Some(trait_ref) = trait_ref {
v.visit_ty(&impl_.self_ty);
if let Some(trait_ref) = &impl_.of_trait {
v.process_path(trait_ref.hir_ref_id, &hir::QPath::Resolved(None, &trait_ref.path));
}
v.process_generic_params(generics, "", item.hir_id);
for impl_item in impl_items {
v.process_generic_params(&impl_.generics, "", item.hir_id);
for impl_item in impl_.items {
v.process_impl_item(
map.impl_item(impl_item.id),
map.local_def_id(item.hir_id).to_def_id(),
......@@ -1287,9 +1280,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
self.process_struct(item, def, ty_params)
}
hir::ItemKind::Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
hir::ItemKind::Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => {
self.process_impl(item, generics, of_trait, &self_ty, items)
}
hir::ItemKind::Impl(ref impl_) => self.process_impl(item, impl_),
hir::ItemKind::Trait(_, _, ref generics, ref trait_refs, methods) => {
self.process_trait(item, generics, trait_refs, methods)
}
......
......@@ -318,7 +318,7 @@ pub fn get_item_data(&self, item: &hir::Item<'_>) -> Option<Data> {
attributes: lower_attributes(item.attrs.to_vec(), self),
}))
}
hir::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => {
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. }) => {
if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind {
// Common case impl for a struct or something basic.
if generated_code(path.span) {
......@@ -410,7 +410,7 @@ pub fn get_method_data(&self, hir_id: hir::HirId, ident: Ident, span: Span) -> O
match self.tcx.impl_of_method(def_id) {
Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
Some(Node::Item(item)) => match item.kind {
hir::ItemKind::Impl { ref self_ty, .. } => {
hir::ItemKind::Impl(hir::Impl { ref self_ty, .. }) => {
let hir = self.tcx.hir();
let mut qualname = String::from("<");
......
......@@ -501,7 +501,7 @@ fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<
Ok(sig)
}
hir::ItemKind::Impl {
hir::ItemKind::Impl(hir::Impl {
unsafety,
polarity,
defaultness,
......@@ -511,7 +511,7 @@ fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<
ref of_trait,
ref self_ty,
items: _,
} => {
}) => {
let mut text = String::new();
if let hir::Defaultness::Default { .. } = defaultness {
text.push_str("default ");
......
......@@ -393,7 +393,7 @@ fn suggest_restricting_param_bound(
hir::Node::Item(hir::Item {
kind:
hir::ItemKind::Trait(_, _, generics, _, _)
| hir::ItemKind::Impl { generics, .. },
| hir::ItemKind::Impl(hir::Impl { generics, .. }),
..
}) if projection.is_some() => {
// Missing restriction on associated type of type parameter (unmet projection).
......@@ -416,7 +416,7 @@ fn suggest_restricting_param_bound(
| hir::ItemKind::Enum(_, generics)
| hir::ItemKind::Union(_, generics)
| hir::ItemKind::Trait(_, _, generics, ..)
| hir::ItemKind::Impl { generics, .. }
| hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Fn(_, generics, _)
| hir::ItemKind::TyAlias(_, generics)
| hir::ItemKind::TraitAlias(generics, _)
......
......@@ -199,7 +199,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
trait_ref, item, cause, pred
);
let items = match item {
Some(hir::Item { kind: hir::ItemKind::Impl { items, .. }, .. }) => items,
Some(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.items,
_ => return,
};
let fix_span =
......@@ -333,7 +333,9 @@ fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elabo
let mut new_cause = cause.clone();
// The first subst is the self ty - use the correct span for it.
if i == 0 {
if let Some(hir::ItemKind::Impl { self_ty, .. }) = item.map(|i| &i.kind) {
if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) =
item.map(|i| &i.kind)
{
new_cause.make_mut().span = self_ty.span;
}
}
......
......@@ -129,8 +129,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
let parent_def_id = tcx.hir().local_def_id(parent_id);
let parent_item = tcx.hir().expect_item(parent_id);
match parent_item.kind {
hir::ItemKind::Impl { ref items, .. } => {
if let Some(impl_item_ref) = items.iter().find(|i| i.id.hir_id == id) {
hir::ItemKind::Impl(ref impl_) => {
if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.hir_id == id) {
let assoc_item =
associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref);
debug_assert_eq!(assoc_item.def_id, def_id);
......@@ -160,8 +160,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
let item = tcx.hir().expect_item(hir_id);
if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
defaultness
if let hir::ItemKind::Impl(impl_) = &item.kind {
impl_.defaultness
} else {
bug!("`impl_defaultness` called on {:?}", item);
}
......@@ -201,8 +201,9 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
.map(|trait_item_ref| trait_item_ref.id)
.map(|id| tcx.hir().local_def_id(id.hir_id).to_def_id()),
),
hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter(
items
hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
impl_
.items
.iter()
.map(|impl_item_ref| impl_item_ref.id)
.map(|id| tcx.hir().local_def_id(id.hir_id).to_def_id()),
......@@ -323,8 +324,8 @@ enum NodeKind {
},
Node::Item(item) => match item.kind {
ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => NodeKind::TraitImpl,
ItemKind::Impl(hir::Impl { of_trait: None, .. }) => NodeKind::InherentImpl,
ItemKind::Fn(..) => NodeKind::Fn,
_ => NodeKind::Other,
},
......
......@@ -2013,11 +2013,11 @@ pub fn res_to_ty(
"generic `Self` types are currently not permitted in anonymous constants",
);
if let Some(hir::Node::Item(&hir::Item {
kind: hir::ItemKind::Impl { self_ty, .. },
kind: hir::ItemKind::Impl(ref impl_),
..
})) = tcx.hir().get_if_local(def_id)
{
err.span_note(self_ty.span, "not a concrete type");
err.span_note(impl_.self_ty.span, "not a concrete type");
}
err.emit();
tcx.ty_error()
......
......@@ -692,11 +692,17 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
}
hir::ItemKind::Fn(..) => {} // entirely within check_item_body
hir::ItemKind::Impl { ref items, .. } => {
hir::ItemKind::Impl(ref impl_) => {
debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
let impl_def_id = tcx.hir().local_def_id(it.hir_id);
if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
check_impl_items_against_trait(
tcx,
it.span,
impl_def_id,
impl_trait_ref,
&impl_.items,
);
let trait_def_id = impl_trait_ref.def_id;
check_on_unimplemented(tcx, trait_def_id, it);
}
......
......@@ -103,35 +103,28 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
//
// won't be allowed unless there's an *explicit* implementation of `Send`
// for `T`
hir::ItemKind::Impl {
defaultness,
defaultness_span,
polarity,
ref of_trait,
ref self_ty,
..
} => {
hir::ItemKind::Impl(ref impl_) => {
let is_auto = tcx
.impl_trait_ref(tcx.hir().local_def_id(item.hir_id))
.map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
let sp = of_trait.as_ref().map(|t| t.path.span).unwrap_or(item.span);
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
let sp = impl_.of_trait.as_ref().map(|t| t.path.span).unwrap_or(item.span);
let mut err =
tcx.sess.struct_span_err(sp, "impls of auto traits cannot be default");
err.span_labels(defaultness_span, "default because of this");
err.span_labels(impl_.defaultness_span, "default because of this");
err.span_label(sp, "auto trait");
err.emit();
}
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
match (tcx.impl_polarity(def_id), polarity) {
match (tcx.impl_polarity(def_id), impl_.polarity) {
(ty::ImplPolarity::Positive, _) => {
check_impl(tcx, item, self_ty, of_trait);
check_impl(tcx, item, impl_.self_ty, &impl_.of_trait);
}
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
// FIXME(#27579): what amount of WF checking do we need for neg impls?
if let hir::Defaultness::Default { .. } = defaultness {
if let hir::Defaultness::Default { .. } = impl_.defaultness {
let mut spans = vec![span];
spans.extend(defaultness_span);
spans.extend(impl_.defaultness_span);
struct_span_err!(
tcx.sess,
spans,
......
......@@ -55,7 +55,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_did);
let sp = match tcx.hir().expect_item(impl_hir_id).kind {
ItemKind::Impl { self_ty, .. } => self_ty.span,
ItemKind::Impl(ref impl_) => impl_.self_ty.span,
_ => bug!("expected Drop impl item"),
};
......@@ -80,7 +80,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
Ok(()) => {}
Err(CopyImplementationError::InfrigingFields(fields)) => {
let item = tcx.hir().expect_item(impl_hir_id);
let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind {
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref tr), .. }) = item.kind {
tr.path.span
} else {
span
......@@ -100,7 +100,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
Err(CopyImplementationError::NotAnAdt) => {
let item = tcx.hir().expect_item(impl_hir_id);
let span =
if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span };
if let ItemKind::Impl(ref impl_) = item.kind { impl_.self_ty.span } else { span };
tcx.sess.emit_err(CopyImplOnNonAdt { span });
}
......@@ -453,7 +453,9 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
return err_info;
} else if diff_fields.len() > 1 {
let item = tcx.hir().expect_item(impl_hir_id);
let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind {
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) =
item.kind
{
t.path.span
} else {
tcx.hir().span(impl_hir_id)
......
......@@ -45,7 +45,9 @@ struct InherentCollect<'tcx> {
impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
let (ty, assoc_items) = match item.kind {
hir::ItemKind::Impl { of_trait: None, ref self_ty, items, .. } => (self_ty, items),
hir::ItemKind::Impl(hir::Impl { of_trait: None, ref self_ty, items, .. }) => {
(self_ty, items)
}
_ => return,
};
......
......@@ -26,7 +26,10 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
let def_id = self.tcx.hir().local_def_id(item.hir_id);
// "Trait" impl
if let hir::ItemKind::Impl { generics, of_trait: Some(ref tr), self_ty, .. } = &item.kind {
if let hir::ItemKind::Impl(hir::Impl {
generics, of_trait: Some(ref tr), self_ty, ..
}) = &item.kind
{
debug!(
"coherence2::orphan check: trait impl {}",
self.tcx.hir().node_to_string(item.hir_id)
......
......@@ -86,8 +86,13 @@ fn check_unsafety_coherence(
impl ItemLikeVisitor<'v> for UnsafetyChecker<'tcx> {
fn visit_item(&mut self, item: &'v hir::Item<'v>) {
if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind {
self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
if let hir::ItemKind::Impl(ref impl_) = item.kind {
self.check_unsafety_coherence(
item,
Some(&impl_.generics),
impl_.unsafety,
impl_.polarity,
);
}
}
......
......@@ -189,7 +189,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
| hir::ItemKind::Enum(_, generics)
| hir::ItemKind::TraitAlias(generics, _)
| hir::ItemKind::Trait(_, _, generics, ..)
| hir::ItemKind::Impl { generics, .. }
| hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Struct(_, generics) => (generics, true),
hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
| hir::ItemKind::TyAlias(_, generics) => (generics, false),
......@@ -531,7 +531,7 @@ fn type_param_predicates(
Node::Item(item) => {
match item.kind {
ItemKind::Fn(.., ref generics, _)
| ItemKind::Impl { ref generics, .. }
| ItemKind::Impl(hir::Impl { ref generics, .. })
| ItemKind::TyAlias(_, ref generics)
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
| ItemKind::Enum(_, ref generics)
......@@ -1310,7 +1310,8 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
Node::Item(item) => {
match item.kind {
ItemKind::Fn(.., ref generics, _) | ItemKind::Impl { ref generics, .. } => generics,
ItemKind::Fn(.., ref generics, _)
| ItemKind::Impl(hir::Impl { ref generics, .. }) => generics,
ItemKind::TyAlias(_, ref generics)
| ItemKind::Enum(_, ref generics)
......@@ -1638,7 +1639,7 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().expect_item(hir_id).kind {
hir::ItemKind::Impl { ref of_trait, .. } => of_trait.as_ref().map(|ast_trait_ref| {
hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id);
AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
}),
......@@ -1651,29 +1652,39 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
let item = tcx.hir().expect_item(hir_id);
match &item.kind {
hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => {
hir::ItemKind::Impl(hir::Impl {
polarity: hir::ImplPolarity::Negative(span),
of_trait,
..
}) => {
if is_rustc_reservation {
let span = span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(*span));
tcx.sess.span_err(span, "reservation impls can't be negative");
}
ty::ImplPolarity::Negative
}
hir::ItemKind::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
hir::ItemKind::Impl(hir::Impl {
polarity: hir::ImplPolarity::Positive,
of_trait: None,
..
}) => {
if is_rustc_reservation {
tcx.sess.span_err(item.span, "reservation impls can't be inherent");
}
ty::ImplPolarity::Positive
}
hir::ItemKind::Impl {
polarity: hir::ImplPolarity::Positive, of_trait: Some(_), ..
} => {
hir::ItemKind::Impl(hir::Impl {
polarity: hir::ImplPolarity::Positive,
of_trait: Some(_),
..
}) => {
if is_rustc_reservation {
ty::ImplPolarity::Reservation
} else {
ty::ImplPolarity::Positive
}
}
ref item => bug!("impl_polarity: {:?} not an impl", item),
item => bug!("impl_polarity: {:?} not an impl", item),
}
}
......@@ -1777,11 +1788,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
Node::Item(item) => {
match item.kind {
ItemKind::Impl { defaultness, ref generics, .. } => {
if defaultness.is_default() {
ItemKind::Impl(ref impl_) => {
if impl_.defaultness.is_default() {
is_default_impl_trait = tcx.impl_trait_ref(def_id);
}
generics
&impl_.generics
}
ItemKind::Fn(.., ref generics, _)
| ItemKind::TyAlias(_, ref generics)
......@@ -2113,14 +2124,14 @@ fn visit_const(&mut self, ct: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
if let hir::Node::Item(item) = node {
if let hir::ItemKind::Impl { ref of_trait, ref self_ty, .. } = item.kind {
if let Some(of_trait) = of_trait {
if let hir::ItemKind::Impl(ref impl_) = item.kind {
if let Some(of_trait) = &impl_.of_trait {
debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
collector.visit_trait_ref(of_trait);
}
debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id);
collector.visit_ty(self_ty);
collector.visit_ty(impl_.self_ty);
}
}
......@@ -2952,7 +2963,7 @@ fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span:
if let Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) = node {
let parent_id = tcx.hir().get_parent_item(hir_id);
let parent_item = tcx.hir().expect_item(parent_id);
if let hir::ItemKind::Impl { of_trait: Some(_), .. } = parent_item.kind {
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = parent_item.kind {
tcx.sess
.struct_span_err(
attr_span,
......
......@@ -243,9 +243,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
icx.to_ty(ty)
}
}
ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => {
icx.to_ty(self_ty)
}
ItemKind::TyAlias(ref self_ty, _)
| ItemKind::Impl(hir::Impl { ref self_ty, .. }) => icx.to_ty(self_ty),
ItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
tcx.mk_fn_def(def_id.to_def_id(), substs)
......
......@@ -80,10 +80,10 @@ struct ImplWfCheck<'tcx> {
impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
if let hir::ItemKind::Impl { ref items, .. } = item.kind {
if let hir::ItemKind::Impl(ref impl_) = item.kind {
let impl_def_id = self.tcx.hir().local_def_id(item.hir_id);
enforce_impl_params_are_constrained(self.tcx, impl_def_id, items);
enforce_impl_items_are_distinct(self.tcx, items);
enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_.items);
enforce_impl_items_are_distinct(self.tcx, impl_.items);
if self.min_specialization {
check_min_specialization(self.tcx, impl_def_id.to_def_id(), item.span);
}
......
......@@ -358,18 +358,16 @@ fn merge_attrs(
let impl_item = match did.as_local() {
Some(did) => {
let hir_id = tcx.hir().local_def_id_to_hir_id(did);
match tcx.hir().expect_item(hir_id).kind {
hir::ItemKind::Impl { self_ty, ref generics, ref items, .. } => {
Some((self_ty, generics, items))
}
match &tcx.hir().expect_item(hir_id).kind {
hir::ItemKind::Impl(impl_) => Some(impl_),
_ => panic!("`DefID` passed to `build_impl` is not an `impl"),
}
}
None => None,
};
let for_ = match impl_item {
Some((self_ty, _, _)) => self_ty.clean(cx),
let for_ = match &impl_item {
Some(impl_) => impl_.self_ty.clean(cx),
None => tcx.type_of(did).clean(cx),
};
......@@ -391,9 +389,13 @@ fn merge_attrs(
let predicates = tcx.explicit_predicates_of(did);
let (trait_items, generics) = match impl_item {
Some((_, generics, items)) => (
items.iter().map(|item| tcx.hir().impl_item(item.id).clean(cx)).collect::<Vec<_>>(),
generics.clean(cx),
Some(impl_) => (
impl_
.items
.iter()
.map(|item| tcx.hir().impl_item(item.id).clean(cx))
.collect::<Vec<_>>(),
impl_.generics.clean(cx),
),
None => (
tcx.associated_items(did)
......
......@@ -2027,7 +2027,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
fields: variant_data.fields().clean(cx),
fields_stripped: false,
}),
ItemKind::Impl { .. } => return clean_impl(item, cx),
ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.hir_id, cx),
// proc macros can have a name set by attributes
ItemKind::Fn(ref sig, ref generics, body_id) => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
......@@ -2081,17 +2081,12 @@ fn clean(&self, _: &DocContext<'_>) -> bool {
}
}
fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec<Item> {
fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &DocContext<'_>) -> Vec<Item> {
let mut ret = Vec::new();
let (trait_, items, for_, unsafety, generics) = match &impl_.kind {
hir::ItemKind::Impl { of_trait, items, self_ty, unsafety, generics, .. } => {
(of_trait, items, self_ty, *unsafety, generics)
}
_ => unreachable!(),
};
let trait_ = trait_.clean(cx);
let items = items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
let def_id = cx.tcx.hir().local_def_id(impl_.hir_id);
let trait_ = impl_.of_trait.clean(cx);
let items =
impl_.items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
let def_id = cx.tcx.hir().local_def_id(hir_id);
// If this impl block is an implementation of the Deref trait, then we
// need to try inlining the target's inherent impl blocks as well.
......@@ -2104,15 +2099,15 @@ fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec<Item> {
.map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
.unwrap_or_default();
let for_ = for_.clean(cx);
let for_ = impl_.self_ty.clean(cx);
let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) {
DefKind::TyAlias => Some(cx.tcx.type_of(did).clean(cx)),
_ => None,
});
let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Impl {
unsafety,
generics: generics.clean(cx),
unsafety: impl_.unsafety,
generics: impl_.generics.clean(cx),
provided_trait_methods: provided.clone(),
trait_,
for_,
......@@ -2121,7 +2116,7 @@ fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec<Item> {
synthetic: false,
blanket_impl: None,
});
Item::from_hir_id_and_parts(impl_.hir_id, None, kind, cx)
Item::from_hir_id_and_parts(hir_id, None, kind, cx)
};
if let Some(type_alias) = type_alias {
ret.push(make_item(trait_.clone(), type_alias, items.clone()));
......
......@@ -1026,8 +1026,8 @@ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
}
fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind {
rustc_hir_pretty::id_to_string(&self.map, self_ty.hir_id)
let name = if let hir::ItemKind::Impl(impl_) = &item.kind {
rustc_hir_pretty::id_to_string(&self.map, impl_.self_ty.hir_id)
} else {
item.ident.to_string()
};
......
......@@ -352,10 +352,10 @@ fn visit_item(
om.items.push((item, renamed));
}
}
hir::ItemKind::Impl { ref of_trait, .. } => {
hir::ItemKind::Impl(ref impl_) => {
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
// them up regardless of where they're located.
if !self.inlining && of_trait.is_none() {
if !self.inlining && impl_.of_trait.is_none() {
om.items.push((item, None));
}
}
......
use crate::utils::{is_copy, match_path, paths, span_lint_and_note};
use rustc_hir::{Item, ItemKind};
use rustc_hir::{Item, ItemKind, Impl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
......@@ -33,10 +33,10 @@
impl<'tcx> LateLintPass<'tcx> for CopyIterator {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Impl {
if let ItemKind::Impl(Impl {
of_trait: Some(ref trait_ref),
..
} = item.kind
}) = item.kind
{
let ty = cx.tcx.type_of(cx.tcx.hir().local_def_id(item.hir_id));
......
......@@ -7,7 +7,7 @@
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, NestedVisitorMap, Visitor};
use rustc_hir::{
BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, TraitRef, UnsafeSource, Unsafety,
BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Impl, TraitRef, UnsafeSource, Unsafety,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::map::Map;
......@@ -164,10 +164,10 @@
impl<'tcx> LateLintPass<'tcx> for Derive {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Impl {
if let ItemKind::Impl(Impl {
of_trait: Some(ref trait_ref),
..
} = item.kind
}) = item.kind
{
let ty = cx.tcx.type_of(cx.tcx.hir().local_def_id(item.hir_id));
let is_automatically_derived = is_automatically_derived(&*item.attrs);
......
......@@ -182,11 +182,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id));
}
},
hir::ItemKind::Impl {
of_trait: ref trait_ref,
..
} => {
self.in_trait_impl = trait_ref.is_some();
hir::ItemKind::Impl(ref impl_) => {
self.in_trait_impl = impl_.of_trait.is_some();
},
_ => {},
}
......
use rustc_hir::intravisit;
use rustc_hir::{self, Body, FnDecl, HirId, HirIdSet, ItemKind, Node};
use rustc_hir::{self, Body, FnDecl, HirId, HirIdSet, ItemKind, Impl, Node};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
......@@ -77,7 +77,7 @@ fn check_fn(
let parent_node = cx.tcx.hir().find(parent_id);
if let Some(Node::Item(item)) = parent_node {
if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = item.kind {
return;
}
}
......
......@@ -57,11 +57,11 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
// check for `impl From<???> for ..`
let impl_def_id = cx.tcx.hir().local_def_id(item.hir_id);
if_chain! {
if let hir::ItemKind::Impl{ items: impl_items, .. } = item.kind;
if let hir::ItemKind::Impl(impl_) = &item.kind;
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id);
if match_def_path(cx, impl_trait_ref.def_id, &FROM_TRAIT);
then {
lint_impl_body(cx, item.span, impl_items);
lint_impl_body(cx, item.span, impl_.items);
}
}
}
......
......@@ -2,7 +2,7 @@
use crate::utils::{in_macro, span_lint_and_then};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{def_id, Crate, Item, ItemKind};
use rustc_hir::{def_id, Crate, Item, ItemKind, Impl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
......@@ -49,11 +49,11 @@ pub struct MultipleInherentImpl {
impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Impl {
if let ItemKind::Impl(Impl {
ref generics,
of_trait: None,
..
} = item.kind
}) = item.kind
{
// Remember for each inherent implementation encountered its span and generics
// but filter out implementations that have generic params (type or lifetime)
......
......@@ -3,7 +3,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_hir::{AssocItemKind, BinOpKind, Expr, ExprKind, ImplItemRef, Item, ItemKind, TraitItemRef};
use rustc_hir::{AssocItemKind, BinOpKind, Expr, ExprKind, ImplItemRef, Item, ItemKind, Impl, TraitItemRef};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
......@@ -115,11 +115,11 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
match item.kind {
ItemKind::Trait(_, _, _, _, ref trait_items) => check_trait_items(cx, item, trait_items),
ItemKind::Impl {
ItemKind::Impl(Impl {
of_trait: None,
items: ref impl_items,
..
} => check_impl_items(cx, item, impl_items),
}) => check_impl_items(cx, item, impl_items),
_ => (),
}
}
......
......@@ -1626,7 +1626,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::Impl
let self_ty = cx.tcx.type_of(def_id);
// if this impl block implements a trait, lint in trait definition instead
if let hir::ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind {
return;
}
......
......@@ -8,7 +8,7 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, ItemKind, Node, PatKind, QPath, TyKind};
use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, ItemKind, Impl, Node, PatKind, QPath, TyKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, TypeFoldable};
......@@ -92,7 +92,7 @@ fn check_fn(
if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
if matches!(
item.kind,
ItemKind::Impl { of_trait: Some(_), .. } | ItemKind::Trait(..)
ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
) {
return;
}
......
......@@ -60,9 +60,9 @@ pub struct NewWithoutDefault {
impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
#[allow(clippy::too_many_lines)]
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
if let hir::ItemKind::Impl {
if let hir::ItemKind::Impl(hir::Impl {
of_trait: None, items, ..
} = item.kind
}) = item.kind
{
for assoc_item in items {
if let hir::AssocItemKind::Fn { has_self: false } = assoc_item.kind {
......
......@@ -7,7 +7,7 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{
BodyId, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
};
use rustc_infer::traits::specialization_graph;
use rustc_lint::{LateContext, LateLintPass, Lint};
......@@ -275,10 +275,10 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
let item = cx.tcx.hir().expect_item(item_hir_id);
match &item.kind {
ItemKind::Impl {
ItemKind::Impl(Impl {
of_trait: Some(of_trait_ref),
..
} => {
}) => {
if_chain! {
// Lint a trait impl item only when the definition is a generic type,
// assuming a assoc const is not meant to be a interior mutable type.
......@@ -317,7 +317,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
}
}
},
ItemKind::Impl { of_trait: None, .. } => {
ItemKind::Impl(Impl { of_trait: None, .. }) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
// Normalize assoc types originated from generic params.
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
......
use crate::utils::{is_automatically_derived, span_lint_hir};
use if_chain::if_chain;
use rustc_hir::{Item, ItemKind};
use rustc_hir::{Item, ItemKind, Impl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
......@@ -34,7 +34,7 @@
impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if_chain! {
if let ItemKind::Impl{ of_trait: Some(ref trait_ref), items: impl_items, .. } = item.kind;
if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
if !is_automatically_derived(&*item.attrs);
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
if trait_ref.path.res.def_id() == eq_trait;
......
......@@ -6,7 +6,7 @@
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, HirId, ItemKind, MutTy, Mutability, Node, PatKind};
use rustc_hir::{BindingAnnotation, Body, FnDecl, HirId, ItemKind, MutTy, Mutability, Node, PatKind, Impl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
......@@ -246,7 +246,7 @@ fn check_fn(
if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
if matches!(
item.kind,
ItemKind::Impl { of_trait: Some(_), .. } | ItemKind::Trait(..)
ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
) {
return;
}
......
......@@ -8,7 +8,7 @@
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{
BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind,
BinOpKind, BodyId, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind, Impl,
Lifetime, MutTy, Mutability, Node, PathSegment, QPath, TraitFn, TraitItem, TraitItemKind, Ty, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
......@@ -132,7 +132,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
if let ImplItemKind::Fn(ref sig, body_id) = item.kind {
let parent_item = cx.tcx.hir().get_parent_item(item.hir_id);
if let Some(Node::Item(it)) = cx.tcx.hir().find(parent_item) {
if let ItemKind::Impl { of_trait: Some(_), .. } = it.kind {
if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = it.kind {
return; // ignore trait impls
}
}
......
use crate::utils::{get_trait_def_id, paths, span_lint};
use rustc_hir::{Item, ItemKind};
use rustc_hir::{Item, ItemKind, Impl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
......@@ -22,11 +22,11 @@
impl<'tcx> LateLintPass<'tcx> for SerdeAPI {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Impl {
if let ItemKind::Impl(Impl {
of_trait: Some(ref trait_ref),
items,
..
} = item.kind
}) = item.kind
{
let did = trait_ref.path.res.def_id();
if let Some(visit_did) = get_trait_def_id(cx, &paths::SERDE_DE_VISITOR) {
......
use crate::utils::{match_def_path, match_trait_method, paths, qpath_res, span_lint};
use if_chain::if_chain;
use rustc_hir::def::Res;
use rustc_hir::{Expr, ExprKind, HirId, ImplItem, ImplItemKind, Item, ItemKind};
use rustc_hir::{Expr, ExprKind, HirId, ImplItem, ImplItemKind, Item, ItemKind, Impl};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
......@@ -111,7 +111,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
fn is_display_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
if_chain! {
if let ItemKind::Impl { of_trait: Some(trait_ref), .. } = &item.kind;
if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), .. }) = &item.kind;
if let Some(did) = trait_ref.trait_def_id();
then {
match_def_path(cx, did, &paths::DISPLAY_TRAIT)
......
......@@ -258,7 +258,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
fn check_fn(&mut self, cx: &LateContext<'_>, _: FnKind<'_>, decl: &FnDecl<'_>, _: &Body<'_>, _: Span, id: HirId) {
// Skip trait implementations; see issue #605.
if let Some(hir::Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_item(id)) {
if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind {
return;
}
}
......@@ -2558,21 +2558,16 @@ fn suggestion<'tcx>(
}
match item.kind {
ItemKind::Impl {
ref generics,
self_ty: ref ty,
ref items,
..
} => {
ItemKind::Impl(ref impl_) => {
let mut vis = ImplicitHasherTypeVisitor::new(cx);
vis.visit_ty(ty);
vis.visit_ty(impl_.self_ty);
for target in &vis.found {
if differing_macro_contexts(item.span, target.span()) {
return;
}
let generics_suggestion_span = generics.span.substitute_dummy({
let generics_suggestion_span = impl_.generics.span.substitute_dummy({
let pos = snippet_opt(cx, item.span.until(target.span()))
.and_then(|snip| Some(item.span.lo() + BytePos(snip.find("impl")? as u32 + 4)));
if let Some(pos) = pos {
......@@ -2583,7 +2578,7 @@ fn suggestion<'tcx>(
});
let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
for item in items.iter().map(|item| cx.tcx.hir().impl_item(item.id)) {
for item in impl_.items.iter().map(|item| cx.tcx.hir().impl_item(item.id)) {
ctr_vis.visit_impl_item(item);
}
......@@ -2596,7 +2591,7 @@ fn suggestion<'tcx>(
target.type_name()
),
move |diag| {
suggestion(cx, diag, generics.span, generics_suggestion_span, target, ctr_vis);
suggestion(cx, diag, impl_.generics.span, generics_suggestion_span, target, ctr_vis);
},
);
}
......
......@@ -5,7 +5,7 @@
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, ExprKind, FnDecl, HirId, ItemKind, Node};
use rustc_hir::{Body, ExprKind, FnDecl, HirId, ItemKind, Impl, Node};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint};
......@@ -77,7 +77,7 @@ fn check_fn(
if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
if matches!(
item.kind,
ItemKind::Impl { of_trait: Some(_), .. } | ItemKind::Trait(..)
ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
) {
return;
}
......
use if_chain::if_chain;
use rustc_hir::def::Res;
use rustc_hir::intravisit::{walk_path, NestedVisitorMap, Visitor};
use rustc_hir::{HirId, ImplItem, ImplItemKind, ItemKind, Path};
use rustc_hir::{HirId, ImplItem, ImplItemKind, ItemKind, Impl, Path};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::map::Map;
use rustc_session::{declare_lint_pass, declare_tool_lint};
......@@ -49,7 +49,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>)
let def_id = cx.tcx.hir().local_def_id(impl_item.hir_id);
let assoc_item = cx.tcx.associated_item(def_id);
if_chain! {
if let ItemKind::Impl { of_trait: None, .. } = parent_item.kind;
if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind;
if assoc_item.fn_has_self_parameter;
if let ImplItemKind::Fn(.., body_id) = &impl_item.kind;
let body = cx.tcx.hir().body(*body_id);
......
......@@ -181,8 +181,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
return;
}
if_chain! {
if let ItemKind::Impl{ self_ty: ref item_type, items: refs, .. } = item.kind;
if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.kind;
if let ItemKind::Impl(impl_) = &item.kind;
if let TyKind::Path(QPath::Resolved(_, ref item_path)) = impl_.self_ty.kind;
then {
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
let should_check = parameters.as_ref().map_or(
......@@ -200,7 +200,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let impl_trait_ref = cx.tcx.impl_trait_ref(impl_def_id);
if let Some(impl_trait_ref) = impl_trait_ref {
for impl_item_ref in refs {
for impl_item_ref in impl_.items {
let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
if let ImplItemKind::Fn(FnSig{ decl: impl_decl, .. }, impl_body_id)
= &impl_item.kind {
......@@ -213,7 +213,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
}
}
} else {
for impl_item_ref in refs {
for impl_item_ref in impl_.items {
let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
visitor.visit_impl_item(impl_item);
}
......
......@@ -423,13 +423,13 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
hir::ItemKind::TraitAlias(..) => {
println!("trait alias");
},
hir::ItemKind::Impl {
hir::ItemKind::Impl(hir::Impl {
of_trait: Some(ref _trait_ref),
..
} => {
}) => {
println!("trait impl");
},
hir::ItemKind::Impl { of_trait: None, .. } => {
hir::ItemKind::Impl(hir::Impl { of_trait: None, .. }) => {
println!("impl");
},
}
......
......@@ -352,11 +352,11 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
} else if is_expn_of(item.span, "impl_lint_pass").is_some()
|| is_expn_of(item.span, "declare_lint_pass").is_some()
{
if let hir::ItemKind::Impl {
if let hir::ItemKind::Impl(hir::Impl {
of_trait: None,
items: ref impl_item_refs,
..
} = item.kind
}) = item.kind
{
let mut collector = LintCollector {
output: &mut self.registered_lints,
......
......@@ -439,8 +439,8 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
if_chain! {
if parent_impl != hir::CRATE_HIR_ID;
if let hir::Node::Item(item) = cx.tcx.hir().get(parent_impl);
if let hir::ItemKind::Impl{ of_trait: trait_ref, .. } = &item.kind;
then { return trait_ref.as_ref(); }
if let hir::ItemKind::Impl(impl_) = &item.kind;
then { return impl_.of_trait.as_ref(); }
}
None
}
......@@ -1530,7 +1530,7 @@ pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
/// ```
pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
matches!(item.kind, ItemKind::Impl { of_trait: Some(_), .. })
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
} else {
false
}
......
......@@ -62,7 +62,7 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool {
let parent_id = cx.tcx.hir().get_parent_item(hir_id);
if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_item(parent_id)) {
if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind {
return true;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册