use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::struct_span_err;
-use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::query::Providers;
let module = tcx.hir_module_items(module_def_id);
for id in module.items() {
if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
- let item = tcx.hir().item(id);
- if let hir::ItemKind::Impl(ref impl_) = item.kind {
- enforce_impl_params_are_constrained(tcx, item.def_id, impl_.items);
- enforce_impl_items_are_distinct(tcx, impl_.items);
- if min_specialization {
- check_min_specialization(tcx, item.def_id.to_def_id(), item.span);
- }
+ enforce_impl_params_are_constrained(tcx, id.def_id);
+ enforce_impl_items_are_distinct(tcx, id.def_id);
+ if min_specialization {
+ check_min_specialization(tcx, id.def_id);
}
}
}
*providers = Providers { check_mod_impl_wf, ..*providers };
}
-fn enforce_impl_params_are_constrained(
- tcx: TyCtxt<'_>,
- impl_def_id: LocalDefId,
- impl_item_refs: &[hir::ImplItemRef],
-) {
+fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
// Every lifetime used in an associated type must be constrained.
let impl_self_ty = tcx.type_of(impl_def_id);
if impl_self_ty.references_error() {
);
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
- let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs
+ let lifetimes_in_associated_types: FxHashSet<_> = tcx
+ .associated_item_def_ids(impl_def_id)
.iter()
- .map(|item_ref| item_ref.id.def_id)
.flat_map(|def_id| {
let item = tcx.associated_item(def_id);
match item.kind {
}
/// Enforce that we do not have two items in an impl with the same name.
-fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) {
+fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
let mut seen_type_items = FxHashMap::default();
let mut seen_value_items = FxHashMap::default();
- for impl_item_ref in impl_item_refs {
- let impl_item = tcx.hir().impl_item(impl_item_ref.id);
+ for &impl_item_ref in tcx.associated_item_def_ids(impl_def_id) {
+ let impl_item = tcx.associated_item(impl_item_ref);
let seen_items = match impl_item.kind {
- hir::ImplItemKind::TyAlias(_) => &mut seen_type_items,
+ ty::AssocKind::Type => &mut seen_type_items,
_ => &mut seen_value_items,
};
- match seen_items.entry(impl_item.ident.normalize_to_macros_2_0()) {
+ let span = tcx.def_span(impl_item_ref);
+ let ident = impl_item.ident(tcx);
+ match seen_items.entry(ident.normalize_to_macros_2_0()) {
Occupied(entry) => {
let mut err = struct_span_err!(
tcx.sess,
- impl_item.span,
+ span,
E0201,
"duplicate definitions with name `{}`:",
- impl_item.ident
- );
- err.span_label(
- *entry.get(),
- format!("previous definition of `{}` here", impl_item.ident),
+ ident
);
- err.span_label(impl_item.span, "duplicate definition");
+ err.span_label(*entry.get(), format!("previous definition of `{}` here", ident));
+ err.span_label(span, "duplicate definition");
err.emit();
}
Vacant(entry) => {
- entry.insert(impl_item.span);
+ entry.insert(span);
}
}
}