about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-01-02 20:00:56 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2019-01-02 20:00:56 +0000
commit5dfc5f205c5b2077a23dcbb3d42456ffa80e9bec (patch)
tree7733e48919fba7653c23830f2df31937934eb1d5
parentec194646fef1a467073ad74b8b68f6f202cfce97 (diff)
downloadrust-5dfc5f205c5b2077a23dcbb3d42456ffa80e9bec.tar.gz
rust-5dfc5f205c5b2077a23dcbb3d42456ffa80e9bec.zip
Wf-check the output type of a function in MIR-typeck
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs2
-rw-r--r--src/test/ui/nll/issue-57265-return-type-wf-check.rs26
-rw-r--r--src/test/ui/nll/issue-57265-return-type-wf-check.stderr12
3 files changed, 39 insertions, 1 deletions
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 796a2f79f75..8bb67521f44 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1452,7 +1452,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 self.check_call_dest(mir, term, &sig, destination, term_location);
 
                 self.prove_predicates(
-                    sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
+                    sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
                     term_location.to_locations(),
                     ConstraintCategory::Boring,
                 );
diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.rs b/src/test/ui/nll/issue-57265-return-type-wf-check.rs
new file mode 100644
index 00000000000..24c61a4926f
--- /dev/null
+++ b/src/test/ui/nll/issue-57265-return-type-wf-check.rs
@@ -0,0 +1,26 @@
+#![feature(nll)]
+
+use std::any::Any;
+
+#[derive(Debug, Clone)]
+struct S<T: 'static>(T);
+
+// S<&'a T> is in the return type, so we get an implied bound
+// &'a T: 'static
+fn foo<'a, T>(x: &'a T) -> (S<&'a T>, Box<dyn Any + 'static>) {
+    let y = S(x);
+
+    let z = Box::new(y.clone()) as Box<dyn Any + 'static>;
+    (y, z)
+}
+
+fn main() {
+    let x = 5;
+
+    // Check that we require that the argument is of type `&'static String`,
+    // so that the return type is well-formed.
+    let (_, z) = foo(&"hello".to_string());
+    //~^ ERROR temporary value dropped while borrowed
+
+    println!("{:?}", z.downcast_ref::<S<&'static String>>());
+}
diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr
new file mode 100644
index 00000000000..db01212597f
--- /dev/null
+++ b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr
@@ -0,0 +1,12 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-57265-return-type-wf-check.rs:22:23
+   |
+LL |     let (_, z) = foo(&"hello".to_string());
+   |                  -----^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
+   |                  |    |
+   |                  |    creates a temporary which is freed while still in use
+   |                  argument requires that borrow lasts for `'static`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.