diff options
Diffstat (limited to 'tests/ui-fulldeps/regions-mock-tcx.rs')
-rw-r--r-- | tests/ui-fulldeps/regions-mock-tcx.rs | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/tests/ui-fulldeps/regions-mock-tcx.rs b/tests/ui-fulldeps/regions-mock-tcx.rs new file mode 100644 index 000000000..63975ef62 --- /dev/null +++ b/tests/ui-fulldeps/regions-mock-tcx.rs @@ -0,0 +1,139 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_imports)] + +// Test a sample usage pattern for regions. Makes use of the +// following features: +// +// - Multiple lifetime parameters +// - Arenas + +#![feature(rustc_private, libc)] + +extern crate rustc_arena; +extern crate libc; + +// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta +// files. +#[allow(unused_extern_crates)] +extern crate rustc_driver; + +use TypeStructure::{TypeInt, TypeFunction}; +use AstKind::{ExprInt, ExprVar, ExprLambda}; +use rustc_arena::TypedArena; +use std::collections::HashMap; +use std::mem; + +type Type<'tcx> = &'tcx TypeStructure<'tcx>; + +#[derive(Copy, Clone, Debug)] +enum TypeStructure<'tcx> { + TypeInt, + TypeFunction(Type<'tcx>, Type<'tcx>), +} + +impl<'tcx> PartialEq for TypeStructure<'tcx> { + fn eq(&self, other: &TypeStructure<'tcx>) -> bool { + match (*self, *other) { + (TypeInt, TypeInt) => true, + (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b, + _ => false + } + } +} + +impl<'tcx> Eq for TypeStructure<'tcx> {} + +type TyArena<'tcx> = TypedArena<TypeStructure<'tcx>>; +type AstArena<'ast> = TypedArena<AstStructure<'ast>>; + +struct TypeContext<'tcx, 'ast> { + ty_arena: &'tcx TyArena<'tcx>, + types: Vec<Type<'tcx>> , + type_table: HashMap<NodeId, Type<'tcx>>, + + ast_arena: &'ast AstArena<'ast>, + ast_counter: usize, +} + +impl<'tcx,'ast> TypeContext<'tcx, 'ast> { + fn new(ty_arena: &'tcx TyArena<'tcx>, ast_arena: &'ast AstArena<'ast>) + -> TypeContext<'tcx, 'ast> { + TypeContext { ty_arena: ty_arena, + types: Vec::new(), + type_table: HashMap::new(), + + ast_arena: ast_arena, + ast_counter: 0 } + } + + fn add_type(&mut self, s: TypeStructure<'tcx>) -> Type<'tcx> { + for &ty in &self.types { + if *ty == s { + return ty; + } + } + + let ty = self.ty_arena.alloc(s); + self.types.push(ty); + ty + } + + fn set_type(&mut self, id: NodeId, ty: Type<'tcx>) -> Type<'tcx> { + self.type_table.insert(id, ty); + ty + } + + fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> { + let id = self.ast_counter; + self.ast_counter += 1; + self.ast_arena.alloc(AstStructure { id: NodeId {id:id}, kind: a }) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +struct NodeId { + id: usize +} + +type Ast<'ast> = &'ast AstStructure<'ast>; + +#[derive(Copy, Clone)] +struct AstStructure<'ast> { + id: NodeId, + kind: AstKind<'ast> +} + +#[derive(Copy, Clone)] +enum AstKind<'ast> { + ExprInt, + ExprVar(usize), + ExprLambda(Ast<'ast>), +} + +fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>, + ast: Ast<'ast>) -> Type<'tcx> +{ + match ast.kind { + ExprInt | ExprVar(_) => { + let ty = tcx.add_type(TypeInt); + tcx.set_type(ast.id, ty) + } + ExprLambda(ast) => { + let arg_ty = tcx.add_type(TypeInt); + let body_ty = compute_types(tcx, ast); + let lambda_ty = tcx.add_type(TypeFunction(arg_ty, body_ty)); + tcx.set_type(ast.id, lambda_ty) + } + } +} + +pub fn main() { + let ty_arena = TypedArena::default(); + let ast_arena = TypedArena::default(); + let mut tcx = TypeContext::new(&ty_arena, &ast_arena); + let ast = tcx.ast(ExprInt); + let ty = compute_types(&mut tcx, ast); + assert_eq!(*ty, TypeInt); +} |