Skip to content

Commit daeafd8

Browse files
committed
Talk about specific types and remove lifetimes from output
1 parent 56aa89c commit daeafd8

14 files changed

+100
-43
lines changed

src/librustc/traits/coherence.rs

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
237237
}
238238

239239
pub enum OrphanCheckErr<'tcx> {
240-
NonLocalInputType(Vec<(Ty<'tcx>, usize)>),
240+
NonLocalInputType(Vec<(Ty<'tcx>, bool)>),
241241
UncoveredTy(Ty<'tcx>),
242242
}
243243

@@ -355,7 +355,7 @@ pub fn orphan_check(
355355
/// Note that this function is never called for types that have both type
356356
/// parameters and inference variables.
357357
fn orphan_check_trait_ref<'tcx>(
358-
tcx: TyCtxt<'_>,
358+
tcx: TyCtxt<'tcx>,
359359
trait_ref: ty::TraitRef<'tcx>,
360360
in_crate: InCrate,
361361
) -> Result<(), OrphanCheckErr<'tcx>> {
@@ -397,14 +397,19 @@ fn orphan_check_trait_ref<'tcx>(
397397
.enumerate()
398398
{
399399
debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
400-
if ty_is_local(tcx, input_ty, in_crate) {
400+
let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
401+
if non_local_tys.is_none() {
401402
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
402403
return Ok(());
403404
} else if let ty::Param(_) = input_ty.kind {
404405
debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
405406
return Err(OrphanCheckErr::UncoveredTy(input_ty))
406407
}
407-
non_local_spans.push((input_ty, i));
408+
if let Some(non_local_tys) = non_local_tys {
409+
for input_ty in non_local_tys {
410+
non_local_spans.push((input_ty, i == 0));
411+
}
412+
}
408413
}
409414
// If we exit above loop, never found a local type.
410415
debug!("orphan_check_trait_ref: no local type");
@@ -416,7 +421,8 @@ fn orphan_check_trait_ref<'tcx>(
416421
// first. Find the first input type that either references a
417422
// type parameter OR some local type.
418423
for (i, input_ty) in trait_ref.input_types().enumerate() {
419-
if ty_is_local(tcx, input_ty, in_crate) {
424+
let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
425+
if non_local_tys.is_none() {
420426
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
421427

422428
// First local input type. Check that there are no
@@ -444,16 +450,20 @@ fn orphan_check_trait_ref<'tcx>(
444450
return Err(OrphanCheckErr::UncoveredTy(param));
445451
}
446452

447-
non_local_spans.push((input_ty, i));
453+
if let Some(non_local_tys) = non_local_tys {
454+
for input_ty in non_local_tys {
455+
non_local_spans.push((input_ty, i == 0));
456+
}
457+
}
448458
}
449459
// If we exit above loop, never found a local type.
450460
debug!("orphan_check_trait_ref: no local type");
451461
Err(OrphanCheckErr::NonLocalInputType(non_local_spans))
452462
}
453463
}
454464

455-
fn uncovered_tys<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
456-
if ty_is_local_constructor(tcx, ty, in_crate) {
465+
fn uncovered_tys<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
466+
if ty_is_non_local_constructor(tcx, ty, in_crate).is_none() {
457467
vec![]
458468
} else if fundamental_ty(ty) {
459469
ty.walk_shallow()
@@ -471,9 +481,23 @@ fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
471481
}
472482
}
473483

474-
fn ty_is_local(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bool {
475-
ty_is_local_constructor(tcx, ty, in_crate) ||
476-
fundamental_ty(ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, in_crate))
484+
fn ty_is_non_local<'t>(tcx: TyCtxt<'t>, ty: Ty<'t>, in_crate: InCrate) -> Option<Vec<Ty<'t>>> {
485+
match ty_is_non_local_constructor(tcx, ty, in_crate) {
486+
Some(ty) => if !fundamental_ty(ty) {
487+
Some(vec![ty])
488+
} else {
489+
let tys: Vec<_> = ty.walk_shallow()
490+
.filter_map(|t| ty_is_non_local(tcx, t, in_crate))
491+
.flat_map(|i| i)
492+
.collect();
493+
if tys.is_empty() {
494+
None
495+
} else {
496+
Some(tys)
497+
}
498+
},
499+
None => None,
500+
}
477501
}
478502

479503
fn fundamental_ty(ty: Ty<'_>) -> bool {
@@ -493,8 +517,12 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
493517
}
494518
}
495519

496-
fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bool {
497-
debug!("ty_is_local_constructor({:?})", ty);
520+
fn ty_is_non_local_constructor<'tcx>(
521+
tcx: TyCtxt<'tcx>,
522+
ty: Ty<'tcx>,
523+
in_crate: InCrate,
524+
) -> Option<Ty<'tcx>> {
525+
debug!("ty_is_non_local_constructor({:?})", ty);
498526

499527
match ty.kind {
500528
ty::Bool |
@@ -513,37 +541,49 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
513541
ty::Tuple(..) |
514542
ty::Param(..) |
515543
ty::Projection(..) => {
516-
false
544+
Some(ty)
517545
}
518546

519547
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate {
520-
InCrate::Local => false,
548+
InCrate::Local => Some(ty),
521549
// The inference variable might be unified with a local
522550
// type in that remote crate.
523-
InCrate::Remote => true,
551+
InCrate::Remote => None,
524552
},
525553

526-
ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
527-
ty::Foreign(did) => def_id_is_local(did, in_crate),
554+
ty::Adt(def, _) => if def_id_is_local(def.did, in_crate) {
555+
None
556+
} else {
557+
Some(ty)
558+
},
559+
ty::Foreign(did) => if def_id_is_local(did, in_crate) {
560+
None
561+
} else {
562+
Some(ty)
563+
},
528564
ty::Opaque(did, _) => {
529565
// Check the underlying type that this opaque
530566
// type resolves to.
531567
// This recursion will eventually terminate,
532568
// since we've already managed to successfully
533569
// resolve all opaque types by this point
534570
let real_ty = tcx.type_of(did);
535-
ty_is_local_constructor(tcx, real_ty, in_crate)
571+
ty_is_non_local_constructor(tcx, real_ty, in_crate)
536572
}
537573

538574
ty::Dynamic(ref tt, ..) => {
539575
if let Some(principal) = tt.principal() {
540-
def_id_is_local(principal.def_id(), in_crate)
576+
if def_id_is_local(principal.def_id(), in_crate) {
577+
None
578+
} else {
579+
Some(ty)
580+
}
541581
} else {
542-
false
582+
Some(ty)
543583
}
544584
}
545585

546-
ty::Error => true,
586+
ty::Error => None,
547587

548588
ty::UnnormalizedProjection(..) |
549589
ty::Closure(..) |

src/librustc_typeck/coherence/orphan.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,28 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
4242
arbitrary types"
4343
);
4444
err.span_label(sp, "impl doesn't use only types from inside the current crate");
45-
for (ty, i) in &tys {
46-
let msg = format!("`{}` is not defined in the current crate", ty);
47-
if *i == 0 {
45+
for (ty, is_target_ty) in &tys {
46+
// FIXME: We want to remove the type arguments from the displayed type.
47+
// The reverse of `resolve_vars_if_possible`.
48+
let mut ty = *ty;
49+
self.tcx.infer_ctxt().enter(|infcx| {
50+
// Remove the lifetimes unnecessary for this error.
51+
ty = infcx.freshen(ty);
52+
});
53+
let msg = format!(
54+
"`{}` is not defined in the current crate{}",
55+
ty,
56+
match &ty.kind {
57+
ty::Slice(_) => " because slices are always considered foreign",
58+
ty::Array(..) => " because arrays are always considered foreign",
59+
_ => "",
60+
},
61+
);
62+
if *is_target_ty {
63+
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
4864
err.span_label(impl_ty.span, &msg);
4965
} else {
66+
// Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
5067
err.span_label(tr.path.span, &msg);
5168
}
5269
}

src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
44
LL | impl Misc for dyn Fundamental<Local> {}
55
| ^^^^^^^^^^^^^^----------------------
66
| | |
7-
| | `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current crate
7+
| | `dyn coherence_fundamental_trait_lib::Fundamental<Local>` is not defined in the current crate
88
| impl doesn't use only types from inside the current crate
99
|
1010
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
44
LL | impl Misc for dyn Fundamental<Local> {}
55
| ^^^^^^^^^^^^^^----------------------
66
| | |
7-
| | `(dyn coherence_fundamental_trait_lib::Fundamental<Local> + 'static)` is not defined in the current crate
7+
| | `dyn coherence_fundamental_trait_lib::Fundamental<Local>` is not defined in the current crate
88
| impl doesn't use only types from inside the current crate
99
|
1010
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1616
LL | impl !Send for dyn Marker2 {}
1717
| ^^^^^^^^^^^^^^^-----------
1818
| | |
19-
| | `(dyn Marker2 + 'static)` is not defined in the current crate
19+
| | `dyn Marker2` is not defined in the current crate
2020
| impl doesn't use only types from inside the current crate
2121
|
2222
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1616
LL | unsafe impl Send for dyn Marker2 {}
1717
| ^^^^^^^^^^^^^^^^^^^^^-----------
1818
| | |
19-
| | `(dyn Marker2 + 'static)` is not defined in the current crate
19+
| | `dyn Marker2` is not defined in the current crate
2020
| impl doesn't use only types from inside the current crate
2121
|
2222
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impls-copy.old.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
7373
LL | impl Copy for [MyType] {}
7474
| ^^^^^^^^^^^^^^--------
7575
| | |
76-
| | `[MyType]` is not defined in the current crate
76+
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
7777
| impl doesn't use only types from inside the current crate
7878
|
7979
= 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
8484
LL | impl Copy for &'static [NotSync] {}
8585
| ^^^^^^^^^^^^^^------------------
8686
| | |
87-
| | `&'static [NotSync]` is not defined in the current crate
87+
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
8888
| impl doesn't use only types from inside the current crate
8989
|
9090
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impls-copy.re.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
7373
LL | impl Copy for [MyType] {}
7474
| ^^^^^^^^^^^^^^--------
7575
| | |
76-
| | `[MyType]` is not defined in the current crate
76+
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
7777
| impl doesn't use only types from inside the current crate
7878
|
7979
= 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
8484
LL | impl Copy for &'static [NotSync] {}
8585
| ^^^^^^^^^^^^^^------------------
8686
| | |
87-
| | `[NotSync]` is not defined in the current crate
87+
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
8888
| impl doesn't use only types from inside the current crate
8989
|
9090
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impls-send.old.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
2121
LL | unsafe impl Send for [MyType] {}
2222
| ^^^^^^^^^^^^^^^^^^^^^--------
2323
| | |
24-
| | `[MyType]` is not defined in the current crate
24+
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
2525
| impl doesn't use only types from inside the current crate
2626
|
2727
= 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
3232
LL | unsafe impl Send for &'static [NotSync] {}
3333
| ^^^^^^^^^^^^^^^^^^^^^------------------
3434
| | |
35-
| | `&'static [NotSync]` is not defined in the current crate
35+
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
3636
| impl doesn't use only types from inside the current crate
3737
|
3838
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impls-send.re.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
2121
LL | unsafe impl Send for [MyType] {}
2222
| ^^^^^^^^^^^^^^^^^^^^^--------
2323
| | |
24-
| | `[MyType]` is not defined in the current crate
24+
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
2525
| impl doesn't use only types from inside the current crate
2626
|
2727
= 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
3232
LL | unsafe impl Send for &'static [NotSync] {}
3333
| ^^^^^^^^^^^^^^^^^^^^^------------------
3434
| | |
35-
| | `[NotSync]` is not defined in the current crate
35+
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
3636
| impl doesn't use only types from inside the current crate
3737
|
3838
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impls-sized.old.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
5151
LL | impl Sized for [MyType] {}
5252
| ^^^^^^^^^^^^^^^--------
5353
| | |
54-
| | `[MyType]` is not defined in the current crate
54+
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
5555
| impl doesn't use only types from inside the current crate
5656
|
5757
= 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
6262
LL | impl Sized for &'static [NotSync] {}
6363
| ^^^^^^^^^^^^^^^------------------
6464
| | |
65-
| | `&'static [NotSync]` is not defined in the current crate
65+
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
6666
| impl doesn't use only types from inside the current crate
6767
|
6868
= note: define and implement a trait or new type instead

src/test/ui/coherence/coherence-impls-sized.re.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
5151
LL | impl Sized for [MyType] {}
5252
| ^^^^^^^^^^^^^^^--------
5353
| | |
54-
| | `[MyType]` is not defined in the current crate
54+
| | `[MyType]` is not defined in the current crate because slices are always considered foreign
5555
| impl doesn't use only types from inside the current crate
5656
|
5757
= 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
6262
LL | impl Sized for &'static [NotSync] {}
6363
| ^^^^^^^^^^^^^^^------------------
6464
| | |
65-
| | `[NotSync]` is not defined in the current crate
65+
| | `[NotSync]` is not defined in the current crate because slices are always considered foreign
6666
| impl doesn't use only types from inside the current crate
6767
|
6868
= note: define and implement a trait or new type instead

src/test/ui/dropck/drop-on-non-struct.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1010
LL | impl<'a> Drop for &'a mut isize {
1111
| ^^^^^^^^^^^^^^^^^^-------------
1212
| | |
13-
| | `&'a mut isize` is not defined in the current crate
13+
| | `isize` is not defined in the current crate
1414
| impl doesn't use only types from inside the current crate
1515
|
1616
= note: define and implement a trait or new type instead

src/test/ui/error-codes/E0206.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
1616
LL | impl Copy for Foo { }
1717
| ^^^^^^^^^^^^^^---
1818
| | |
19-
| | `[u8; _]` is not defined in the current crate
19+
| | `[u8; _]` is not defined in the current crate because arrays are always considered foreign
2020
| impl doesn't use only types from inside the current crate
2121
|
2222
= note: define and implement a trait or new type instead

0 commit comments

Comments
 (0)