about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2017-11-26 17:28:04 -0300
committerNiko Matsakis <niko@alum.mit.edu>2017-12-13 06:03:26 -0500
commit5010496677ee5eb2bdfcbf104eaaa19130d0dc17 (patch)
treef1b050c38eeffc0e85f6b88b46bbf93a55582ed4 /src
parentc9159262d161cd64d828f7821dca5e07926e34f2 (diff)
downloadrust-5010496677ee5eb2bdfcbf104eaaa19130d0dc17.tar.gz
rust-5010496677ee5eb2bdfcbf104eaaa19130d0dc17.zip
Check Aggregate predicates
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/transform/type_check.rs27
-rw-r--r--src/test/compile-fail/nll/where_clauses_in_structs.rs28
2 files changed, 55 insertions, 0 deletions
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 6c6ae3d02da..19c22d7017d 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -1168,6 +1168,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     ) {
         let tcx = self.tcx();
 
+        self.prove_aggregate_predicates(aggregate_kind, location);
+
         match aggregate_kind {
             // tuple rvalue field type is always the type of the op. Nothing to check here.
             AggregateKind::Tuple => return,
@@ -1235,6 +1237,31 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         }
     }
 
+    fn prove_aggregate_predicates(
+        &mut self,
+        aggregate_kind: &AggregateKind<'tcx>,
+        location: Location,
+    ) {
+        let tcx = self.tcx();
+
+        let instantiated_predicates = match aggregate_kind {
+            AggregateKind::Adt(def, _, substs, _) => {
+                tcx.predicates_of(def.did).instantiate(tcx, substs)
+            }
+
+            AggregateKind::Closure(def_id, substs) |
+            AggregateKind::Generator(def_id, substs, _) => {
+                tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
+            }
+
+            AggregateKind::Array(_) |
+            AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
+        };
+
+        let predicates = self.normalize(&instantiated_predicates.predicates, location);
+        self.prove_predicates(&predicates, location);
+    }
+
     fn prove_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>, location: Location) {
         self.prove_predicates(
             &[
diff --git a/src/test/compile-fail/nll/where_clauses_in_structs.rs b/src/test/compile-fail/nll/where_clauses_in_structs.rs
new file mode 100644
index 00000000000..0c4fd5dead3
--- /dev/null
+++ b/src/test/compile-fail/nll/where_clauses_in_structs.rs
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+// compile-flags: -Z borrowck=mir -Z nll
+
+#![allow(dead_code)]
+
+use std::cell::Cell;
+
+struct Foo<'a: 'b, 'b> {
+    x: Cell<&'a u32>,
+    y: Cell<&'b u32>,
+}
+
+fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) {
+    Foo { x, y };
+    //~^ ERROR free region `'_#1r` does not outlive free region `'_#2r`
+    //~| WARNING not reporting region error due to -Znll
+}
+
+fn main() {}