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