]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass-fulldeps/regions-mock-tcx.rs
Auto merge of #54919 - alexcrichton:update-cargo, r=Mark-Simulacrum
[rust.git] / src / test / run-pass-fulldeps / regions-mock-tcx.rs
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 #![allow(dead_code)]
12 #![allow(unused_imports)]
13
14 // Test a sample usage pattern for regions. Makes use of the
15 // following features:
16 //
17 // - Multiple lifetime parameters
18 // - Arenas
19
20 #![feature(rustc_private, libc)]
21
22 extern crate arena;
23 extern crate libc;
24
25 use TypeStructure::{TypeInt, TypeFunction};
26 use AstKind::{ExprInt, ExprVar, ExprLambda};
27 use arena::TypedArena;
28 use std::collections::HashMap;
29 use std::mem;
30
31 type Type<'tcx> = &'tcx TypeStructure<'tcx>;
32
33 #[derive(Copy, Clone, Debug)]
34 enum TypeStructure<'tcx> {
35     TypeInt,
36     TypeFunction(Type<'tcx>, Type<'tcx>),
37 }
38
39 impl<'tcx> PartialEq for TypeStructure<'tcx> {
40     fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
41         match (*self, *other) {
42             (TypeInt, TypeInt) => true,
43             (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b,
44             _ => false
45         }
46     }
47 }
48
49 impl<'tcx> Eq for TypeStructure<'tcx> {}
50
51 type TyArena<'tcx> = TypedArena<TypeStructure<'tcx>>;
52 type AstArena<'ast> = TypedArena<AstStructure<'ast>>;
53
54 struct TypeContext<'tcx, 'ast> {
55     ty_arena: &'tcx TyArena<'tcx>,
56     types: Vec<Type<'tcx>> ,
57     type_table: HashMap<NodeId, Type<'tcx>>,
58
59     ast_arena: &'ast AstArena<'ast>,
60     ast_counter: usize,
61 }
62
63 impl<'tcx,'ast> TypeContext<'tcx, 'ast> {
64     fn new(ty_arena: &'tcx TyArena<'tcx>, ast_arena: &'ast AstArena<'ast>)
65            -> TypeContext<'tcx, 'ast> {
66         TypeContext { ty_arena: ty_arena,
67                       types: Vec::new(),
68                       type_table: HashMap::new(),
69
70                       ast_arena: ast_arena,
71                       ast_counter: 0 }
72     }
73
74     fn add_type(&mut self, s: TypeStructure<'tcx>) -> Type<'tcx> {
75         for &ty in &self.types {
76             if *ty == s {
77                 return ty;
78             }
79         }
80
81         let ty = self.ty_arena.alloc(s);
82         self.types.push(ty);
83         ty
84     }
85
86     fn set_type(&mut self, id: NodeId, ty: Type<'tcx>) -> Type<'tcx> {
87         self.type_table.insert(id, ty);
88         ty
89     }
90
91     fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> {
92         let id = self.ast_counter;
93         self.ast_counter += 1;
94         self.ast_arena.alloc(AstStructure { id: NodeId {id:id}, kind: a })
95     }
96 }
97
98 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
99 struct NodeId {
100     id: usize
101 }
102
103 type Ast<'ast> = &'ast AstStructure<'ast>;
104
105 #[derive(Copy, Clone)]
106 struct AstStructure<'ast> {
107     id: NodeId,
108     kind: AstKind<'ast>
109 }
110
111 #[derive(Copy, Clone)]
112 enum AstKind<'ast> {
113     ExprInt,
114     ExprVar(usize),
115     ExprLambda(Ast<'ast>),
116 }
117
118 fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>,
119                             ast: Ast<'ast>) -> Type<'tcx>
120 {
121     match ast.kind {
122         ExprInt | ExprVar(_) => {
123             let ty = tcx.add_type(TypeInt);
124             tcx.set_type(ast.id, ty)
125         }
126         ExprLambda(ast) => {
127             let arg_ty = tcx.add_type(TypeInt);
128             let body_ty = compute_types(tcx, ast);
129             let lambda_ty = tcx.add_type(TypeFunction(arg_ty, body_ty));
130             tcx.set_type(ast.id, lambda_ty)
131         }
132     }
133 }
134
135 pub fn main() {
136     let ty_arena = TypedArena::default();
137     let ast_arena = TypedArena::default();
138     let mut tcx = TypeContext::new(&ty_arena, &ast_arena);
139     let ast = tcx.ast(ExprInt);
140     let ty = compute_types(&mut tcx, ast);
141     assert_eq!(*ty, TypeInt);
142 }