diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index afdc414c163ce..46a7041fff672 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -305,9 +305,9 @@ fn create_region_substs<'tcx>( rscope.anon_regions(span, expected_num_region_params); if supplied_num_region_params != 0 || anon_regions.is_err() { - span_err!(tcx.sess, span, E0107, - "wrong number of lifetime parameters: expected {}, found {}", - expected_num_region_params, supplied_num_region_params); + report_lifetime_number_error(tcx, span, + supplied_num_region_params, + expected_num_region_params); } match anon_regions { @@ -355,31 +355,14 @@ fn create_substs_for_ast_path<'tcx>( .count(); let mut type_substs = types_provided; + check_type_argument_count(this.tcx(), span, supplied_ty_param_count, + required_ty_param_count, formal_ty_param_count); + if supplied_ty_param_count < required_ty_param_count { - let expected = if required_ty_param_count < formal_ty_param_count { - "expected at least" - } else { - "expected" - }; - span_err!(this.tcx().sess, span, E0243, - "wrong number of type arguments: {} {}, found {}", - expected, - required_ty_param_count, - supplied_ty_param_count); while type_substs.len() < required_ty_param_count { type_substs.push(tcx.types.err); } } else if supplied_ty_param_count > formal_ty_param_count { - let expected = if required_ty_param_count < formal_ty_param_count { - "expected at most" - } else { - "expected" - }; - span_err!(this.tcx().sess, span, E0244, - "wrong number of type arguments: {} {}, found {}", - expected, - formal_ty_param_count, - supplied_ty_param_count); type_substs.truncate(formal_ty_param_count); } assert!(type_substs.len() >= required_ty_param_count && @@ -1847,7 +1830,16 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, if ty::try_add_builtin_trait(tcx, trait_did, &mut builtin_bounds) { - // FIXME(#20302) -- we should check for things like Copy + let segments = &b.trait_ref.path.segments; + let parameters = &segments[segments.len() - 1].parameters; + if parameters.types().len() > 0 { + check_type_argument_count(tcx, b.trait_ref.path.span, + parameters.types().len(), 0, 0); + } + if parameters.lifetimes().len() > 0{ + report_lifetime_number_error(tcx, b.trait_ref.path.span, + parameters.lifetimes().len(), 0); + } continue; // success } } @@ -1880,3 +1872,34 @@ fn prohibit_projections<'tcx>(tcx: &ty::ctxt<'tcx>, "associated type bindings are not allowed here"); } } + +fn check_type_argument_count(tcx: &ty::ctxt, span: Span, supplied: usize, + required: usize, accepted: usize) { + if supplied < required { + let expected = if required < accepted { + "expected at least" + } else { + "expected" + }; + span_err!(tcx.sess, span, E0243, + "wrong number of type arguments: {} {}, found {}", + expected, required, supplied); + } else if supplied > accepted { + let expected = if required < accepted { + "expected at most" + } else { + "expected" + }; + span_err!(tcx.sess, span, E0244, + "wrong number of type arguments: {} {}, found {}", + expected, + accepted, + supplied); + } +} + +fn report_lifetime_number_error(tcx: &ty::ctxt, span: Span, number: usize, expected: usize) { + span_err!(tcx.sess, span, E0107, + "wrong number of lifetime parameters: expected {}, found {}", + expected, number); +} diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 17cf92d39d8f5..0b8ebcf3fe930 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -171,7 +171,7 @@ register_diagnostics! { E0247, // found module name used as a type E0248, // found value name used as a type E0249, // expected constant expr for array length - E0250 // expected constant expr for array length + E0250, // expected constant expr for array length } __build_diagnostic_array! { DIAGNOSTICS } diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 4e94be59ade0d..7cc07e926b267 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -332,6 +332,7 @@ pub fn winsorize(samples: &mut [T], pct: T) { /// Returns a HashMap with the number of occurrences of every element in the /// sequence that the iterator exposes. +#[cfg(not(stage0))] pub fn freq_count(iter: T) -> hash_map::HashMap where T: Iterator, U: Eq + Clone + Hash { diff --git a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs new file mode 100644 index 0000000000000..fb6c43a19059a --- /dev/null +++ b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs @@ -0,0 +1,28 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo1, U>(x: T) {} +//~^ ERROR: wrong number of type arguments: expected 0, found 1 + +trait Trait: Copy {} +//~^ ERROR: wrong number of type arguments: expected 0, found 1 + +struct MyStruct1>; +//~^ ERROR wrong number of type arguments: expected 0, found 1 + +struct MyStruct2<'a, T: Copy<'a>>; +//~^ ERROR: wrong number of lifetime parameters: expected 0, found 1 + +fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} +//~^ ERROR: wrong number of type arguments: expected 0, found 1 +//~^^ ERROR: wrong number of lifetime parameters: expected 0, found 1 + +fn main() { +}