diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 6f90ed81924..5f9910340c4 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -295,8 +295,8 @@ pub fn phase_3_run_analysis_passes(sess: Session, let region_map = time(time_passes, "region resolution", (), |_| middle::region::resolve_crate(sess, krate)); - let ty_cx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map, freevars, - region_map, lang_items); + let ty_cx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map, + freevars, region_map, lang_items); // passes are timed inside typeck let (method_map, vtable_map) = typeck::check_crate(ty_cx, trait_map, krate); @@ -975,6 +975,7 @@ pub fn build_session_(sopts: @session::Options, lints: RefCell::new(HashMap::new()), node_id: Cell::new(1), crate_types: @RefCell::new(~[]), + features: front::feature_gate::Features::new() } } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index e023190e5f4..9a33c54d50f 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -12,6 +12,7 @@ use back::target_strs; use back; use driver::driver::host_triple; +use front; use metadata::filesearch; use metadata; use middle::lint; @@ -186,6 +187,7 @@ pub struct Session_ { ~[(lint::Lint, codemap::Span, ~str)]>>, node_id: Cell, crate_types: @RefCell<~[CrateType]>, + features: front::feature_gate::Features } pub type Session = @Session_; diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index 52553af53c7..813bceafed5 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -30,6 +30,8 @@ use syntax::parse::token; use driver::session::Session; +use std::cell::Cell; + /// This is a list of all known features since the beginning of time. This list /// can never shrink, it may only be expanded (in order to prevent old programs /// from failing to compile). The status of each feature may change, however. @@ -69,6 +71,19 @@ enum Status { Accepted, } +/// A set of features to be used by later passes. +pub struct Features { + default_type_params: Cell +} + +impl Features { + pub fn new() -> Features { + Features { + default_type_params: Cell::new(false) + } + } +} + struct Context { features: ~[&'static str], sess: Session, @@ -315,4 +330,6 @@ pub fn check_crate(sess: Session, krate: &ast::Crate) { visit::walk_crate(&mut cx, krate, ()); sess.abort_if_errors(); + + sess.features.default_type_params.set(cx.has_feature("default_type_params")); } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 36ed4913cdb..242b9906c72 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -88,7 +88,6 @@ pub enum Lint { AttributeUsage, UnknownFeatures, UnknownCrateType, - DefaultTypeParamUsage, ManagedHeapMemory, OwnedHeapMemory, @@ -382,14 +381,7 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ lint: UnusedResult, desc: "unused result of an expression in a statement", default: allow, - }), - - ("default_type_param_usage", - LintSpec { - lint: DefaultTypeParamUsage, - desc: "prevents explicitly setting a type parameter with a default", - default: deny, - }), + }) ]; /* diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b351b5c0cb8..7a6de3ef5dd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1079,6 +1079,7 @@ pub fn mk_ctxt(s: session::Session, region_maps: middle::region::RegionMaps, lang_items: @middle::lang_items::LanguageItems) -> ctxt { + @ctxt_ { named_region_map: named_region_map, item_variance_map: RefCell::new(HashMap::new()), @@ -1126,7 +1127,7 @@ pub fn mk_ctxt(s: session::Session, upvar_borrow_map: RefCell::new(HashMap::new()), extern_const_statics: RefCell::new(HashMap::new()), extern_const_variants: RefCell::new(HashMap::new()), - } + } } // Type constructors diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 70b739e33d9..e569f0756e6 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -51,7 +51,6 @@ use middle::const_eval; -use middle::lint; use middle::subst::Subst; use middle::ty::{substs}; use middle::ty::{ty_param_substs_and_ty}; @@ -219,11 +218,12 @@ fn ast_path_substs( expected, formal_ty_param_count, supplied_ty_param_count)); } - if supplied_ty_param_count > required_ty_param_count { - let id = path.segments.iter().flat_map(|s| s.types.iter()) - .nth(required_ty_param_count).unwrap().id; - this.tcx().sess.add_lint(lint::DefaultTypeParamUsage, id, path.span, - ~"provided type arguments with defaults"); + if supplied_ty_param_count > required_ty_param_count + && !this.tcx().sess.features.default_type_params.get() { + this.tcx().sess.span_err(path.span, "default type parameters are \ + experimental and possibly buggy"); + this.tcx().sess.span_note(path.span, "add #[feature(default_type_params)] \ + to the crate attributes to enable"); } let tps = path.segments.iter().flat_map(|s| s.types.iter()) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index ac17d327166..5d89f2d2c68 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -81,7 +81,6 @@ use middle::const_eval; use middle::lang_items::{ExchangeHeapLangItem, GcLangItem}; use middle::lang_items::{ManagedHeapLangItem}; use middle::lint::UnreachableCode; -use middle::lint; use middle::pat_util::pat_id_map; use middle::pat_util; use middle::subst::Subst; @@ -3750,9 +3749,12 @@ pub fn instantiate_path(fcx: @FnCtxt, expected, user_ty_param_req, ty_substs_len)); (fcx.infcx().next_ty_vars(ty_param_count), regions) } else { - if ty_substs_len > user_ty_param_req { - fcx.tcx().sess.add_lint(lint::DefaultTypeParamUsage, node_id, pth.span, - ~"provided type arguments with defaults"); + if ty_substs_len > user_ty_param_req + && !fcx.tcx().sess.features.default_type_params.get() { + fcx.tcx().sess.span_err(pth.span, "default type parameters are \ + experimental and possibly buggy"); + fcx.tcx().sess.span_note(pth.span, "add #[feature(default_type_params)] \ + to the crate attributes to enable"); } // Build up the list of type parameters, inserting the self parameter diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d7fc85bc259..e96eedea5cb 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -56,6 +56,8 @@ // Turn on default type parameters. #[feature(default_type_params)]; +// NOTE remove the following two attributes after the next snapshot. +#[allow(unrecognized_lint)]; #[allow(default_type_param_usage)]; // Don't link to std. We are std. diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 0b9158547ed..acae4f9efa6 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -13,7 +13,6 @@ use codemap::Span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -use parse::token::InternedString; pub fn expand_deriving_hash(cx: &mut ExtCtxt, span: Span, @@ -21,29 +20,18 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, item: @Item, push: |@Item|) { - let allow_default_type_param_usage = cx.attribute( - span, - cx.meta_list( - span, - InternedString::new("allow"), - ~[cx.meta_word(span, InternedString::new("default_type_param_usage"))])); - let hash_trait_def = TraitDef { span: span, - attributes: ~[allow_default_type_param_usage], - path: Path::new_(~["std", "hash", "Hash"], None, - ~[~Literal(Path::new_local("__H"))], true), + attributes: ~[], + path: Path::new(~["std", "hash", "Hash"]), additional_bounds: ~[], - generics: LifetimeBounds { - lifetimes: ~[], - bounds: ~[("__H", ~[Path::new(~["std", "io", "Writer"])])], - }, + generics: LifetimeBounds::empty(), methods: ~[ MethodDef { name: "hash", generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), - args: ~[Ptr(~Literal(Path::new_local("__H")), + args: ~[Ptr(~Literal(Path::new(~["std", "hash", "sip", "SipState"])), Borrowed(None, MutMutable))], ret_ty: nil_ty(), inline: true, diff --git a/src/test/compile-fail/lint-default-type-param-usage.rs b/src/test/compile-fail/gated-default-type-param-usage.rs similarity index 73% rename from src/test/compile-fail/lint-default-type-param-usage.rs rename to src/test/compile-fail/gated-default-type-param-usage.rs index e8cacb02de8..9961a81a85a 100644 --- a/src/test/compile-fail/lint-default-type-param-usage.rs +++ b/src/test/compile-fail/gated-default-type-param-usage.rs @@ -8,16 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[feature(default_type_params)]; +// aux-build:default_type_params_xc.rs #[deny(default_type_param_usage)]; -pub struct Heap; - -pub struct Vec; +extern crate default_type_params_xc; pub struct FooAlloc; -pub type VecFoo = Vec; //~ ERROR provided type arguments with defaults +pub type VecFoo = default_type_params_xc::FakeVec; +//~^ ERROR: default type parameters are experimental fn main() {} diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs index 412e780f8a2..72b41601891 100644 --- a/src/test/run-pass/generic-default-type-params-cross-crate.rs +++ b/src/test/run-pass/generic-default-type-params-cross-crate.rs @@ -13,8 +13,6 @@ // ignore-fast #[feature] doesn't work with check-fast #[feature(default_type_params)]; -#[allow(default_type_param_usage)]; - extern crate default_type_params_xc; struct Vec; diff --git a/src/test/run-pass/generic-default-type-params.rs b/src/test/run-pass/generic-default-type-params.rs index b2d20b859df..889d5c948eb 100644 --- a/src/test/run-pass/generic-default-type-params.rs +++ b/src/test/run-pass/generic-default-type-params.rs @@ -11,8 +11,6 @@ // ignore-fast #[feature] doesn't work with check-fast #[feature(default_type_params)]; -#[allow(default_type_param_usage)]; - struct Foo { a: A }