E0173,
E0174,
E0177,
- E0178
+ E0178,
+ E0179 // parenthesized params may only be used with a trait
)
}
}
+ 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> {
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())
}
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())
}
};
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>(
}
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);
}
}
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>) {