Skip to content

Commit 9cc8453

Browse files
committed
Adjust feature gates to allow for parenthetical notation to be used
with the fn traits
1 parent 698db04 commit 9cc8453

File tree

6 files changed

+59
-47
lines changed

6 files changed

+59
-47
lines changed

src/librustc/diagnostics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,6 @@ register_diagnostics!(
6767
E0173,
6868
E0174,
6969
E0177,
70-
E0178
70+
E0178,
71+
E0179 // parenthesized params may only be used with a trait
7172
)

src/librustc/middle/lang_items.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,22 @@ impl LanguageItems {
114114
}
115115
}
116116

117+
pub fn fn_trait_kind(&self, id: ast::DefId) -> Option<ty::UnboxedClosureKind> {
118+
let def_id_kinds = [
119+
(self.fn_trait(), ty::FnUnboxedClosureKind),
120+
(self.fn_mut_trait(), ty::FnMutUnboxedClosureKind),
121+
(self.fn_once_trait(), ty::FnOnceUnboxedClosureKind),
122+
];
123+
124+
for &(opt_def_id, kind) in def_id_kinds.iter() {
125+
if Some(id) == opt_def_id {
126+
return Some(kind);
127+
}
128+
}
129+
130+
None
131+
}
132+
117133
$(
118134
#[allow(dead_code)]
119135
pub fn $method(&self) -> Option<ast::DefId> {

src/librustc_typeck/astconv.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
235235
convert_angle_bracketed_parameters(this, rscope, data)
236236
}
237237
ast::ParenthesizedParameters(ref data) => {
238-
span_err!(tcx.sess, path.span, E0169,
238+
span_err!(tcx.sess, path.span, E0173,
239239
"parenthesized parameters may only be used with a trait");
240240
(Vec::new(), convert_parenthesized_parameters(this, data), Vec::new())
241241
}
@@ -581,6 +581,19 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
581581
convert_angle_bracketed_parameters(this, &shifted_rscope, data)
582582
}
583583
ast::ParenthesizedParameters(ref data) => {
584+
// For now, require that parenthetical notation be used
585+
// only with `Fn()` etc.
586+
if !this.tcx().sess.features.borrow().unboxed_closures &&
587+
this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none()
588+
{
589+
this.tcx().sess.span_err(path.span,
590+
"parenthetical notation is only stable when \
591+
used with the `Fn` family of traits");
592+
span_help!(this.tcx().sess, path.span,
593+
"add `#![feature(unboxed_closures)]` to \
594+
the crate attributes to enable");
595+
}
596+
584597
(Vec::new(), convert_parenthesized_parameters(this, data), Vec::new())
585598
}
586599
};

src/librustc_typeck/check/closure.rs

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -188,42 +188,35 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
188188
debug!("deduce_unboxed_closure_expectations_from_object_type({})",
189189
trait_ref.repr(tcx));
190190

191-
let def_id_kinds = [
192-
(tcx.lang_items.fn_trait(), ty::FnUnboxedClosureKind),
193-
(tcx.lang_items.fn_mut_trait(), ty::FnMutUnboxedClosureKind),
194-
(tcx.lang_items.fn_once_trait(), ty::FnOnceUnboxedClosureKind),
195-
];
196-
197-
for &(def_id, kind) in def_id_kinds.iter() {
198-
if Some(trait_ref.def_id) == def_id {
199-
debug!("found object type {}", kind);
200-
201-
let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0);
202-
let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(arg_param_ty);
203-
debug!("arg_param_ty {}", arg_param_ty.repr(tcx));
204-
205-
let input_tys = match arg_param_ty.sty {
206-
ty::ty_tup(ref tys) => { (*tys).clone() }
207-
_ => { continue; }
208-
};
209-
debug!("input_tys {}", input_tys.repr(tcx));
191+
let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id) {
192+
Some(k) => k,
193+
None => { return None; }
194+
};
210195

211-
let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1);
212-
let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(ret_param_ty);
213-
debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
196+
debug!("found object type {}", kind);
214197

215-
let fn_sig = ty::FnSig {
216-
inputs: input_tys,
217-
output: ty::FnConverging(ret_param_ty),
218-
variadic: false
219-
};
220-
debug!("fn_sig {}", fn_sig.repr(tcx));
198+
let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0);
199+
let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(arg_param_ty);
200+
debug!("arg_param_ty {}", arg_param_ty.repr(tcx));
221201

222-
return Some((fn_sig, kind));
223-
}
224-
}
202+
let input_tys = match arg_param_ty.sty {
203+
ty::ty_tup(ref tys) => { (*tys).clone() }
204+
_ => { return None; }
205+
};
206+
debug!("input_tys {}", input_tys.repr(tcx));
225207

226-
None
208+
let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1);
209+
let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(ret_param_ty);
210+
debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
211+
212+
let fn_sig = ty::FnSig {
213+
inputs: input_tys,
214+
output: ty::FnConverging(ret_param_ty),
215+
variadic: false
216+
};
217+
debug!("fn_sig {}", fn_sig.repr(tcx));
218+
219+
return Some((fn_sig, kind));
227220
}
228221

229222
fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5159,6 +5159,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
51595159
}
51605160

51615161
ast::ParenthesizedParameters(ref data) => {
5162+
span_err!(fcx.tcx().sess, span, E0173,
5163+
"parenthesized parameters may only be used with a trait");
51625164
push_explicit_parenthesized_parameters_from_segment_to_substs(
51635165
fcx, space, span, type_defs, data, substs);
51645166
}

src/libsyntax/feature_gate.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -374,19 +374,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
374374
}
375375
visit::walk_fn(self, fn_kind, fn_decl, block, span);
376376
}
377-
378-
fn visit_path_parameters(&mut self, path_span: Span, parameters: &'v ast::PathParameters) {
379-
match *parameters {
380-
ast::ParenthesizedParameters(..) => {
381-
self.gate_feature("unboxed_closures",
382-
path_span,
383-
"parenthetical parameter notation is subject to change");
384-
}
385-
ast::AngleBracketedParameters(..) => { }
386-
}
387-
388-
visit::walk_path_parameters(self, path_span, parameters)
389-
}
390377
}
391378

392379
pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, Vec<Span>) {

0 commit comments

Comments
 (0)