diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 91caacf73a0..fd642f452b2 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -65,6 +65,7 @@ enum lint { non_camel_case_types, structural_records, type_limits, + default_methods, managed_heap_memory, owned_heap_memory, @@ -200,7 +201,12 @@ fn get_lint_dict() -> lint_dict { (~"type_limits", @{lint: type_limits, desc: ~"comparisons made useless by limits of the types involved", - default: warn}) + default: warn}), + + (~"default_methods", + @{lint: default_methods, + desc: ~"allow default methods", + default: forbid}), /* FIXME(#3266)--make liveness warnings lintable (~"unused_variable", @@ -414,6 +420,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_structural_records(cx, i); check_item_deprecated_modes(cx, i); check_item_type_limits(cx, i); + check_item_default_methods(cx, i); } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -563,6 +570,27 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) { visit::visit_item(it, (), visit); } +fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) { + match item.node { + ast::item_trait(_, _, methods) => { + for methods.each |method| { + match *method { + ast::required(*) => {} + ast::provided(*) => { + cx.sess.span_lint( + default_methods, + item.id, + item.id, + item.span, + ~"default methods are experimental"); + } + } + } + } + _ => {} + } +} + fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) { let visit = item_stopping_visitor(visit::mk_simple_visitor(@{ visit_expr: fn@(e: @ast::expr) { diff --git a/src/test/compile-fail/lint-default-methods.rs b/src/test/compile-fail/lint-default-methods.rs new file mode 100644 index 00000000000..97662225dec --- /dev/null +++ b/src/test/compile-fail/lint-default-methods.rs @@ -0,0 +1,8 @@ +#[forbid(default_methods)]; + +trait Foo { + fn bar() { io::println("hi"); } //~ ERROR default methods are experimental +} + +fn main() {} +