1
Fork 0

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:
Ralf Jung 2018-03-10 11:43:51 +01:00
parent 81130ed4b1
commit 562b44d8c3
6 changed files with 68 additions and 33 deletions

View file

@ -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",
);
}
}

View file

@ -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,

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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"