about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSean Patrick Santos <SeanPatrickSantos@gmail.com>2015-05-04 01:39:10 -0600
committerSean Patrick Santos <SeanPatrickSantos@gmail.com>2015-05-17 15:30:32 -0600
commitfbe8066ac39546073b4d76bcb9928cf83886e8b2 (patch)
tree4f14c4da2d0e27acc595d11d14b195cea13ba899
parent8b7c17db2235a2a3f2c71242b11fc429a8d05a90 (diff)
downloadrust-fbe8066ac39546073b4d76bcb9928cf83886e8b2.tar.gz
rust-fbe8066ac39546073b4d76bcb9928cf83886e8b2.zip
Catch associated consts that depend on type parameters in type checking.
Constants with values that depend on generic parameters or `Self` cause
ICEs in `check_const`, and are not yet accepted via RFC, so we need to
throw a proper error in these cases.
-rw-r--r--src/librustc_typeck/check/mod.rs28
-rw-r--r--src/test/compile-fail/associated-const-type-parameters.rs26
2 files changed, 54 insertions, 0 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f13305bba34..7c270bf4a30 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3765,6 +3765,21 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
 {
     // If fully resolved already, we don't have to do anything.
     if path_res.depth == 0 {
+        // Associated constants can't depend on generic types.
+        if let Some(ty) = opt_self_ty {
+            match path_res.full_def() {
+                def::DefAssociatedConst(..) => {
+                    if ty::type_has_params(ty) || ty::type_has_self(ty) {
+                        fcx.sess().span_err(span,
+                                            "Associated consts cannot depend \
+                                             on type parameters or Self.");
+                        fcx.write_error(node_id);
+                        return None;
+                    }
+                }
+                _ => {}
+            }
+        }
         Some((opt_self_ty, &path.segments, path_res.base_def))
     } else {
         let mut def = path_res.base_def;
@@ -3780,6 +3795,19 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
         let item_name = item_segment.identifier.name;
         match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
             Ok((def, lp)) => {
+                // Associated constants can't depend on generic types.
+                match def {
+                    def::DefAssociatedConst(..) => {
+                        if ty::type_has_params(ty) || ty::type_has_self(ty) {
+                            fcx.sess().span_err(span,
+                                                "Associated consts cannot depend \
+                                                 on type parameters or Self.");
+                            fcx.write_error(node_id);
+                            return None;
+                        }
+                    }
+                    _ => {}
+                }
                 // Write back the new resolution.
                 fcx.ccx.tcx.def_map.borrow_mut()
                        .insert(node_id, def::PathResolution {
diff --git a/src/test/compile-fail/associated-const-type-parameters.rs b/src/test/compile-fail/associated-const-type-parameters.rs
new file mode 100644
index 00000000000..bbe252fc151
--- /dev/null
+++ b/src/test/compile-fail/associated-const-type-parameters.rs
@@ -0,0 +1,26 @@
+// 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.
+
+#![feature(associated_consts)]
+
+pub trait Foo {
+    const MIN: i32;
+
+    fn get_min() -> i32 {
+        Self::MIN //~ Associated consts cannot depend on type parameters or Self.
+    }
+}
+
+fn get_min<T: Foo>() -> i32 {
+    T::MIN; //~ Associated consts cannot depend on type parameters or Self.
+    <T as Foo>::MIN //~ Associated consts cannot depend on type parameters or Self.
+}
+
+fn main() {}