提交 3e531ed0 编写于 作者: E Eduard Burtescu

Gate default type parameter overrides.

Fixes #12423.
上级 67209775
......@@ -296,8 +296,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);
......@@ -976,6 +976,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()
}
}
......
......@@ -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<ast::NodeId>,
crate_types: @RefCell<~[CrateType]>,
features: front::feature_gate::Features
}
pub type Session = @Session_;
......
......@@ -30,6 +30,8 @@
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<bool>
}
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"));
}
......@@ -88,7 +88,6 @@ pub enum Lint {
AttributeUsage,
UnknownFeatures,
UnknownCrateType,
DefaultTypeParamUsage,
ManagedHeapMemory,
OwnedHeapMemory,
......@@ -382,14 +381,7 @@ enum LintSource {
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,
}),
})
];
/*
......
......@@ -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
......
......@@ -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<AC:AstConv,RS:RegionScope>(
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())
......
......@@ -81,7 +81,6 @@
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
......
......@@ -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.
......
......@@ -13,7 +13,6 @@
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,
......
......@@ -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<T, A = Heap>;
extern crate default_type_params_xc;
pub struct FooAlloc;
pub type VecFoo<T> = Vec<T, FooAlloc>; //~ ERROR provided type arguments with defaults
pub type VecFoo<T> = default_type_params_xc::FakeVec<T, FooAlloc>;
//~^ ERROR: default type parameters are experimental
fn main() {}
......@@ -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<T, A = default_type_params_xc::Heap>;
......
......@@ -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 = (int, char)> {
a: A
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册