about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/diagnostics.rs1
-rw-r--r--src/librustc/middle/astconv_util.rs40
-rw-r--r--src/librustc_typeck/astconv.rs21
-rw-r--r--src/librustc_typeck/check/mod.rs5
-rw-r--r--src/librustc_typeck/diagnostics.rs1
-rw-r--r--src/test/compile-fail/issue-24682.rs31
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() {
+}