From 9a5e7ba4c7eefb2f40389966c562fbadcc778625 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 27 Oct 2014 14:03:25 -0400 Subject: [PATCH] Teach variance checker about the lifetime bounds that appear in trait object types. --- src/librustc/middle/typeck/variance.rs | 6 ++++- .../variance-trait-object-bound.rs | 26 +++++++++++++++++++ src/test/run-pass/issue-16668.rs | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/variance-trait-object-bound.rs diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index 5e62a8e9451..9a90381854a 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -778,7 +778,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { variance); } - ty::ty_trait(box ty::TyTrait { def_id, ref substs, .. }) => { + ty::ty_trait(box ty::TyTrait { def_id, ref substs, bounds }) => { let trait_def = ty::lookup_trait_def(self.tcx(), def_id); let generics = &trait_def.generics; @@ -796,6 +796,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { assert!(generics.types.is_empty_in(subst::FnSpace)); assert!(generics.regions.is_empty_in(subst::FnSpace)); + // The type `Foo` is contravariant w/r/t `'a`: + let contra = self.contravariant(variance); + self.add_constraints_from_region(bounds.region_bound, contra); + self.add_constraints_from_substs( def_id, generics.types.get_slice(subst::TypeSpace), diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs new file mode 100644 index 00000000000..c61f2ff79c0 --- /dev/null +++ b/src/test/compile-fail/variance-trait-object-bound.rs @@ -0,0 +1,26 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Checks that regions which appear in a trait object type are +// observed by the variance inference algorithm (and hence +// `TOption` is contavariant w/r/t `'a` and not bivariant). +// +// Issue #18262. + +use std::mem; + +trait T { fn foo(); } + +#[rustc_variance] +struct TOption<'a> { //~ ERROR regions=[[-];[];[]] + v: Option>, +} + +fn main() { } diff --git a/src/test/run-pass/issue-16668.rs b/src/test/run-pass/issue-16668.rs index b66fb4306d0..92f8030a0dc 100644 --- a/src/test/run-pass/issue-16668.rs +++ b/src/test/run-pass/issue-16668.rs @@ -17,7 +17,7 @@ struct Parser<'a, I, O> { } impl<'a, I, O: 'a> Parser<'a, I, O> { - fn compose(mut self, mut rhs: Parser) -> Parser<'a, I, K> { + fn compose(mut self, mut rhs: Parser<'a, O, K>) -> Parser<'a, I, K> { Parser { parse: box move |&mut: x: I| { match self.parse.call_mut((x,)) {