diff options
| -rw-r--r-- | src/librustc/diagnostics.rs | 1 | ||||
| -rw-r--r-- | src/librustc/middle/astconv_util.rs | 40 | ||||
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 21 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 5 | ||||
| -rw-r--r-- | src/librustc_typeck/diagnostics.rs | 1 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-24682.rs | 31 |
6 files changed, 66 insertions, 33 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 91845e916d4..9616b596c06 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1895,6 +1895,7 @@ register_diagnostics! { // E0006 // merged with E0005 // E0134, // E0135, + E0229, // associated type bindings are not allowed here E0264, // unknown external lang item E0278, // requirement is not satisfied E0279, // requirement is not satisfied diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 1700efe23e9..3b837277203 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -16,36 +16,40 @@ use middle::def; use middle::ty::{self, Ty}; -use rustc_front::hir as ast; -pub const NO_REGIONS: usize = 1; -pub const NO_TPS: usize = 2; +use syntax::codemap::Span; +use rustc_front::hir as ast; -pub fn check_path_args(tcx: &ty::ctxt, segments: &[ast::PathSegment], flags: usize) { +pub fn prohibit_type_params(tcx: &ty::ctxt, segments: &[ast::PathSegment]) { for segment in segments { - if (flags & NO_TPS) != 0 { - for typ in segment.parameters.types() { - span_err!(tcx.sess, typ.span, E0109, - "type parameters are not allowed on this type"); - break; - } + for typ in segment.parameters.types() { + span_err!(tcx.sess, typ.span, E0109, + "type parameters are not allowed on this type"); + break; } - - if (flags & NO_REGIONS) != 0 { - for lifetime in segment.parameters.lifetimes() { - span_err!(tcx.sess, lifetime.span, E0110, - "lifetime parameters are not allowed on this type"); - break; - } + for lifetime in segment.parameters.lifetimes() { + span_err!(tcx.sess, lifetime.span, E0110, + "lifetime parameters are not allowed on this type"); + break; + } + for binding in segment.parameters.bindings() { + prohibit_projection(tcx, binding.span); + break; } } } +pub fn prohibit_projection(tcx: &ty::ctxt, span: Span) +{ + span_err!(tcx.sess, span, E0229, + "associated type bindings are not allowed here"); +} + pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>, segments: &[ast::PathSegment], nty: ast::PrimTy) -> Ty<'tcx> { - check_path_args(tcx, segments, NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, segments); match nty { ast::TyBool => tcx.types.bool, ast::TyChar => tcx.types.char, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index fb61f1ef42d..3883102fb2e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -48,7 +48,7 @@ //! case but `&a` in the second. Basically, defaults that appear inside //! an rptr (`&r.T`) use the region `r` that appears in the rptr. -use middle::astconv_util::{prim_ty_to_ty, check_path_args, NO_TPS, NO_REGIONS}; +use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection}; use middle::const_eval::{self, ConstVal}; use middle::const_eval::EvalHint::UncheckedExprHint; use middle::def; @@ -1210,7 +1210,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name); - check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, slice::ref_slice(item_segment)); // Find the type of the associated item, and the trait where the associated // item is declared. @@ -1312,7 +1312,7 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>, { let tcx = this.tcx(); - check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, slice::ref_slice(item_segment)); let self_ty = if let Some(ty) = opt_self_ty { ty @@ -1401,7 +1401,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>, base_segments.last().unwrap(), &mut projection_bounds); - check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, base_segments.split_last().unwrap().1); trait_ref_to_object_type(this, rscope, span, @@ -1410,7 +1410,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>, &[]) } def::DefTy(did, _) | def::DefStruct(did) => { - check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, base_segments.split_last().unwrap().1); ast_path_to_ty(this, rscope, span, @@ -1419,12 +1419,12 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>, base_segments.last().unwrap()) } def::DefTyParam(space, index, _, name) => { - check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, base_segments); tcx.mk_param(space, index, name) } def::DefSelfTy(_, Some((_, self_ty_id))) => { // Self in impl (we know the concrete type). - check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, base_segments); if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&self_ty_id) { if let Some(free_substs) = this.get_free_substs() { ty.subst(tcx, free_substs) @@ -1437,11 +1437,11 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>, } def::DefSelfTy(Some(_), None) => { // Self in trait. - check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, base_segments); tcx.mk_self_type() } def::DefAssociatedTy(trait_did, _) => { - check_path_args(tcx, &base_segments[..base_segments.len()-2], NO_TPS | NO_REGIONS); + prohibit_type_params(tcx, &base_segments[..base_segments.len()-2]); qpath_to_ty(this, rscope, span, @@ -2185,8 +2185,7 @@ fn prohibit_projections<'tcx>(tcx: &ty::ctxt<'tcx>, bindings: &[ConvertedBinding<'tcx>]) { for binding in bindings.iter().take(1) { - span_err!(tcx.sess, binding.span, E0229, - "associated type bindings are not allowed here"); + prohibit_projection(tcx, binding.span); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index b1fbf97d1a7..0185cea60cc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,7 +83,7 @@ use self::TupleArgumentsFlag::*; use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode}; use check::_match::pat_ctxt; use fmt_macros::{Parser, Piece, Position}; -use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS}; +use middle::astconv_util::prohibit_type_params; use middle::def; use middle::def_id::{DefId, LOCAL_CRATE}; use middle::infer; @@ -4535,8 +4535,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, for (opt_space, segment) in segment_spaces.iter().zip(segments) { match *opt_space { None => { - check_path_args(fcx.tcx(), slice::ref_slice(segment), - NO_TPS | NO_REGIONS); + prohibit_type_params(fcx.tcx(), slice::ref_slice(segment)); } Some(space) => { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8a2f8b1cf4b..4bbb33164d2 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3294,7 +3294,6 @@ register_diagnostics! { E0226, // only a single explicit lifetime bound is permitted E0227, // ambiguous lifetime bound, explicit lifetime bound required E0228, // explicit lifetime bound required - E0229, // associated type bindings are not allowed here E0230, // there is no type parameter on trait E0231, // only named substitution parameters are allowed // E0233, diff --git a/src/test/compile-fail/issue-24682.rs b/src/test/compile-fail/issue-24682.rs new file mode 100644 index 00000000000..0e872f71df4 --- /dev/null +++ b/src/test/compile-fail/issue-24682.rs @@ -0,0 +1,31 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait A: Sized { + type N; + fn x() -> + Self< + N= //~ ERROR associated type bindings are not allowed here + Self::N> { + loop {} + } + fn y(&self) -> + std + <N=()> //~ ERROR associated type bindings are not allowed here + ::option::Option<()> + { None } + fn z(&self) -> + u32<N=()> //~ ERROR associated type bindings are not allowed here + { 42 } + +} + +fn main() { +} |
