Skip to content

Commit c5cb156

Browse files
committed
Auto merge of rust-lang#106358 - TroyNeubauer:improve-foreign-orphan-error, r=estebank
Implement fix for rust-lang#67535 Implements a fix for rust-lang#67535 r? `@estebank`
2 parents ee11bfd + 4cb9030 commit c5cb156

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

compiler/rustc_hir_analysis/src/coherence/orphan.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn do_orphan_check_impl<'tcx>(
5353
sp,
5454
item.span,
5555
tr.path.span,
56-
trait_ref.self_ty(),
56+
trait_ref,
5757
impl_.self_ty.span,
5858
&impl_.generics,
5959
err,
@@ -154,11 +154,12 @@ fn emit_orphan_check_error<'tcx>(
154154
sp: Span,
155155
full_impl_span: Span,
156156
trait_span: Span,
157-
self_ty: Ty<'tcx>,
157+
trait_ref: ty::TraitRef<'tcx>,
158158
self_ty_span: Span,
159159
generics: &hir::Generics<'tcx>,
160160
err: traits::OrphanCheckErr<'tcx>,
161161
) -> Result<!, ErrorGuaranteed> {
162+
let self_ty = trait_ref.self_ty();
162163
Err(match err {
163164
traits::OrphanCheckErr::NonLocalInputType(tys) => {
164165
let msg = match self_ty.kind() {
@@ -187,7 +188,14 @@ fn emit_orphan_check_error<'tcx>(
187188
let msg = |ty: &str, postfix: &str| {
188189
format!("{ty} is not defined in the current crate{postfix}")
189190
};
190-
let this = |name: &str| msg("this", &format!(" because {name} are always foreign"));
191+
192+
let this = |name: &str| {
193+
if !trait_ref.def_id.is_local() && !is_target_ty {
194+
msg("this", &format!(" because this is a foreign trait"))
195+
} else {
196+
msg("this", &format!(" because {name} are always foreign"))
197+
}
198+
};
191199
let msg = match &ty.kind() {
192200
ty::Slice(_) => this("slices"),
193201
ty::Array(..) => this("arrays"),

src/test/ui/issues/issue-67535.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fn main() {}
2+
3+
impl std::ops::AddAssign for () {
4+
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
5+
fn add_assign(&self, other: ()) -> () {
6+
()
7+
}
8+
}
9+
10+
impl std::ops::AddAssign for [(); 1] {
11+
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
12+
fn add_assign(&self, other: [(); 1]) -> [(); 1] {
13+
[()]
14+
}
15+
}
16+
17+
impl std::ops::AddAssign for &[u8] {
18+
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
19+
fn add_assign(&self, other: &[u8]) -> &[u8] {
20+
self
21+
}
22+
}

src/test/ui/issues/issue-67535.stderr

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
2+
--> $DIR/issue-67535.rs:3:1
3+
|
4+
LL | impl std::ops::AddAssign for () {
5+
| ^^^^^-------------------^^^^^--
6+
| | | |
7+
| | | this is not defined in the current crate because tuples are always foreign
8+
| | this is not defined in the current crate because this is a foreign trait
9+
| impl doesn't use only types from inside the current crate
10+
|
11+
= note: define and implement a trait or new type instead
12+
13+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
14+
--> $DIR/issue-67535.rs:10:1
15+
|
16+
LL | impl std::ops::AddAssign for [(); 1] {
17+
| ^^^^^-------------------^^^^^-------
18+
| | | |
19+
| | | this is not defined in the current crate because arrays are always foreign
20+
| | this is not defined in the current crate because this is a foreign trait
21+
| impl doesn't use only types from inside the current crate
22+
|
23+
= note: define and implement a trait or new type instead
24+
25+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
26+
--> $DIR/issue-67535.rs:17:1
27+
|
28+
LL | impl std::ops::AddAssign for &[u8] {
29+
| ^^^^^-------------------^^^^^-----
30+
| | | |
31+
| | | this is not defined in the current crate because slices are always foreign
32+
| | this is not defined in the current crate because this is a foreign trait
33+
| impl doesn't use only types from inside the current crate
34+
|
35+
= note: define and implement a trait or new type instead
36+
37+
error: aborting due to 3 previous errors
38+
39+
For more information about this error, try `rustc --explain E0117`.

src/tools/tidy/src/ui_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::path::Path;
1010
const ENTRY_LIMIT: usize = 1000;
1111
// FIXME: The following limits should be reduced eventually.
1212
const ROOT_ENTRY_LIMIT: usize = 939;
13-
const ISSUES_ENTRY_LIMIT: usize = 2020;
13+
const ISSUES_ENTRY_LIMIT: usize = 2050;
1414

1515
fn check_entries(path: &Path, bad: &mut bool) {
1616
for dir in Walk::new(&path.join("test/ui")) {

0 commit comments

Comments
 (0)