Skip to content

Commit

Permalink
Make it an error to use parenthetical notation with
Browse files Browse the repository at this point in the history
something other than a trait type.
  • Loading branch information
nikomatsakis committed Nov 18, 2014
1 parent 0b90cde commit 9c808ff
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 55 deletions.
3 changes: 2 additions & 1 deletion src/librustc/diagnostics.rs
Expand Up @@ -144,5 +144,6 @@ register_diagnostics!(
E0165,
E0166,
E0167,
E0168
E0168,
E0169
)
127 changes: 75 additions & 52 deletions src/librustc/middle/typeck/astconv.rs
Expand Up @@ -202,7 +202,7 @@ pub fn opt_ast_region_to_region<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
r
}

fn ast_path_substs<'tcx,AC,RS>(
fn ast_path_substs_for_ty<'tcx,AC,RS>(
this: &AC,
rscope: &RS,
decl_def_id: ast::DefId,
Expand Down Expand Up @@ -233,12 +233,35 @@ fn ast_path_substs<'tcx,AC,RS>(
assert!(decl_generics.types.all(|d| d.space != FnSpace));

let (regions, types) = match path.segments.last().unwrap().parameters {
ast::AngleBracketedParameters(ref data) =>
angle_bracketed_parameters(this, rscope, data),
ast::ParenthesizedParameters(ref data) =>
parenthesized_parameters(this, binder_id, data),
ast::AngleBracketedParameters(ref data) => {
convert_angle_bracketed_parameters(this, rscope, data)
}
ast::ParenthesizedParameters(ref data) => {
span_err!(tcx.sess, path.span, E0169,
"parenthesized parameters may only be used with a trait");
(Vec::new(), convert_parenthesized_parameters(this, data))
}
};

create_substs_for_ast_path(this, rscope, path.span, decl_def_id,
decl_generics, self_ty, types, regions, associated_ty)
}

fn create_substs_for_ast_path<'tcx,AC,RS>(
this: &AC,
rscope: &RS,
span: Span,
decl_def_id: ast::DefId,
decl_generics: &ty::Generics,
self_ty: Option<ty::t>,
types: Vec<ty::t>,
regions: Vec<ty::Region>,
associated_ty: Option<ty::t>)
-> Substs
where AC: AstConv<'tcx>, RS: RegionScope
{
let tcx = this.tcx();

// If the type is parameterized by the this region, then replace this
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
Expand All @@ -248,10 +271,10 @@ fn ast_path_substs<'tcx,AC,RS>(
regions
} else {
let anon_regions =
rscope.anon_regions(path.span, expected_num_region_params);
rscope.anon_regions(span, expected_num_region_params);

if supplied_num_region_params != 0 || anon_regions.is_err() {
span_err!(tcx.sess, path.span, E0107,
span_err!(tcx.sess, span, E0107,
"wrong number of lifetime parameters: expected {}, found {}",
expected_num_region_params, supplied_num_region_params);
}
Expand Down Expand Up @@ -283,7 +306,7 @@ fn ast_path_substs<'tcx,AC,RS>(
} else {
"expected"
};
this.tcx().sess.span_fatal(path.span,
this.tcx().sess.span_fatal(span,
format!("wrong number of type arguments: {} {}, found {}",
expected,
required_ty_param_count,
Expand All @@ -294,7 +317,7 @@ fn ast_path_substs<'tcx,AC,RS>(
} else {
"expected"
};
this.tcx().sess.span_fatal(path.span,
this.tcx().sess.span_fatal(span,
format!("wrong number of type arguments: {} {}, found {}",
expected,
formal_ty_param_count,
Expand All @@ -303,9 +326,9 @@ fn ast_path_substs<'tcx,AC,RS>(

if supplied_ty_param_count > required_ty_param_count
&& !this.tcx().sess.features.borrow().default_type_params {
span_err!(this.tcx().sess, path.span, E0108,
span_err!(this.tcx().sess, span, E0108,
"default type parameters are experimental and possibly buggy");
span_help!(this.tcx().sess, path.span,
span_help!(this.tcx().sess, span,
"add #![feature(default_type_params)] to the crate attributes to enable");
}

Expand All @@ -331,66 +354,66 @@ fn ast_path_substs<'tcx,AC,RS>(
// This is a default type parameter.
let default = default.subst_spanned(tcx,
&substs,
Some(path.span));
Some(span));
substs.types.push(TypeSpace, default);
}
None => {
tcx.sess.span_bug(path.span,
"extra parameter without default");
tcx.sess.span_bug(span, "extra parameter without default");
}
}
}

for param in decl_generics.types.get_slice(AssocSpace).iter() {
substs.types.push(
AssocSpace,
this.associated_type_binding(path.span,
this.associated_type_binding(span,
associated_ty,
decl_def_id,
param.def_id))
}

return substs;
}

fn angle_bracketed_parameters<'tcx, AC, RS>(this: &AC,
rscope: &RS,
data: &ast::AngleBracketedParameterData)
-> (Vec<ty::Region>, Vec<ty::t>)
where AC: AstConv<'tcx>, RS: RegionScope
{
let regions: Vec<_> =
data.lifetimes.iter()
.map(|l| ast_region_to_region(this.tcx(), l))
.collect();

let types: Vec<_> =
data.types.iter()
.map(|t| ast_ty_to_ty(this, rscope, &**t))
.collect();

(regions, types)
}
fn convert_angle_bracketed_parameters<'tcx, AC, RS>(this: &AC,
rscope: &RS,
data: &ast::AngleBracketedParameterData)
-> (Vec<ty::Region>, Vec<ty::t>)
where AC: AstConv<'tcx>, RS: RegionScope
{
let regions: Vec<_> =
data.lifetimes.iter()
.map(|l| ast_region_to_region(this.tcx(), l))
.collect();

fn parenthesized_parameters<'tcx,AC>(this: &AC,
binder_id: ast::NodeId,
data: &ast::ParenthesizedParameterData)
-> (Vec<ty::Region>, Vec<ty::t>)
where AC: AstConv<'tcx>
{
let binding_rscope = BindingRscope::new(binder_id);

let inputs = data.inputs.iter()
.map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
.collect();
let input_ty = ty::mk_tup(this.tcx(), inputs);

let output = match data.output {
Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty),
None => ty::mk_nil(this.tcx())
};
let types: Vec<_> =
data.types.iter()
.map(|t| ast_ty_to_ty(this, rscope, &**t))
.collect();

(regions, types)
}

fn convert_parenthesized_parameters<'tcx,AC>(this: &AC,
data: &ast::ParenthesizedParameterData)
-> Vec<ty::t>
where AC: AstConv<'tcx>
{
let binding_rscope = BindingRscope::new();

let inputs = data.inputs.iter()
.map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
.collect();
let input_ty = ty::mk_tup(this.tcx(), inputs);

let output = match data.output {
Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty),
None => ty::mk_nil(this.tcx()),
};

vec![input_ty, output]
}

(Vec::new(), vec![input_ty, output])
}
}

pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/typeck/check/mod.rs
Expand Up @@ -4452,8 +4452,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
let type_and_substs = astconv::ast_path_to_ty_relaxed(fcx,
fcx.infcx(),
struct_id,
path,
expr.id);
path);
match fcx.mk_subty(false,
infer::Misc(path.span),
actual_structure_type,
Expand Down

0 comments on commit 9c808ff

Please sign in to comment.