diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c6698cbd006..bdb36ab15b6 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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", ); } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 779aa3a9037..38f7a0b6faa 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -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, diff --git a/src/test/compile-fail/issue-17994.rs b/src/test/compile-fail/issue-17994.rs index 0f30e2461cf..7c3811e2ef2 100644 --- a/src/test/compile-fail/issue-17994.rs +++ b/src/test/compile-fail/issue-17994.rs @@ -10,5 +10,5 @@ trait Tr {} type Huh 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() {} diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index cc9eed7e654..8bd9b0a901d 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,7 @@ mod traits { pub trait PubTr {} pub type Alias = 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 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 where T: PrivTr {} //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs index ed368e8f150..7ec3afd9c87 100644 --- a/src/test/ui/type-alias-bounds.rs +++ b/src/test/ui/type-alias-bounds.rs @@ -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 = Vec; -//~^ 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 where T: Send = Vec; -//~^ 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); -//~^ 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); -//~^ 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); +type MySendable = Sendable; // no error here! + +// However, bounds *are* taken into account when accessing associated types +trait Bound { type Assoc; } +type T1 = U::Assoc; +//~^ WARN bounds on generic parameters are not enforced in type aliases +type T2 where U: Bound = U::Assoc; +//~^ WARN where clauses are not enforced in type aliases +type T3 = U::Assoc; +//~^ ERROR associated type `Assoc` not found for `U` +type T4 = ::Assoc; + fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 5237f3c19ef..46aacd7321c 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -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 = Vec; | ^^^^ ^^^^ | - = 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 where T: Send = Vec; | ^^^^^^^ -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); | ^^ ^^ -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); | ^^^^^ ^^^^^ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:56:12 + | +LL | type T1 = U::Assoc; + | ^^^^^ + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:58:18 + | +LL | type T2 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::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"