Skip to content

Commit e051890

Browse files
authored
Unrolled build for #142415
Rollup merge of #142415 - xizheyin:141679, r=estebank Add note when inherent impl for a alias type defined outside of the crate Fixes #141679 r? compiler
2 parents 605f49b + ed90b35 commit e051890

8 files changed

Lines changed: 72 additions & 9 deletions

File tree

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,22 @@ impl<'tcx> InherentCollect<'tcx> {
110110
Ok(())
111111
} else {
112112
let impl_span = self.tcx.def_span(impl_def_id);
113-
Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideNew { span: impl_span }))
113+
let mut err = errors::InherentTyOutsideNew { span: impl_span, note: None };
114+
115+
if let hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)) =
116+
self.tcx.hir_node_by_def_id(impl_def_id).expect_item().expect_impl().self_ty.kind
117+
&& let rustc_hir::def::Res::Def(DefKind::TyAlias, def_id) = path.res
118+
{
119+
let ty_name = self.tcx.def_path_str(def_id);
120+
let alias_ty_name = self.tcx.type_of(def_id).skip_binder().to_string();
121+
err.note = Some(errors::InherentTyOutsideNewAliasNote {
122+
span: self.tcx.def_span(def_id),
123+
ty_name,
124+
alias_ty_name,
125+
});
126+
}
127+
128+
Err(self.tcx.dcx().emit_err(err))
114129
}
115130
}
116131

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,11 +1223,27 @@ pub(crate) struct InherentTyOutsideRelevant {
12231223

12241224
#[derive(Diagnostic)]
12251225
#[diag("cannot define inherent `impl` for a type outside of the crate where the type is defined", code = E0116)]
1226-
#[note("define and implement a trait or new type instead")]
1226+
#[help(
1227+
"consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it"
1228+
)]
1229+
#[note(
1230+
"for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>"
1231+
)]
12271232
pub(crate) struct InherentTyOutsideNew {
12281233
#[primary_span]
12291234
#[label("impl for type defined outside of crate")]
12301235
pub span: Span,
1236+
#[subdiagnostic]
1237+
pub note: Option<InherentTyOutsideNewAliasNote>,
1238+
}
1239+
1240+
#[derive(Subdiagnostic)]
1241+
#[note("`{$ty_name}` does not define a new type, only an alias of `{$alias_ty_name}` defined here")]
1242+
pub(crate) struct InherentTyOutsideNewAliasNote {
1243+
#[primary_span]
1244+
pub span: Span,
1245+
pub ty_name: String,
1246+
pub alias_ty_name: String,
12311247
}
12321248

12331249
#[derive(Diagnostic)]

tests/ui/error-codes/E0116.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
44
LL | impl Vec<u8> {}
55
| ^^^^^^^^^^^^ impl for type defined outside of crate
66
|
7-
= note: define and implement a trait or new type instead
7+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
8+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
89

910
error: aborting due to 1 previous error
1011

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use std::rc::Rc;
2+
pub struct Foo;
3+
4+
pub type Function = Rc<Foo>;
5+
6+
impl Function {}
7+
//~^ ERROR cannot define inherent `impl` for a type outside of the crate where the type is defined [E0116]
8+
fn main(){}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
2+
--> $DIR/insufficient-suggestion-issue-141679.rs:6:1
3+
|
4+
LL | impl Function {}
5+
| ^^^^^^^^^^^^^ impl for type defined outside of crate
6+
|
7+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
8+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
9+
note: `Function` does not define a new type, only an alias of `Rc<Foo>` defined here
10+
--> $DIR/insufficient-suggestion-issue-141679.rs:4:1
11+
|
12+
LL | pub type Function = Rc<Foo>;
13+
| ^^^^^^^^^^^^^^^^^
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0116`.

tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,35 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
44
LL | impl extern_crate::StructWithAttr {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
66
|
7-
= note: define and implement a trait or new type instead
7+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
8+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
89

910
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
1011
--> $DIR/no-attr-empty-impl.rs:7:1
1112
|
1213
LL | impl extern_crate::StructNoAttr {}
1314
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
1415
|
15-
= note: define and implement a trait or new type instead
16+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
17+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
1618

1719
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
1820
--> $DIR/no-attr-empty-impl.rs:10:1
1921
|
2022
LL | impl extern_crate::EnumWithAttr {}
2123
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
2224
|
23-
= note: define and implement a trait or new type instead
25+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
26+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
2427

2528
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
2629
--> $DIR/no-attr-empty-impl.rs:13:1
2730
|
2831
LL | impl extern_crate::EnumNoAttr {}
2932
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
3033
|
31-
= note: define and implement a trait or new type instead
34+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
35+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
3236

3337
error[E0390]: cannot define inherent `impl` for primitive types
3438
--> $DIR/no-attr-empty-impl.rs:16:1

tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
44
LL | impl Vec<usize> {}
55
| ^^^^^^^^^^^^^^^ impl for type defined outside of crate
66
|
7-
= note: define and implement a trait or new type instead
7+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
8+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
89

910
error: aborting due to 1 previous error
1011

tests/ui/traits/trait-or-new-type-instead.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
44
LL | impl<T> Option<T> {
55
| ^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
66
|
7-
= note: define and implement a trait or new type instead
7+
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
8+
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
89

910
error: aborting due to 1 previous error
1011

0 commit comments

Comments
 (0)