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