From b83daea479ceee19445058001ed0a6412ec25889 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 26 May 2018 11:47:38 +0100 Subject: [PATCH] Register outlives predicates from queries the right way around. --- src/librustc_traits/util.rs | 12 +++++---- src/test/ui/nll/normalization-bounds-error.rs | 26 +++++++++++++++++++ .../ui/nll/normalization-bounds-error.stderr | 23 ++++++++++++++++ src/test/ui/nll/normalization-bounds.rs | 26 +++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/nll/normalization-bounds-error.rs create mode 100644 src/test/ui/nll/normalization-bounds-error.stderr create mode 100644 src/test/ui/nll/normalization-bounds.rs diff --git a/src/librustc_traits/util.rs b/src/librustc_traits/util.rs index e4cb118a4f7f8..cdf20bdafadc4 100644 --- a/src/librustc_traits/util.rs +++ b/src/librustc_traits/util.rs @@ -74,17 +74,19 @@ where let mut outlives: Vec<_> = constraints .into_iter() .map(|(k, _)| match *k { + // Swap regions because we are going from sub (<=) to outlives + // (>=). Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate( - tcx.mk_region(ty::ReVar(v1)).into(), - tcx.mk_region(ty::ReVar(v2)), + tcx.mk_region(ty::ReVar(v2)).into(), + tcx.mk_region(ty::ReVar(v1)), ), Constraint::VarSubReg(v1, r2) => { - ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v1)).into(), r2) + ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1))) } Constraint::RegSubVar(r1, v2) => { - ty::OutlivesPredicate(r1.into(), tcx.mk_region(ty::ReVar(v2))) + ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1) } - Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r1.into(), r2), + Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1), }) .map(ty::Binder::dummy) // no bound regions in the code above .collect(); diff --git a/src/test/ui/nll/normalization-bounds-error.rs b/src/test/ui/nll/normalization-bounds-error.rs new file mode 100644 index 0000000000000..65b5cc12478c8 --- /dev/null +++ b/src/test/ui/nll/normalization-bounds-error.rs @@ -0,0 +1,26 @@ +// Copyright 2018 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. + +// Check that we error when a bound from the impl is not satisfied when +// normalizing an associated type. + +#![feature(nll)] +trait Visitor<'d> { + type Value; +} + +impl<'a, 'd: 'a> Visitor<'d> for &'a () { + type Value = (); +} + +fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} +//~^ ERROR + +fn main() {} diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr new file mode 100644 index 0000000000000..970384f9d56ff --- /dev/null +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -0,0 +1,23 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements + --> $DIR/normalization-bounds-error.rs:23:1 + | +LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 23:1... + --> $DIR/normalization-bounds-error.rs:23:1 + | +LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 23:1... + --> $DIR/normalization-bounds-error.rs:23:1 + | +LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...so that the types are compatible: + expected Visitor<'d> + found Visitor<'_> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/nll/normalization-bounds.rs b/src/test/ui/nll/normalization-bounds.rs new file mode 100644 index 0000000000000..722a6c00e750c --- /dev/null +++ b/src/test/ui/nll/normalization-bounds.rs @@ -0,0 +1,26 @@ +// Copyright 2018 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. + +// Check that lifetime bounds get checked the right way around with NLL enabled. + +//run-pass + +#![feature(nll)] +trait Visitor<'d> { + type Value; +} + +impl<'a, 'd: 'a> Visitor<'d> for &'a () { + type Value = (); +} + +fn visit_seq<'d: 'a, 'a>() -> <&'a () as Visitor<'d>>::Value {} + +fn main() {}