about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/astconv_util.rs89
-rw-r--r--src/librustc/middle/const_eval.rs14
-rw-r--r--src/librustc/middle/typeck/astconv.rs70
-rw-r--r--src/librustc/middle/typeck/check/mod.rs44
5 files changed, 119 insertions, 99 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index d8da4df08bc..5637f5d1755 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -59,6 +59,7 @@ pub mod back {
 }
 
 pub mod middle {
+    pub mod astconv_util;
     pub mod astencode;
     pub mod borrowck;
     pub mod cfg;
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs
new file mode 100644
index 00000000000..6b90bcd60e7
--- /dev/null
+++ b/src/librustc/middle/astconv_util.rs
@@ -0,0 +1,89 @@
+// Copyright 2012-2014 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.
+
+/*!
+ * This module contains a simple utility routine
+ * used by both `typeck` and `const_eval`.
+ * Almost certainly this could (and should) be refactored out of existence.
+ */
+
+use middle::def;
+use middle::ty::{mod, Ty};
+use syntax::ast;
+use util::ppaux::Repr;
+
+pub const NO_REGIONS: uint = 1;
+pub const NO_TPS: uint = 2;
+
+pub fn check_path_args(tcx: &ty::ctxt,
+                       path: &ast::Path,
+                       flags: uint) {
+    if (flags & NO_TPS) != 0u {
+        if path.segments.iter().any(|s| s.parameters.has_types()) {
+            span_err!(tcx.sess, path.span, E0109,
+                "type parameters are not allowed on this type");
+        }
+    }
+
+    if (flags & NO_REGIONS) != 0u {
+        if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
+            span_err!(tcx.sess, path.span, E0110,
+                "region parameters are not allowed on this type");
+        }
+    }
+}
+
+pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
+                               -> Option<Ty<'tcx>> {
+    match ast_ty.node {
+        ast::TyPath(ref path, id) => {
+            let a_def = match tcx.def_map.borrow().get(&id) {
+                None => {
+                    tcx.sess.span_bug(ast_ty.span,
+                                      format!("unbound path {}",
+                                              path.repr(tcx)).as_slice())
+                }
+                Some(&d) => d
+            };
+            match a_def {
+                def::DefPrimTy(nty) => {
+                    match nty {
+                        ast::TyBool => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_bool())
+                        }
+                        ast::TyChar => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_char())
+                        }
+                        ast::TyInt(it) => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_mach_int(it))
+                        }
+                        ast::TyUint(uit) => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_mach_uint(uit))
+                        }
+                        ast::TyFloat(ft) => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_mach_float(ft))
+                        }
+                        ast::TyStr => {
+                            Some(ty::mk_str(tcx))
+                        }
+                    }
+                }
+                _ => None
+            }
+        }
+        _ => None
+    }
+}
+
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index d5a292b9f09..43726f55bb9 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -17,8 +17,8 @@ pub use self::constness::*;
 use metadata::csearch;
 use middle::{astencode, def};
 use middle::pat_util::def_to_path;
-use middle::ty::{mod, Ty};
-use middle::typeck::{astconv, check};
+use middle::ty::{mod};
+use middle::astconv_util::{ast_ty_to_prim_ty};
 use util::nodemap::DefIdMap;
 
 use syntax::ast::{mod, Expr};
@@ -277,14 +277,6 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, t: &ast::Ty) {
-        if let ast::TyFixedLengthVec(_, ref expr) = t.node {
-            check::check_const_in_type(self.tcx, &**expr, ty::mk_uint());
-        }
-
-        visit::walk_ty(self, t);
-    }
-
     fn visit_expr_post(&mut self, e: &Expr) {
         self.classify(e);
     }
@@ -504,7 +496,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
         // populated in the ctxt, which was causing things to blow up
         // (#5900). Fall back to doing a limited lookup to get past it.
         let ety = ty::expr_ty_opt(tcx, e)
-                .or_else(|| astconv::ast_ty_to_prim_ty(tcx, &**target_ty))
+                .or_else(|| ast_ty_to_prim_ty(tcx, &**target_ty))
                 .unwrap_or_else(|| {
                     tcx.sess.span_fatal(target_ty.span,
                                         "target type not found for const cast")
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 89c004fc645..abdf66eeb3b 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -46,6 +46,8 @@
 //! Note that the self region for the `foo` defaulted to `&` in the first
 //! 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::{ast_ty_to_prim_ty, check_path_args, NO_TPS, NO_REGIONS};
 use middle::const_eval;
 use middle::def;
 use middle::resolve_lifetime as rl;
@@ -553,74 +555,6 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
     }
 }
 
-pub const NO_REGIONS: uint = 1;
-pub const NO_TPS: uint = 2;
-
-fn check_path_args(tcx: &ty::ctxt,
-                   path: &ast::Path,
-                   flags: uint) {
-    if (flags & NO_TPS) != 0u {
-        if path.segments.iter().any(|s| s.parameters.has_types()) {
-            span_err!(tcx.sess, path.span, E0109,
-                "type parameters are not allowed on this type");
-        }
-    }
-
-    if (flags & NO_REGIONS) != 0u {
-        if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
-            span_err!(tcx.sess, path.span, E0110,
-                "region parameters are not allowed on this type");
-        }
-    }
-}
-
-pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
-                               -> Option<Ty<'tcx>> {
-    match ast_ty.node {
-        ast::TyPath(ref path, id) => {
-            let a_def = match tcx.def_map.borrow().get(&id) {
-                None => {
-                    tcx.sess.span_bug(ast_ty.span,
-                                      format!("unbound path {}",
-                                              path.repr(tcx)).as_slice())
-                }
-                Some(&d) => d
-            };
-            match a_def {
-                def::DefPrimTy(nty) => {
-                    match nty {
-                        ast::TyBool => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_bool())
-                        }
-                        ast::TyChar => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_char())
-                        }
-                        ast::TyInt(it) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_int(it))
-                        }
-                        ast::TyUint(uit) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_uint(uit))
-                        }
-                        ast::TyFloat(ft) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_float(ft))
-                        }
-                        ast::TyStr => {
-                            Some(ty::mk_str(tcx))
-                        }
-                    }
-                }
-                _ => None
-            }
-        }
-        _ => None
-    }
-}
-
 /// Converts the given AST type to a built-in type. A "built-in type" is, at
 /// present, either a core numeric type, a string, or `Box`.
 pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 02106f25304..cacccbda53c 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -361,6 +361,17 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemTypesVisitor<'a, 'tcx> {
         check_item(self.ccx, i);
         visit::walk_item(self, i);
     }
+
+    fn visit_ty(&mut self, t: &ast::Ty) {
+        match t.node {
+            ast::TyFixedLengthVec(_, ref expr) => {
+                check_const_in_type(self.ccx, &**expr, ty::mk_uint());
+            }
+            _ => {}
+        }
+
+        visit::walk_ty(self, t);
+    }
 }
 
 pub fn check_item_types(ccx: &CrateCtxt) {
@@ -4672,25 +4683,18 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 /// Checks a constant appearing in a type. At the moment this is just the
 /// length expression in a fixed-length vector, but someday it might be
 /// extended to type-level numeric literals.
-pub fn check_const_in_type<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                 expr: &ast::Expr,
-                                 expected_type: Ty<'tcx>) {
-    // Synthesize a crate context. The trait map is not needed here (though I
-    // imagine it will be if we have associated statics --pcwalton), so we
-    // leave it blank.
-    let ccx = CrateCtxt {
-        trait_map: NodeMap::new(),
-        tcx: tcx,
-    };
-    let inh = static_inherited_fields(&ccx);
-    let fcx = blank_fn_ctxt(&ccx, &inh, ty::FnConverging(expected_type), expr.id);
+fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
+                                expr: &ast::Expr,
+                                expected_type: Ty<'tcx>) {
+    let inh = static_inherited_fields(ccx);
+    let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
     check_const_with_ty(&fcx, expr.span, expr, expected_type);
 }
 
-pub fn check_const(ccx: &CrateCtxt,
-                   sp: Span,
-                   e: &ast::Expr,
-                   id: ast::NodeId) {
+fn check_const(ccx: &CrateCtxt,
+               sp: Span,
+               e: &ast::Expr,
+               id: ast::NodeId) {
     let inh = static_inherited_fields(ccx);
     let rty = ty::node_id_to_type(ccx.tcx, id);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
@@ -4698,10 +4702,10 @@ pub fn check_const(ccx: &CrateCtxt,
     check_const_with_ty(&fcx, sp, e, declty);
 }
 
-pub fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                     _: Span,
-                                     e: &ast::Expr,
-                                     declty: Ty<'tcx>) {
+fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                 _: Span,
+                                 e: &ast::Expr,
+                                 declty: Ty<'tcx>) {
     // Gather locals in statics (because of block expressions).
     // This is technically unnecessary because locals in static items are forbidden,
     // but prevents type checking from blowing up before const checking can properly