diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-01-11 18:17:46 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-01-11 18:17:51 +0530 |
| commit | add20bbb6dae07fddc80bc46f53296fbf5679f27 (patch) | |
| tree | 9e3d1ac2355dd06d3fd0ca47929b3c19bec1adff /src | |
| parent | e1832779483df51b59367250850213d8e7fe159a (diff) | |
| download | rust-add20bbb6dae07fddc80bc46f53296fbf5679f27.tar.gz rust-add20bbb6dae07fddc80bc46f53296fbf5679f27.zip | |
Move error to typeck::check
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/lint/builtin.rs | 63 | ||||
| -rw-r--r-- | src/librustc/lint/context.rs | 1 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 50 | ||||
| -rw-r--r-- | src/librustc_typeck/lib.rs | 1 | ||||
| -rw-r--r-- | src/test/compile-fail/on-unimplemented.rs | 15 |
5 files changed, 50 insertions, 80 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 29d37af30fc..300b9aaf100 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -26,9 +26,6 @@ //! a `pub fn new()`. use self::MethodContext::*; - -use fmt_macros::{Parser, Piece, Position}; - use metadata::csearch; use middle::def::*; use middle::subst::Substs; @@ -1924,63 +1921,3 @@ impl LintPass for UnstableFeatures { } } } - -/// Checks usage of `#[on_unimplemented]` -#[derive(Copy)] -pub struct BadOnUnimplemented; - -declare_lint!(BAD_ON_UNIMPLEMENTED, Deny, - "Checks usage of `#[on_unimplemented]`"); - -impl LintPass for BadOnUnimplemented { - fn get_lints(&self) -> LintArray { - lint_array!(BAD_ON_UNIMPLEMENTED) - } - fn check_item(&mut self, ctx: &Context, item: &ast::Item) { - match item.node { - ast::ItemTrait(_, ref generics, _, _) => { - if let Some(ref attr) = item.attrs.iter().find(|&: a| { - a.check_name("on_unimplemented") - }) { - if let Some(ref istring) = attr.value_str() { - let mut parser = Parser::new(istring.get()); - let types = generics.ty_params.as_slice(); - for token in parser { - match token { - Piece::String(_) => (), // Normal string, no need to check it - Piece::NextArgument(a) => match a.position { - // `{Self}` is allowed - Position::ArgumentNamed(s) if s == "Self" => (), - // So is `{A}` if A is a type parameter - Position::ArgumentNamed(s) => match types.iter().find(|t| { - t.ident.as_str() == s - }) { - Some(_) => (), - None => { - ctx.span_lint(BAD_ON_UNIMPLEMENTED, attr.span, - format!("there is no type parameter \ - {} on trait {}", - s, item.ident.as_str()) - .as_slice()); - } - }, - // `{:1}` and `{}` are not to be used - Position::ArgumentIs(_) | Position::ArgumentNext => { - ctx.span_lint(BAD_ON_UNIMPLEMENTED, attr.span, - "only named substitution \ - parameters are allowed"); - } - } - } - } - } else { - ctx.span_lint(BAD_ON_UNIMPLEMENTED, attr.span, - "this attribute must have a value, \ - eg `#[on_unimplemented = \"foo\"]`") - } - } - }, - _ => () // Not a trait def, move along - } - } -} \ No newline at end of file diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index b50c505a3ac..95e1e8d44bf 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -211,7 +211,6 @@ impl LintStore { UnusedAllocation, MissingCopyImplementations, UnstableFeatures, - BadOnUnimplemented, ); add_builtin_with_new!(sess, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1d184131ded..de6c884d6d7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,6 +83,7 @@ use self::TupleArgumentsFlag::*; use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv}; use check::_match::pat_ctxt; +use fmt_macros::{Parser, Piece, Position}; use middle::{const_eval, def}; use middle::infer; use middle::lang_items::IteratorItem; @@ -113,6 +114,7 @@ use std::mem::replace; use std::rc::Rc; use std::iter::repeat; use syntax::{self, abi, attr}; +use syntax::attr::AttrMetaMethods; use syntax::ast::{self, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId}; use syntax::ast_util::{self, local_def, PostExpansionMethod}; use syntax::codemap::{self, Span}; @@ -726,7 +728,8 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { } } - ast::ItemTrait(_, _, _, ref trait_methods) => { + ast::ItemTrait(_, ref generics, _, ref trait_methods) => { + check_trait_on_unimplemented(ccx, generics, it); let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id)); for trait_method in trait_methods.iter() { match *trait_method { @@ -776,6 +779,51 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) { } } +fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + generics: &ast::Generics, + item: &ast::Item) { + if let Some(ref attr) = item.attrs.iter().find(|&: a| { + a.check_name("on_unimplemented") + }) { + if let Some(ref istring) = attr.value_str() { + let mut parser = Parser::new(istring.get()); + let types = generics.ty_params.as_slice(); + for token in parser { + match token { + Piece::String(_) => (), // Normal string, no need to check it + Piece::NextArgument(a) => match a.position { + // `{Self}` is allowed + Position::ArgumentNamed(s) if s == "Self" => (), + // So is `{A}` if A is a type parameter + Position::ArgumentNamed(s) => match types.iter().find(|t| { + t.ident.as_str() == s + }) { + Some(_) => (), + None => { + ccx.tcx.sess.span_err(attr.span, + format!("there is no type parameter \ + {} on trait {}", + s, item.ident.as_str()) + .as_slice()); + } + }, + // `{:1}` and `{}` are not to be used + Position::ArgumentIs(_) | Position::ArgumentNext => { + ccx.tcx.sess.span_err(attr.span, + "only named substitution \ + parameters are allowed"); + } + } + } + } + } else { + ccx.tcx.sess.span_err(attr.span, + "this attribute must have a value, \ + eg `#[on_unimplemented = \"foo\"]`") + } + } +} + /// Type checks a method body. /// /// # Parameters diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index f15d53290e7..68b152dee23 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -84,6 +84,7 @@ This API is completely unstable and subject to change. #[macro_use] extern crate syntax; extern crate arena; +extern crate fmt_macros; extern crate rustc; pub use rustc::lint; diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs index 3f899288f50..20b4448ea77 100644 --- a/src/test/compile-fail/on-unimplemented.rs +++ b/src/test/compile-fail/on-unimplemented.rs @@ -26,16 +26,6 @@ fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B { MyFromIterator::my_from_iter(it) } -#[on_unimplemented] //~ ERROR the #[on_unimplemented] attribute on trait definition for BadAnnotation1 must have a value, eg `#[on_unimplemented = "foo"]` -trait BadAnnotation1 {} - -#[on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] -//~^ ERROR the #[on_unimplemented] attribute on trait definition for BadAnnotation2<A, B> refers to non-existent type parameter C -trait BadAnnotation2<A,B> {} - -fn trigger1<T: BadAnnotation1>(t: T) {} -fn trigger2<A, B, T: BadAnnotation2<A,B>>(t: T) {} - pub fn main() { let x = vec!(1u8, 2, 3, 4); let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect() @@ -43,9 +33,4 @@ pub fn main() { //~^^ NOTE a collection of type `core::option::Option<collections::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8` let x: String = foobar(); //~ ERROR //~^ NOTE test error `collections::string::String` with `u8` `_` `u32` - - // The following two have errors in their annotations, so the regular error should be thrown - trigger1(1u8); //~ ERROR the trait `BadAnnotation1` is not implemented for the type `u8` - trigger2::<u8, u8, u8>(1u8); //~ ERROR the trait `BadAnnotation2<u8, u8>` is not implemented - } |
