remove ItemLikeVisitor impl for InherentCollect
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
This commit is contained in:
parent
c27f30835c
commit
63849b6ecf
4 changed files with 84 additions and 78 deletions
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
||||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
|
||||||
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
|
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
|
||||||
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
|
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -19,7 +19,9 @@ use rustc_span::Span;
|
||||||
/// On-demand query: yields a map containing all types mapped to their inherent impls.
|
/// On-demand query: yields a map containing all types mapped to their inherent impls.
|
||||||
pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls {
|
pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls {
|
||||||
let mut collect = InherentCollect { tcx, impls_map: Default::default() };
|
let mut collect = InherentCollect { tcx, impls_map: Default::default() };
|
||||||
tcx.hir().visit_all_item_likes(&mut collect);
|
for id in tcx.hir().items() {
|
||||||
|
collect.check_item(id);
|
||||||
|
}
|
||||||
collect.impls_map
|
collect.impls_map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,79 +48,6 @@ struct InherentCollect<'tcx> {
|
||||||
impls_map: CrateInherentImpls,
|
impls_map: CrateInherentImpls,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
|
|
||||||
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
|
||||||
let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let self_ty = self.tcx.type_of(item.def_id);
|
|
||||||
match *self_ty.kind() {
|
|
||||||
ty::Adt(def, _) => {
|
|
||||||
self.check_def_id(item, self_ty, def.did());
|
|
||||||
}
|
|
||||||
ty::Foreign(did) => {
|
|
||||||
self.check_def_id(item, self_ty, did);
|
|
||||||
}
|
|
||||||
ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
|
|
||||||
self.check_def_id(item, self_ty, data.principal_def_id().unwrap());
|
|
||||||
}
|
|
||||||
ty::Dynamic(..) => {
|
|
||||||
struct_span_err!(
|
|
||||||
self.tcx.sess,
|
|
||||||
ty.span,
|
|
||||||
E0785,
|
|
||||||
"cannot define inherent `impl` for a dyn auto trait"
|
|
||||||
)
|
|
||||||
.span_label(ty.span, "impl requires at least one non-auto trait")
|
|
||||||
.note("define and implement a new trait or type instead")
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
ty::Bool
|
|
||||||
| ty::Char
|
|
||||||
| ty::Int(_)
|
|
||||||
| ty::Uint(_)
|
|
||||||
| ty::Float(_)
|
|
||||||
| ty::Str
|
|
||||||
| ty::Array(..)
|
|
||||||
| ty::Slice(_)
|
|
||||||
| ty::RawPtr(_)
|
|
||||||
| ty::Ref(..)
|
|
||||||
| ty::Never
|
|
||||||
| ty::Tuple(..) => self.check_primitive_impl(item.def_id, self_ty, items, ty.span),
|
|
||||||
ty::FnPtr(_) | ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
self.tcx.sess,
|
|
||||||
ty.span,
|
|
||||||
E0118,
|
|
||||||
"no nominal type found for inherent implementation"
|
|
||||||
);
|
|
||||||
|
|
||||||
err.span_label(ty.span, "impl requires a nominal type")
|
|
||||||
.note("either implement a trait on it or create a newtype to wrap it instead");
|
|
||||||
|
|
||||||
err.emit();
|
|
||||||
}
|
|
||||||
ty::FnDef(..)
|
|
||||||
| ty::Closure(..)
|
|
||||||
| ty::Generator(..)
|
|
||||||
| ty::GeneratorWitness(..)
|
|
||||||
| ty::Bound(..)
|
|
||||||
| ty::Placeholder(_)
|
|
||||||
| ty::Infer(_) => {
|
|
||||||
bug!("unexpected impl self type of impl: {:?} {:?}", item.def_id, self_ty);
|
|
||||||
}
|
|
||||||
ty::Error(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
|
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
|
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const INTO_CORE: &str = "consider moving this inherent impl into `core` if possible";
|
const INTO_CORE: &str = "consider moving this inherent impl into `core` if possible";
|
||||||
const INTO_DEFINING_CRATE: &str =
|
const INTO_DEFINING_CRATE: &str =
|
||||||
"consider moving this inherent impl into the crate defining the type if possible";
|
"consider moving this inherent impl into the crate defining the type if possible";
|
||||||
|
@ -246,4 +175,74 @@ impl<'tcx> InherentCollect<'tcx> {
|
||||||
bug!("unexpected primitive type: {:?}", ty);
|
bug!("unexpected primitive type: {:?}", ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_item(&mut self, id: hir::ItemId) {
|
||||||
|
if !matches!(self.tcx.hir().def_kind(id.def_id), DefKind::Impl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = self.tcx.hir().item(id);
|
||||||
|
let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let self_ty = self.tcx.type_of(item.def_id);
|
||||||
|
match *self_ty.kind() {
|
||||||
|
ty::Adt(def, _) => {
|
||||||
|
self.check_def_id(item, self_ty, def.did());
|
||||||
|
}
|
||||||
|
ty::Foreign(did) => {
|
||||||
|
self.check_def_id(item, self_ty, did);
|
||||||
|
}
|
||||||
|
ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
|
||||||
|
self.check_def_id(item, self_ty, data.principal_def_id().unwrap());
|
||||||
|
}
|
||||||
|
ty::Dynamic(..) => {
|
||||||
|
struct_span_err!(
|
||||||
|
self.tcx.sess,
|
||||||
|
ty.span,
|
||||||
|
E0785,
|
||||||
|
"cannot define inherent `impl` for a dyn auto trait"
|
||||||
|
)
|
||||||
|
.span_label(ty.span, "impl requires at least one non-auto trait")
|
||||||
|
.note("define and implement a new trait or type instead")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
ty::Bool
|
||||||
|
| ty::Char
|
||||||
|
| ty::Int(_)
|
||||||
|
| ty::Uint(_)
|
||||||
|
| ty::Float(_)
|
||||||
|
| ty::Str
|
||||||
|
| ty::Array(..)
|
||||||
|
| ty::Slice(_)
|
||||||
|
| ty::RawPtr(_)
|
||||||
|
| ty::Ref(..)
|
||||||
|
| ty::Never
|
||||||
|
| ty::Tuple(..) => self.check_primitive_impl(item.def_id, self_ty, items, ty.span),
|
||||||
|
ty::FnPtr(_) | ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
|
||||||
|
let mut err = struct_span_err!(
|
||||||
|
self.tcx.sess,
|
||||||
|
ty.span,
|
||||||
|
E0118,
|
||||||
|
"no nominal type found for inherent implementation"
|
||||||
|
);
|
||||||
|
|
||||||
|
err.span_label(ty.span, "impl requires a nominal type")
|
||||||
|
.note("either implement a trait on it or create a newtype to wrap it instead");
|
||||||
|
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
ty::FnDef(..)
|
||||||
|
| ty::Closure(..)
|
||||||
|
| ty::Generator(..)
|
||||||
|
| ty::GeneratorWitness(..)
|
||||||
|
| ty::Bound(..)
|
||||||
|
| ty::Placeholder(_)
|
||||||
|
| ty::Infer(_) => {
|
||||||
|
bug!("unexpected impl self type of impl: {:?} {:?}", item.def_id, self_ty);
|
||||||
|
}
|
||||||
|
ty::Error(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,14 @@ pub fn test_inferred_outlives(tcx: TyCtxt<'_>) {
|
||||||
// attribute and report an error with various results if found.
|
// attribute and report an error with various results if found.
|
||||||
if tcx.has_attr(id.def_id.to_def_id(), sym::rustc_outlives) {
|
if tcx.has_attr(id.def_id.to_def_id(), sym::rustc_outlives) {
|
||||||
let inferred_outlives_of = tcx.inferred_outlives_of(id.def_id);
|
let inferred_outlives_of = tcx.inferred_outlives_of(id.def_id);
|
||||||
struct_span_err!(tcx.sess, tcx.hir().span(id.hir_id()), E0640, "{:?}", inferred_outlives_of).emit();
|
struct_span_err!(
|
||||||
|
tcx.sess,
|
||||||
|
tcx.hir().span(id.hir_id()),
|
||||||
|
E0640,
|
||||||
|
"{:?}",
|
||||||
|
inferred_outlives_of
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ mod x {
|
||||||
mod y {
|
mod y {
|
||||||
use {Foo, Bar};
|
use {Foo, Bar};
|
||||||
|
|
||||||
#[rustc_then_this_would_need(typeck)] //~ ERROR no path
|
#[rustc_then_this_would_need(typeck)] //~ ERROR OK
|
||||||
pub fn call_bar() {
|
pub fn call_bar() {
|
||||||
char::bar('a');
|
char::bar('a');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: no path from `x::<impl Foo for char>` to `typeck`
|
error: OK
|
||||||
--> $DIR/dep-graph-trait-impl-two-traits.rs:32:5
|
--> $DIR/dep-graph-trait-impl-two-traits.rs:32:5
|
||||||
|
|
|
|
||||||
LL | #[rustc_then_this_would_need(typeck)]
|
LL | #[rustc_then_this_would_need(typeck)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue