]> git.proxmox.com Git - rustc.git/blame - tests/ui-fulldeps/regions-mock-tcx.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / tests / ui-fulldeps / regions-mock-tcx.rs
CommitLineData
416331ca
XL
1// run-pass
2
0bf4aa26
XL
3#![allow(dead_code)]
4#![allow(unused_imports)]
1a4d82fc
JJ
5
6// Test a sample usage pattern for regions. Makes use of the
7// following features:
8//
9// - Multiple lifetime parameters
10// - Arenas
11
041b39d2 12#![feature(rustc_private, libc)]
c34b1796 13
f035d41b 14extern crate rustc_arena;
1a4d82fc
JJ
15extern crate libc;
16
9c376795
FG
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)]
20extern crate rustc_driver;
21
1a4d82fc
JJ
22use TypeStructure::{TypeInt, TypeFunction};
23use AstKind::{ExprInt, ExprVar, ExprLambda};
f035d41b 24use rustc_arena::TypedArena;
1a4d82fc
JJ
25use std::collections::HashMap;
26use std::mem;
27
28type Type<'tcx> = &'tcx TypeStructure<'tcx>;
29
c34b1796 30#[derive(Copy, Clone, Debug)]
1a4d82fc
JJ
31enum TypeStructure<'tcx> {
32 TypeInt,
33 TypeFunction(Type<'tcx>, Type<'tcx>),
34}
35
1a4d82fc
JJ
36impl<'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
46impl<'tcx> Eq for TypeStructure<'tcx> {}
47
85aaf69f
SL
48type TyArena<'tcx> = TypedArena<TypeStructure<'tcx>>;
49type AstArena<'ast> = TypedArena<AstStructure<'ast>>;
50
1a4d82fc 51struct TypeContext<'tcx, 'ast> {
85aaf69f 52 ty_arena: &'tcx TyArena<'tcx>,
1a4d82fc
JJ
53 types: Vec<Type<'tcx>> ,
54 type_table: HashMap<NodeId, Type<'tcx>>,
55
85aaf69f 56 ast_arena: &'ast AstArena<'ast>,
c34b1796 57 ast_counter: usize,
1a4d82fc
JJ
58}
59
60impl<'tcx,'ast> TypeContext<'tcx, 'ast> {
85aaf69f 61 fn new(ty_arena: &'tcx TyArena<'tcx>, ast_arena: &'ast AstArena<'ast>)
1a4d82fc
JJ
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> {
85aaf69f 72 for &ty in &self.types {
1a4d82fc
JJ
73 if *ty == s {
74 return ty;
75 }
76 }
77
85aaf69f 78 let ty = self.ty_arena.alloc(s);
1a4d82fc
JJ
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;
85aaf69f 91 self.ast_arena.alloc(AstStructure { id: NodeId {id:id}, kind: a })
1a4d82fc
JJ
92 }
93}
94
c34b1796 95#[derive(Copy, Clone, PartialEq, Eq, Hash)]
1a4d82fc 96struct NodeId {
c34b1796 97 id: usize
1a4d82fc
JJ
98}
99
1a4d82fc
JJ
100type Ast<'ast> = &'ast AstStructure<'ast>;
101
c34b1796 102#[derive(Copy, Clone)]
1a4d82fc
JJ
103struct AstStructure<'ast> {
104 id: NodeId,
105 kind: AstKind<'ast>
106}
107
c34b1796 108#[derive(Copy, Clone)]
1a4d82fc
JJ
109enum AstKind<'ast> {
110 ExprInt,
c34b1796 111 ExprVar(usize),
1a4d82fc
JJ
112 ExprLambda(Ast<'ast>),
113}
114
1a4d82fc
JJ
115fn 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
132pub fn main() {
0bf4aa26
XL
133 let ty_arena = TypedArena::default();
134 let ast_arena = TypedArena::default();
1a4d82fc
JJ
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}