Add note when inherent impl for a alias type defined outside of the crate

This commit is contained in:
xizheyin 2026-02-09 15:06:55 +08:00
parent 3b705eae4f
commit ed90b35669
8 changed files with 55 additions and 11 deletions

View file

@ -110,7 +110,22 @@ impl<'tcx> InherentCollect<'tcx> {
Ok(())
} else {
let impl_span = self.tcx.def_span(impl_def_id);
Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideNew { span: impl_span }))
let mut err = errors::InherentTyOutsideNew { span: impl_span, note: None };
if let hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)) =
self.tcx.hir_node_by_def_id(impl_def_id).expect_item().expect_impl().self_ty.kind
&& let rustc_hir::def::Res::Def(DefKind::TyAlias, def_id) = path.res
{
let ty_name = self.tcx.def_path_str(def_id);
let alias_ty_name = self.tcx.type_of(def_id).skip_binder().to_string();
err.note = Some(errors::InherentTyOutsideNewAliasNote {
span: self.tcx.def_span(def_id),
ty_name,
alias_ty_name,
});
}
Err(self.tcx.dcx().emit_err(err))
}
}

View file

@ -1223,11 +1223,27 @@ pub(crate) struct InherentTyOutsideRelevant {
#[derive(Diagnostic)]
#[diag("cannot define inherent `impl` for a type outside of the crate where the type is defined", code = E0116)]
#[note("define and implement a trait or new type instead")]
#[help(
"consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it"
)]
#[note(
"for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>"
)]
pub(crate) struct InherentTyOutsideNew {
#[primary_span]
#[label("impl for type defined outside of crate")]
pub span: Span,
#[subdiagnostic]
pub note: Option<InherentTyOutsideNewAliasNote>,
}
#[derive(Subdiagnostic)]
#[note("`{$ty_name}` does not define a new type, only an alias of `{$alias_ty_name}` defined here")]
pub(crate) struct InherentTyOutsideNewAliasNote {
#[primary_span]
pub span: Span,
pub ty_name: String,
pub alias_ty_name: String,
}
#[derive(Diagnostic)]

View file

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

View file

@ -5,4 +5,4 @@ pub type Function = Rc<Foo>;
impl Function {}
//~^ ERROR cannot define inherent `impl` for a type outside of the crate where the type is defined [E0116]
fn main(){}
fn main(){}

View file

@ -4,7 +4,13 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
LL | impl Function {}
| ^^^^^^^^^^^^^ impl for type defined outside of crate
|
= note: define and implement a trait or new type instead
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
note: `Function` does not define a new type, only an alias of `Rc<Foo>` defined here
--> $DIR/insufficient-suggestion-issue-141679.rs:4:1
|
LL | pub type Function = Rc<Foo>;
| ^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
LL | impl extern_crate::StructWithAttr {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
|
= note: define and implement a trait or new type instead
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
--> $DIR/no-attr-empty-impl.rs:7:1
@ -12,7 +13,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
LL | impl extern_crate::StructNoAttr {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
|
= note: define and implement a trait or new type instead
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
--> $DIR/no-attr-empty-impl.rs:10:1
@ -20,7 +22,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
LL | impl extern_crate::EnumWithAttr {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
|
= note: define and implement a trait or new type instead
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
--> $DIR/no-attr-empty-impl.rs:13:1
@ -28,7 +31,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
LL | impl extern_crate::EnumNoAttr {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate
|
= note: define and implement a trait or new type instead
= help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it
= note: for more details about the orphan rules, see <https://doc.rust-lang.org/reference/items/implementations.html?highlight=orphan#orphan-rules>
error[E0390]: cannot define inherent `impl` for primitive types
--> $DIR/no-attr-empty-impl.rs:16:1

View file

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

View file

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