Talk about specific types and remove lifetimes from output
This commit is contained in:
parent
56aa89cdbe
commit
daeafd895d
14 changed files with 100 additions and 43 deletions
|
@ -237,7 +237,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
|
|||
}
|
||||
|
||||
pub enum OrphanCheckErr<'tcx> {
|
||||
NonLocalInputType(Vec<(Ty<'tcx>, usize)>),
|
||||
NonLocalInputType(Vec<(Ty<'tcx>, bool)>),
|
||||
UncoveredTy(Ty<'tcx>),
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ pub fn orphan_check(
|
|||
/// Note that this function is never called for types that have both type
|
||||
/// parameters and inference variables.
|
||||
fn orphan_check_trait_ref<'tcx>(
|
||||
tcx: TyCtxt<'_>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
in_crate: InCrate,
|
||||
) -> Result<(), OrphanCheckErr<'tcx>> {
|
||||
|
@ -397,14 +397,19 @@ fn orphan_check_trait_ref<'tcx>(
|
|||
.enumerate()
|
||||
{
|
||||
debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
|
||||
if ty_is_local(tcx, input_ty, in_crate) {
|
||||
let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
|
||||
if non_local_tys.is_none() {
|
||||
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
|
||||
return Ok(());
|
||||
} else if let ty::Param(_) = input_ty.kind {
|
||||
debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
|
||||
return Err(OrphanCheckErr::UncoveredTy(input_ty))
|
||||
}
|
||||
non_local_spans.push((input_ty, i));
|
||||
if let Some(non_local_tys) = non_local_tys {
|
||||
for input_ty in non_local_tys {
|
||||
non_local_spans.push((input_ty, i == 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we exit above loop, never found a local type.
|
||||
debug!("orphan_check_trait_ref: no local type");
|
||||
|
@ -416,7 +421,8 @@ fn orphan_check_trait_ref<'tcx>(
|
|||
// first. Find the first input type that either references a
|
||||
// type parameter OR some local type.
|
||||
for (i, input_ty) in trait_ref.input_types().enumerate() {
|
||||
if ty_is_local(tcx, input_ty, in_crate) {
|
||||
let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
|
||||
if non_local_tys.is_none() {
|
||||
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
|
||||
|
||||
// First local input type. Check that there are no
|
||||
|
@ -444,7 +450,11 @@ fn orphan_check_trait_ref<'tcx>(
|
|||
return Err(OrphanCheckErr::UncoveredTy(param));
|
||||
}
|
||||
|
||||
non_local_spans.push((input_ty, i));
|
||||
if let Some(non_local_tys) = non_local_tys {
|
||||
for input_ty in non_local_tys {
|
||||
non_local_spans.push((input_ty, i == 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we exit above loop, never found a local type.
|
||||
debug!("orphan_check_trait_ref: no local type");
|
||||
|
@ -452,8 +462,8 @@ fn orphan_check_trait_ref<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn uncovered_tys<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
|
||||
if ty_is_local_constructor(tcx, ty, in_crate) {
|
||||
fn uncovered_tys<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
|
||||
if ty_is_non_local_constructor(tcx, ty, in_crate).is_none() {
|
||||
vec![]
|
||||
} else if fundamental_ty(ty) {
|
||||
ty.walk_shallow()
|
||||
|
@ -471,9 +481,23 @@ fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn ty_is_local(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bool {
|
||||
ty_is_local_constructor(tcx, ty, in_crate) ||
|
||||
fundamental_ty(ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, in_crate))
|
||||
fn ty_is_non_local<'t>(tcx: TyCtxt<'t>, ty: Ty<'t>, in_crate: InCrate) -> Option<Vec<Ty<'t>>> {
|
||||
match ty_is_non_local_constructor(tcx, ty, in_crate) {
|
||||
Some(ty) => if !fundamental_ty(ty) {
|
||||
Some(vec![ty])
|
||||
} else {
|
||||
let tys: Vec<_> = ty.walk_shallow()
|
||||
.filter_map(|t| ty_is_non_local(tcx, t, in_crate))
|
||||
.flat_map(|i| i)
|
||||
.collect();
|
||||
if tys.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(tys)
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn fundamental_ty(ty: Ty<'_>) -> bool {
|
||||
|
@ -493,8 +517,12 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bool {
|
||||
debug!("ty_is_local_constructor({:?})", ty);
|
||||
fn ty_is_non_local_constructor<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
in_crate: InCrate,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
debug!("ty_is_non_local_constructor({:?})", ty);
|
||||
|
||||
match ty.kind {
|
||||
ty::Bool |
|
||||
|
@ -513,18 +541,26 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
|
|||
ty::Tuple(..) |
|
||||
ty::Param(..) |
|
||||
ty::Projection(..) => {
|
||||
false
|
||||
Some(ty)
|
||||
}
|
||||
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate {
|
||||
InCrate::Local => false,
|
||||
InCrate::Local => Some(ty),
|
||||
// The inference variable might be unified with a local
|
||||
// type in that remote crate.
|
||||
InCrate::Remote => true,
|
||||
InCrate::Remote => None,
|
||||
},
|
||||
|
||||
ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
|
||||
ty::Foreign(did) => def_id_is_local(did, in_crate),
|
||||
ty::Adt(def, _) => if def_id_is_local(def.did, in_crate) {
|
||||
None
|
||||
} else {
|
||||
Some(ty)
|
||||
},
|
||||
ty::Foreign(did) => if def_id_is_local(did, in_crate) {
|
||||
None
|
||||
} else {
|
||||
Some(ty)
|
||||
},
|
||||
ty::Opaque(did, _) => {
|
||||
// Check the underlying type that this opaque
|
||||
// type resolves to.
|
||||
|
@ -532,18 +568,22 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
|
|||
// since we've already managed to successfully
|
||||
// resolve all opaque types by this point
|
||||
let real_ty = tcx.type_of(did);
|
||||
ty_is_local_constructor(tcx, real_ty, in_crate)
|
||||
ty_is_non_local_constructor(tcx, real_ty, in_crate)
|
||||
}
|
||||
|
||||
ty::Dynamic(ref tt, ..) => {
|
||||
if let Some(principal) = tt.principal() {
|
||||
def_id_is_local(principal.def_id(), in_crate)
|
||||
if def_id_is_local(principal.def_id(), in_crate) {
|
||||
None
|
||||
} else {
|
||||
Some(ty)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
Some(ty)
|
||||
}
|
||||
}
|
||||
|
||||
ty::Error => true,
|
||||
ty::Error => None,
|
||||
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Closure(..) |
|
||||
|
|
|
@ -42,11 +42,28 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
|
|||
arbitrary types"
|
||||
);
|
||||
err.span_label(sp, "impl doesn't use only types from inside the current crate");
|
||||
for (ty, i) in &tys {
|
||||
let msg = format!("`{}` is not defined in the current crate", ty);
|
||||
if *i == 0 {
|
||||
for (ty, is_target_ty) in &tys {
|
||||
// FIXME: We want to remove the type arguments from the displayed type.
|
||||
// The reverse of `resolve_vars_if_possible`.
|
||||
let mut ty = *ty;
|
||||
self.tcx.infer_ctxt().enter(|infcx| {
|
||||
// Remove the lifetimes unnecessary for this error.
|
||||
ty = infcx.freshen(ty);
|
||||
});
|
||||
let msg = format!(
|
||||
"`{}` is not defined in the current crate{}",
|
||||
ty,
|
||||
match &ty.kind {
|
||||
ty::Slice(_) => " because slices are always considered foreign",
|
||||
ty::Array(..) => " because arrays are always considered foreign",
|
||||
_ => "",
|
||||
},
|
||||
);
|
||||
if *is_target_ty {
|
||||
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
||||
err.span_label(impl_ty.span, &msg);
|
||||
} else {
|
||||
// Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
|
||||
err.span_label(tr.path.span, &msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Misc for dyn Fundamental<Local> {}
|
||||
| ^^^^^^^^^^^^^^----------------------
|
||||
| | |
|
||||
| | `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current crate
|
||||
| | `dyn coherence_fundamental_trait_lib::Fundamental<Local>` is not defined in the current crate
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Misc for dyn Fundamental<Local> {}
|
||||
| ^^^^^^^^^^^^^^----------------------
|
||||
| | |
|
||||
| | `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current crate
|
||||
| | `dyn coherence_fundamental_trait_lib::Fundamental<Local>` is not defined in the current crate
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl !Send for dyn Marker2 {}
|
||||
| ^^^^^^^^^^^^^^^-----------
|
||||
| | |
|
||||
| | `(dyn Marker2 + 'static)` is not defined in the current crate
|
||||
| | `dyn Marker2` is not defined in the current crate
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | unsafe impl Send for dyn Marker2 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^-----------
|
||||
| | |
|
||||
| | `(dyn Marker2 + 'static)` is not defined in the current crate
|
||||
| | `dyn Marker2` is not defined in the current crate
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -73,7 +73,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Copy for [MyType] {}
|
||||
| ^^^^^^^^^^^^^^--------
|
||||
| | |
|
||||
| | `[MyType]` is not defined in the current crate
|
||||
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
@ -84,7 +84,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Copy for &'static [NotSync] {}
|
||||
| ^^^^^^^^^^^^^^------------------
|
||||
| | |
|
||||
| | `&'static [NotSync]` is not defined in the current crate
|
||||
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -73,7 +73,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Copy for [MyType] {}
|
||||
| ^^^^^^^^^^^^^^--------
|
||||
| | |
|
||||
| | `[MyType]` is not defined in the current crate
|
||||
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
@ -84,7 +84,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Copy for &'static [NotSync] {}
|
||||
| ^^^^^^^^^^^^^^------------------
|
||||
| | |
|
||||
| | `[NotSync]` is not defined in the current crate
|
||||
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -21,7 +21,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | unsafe impl Send for [MyType] {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^--------
|
||||
| | |
|
||||
| | `[MyType]` is not defined in the current crate
|
||||
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
@ -32,7 +32,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | unsafe impl Send for &'static [NotSync] {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^------------------
|
||||
| | |
|
||||
| | `&'static [NotSync]` is not defined in the current crate
|
||||
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -21,7 +21,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | unsafe impl Send for [MyType] {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^--------
|
||||
| | |
|
||||
| | `[MyType]` is not defined in the current crate
|
||||
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
@ -32,7 +32,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | unsafe impl Send for &'static [NotSync] {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^------------------
|
||||
| | |
|
||||
| | `[NotSync]` is not defined in the current crate
|
||||
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Sized for [MyType] {}
|
||||
| ^^^^^^^^^^^^^^^--------
|
||||
| | |
|
||||
| | `[MyType]` is not defined in the current crate
|
||||
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
@ -62,7 +62,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Sized for &'static [NotSync] {}
|
||||
| ^^^^^^^^^^^^^^^------------------
|
||||
| | |
|
||||
| | `&'static [NotSync]` is not defined in the current crate
|
||||
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Sized for [MyType] {}
|
||||
| ^^^^^^^^^^^^^^^--------
|
||||
| | |
|
||||
| | `[MyType]` is not defined in the current crate
|
||||
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
@ -62,7 +62,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Sized for &'static [NotSync] {}
|
||||
| ^^^^^^^^^^^^^^^------------------
|
||||
| | |
|
||||
| | `[NotSync]` is not defined in the current crate
|
||||
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -10,7 +10,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl<'a> Drop for &'a mut isize {
|
||||
| ^^^^^^^^^^^^^^^^^^-------------
|
||||
| | |
|
||||
| | `&'a mut isize` is not defined in the current crate
|
||||
| | `isize` is not defined in the current crate
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
|
@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
|||
LL | impl Copy for Foo { }
|
||||
| ^^^^^^^^^^^^^^---
|
||||
| | |
|
||||
| | `[u8; _]` is not defined in the current crate
|
||||
| | `[u8; _]` is not defined in the current crate because arrays are always considered foreign
|
||||
| impl doesn't use only types from inside the current crate
|
||||
|
|
||||
= note: define and implement a trait or new type instead
|
||||
|
|
Loading…
Add table
Reference in a new issue