Skip to content

Commit 55470ab

Browse files
committed
Remove one dependence on typeck from const_eval.
1 parent 00ca861 commit 55470ab

File tree

5 files changed

+119
-99
lines changed

5 files changed

+119
-99
lines changed

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub mod back {
5959
}
6060

6161
pub mod middle {
62+
pub mod astconv_util;
6263
pub mod astencode;
6364
pub mod borrowck;
6465
pub mod cfg;

src/librustc/middle/astconv_util.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/*!
12+
* This module contains a simple utility routine
13+
* used by both `typeck` and `const_eval`.
14+
* Almost certainly this could (and should) be refactored out of existence.
15+
*/
16+
17+
use middle::def;
18+
use middle::ty::{mod, Ty};
19+
use syntax::ast;
20+
use util::ppaux::Repr;
21+
22+
pub const NO_REGIONS: uint = 1;
23+
pub const NO_TPS: uint = 2;
24+
25+
pub fn check_path_args(tcx: &ty::ctxt,
26+
path: &ast::Path,
27+
flags: uint) {
28+
if (flags & NO_TPS) != 0u {
29+
if path.segments.iter().any(|s| s.parameters.has_types()) {
30+
span_err!(tcx.sess, path.span, E0109,
31+
"type parameters are not allowed on this type");
32+
}
33+
}
34+
35+
if (flags & NO_REGIONS) != 0u {
36+
if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
37+
span_err!(tcx.sess, path.span, E0110,
38+
"region parameters are not allowed on this type");
39+
}
40+
}
41+
}
42+
43+
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
44+
-> Option<Ty<'tcx>> {
45+
match ast_ty.node {
46+
ast::TyPath(ref path, id) => {
47+
let a_def = match tcx.def_map.borrow().get(&id) {
48+
None => {
49+
tcx.sess.span_bug(ast_ty.span,
50+
format!("unbound path {}",
51+
path.repr(tcx)).as_slice())
52+
}
53+
Some(&d) => d
54+
};
55+
match a_def {
56+
def::DefPrimTy(nty) => {
57+
match nty {
58+
ast::TyBool => {
59+
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
60+
Some(ty::mk_bool())
61+
}
62+
ast::TyChar => {
63+
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
64+
Some(ty::mk_char())
65+
}
66+
ast::TyInt(it) => {
67+
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
68+
Some(ty::mk_mach_int(it))
69+
}
70+
ast::TyUint(uit) => {
71+
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
72+
Some(ty::mk_mach_uint(uit))
73+
}
74+
ast::TyFloat(ft) => {
75+
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
76+
Some(ty::mk_mach_float(ft))
77+
}
78+
ast::TyStr => {
79+
Some(ty::mk_str(tcx))
80+
}
81+
}
82+
}
83+
_ => None
84+
}
85+
}
86+
_ => None
87+
}
88+
}
89+

src/librustc/middle/const_eval.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ pub use self::constness::*;
1717
use metadata::csearch;
1818
use middle::{astencode, def};
1919
use middle::pat_util::def_to_path;
20-
use middle::ty::{mod, Ty};
21-
use middle::typeck::{astconv, check};
20+
use middle::ty::{mod};
21+
use middle::astconv_util::{ast_ty_to_prim_ty};
2222
use util::nodemap::DefIdMap;
2323

2424
use syntax::ast::{mod, Expr};
@@ -277,14 +277,6 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
277277
}
278278

279279
impl<'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
280-
fn visit_ty(&mut self, t: &ast::Ty) {
281-
if let ast::TyFixedLengthVec(_, ref expr) = t.node {
282-
check::check_const_in_type(self.tcx, &**expr, ty::mk_uint());
283-
}
284-
285-
visit::walk_ty(self, t);
286-
}
287-
288280
fn visit_expr_post(&mut self, e: &Expr) {
289281
self.classify(e);
290282
}
@@ -504,7 +496,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
504496
// populated in the ctxt, which was causing things to blow up
505497
// (#5900). Fall back to doing a limited lookup to get past it.
506498
let ety = ty::expr_ty_opt(tcx, e)
507-
.or_else(|| astconv::ast_ty_to_prim_ty(tcx, &**target_ty))
499+
.or_else(|| ast_ty_to_prim_ty(tcx, &**target_ty))
508500
.unwrap_or_else(|| {
509501
tcx.sess.span_fatal(target_ty.span,
510502
"target type not found for const cast")

src/librustc/middle/typeck/astconv.rs

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
//! Note that the self region for the `foo` defaulted to `&` in the first
4747
//! case but `&a` in the second. Basically, defaults that appear inside
4848
//! an rptr (`&r.T`) use the region `r` that appears in the rptr.
49+
50+
use middle::astconv_util::{ast_ty_to_prim_ty, check_path_args, NO_TPS, NO_REGIONS};
4951
use middle::const_eval;
5052
use middle::def;
5153
use middle::resolve_lifetime as rl;
@@ -553,74 +555,6 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
553555
}
554556
}
555557

556-
pub const NO_REGIONS: uint = 1;
557-
pub const NO_TPS: uint = 2;
558-
559-
fn check_path_args(tcx: &ty::ctxt,
560-
path: &ast::Path,
561-
flags: uint) {
562-
if (flags & NO_TPS) != 0u {
563-
if path.segments.iter().any(|s| s.parameters.has_types()) {
564-
span_err!(tcx.sess, path.span, E0109,
565-
"type parameters are not allowed on this type");
566-
}
567-
}
568-
569-
if (flags & NO_REGIONS) != 0u {
570-
if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
571-
span_err!(tcx.sess, path.span, E0110,
572-
"region parameters are not allowed on this type");
573-
}
574-
}
575-
}
576-
577-
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
578-
-> Option<Ty<'tcx>> {
579-
match ast_ty.node {
580-
ast::TyPath(ref path, id) => {
581-
let a_def = match tcx.def_map.borrow().get(&id) {
582-
None => {
583-
tcx.sess.span_bug(ast_ty.span,
584-
format!("unbound path {}",
585-
path.repr(tcx)).as_slice())
586-
}
587-
Some(&d) => d
588-
};
589-
match a_def {
590-
def::DefPrimTy(nty) => {
591-
match nty {
592-
ast::TyBool => {
593-
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
594-
Some(ty::mk_bool())
595-
}
596-
ast::TyChar => {
597-
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
598-
Some(ty::mk_char())
599-
}
600-
ast::TyInt(it) => {
601-
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
602-
Some(ty::mk_mach_int(it))
603-
}
604-
ast::TyUint(uit) => {
605-
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
606-
Some(ty::mk_mach_uint(uit))
607-
}
608-
ast::TyFloat(ft) => {
609-
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
610-
Some(ty::mk_mach_float(ft))
611-
}
612-
ast::TyStr => {
613-
Some(ty::mk_str(tcx))
614-
}
615-
}
616-
}
617-
_ => None
618-
}
619-
}
620-
_ => None
621-
}
622-
}
623-
624558
/// Converts the given AST type to a built-in type. A "built-in type" is, at
625559
/// present, either a core numeric type, a string, or `Box`.
626560
pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(

src/librustc/middle/typeck/check/mod.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,17 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemTypesVisitor<'a, 'tcx> {
361361
check_item(self.ccx, i);
362362
visit::walk_item(self, i);
363363
}
364+
365+
fn visit_ty(&mut self, t: &ast::Ty) {
366+
match t.node {
367+
ast::TyFixedLengthVec(_, ref expr) => {
368+
check_const_in_type(self.ccx, &**expr, ty::mk_uint());
369+
}
370+
_ => {}
371+
}
372+
373+
visit::walk_ty(self, t);
374+
}
364375
}
365376

366377
pub fn check_item_types(ccx: &CrateCtxt) {
@@ -4672,36 +4683,29 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
46724683
/// Checks a constant appearing in a type. At the moment this is just the
46734684
/// length expression in a fixed-length vector, but someday it might be
46744685
/// extended to type-level numeric literals.
4675-
pub fn check_const_in_type<'tcx>(tcx: &ty::ctxt<'tcx>,
4676-
expr: &ast::Expr,
4677-
expected_type: Ty<'tcx>) {
4678-
// Synthesize a crate context. The trait map is not needed here (though I
4679-
// imagine it will be if we have associated statics --pcwalton), so we
4680-
// leave it blank.
4681-
let ccx = CrateCtxt {
4682-
trait_map: NodeMap::new(),
4683-
tcx: tcx,
4684-
};
4685-
let inh = static_inherited_fields(&ccx);
4686-
let fcx = blank_fn_ctxt(&ccx, &inh, ty::FnConverging(expected_type), expr.id);
4686+
fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4687+
expr: &ast::Expr,
4688+
expected_type: Ty<'tcx>) {
4689+
let inh = static_inherited_fields(ccx);
4690+
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
46874691
check_const_with_ty(&fcx, expr.span, expr, expected_type);
46884692
}
46894693

4690-
pub fn check_const(ccx: &CrateCtxt,
4691-
sp: Span,
4692-
e: &ast::Expr,
4693-
id: ast::NodeId) {
4694+
fn check_const(ccx: &CrateCtxt,
4695+
sp: Span,
4696+
e: &ast::Expr,
4697+
id: ast::NodeId) {
46944698
let inh = static_inherited_fields(ccx);
46954699
let rty = ty::node_id_to_type(ccx.tcx, id);
46964700
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
46974701
let declty = (*fcx.ccx.tcx.tcache.borrow())[local_def(id)].ty;
46984702
check_const_with_ty(&fcx, sp, e, declty);
46994703
}
47004704

4701-
pub fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4702-
_: Span,
4703-
e: &ast::Expr,
4704-
declty: Ty<'tcx>) {
4705+
fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4706+
_: Span,
4707+
e: &ast::Expr,
4708+
declty: Ty<'tcx>) {
47054709
// Gather locals in statics (because of block expressions).
47064710
// This is technically unnecessary because locals in static items are forbidden,
47074711
// but prevents type checking from blowing up before const checking can properly

0 commit comments

Comments
 (0)