1
Fork 0

Normalize trait ref before orphan check & consider ty params in alias types to be uncovered

This commit is contained in:
León Orell Valerian Liehr 2023-10-15 13:40:17 +02:00
parent c2f2db79ca
commit 951e902562
No known key found for this signature in database
GPG key ID: D17A07215F68E713
33 changed files with 1055 additions and 145 deletions

View file

@ -101,6 +101,7 @@ declare_lint_pass! {
TYVAR_BEHIND_RAW_POINTER,
UNCONDITIONAL_PANIC,
UNCONDITIONAL_RECURSION,
UNCOVERED_PARAM_IN_PROJECTION,
UNDEFINED_NAKED_FUNCTION_ABI,
UNEXPECTED_CFGS,
UNFULFILLED_LINT_EXPECTATIONS,
@ -4741,3 +4742,68 @@ declare_lint! {
};
crate_level_only
}
declare_lint! {
/// The `uncovered_param_in_projection` lint detects a violation of one of Rust's orphan rules for
/// foreign trait implementations that concerns the use of type parameters inside trait associated
/// type paths ("projections") whose output may not be a local type that is mistakenly considered
/// to "cover" said parameters which is **unsound** and which may be rejected by a future version
/// of the compiler.
///
/// Originally reported in [#99554].
///
/// [#99554]: https://github.com/rust-lang/rust/issues/99554
///
/// ### Example
///
/// ```rust,ignore (dependent)
/// // dependency.rs
/// #![crate_type = "lib"]
///
/// pub trait Trait<T, U> {}
/// ```
///
/// ```edition2021,ignore (needs dependency)
/// // dependent.rs
/// trait Identity {
/// type Output;
/// }
///
/// impl<T> Identity for T {
/// type Output = T;
/// }
///
/// struct Local;
///
/// impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
///
/// fn main() {}
/// ```
///
/// This will produce:
///
/// ```text
/// warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
/// --> dependent.rs:11:6
/// |
/// 11 | impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
/// | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
/// |
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
/// = note: for more information, see issue #124559 <https://github.com/rust-lang/rust/issues/124559>
/// = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
/// = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
/// = note: `#[warn(uncovered_param_in_projection)]` on by default
/// ```
///
/// ### Explanation
///
/// FIXME(fmease): Write explainer.
pub UNCOVERED_PARAM_IN_PROJECTION,
Warn,
"impl contains type parameters that are not covered",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
reference: "issue #124559 <https://github.com/rust-lang/rust/issues/124559>",
};
}