diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c448af2288a..5ed1da2fede 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -111,7 +111,7 @@ pub trait AstConv<'tcx> { } /// What type should we use when a type is omitted? - fn ty_infer(&self, span: Span) -> Ty<'tcx>; + fn ty_infer(&self, default: Option>, span: Span) -> Ty<'tcx>; /// Projecting an associated type from a (potentially) /// higher-ranked trait reference is more complicated, because of @@ -403,7 +403,7 @@ fn create_substs_for_ast_path<'tcx>( // they were optional (e.g. paths inside expressions). let mut type_substs = if param_mode == PathParamMode::Optional && types_provided.is_empty() { - (0..formal_ty_param_count).map(|_| this.ty_infer(span)).collect() + ty_param_defs.iter().map(|p| this.ty_infer(p.default, span)).collect() } else { types_provided }; @@ -1661,7 +1661,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, // values in a ExprClosure, or as // the type of local variables. Both of these cases are // handled specially and will not descend into this routine. - this.ty_infer(ast_ty.span) + this.ty_infer(None, ast_ty.span) } }; @@ -1677,7 +1677,7 @@ pub fn ty_of_arg<'tcx>(this: &AstConv<'tcx>, { match a.ty.node { ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(), - ast::TyInfer => this.ty_infer(a.ty.span), + ast::TyInfer => this.ty_infer(None, a.ty.span), _ => ast_ty_to_ty(this, rscope, &*a.ty), } } @@ -1796,7 +1796,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, let output_ty = match decl.output { ast::Return(ref output) if output.node == ast::TyInfer => - ty::FnConverging(this.ty_infer(output.span)), + ty::FnConverging(this.ty_infer(None, output.span)), ast::Return(ref output) => ty::FnConverging(convert_ty_with_lifetime_elision(this, implied_output_region, @@ -1936,7 +1936,7 @@ pub fn ty_of_closure<'tcx>( _ if is_infer && expected_ret_ty.is_some() => expected_ret_ty.unwrap(), _ if is_infer => - ty::FnConverging(this.ty_infer(decl.output.span())), + ty::FnConverging(this.ty_infer(None, decl.output.span())), ast::Return(ref output) => ty::FnConverging(ast_ty_to_ty(this, &rb, &**output)), ast::DefaultReturn(..) => unreachable!(), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e226b0b21a1..ae2b3448e01 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1138,8 +1138,13 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { trait_def.associated_type_names.contains(&assoc_name) } - fn ty_infer(&self, _span: Span) -> Ty<'tcx> { - self.infcx().next_ty_var() + fn ty_infer(&self, default: Option>, _span: Span) -> Ty<'tcx> { + let ty_var = self.infcx().next_ty_var(); + match default { + Some(default) => { self.infcx().defaults.borrow_mut().insert(ty_var, default); } + None => {} + } + ty_var } fn projected_ty_from_poly_trait_ref(&self, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 5a6519cb4b7..695991a97f0 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> { } } - fn ty_infer(&self, span: Span) -> Ty<'tcx> { + fn ty_infer(&self, _default: Option>, span: Span) -> Ty<'tcx> { span_err!(self.tcx().sess, span, E0121, "the type placeholder `_` is not allowed within types on item signatures"); self.tcx().types.err diff --git a/src/test/compile-fail/default_ty_param_type_alias.rs b/src/test/run-pass/default_ty_param_type_alias.rs similarity index 100% rename from src/test/compile-fail/default_ty_param_type_alias.rs rename to src/test/run-pass/default_ty_param_type_alias.rs