Rename ignored_generic_bounds -> type_alias_bounds
First of all, the lint is specific for type aliases. Second, it turns out the bounds are not entirely ignored but actually used when accessing associated types. So change the wording of the lint, and adapt its name to reality. The lint has never been on stable or beta, so renaming is safe.
This commit is contained in:
parent
81130ed4b1
commit
562b44d8c3
6 changed files with 68 additions and 33 deletions
|
@ -1316,24 +1316,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
|
|||
}
|
||||
}
|
||||
|
||||
/// Lint for trait and lifetime bounds that are (accidentally) accepted by the parser, but
|
||||
/// ignored later.
|
||||
/// Lint for trait and lifetime bounds in type aliases being mostly ignored:
|
||||
/// They are relevant when using associated types, but otherwise neither checked
|
||||
/// at definition site nor enforced at use site.
|
||||
|
||||
pub struct IgnoredGenericBounds;
|
||||
pub struct TypeAliasBounds;
|
||||
|
||||
declare_lint! {
|
||||
IGNORED_GENERIC_BOUNDS,
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
Warn,
|
||||
"these generic bounds are ignored"
|
||||
"bounds in type aliases are not enforced"
|
||||
}
|
||||
|
||||
impl LintPass for IgnoredGenericBounds {
|
||||
impl LintPass for TypeAliasBounds {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(IGNORED_GENERIC_BOUNDS)
|
||||
lint_array!(TYPE_ALIAS_BOUNDS)
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for IgnoredGenericBounds {
|
||||
impl EarlyLintPass for TypeAliasBounds {
|
||||
fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
|
||||
let type_alias_generics = match item.node {
|
||||
ast::ItemKind::Ty(_, ref generics) => generics,
|
||||
|
@ -1343,8 +1344,8 @@ impl EarlyLintPass for IgnoredGenericBounds {
|
|||
if !type_alias_generics.where_clause.predicates.is_empty() {
|
||||
let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter()
|
||||
.map(|pred| pred.span()).collect();
|
||||
cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
|
||||
"where clauses are ignored in type aliases");
|
||||
cx.span_lint(TYPE_ALIAS_BOUNDS, spans,
|
||||
"where clauses are not enforced in type aliases");
|
||||
}
|
||||
// The parameters must not have bounds
|
||||
for param in type_alias_generics.params.iter() {
|
||||
|
@ -1354,9 +1355,9 @@ impl EarlyLintPass for IgnoredGenericBounds {
|
|||
};
|
||||
if !spans.is_empty() {
|
||||
cx.span_lint(
|
||||
IGNORED_GENERIC_BOUNDS,
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
spans,
|
||||
"bounds on generic parameters are ignored in type aliases",
|
||||
"bounds on generic parameters are not enforced in type aliases",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
UnusedImportBraces,
|
||||
AnonymousParameters,
|
||||
UnusedDocComment,
|
||||
IgnoredGenericBounds,
|
||||
TypeAliasBounds,
|
||||
);
|
||||
|
||||
add_early_builtin_with_new!(sess,
|
||||
|
|
|
@ -10,5 +10,5 @@
|
|||
|
||||
trait Tr {}
|
||||
type Huh<T> where T: Tr = isize; //~ ERROR type parameter `T` is unused
|
||||
//~| WARNING where clauses are ignored in type aliases
|
||||
//~| WARNING where clauses are not enforced in type aliases
|
||||
fn main() {}
|
||||
|
|
|
@ -58,7 +58,7 @@ mod traits {
|
|||
pub trait PubTr {}
|
||||
|
||||
pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
|
||||
//~^ WARNING bounds on generic parameters are ignored
|
||||
//~^ WARNING bounds on generic parameters are not enforced in type aliases
|
||||
//~| WARNING hard error
|
||||
pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||
//~^ WARNING hard error
|
||||
|
@ -85,7 +85,7 @@ mod traits_where {
|
|||
pub type Alias<T> where T: PrivTr = T;
|
||||
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||
//~| WARNING hard error
|
||||
//~| WARNING where clauses are ignored in type aliases
|
||||
//~| WARNING where clauses are not enforced in type aliases
|
||||
pub trait Tr2<T> where T: PrivTr {}
|
||||
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||
//~| WARNING hard error
|
||||
|
|
|
@ -10,21 +10,20 @@
|
|||
|
||||
// Test ignored_generic_bounds lint warning about bounds in type aliases
|
||||
|
||||
// must-compile-successfully
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
type SVec<T: Send+Send> = Vec<T>;
|
||||
//~^ WARN bounds on generic parameters are ignored in type aliases
|
||||
//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
|
||||
type S2Vec<T> where T: Send = Vec<T>;
|
||||
//~^ WARN where clauses are ignored in type aliases
|
||||
//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
|
||||
type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>);
|
||||
//~^ WARN bounds on generic parameters are ignored in type aliases
|
||||
//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
|
||||
type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>);
|
||||
//~^ WARN bounds on generic parameters are ignored in type aliases
|
||||
//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
|
||||
type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
|
||||
//~^ WARN where clauses are ignored in type aliases
|
||||
//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
|
||||
|
||||
static STATIC : u32 = 0;
|
||||
|
||||
|
@ -48,4 +47,18 @@ fn foo<'a>(y: &'a i32) {
|
|||
x.1.push(y); // &'a i32: 'static does not hold
|
||||
}
|
||||
|
||||
// Bounds are not checked either, i.e. the definition is not necessarily well-formed
|
||||
struct Sendable<T: Send>(T);
|
||||
type MySendable<T> = Sendable<T>; // no error here!
|
||||
|
||||
// However, bounds *are* taken into account when accessing associated types
|
||||
trait Bound { type Assoc; }
|
||||
type T1<U: Bound> = U::Assoc;
|
||||
//~^ WARN bounds on generic parameters are not enforced in type aliases
|
||||
type T2<U> where U: Bound = U::Assoc;
|
||||
//~^ WARN where clauses are not enforced in type aliases
|
||||
type T3<U> = U::Assoc;
|
||||
//~^ ERROR associated type `Assoc` not found for `U`
|
||||
type T4<U> = <U as Bound>::Assoc;
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,32 +1,53 @@
|
|||
warning: bounds on generic parameters are ignored in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:18:14
|
||||
warning: bounds on generic parameters are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:17:14
|
||||
|
|
||||
LL | type SVec<T: Send+Send> = Vec<T>;
|
||||
| ^^^^ ^^^^
|
||||
|
|
||||
= note: #[warn(ignored_generic_bounds)] on by default
|
||||
= note: #[warn(type_alias_bounds)] on by default
|
||||
|
||||
warning: where clauses are ignored in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:20:21
|
||||
warning: where clauses are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:19:21
|
||||
|
|
||||
LL | type S2Vec<T> where T: Send = Vec<T>;
|
||||
| ^^^^^^^
|
||||
|
||||
warning: bounds on generic parameters are ignored in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:22:19
|
||||
warning: bounds on generic parameters are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:21:19
|
||||
|
|
||||
LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>);
|
||||
| ^^ ^^
|
||||
|
||||
warning: bounds on generic parameters are ignored in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:24:18
|
||||
warning: bounds on generic parameters are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:23:18
|
||||
|
|
||||
LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>);
|
||||
| ^^ ^^
|
||||
|
||||
warning: where clauses are ignored in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:26:25
|
||||
warning: where clauses are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:25:25
|
||||
|
|
||||
LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
|
||||
| ^^^^^ ^^^^^
|
||||
|
||||
warning: bounds on generic parameters are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:56:12
|
||||
|
|
||||
LL | type T1<U: Bound> = U::Assoc;
|
||||
| ^^^^^
|
||||
|
||||
warning: where clauses are not enforced in type aliases
|
||||
--> $DIR/type-alias-bounds.rs:58:18
|
||||
|
|
||||
LL | type T2<U> where U: Bound = U::Assoc;
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0220]: associated type `Assoc` not found for `U`
|
||||
--> $DIR/type-alias-bounds.rs:60:14
|
||||
|
|
||||
LL | type T3<U> = U::Assoc;
|
||||
| ^^^^^^^^ associated type `Assoc` not found
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
If you want more information on this error, try using "rustc --explain E0220"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue