From 3ebdbac2651cd21f2efda8d3b381ed396d7bb725 Mon Sep 17 00:00:00 2001 From: Ahmed Charles Date: Sat, 24 Jan 2015 09:53:05 -0800 Subject: [PATCH 1/3] Do not permit type parameters on builtin bounds. --- src/librustc_typeck/astconv.rs | 10 +++++-- src/librustc_typeck/diagnostics.rs | 3 ++- .../typeck-builtin-bound-type-parameters.rs | 27 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/test/compile-fail/typeck-builtin-bound-type-parameters.rs diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index afdc414c163..bb27918075d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1847,8 +1847,14 @@ 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 - continue; // success + let segments = &b.trait_ref.path.segments; + let parameters = &segments[segments.len() - 1].parameters; + if parameters.is_empty() { + continue; // success + } + span_err!(tcx.sess, b.trait_ref.path.span, E0316, + "builtin bounds do not require arguments, {} given", + parameters.types().len()); } } _ => { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 17cf92d39d8..82334eb253b 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -171,7 +171,8 @@ 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 + E0316 // wrong number of type arguments to a built-in trait } __build_diagnostic_array! { DIAGNOSTICS } 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 00000000000..3914fb96a0d --- /dev/null +++ b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs @@ -0,0 +1,27 @@ +// 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: builtin bounds do not require arguments, 1 given + +trait Trait: Copy {} +//~^ ERROR: builtin bounds do not require arguments, 1 given + +struct MyStruct1>; +//~^ ERROR: builtin bounds do not require arguments, 1 given + +struct MyStruct2<'a, T: Copy<'a>>; +//~^ ERROR: builtin bounds do not require arguments, 1 given + +fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} +//~^ ERROR: builtin bounds do not require arguments, 1 given + +fn main() { +} From a1945197c32d4e81b9fa30e61f3544a484b5491a Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sun, 22 Feb 2015 02:13:38 +0100 Subject: [PATCH 2/3] continue when builtin bounds are registered --- src/librustc_typeck/astconv.rs | 10 +++++----- src/libtest/stats.rs | 1 + .../typeck-builtin-bound-type-parameters.rs | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index bb27918075d..866c0b8cb42 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1849,12 +1849,12 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, &mut builtin_bounds) { let segments = &b.trait_ref.path.segments; let parameters = &segments[segments.len() - 1].parameters; - if parameters.is_empty() { - continue; // success + if !parameters.is_empty() { + span_err!(tcx.sess, b.trait_ref.path.span, E0316, + "builtin bounds do not require arguments, {} given", + parameters.lifetimes().len() + parameters.types().len()); } - span_err!(tcx.sess, b.trait_ref.path.span, E0316, - "builtin bounds do not require arguments, {} given", - parameters.types().len()); + continue; // success } } _ => { diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 4e94be59ade..7cc07e926b2 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 index 3914fb96a0d..b6d45b1bbf8 100644 --- a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs +++ b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs @@ -15,13 +15,13 @@ trait Trait: Copy {} //~^ ERROR: builtin bounds do not require arguments, 1 given struct MyStruct1>; -//~^ ERROR: builtin bounds do not require arguments, 1 given +//~^ ERROR builtin bounds do not require arguments, 1 given struct MyStruct2<'a, T: Copy<'a>>; //~^ ERROR: builtin bounds do not require arguments, 1 given fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} -//~^ ERROR: builtin bounds do not require arguments, 1 given +//~^ ERROR builtin bounds do not require arguments, 2 given fn main() { } From 7ff11d7be8f5523674996bb7941e01b1991fd039 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sun, 22 Feb 2015 16:31:03 +0100 Subject: [PATCH 3/3] Unify lifetime/type arguments error messages for (non-)builtin bounds --- src/librustc_typeck/astconv.rs | 71 ++++++++++++------- src/librustc_typeck/diagnostics.rs | 1 - .../typeck-builtin-bound-type-parameters.rs | 11 +-- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 866c0b8cb42..46a7041fff6 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 && @@ -1849,10 +1832,13 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, &mut builtin_bounds) { let segments = &b.trait_ref.path.segments; let parameters = &segments[segments.len() - 1].parameters; - if !parameters.is_empty() { - span_err!(tcx.sess, b.trait_ref.path.span, E0316, - "builtin bounds do not require arguments, {} given", - parameters.lifetimes().len() + parameters.types().len()); + 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 } @@ -1886,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 82334eb253b..0b8ebcf3fe9 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -172,7 +172,6 @@ register_diagnostics! { E0248, // found value name used as a type E0249, // expected constant expr for array length E0250, // expected constant expr for array length - E0316 // wrong number of type arguments to a built-in trait } __build_diagnostic_array! { DIAGNOSTICS } diff --git a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs index b6d45b1bbf8..fb6c43a1905 100644 --- a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs +++ b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs @@ -9,19 +9,20 @@ // except according to those terms. fn foo1, U>(x: T) {} -//~^ ERROR: builtin bounds do not require arguments, 1 given +//~^ ERROR: wrong number of type arguments: expected 0, found 1 trait Trait: Copy {} -//~^ ERROR: builtin bounds do not require arguments, 1 given +//~^ ERROR: wrong number of type arguments: expected 0, found 1 struct MyStruct1>; -//~^ ERROR builtin bounds do not require arguments, 1 given +//~^ ERROR wrong number of type arguments: expected 0, found 1 struct MyStruct2<'a, T: Copy<'a>>; -//~^ ERROR: builtin bounds do not require arguments, 1 given +//~^ ERROR: wrong number of lifetime parameters: expected 0, found 1 fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} -//~^ ERROR builtin bounds do not require arguments, 2 given +//~^ ERROR: wrong number of type arguments: expected 0, found 1 +//~^^ ERROR: wrong number of lifetime parameters: expected 0, found 1 fn main() { }