提交 9cc8453a 编写于 作者: N Niko Matsakis

Adjust feature gates to allow for parenthetical notation to be used

with the fn traits
上级 698db04a
......@@ -67,5 +67,6 @@
E0173,
E0174,
E0177,
E0178
E0178,
E0179 // parenthesized params may only be used with a trait
)
......@@ -114,6 +114,22 @@ pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
}
}
pub fn fn_trait_kind(&self, id: ast::DefId) -> Option<ty::UnboxedClosureKind> {
let def_id_kinds = [
(self.fn_trait(), ty::FnUnboxedClosureKind),
(self.fn_mut_trait(), ty::FnMutUnboxedClosureKind),
(self.fn_once_trait(), ty::FnOnceUnboxedClosureKind),
];
for &(opt_def_id, kind) in def_id_kinds.iter() {
if Some(id) == opt_def_id {
return Some(kind);
}
}
None
}
$(
#[allow(dead_code)]
pub fn $method(&self) -> Option<ast::DefId> {
......
......@@ -235,7 +235,7 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
convert_angle_bracketed_parameters(this, rscope, data)
}
ast::ParenthesizedParameters(ref data) => {
span_err!(tcx.sess, path.span, E0169,
span_err!(tcx.sess, path.span, E0173,
"parenthesized parameters may only be used with a trait");
(Vec::new(), convert_parenthesized_parameters(this, data), Vec::new())
}
......@@ -581,6 +581,19 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
convert_angle_bracketed_parameters(this, &shifted_rscope, data)
}
ast::ParenthesizedParameters(ref data) => {
// For now, require that parenthetical notation be used
// only with `Fn()` etc.
if !this.tcx().sess.features.borrow().unboxed_closures &&
this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none()
{
this.tcx().sess.span_err(path.span,
"parenthetical notation is only stable when \
used with the `Fn` family of traits");
span_help!(this.tcx().sess, path.span,
"add `#![feature(unboxed_closures)]` to \
the crate attributes to enable");
}
(Vec::new(), convert_parenthesized_parameters(this, data), Vec::new())
}
};
......
......@@ -188,42 +188,35 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
debug!("deduce_unboxed_closure_expectations_from_object_type({})",
trait_ref.repr(tcx));
let def_id_kinds = [
(tcx.lang_items.fn_trait(), ty::FnUnboxedClosureKind),
(tcx.lang_items.fn_mut_trait(), ty::FnMutUnboxedClosureKind),
(tcx.lang_items.fn_once_trait(), ty::FnOnceUnboxedClosureKind),
];
for &(def_id, kind) in def_id_kinds.iter() {
if Some(trait_ref.def_id) == def_id {
debug!("found object type {}", kind);
let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0);
let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(arg_param_ty);
debug!("arg_param_ty {}", arg_param_ty.repr(tcx));
let input_tys = match arg_param_ty.sty {
ty::ty_tup(ref tys) => { (*tys).clone() }
_ => { continue; }
};
debug!("input_tys {}", input_tys.repr(tcx));
let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id) {
Some(k) => k,
None => { return None; }
};
let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1);
let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(ret_param_ty);
debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
debug!("found object type {}", kind);
let fn_sig = ty::FnSig {
inputs: input_tys,
output: ty::FnConverging(ret_param_ty),
variadic: false
};
debug!("fn_sig {}", fn_sig.repr(tcx));
let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0);
let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(arg_param_ty);
debug!("arg_param_ty {}", arg_param_ty.repr(tcx));
return Some((fn_sig, kind));
}
}
let input_tys = match arg_param_ty.sty {
ty::ty_tup(ref tys) => { (*tys).clone() }
_ => { return None; }
};
debug!("input_tys {}", input_tys.repr(tcx));
None
let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1);
let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(ret_param_ty);
debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
let fn_sig = ty::FnSig {
inputs: input_tys,
output: ty::FnConverging(ret_param_ty),
variadic: false
};
debug!("fn_sig {}", fn_sig.repr(tcx));
return Some((fn_sig, kind));
}
fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(
......
......@@ -5159,6 +5159,8 @@ fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
}
ast::ParenthesizedParameters(ref data) => {
span_err!(fcx.tcx().sess, span, E0173,
"parenthesized parameters may only be used with a trait");
push_explicit_parenthesized_parameters_from_segment_to_substs(
fcx, space, span, type_defs, data, substs);
}
......
......@@ -374,19 +374,6 @@ fn visit_fn(&mut self,
}
visit::walk_fn(self, fn_kind, fn_decl, block, span);
}
fn visit_path_parameters(&mut self, path_span: Span, parameters: &'v ast::PathParameters) {
match *parameters {
ast::ParenthesizedParameters(..) => {
self.gate_feature("unboxed_closures",
path_span,
"parenthetical parameter notation is subject to change");
}
ast::AngleBracketedParameters(..) => { }
}
visit::walk_path_parameters(self, path_span, parameters)
}
}
pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, Vec<Span>) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册