diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2013-11-08 16:19:28 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2013-11-08 19:47:57 -0500 |
| commit | f4f4a35b5b1fe54b05b2dac3428c55ef2d3923b1 (patch) | |
| tree | 3b83560a12576c1d39ff2f5fd518cbbac88849a5 | |
| parent | f36a891fe22f656454b70b8f2aa64bef9133e7f0 (diff) | |
| download | rust-f4f4a35b5b1fe54b05b2dac3428c55ef2d3923b1.tar.gz rust-f4f4a35b5b1fe54b05b2dac3428c55ef2d3923b1.zip | |
Add new tests showing multiple lifetime parameters in use
3 files changed, 165 insertions, 2 deletions
diff --git a/src/test/compile-fail/regions-variance-contravariant-use-covariant-in-second-position.rs b/src/test/compile-fail/regions-variance-contravariant-use-covariant-in-second-position.rs new file mode 100644 index 00000000000..77a54fec7bf --- /dev/null +++ b/src/test/compile-fail/regions-variance-contravariant-use-covariant-in-second-position.rs @@ -0,0 +1,39 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that a type which is covariant with respect to its region +// parameter yields an error when used in a contravariant way. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +// `S` is contravariant with respect to both parameters. +struct S<'a, 'b> { + f: &'a int, + g: &'b int, +} + +fn use_<'short,'long>(c: S<'long, 'short>, + s: &'short int, + l: &'long int, + _where:Option<&'short &'long ()>) { + + let _: S<'long, 'short> = c; // OK + let _: S<'short, 'short> = c; // OK + + // Test whether S<_,'short> <: S<_,'long>. Since + // 'short <= 'long, this would be true if the Contravariant type were + // covariant with respect to its parameter 'a. + + let _: S<'long, 'long> = c; //~ ERROR mismatched types + //~^ ERROR cannot infer an appropriate lifetime +} + +fn main() {} diff --git a/src/test/compile-fail/regions-variance-contravariant-use-covariant.rs b/src/test/compile-fail/regions-variance-contravariant-use-covariant.rs index 5ac4afb6bfc..3f0161d9deb 100644 --- a/src/test/compile-fail/regions-variance-contravariant-use-covariant.rs +++ b/src/test/compile-fail/regions-variance-contravariant-use-covariant.rs @@ -14,8 +14,8 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. -// This is covariant with respect to 'a, meaning that -// Covariant<'foo> <: Covariant<'static> because +// This is contravariant with respect to 'a, meaning that +// Contravariant<'foo> <: Contravariant<'static> because // 'foo <= 'static struct Contravariant<'a> { f: &'a int diff --git a/src/test/run-pass/regions-mock-tcx.rs b/src/test/run-pass/regions-mock-tcx.rs new file mode 100644 index 00000000000..f98e475094c --- /dev/null +++ b/src/test/run-pass/regions-mock-tcx.rs @@ -0,0 +1,124 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test a sample usage pattern for regions. Makes use of the +// following features: +// +// - Multiple lifetime parameters +// - Arenas + +extern mod extra; + +use extra::arena; +use extra::arena::Arena; +use std::hashmap::HashMap; +use std::cast; +use std::libc; +use std::mem; + +type Type<'tcx> = &'tcx TypeStructure<'tcx>; + +#[deriving(Eq)] +enum TypeStructure<'tcx> { + TypeInt, + TypeFunction(Type<'tcx>, Type<'tcx>), +} + +struct TypeContext<'tcx, 'ast> { + ty_arena: &'tcx Arena, + types: ~[Type<'tcx>], + type_table: HashMap<NodeId, Type<'tcx>>, + + ast_arena: &'ast Arena, + ast_counter: uint, +} + +impl<'tcx,'ast> TypeContext<'tcx, 'ast> { + fn new(ty_arena: &'tcx Arena, ast_arena: &'ast Arena) + -> TypeContext<'tcx, 'ast> { + TypeContext { ty_arena: ty_arena, + types: ~[], + 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.iter() { + 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 }) + } +} + +#[deriving(Eq, IterBytes)] +struct NodeId { + id: uint +} + +type Ast<'ast> = &'ast AstStructure<'ast>; + +struct AstStructure<'ast> { + id: NodeId, + kind: AstKind<'ast> +} + +enum AstKind<'ast> { + ExprInt, + ExprVar(uint), + 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 = arena::Arena::new(); + let ast_arena = arena::Arena::new(); + 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); +} |
