Auto merge of #79322 - jyn514:refactor-impl, r=estebank
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. See `rustc_save_analysis::dump_visitor::process_impl` or `rustdoc::clean::clean_impl` for a good example of how this makes `impl`s easier to work with. r? `@petrochenkov` maybe?
This commit is contained in:
commit
150d1fee04
61 changed files with 258 additions and 246 deletions
|
@ -2011,11 +2011,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
"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 @@ impl UnsafetyChecker<'tcx> {
|
|||
|
||||
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 const_evaluatable_predicates_of<'tcx>(
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue