about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-07-31 18:13:49 +0300
committerNiko Matsakis <niko@alum.mit.edu>2017-07-31 18:13:49 +0300
commit8f67f1efaf792a0c3ef629e1e62e53eba7365a1c (patch)
treeded11cf8d42c93120e8bc3c2c66fc78b09841273
parent851c77088db304f0fba5318db39b3b31521aa274 (diff)
downloadrust-8f67f1efaf792a0c3ef629e1e62e53eba7365a1c.tar.gz
rust-8f67f1efaf792a0c3ef629e1e62e53eba7365a1c.zip
add comments from arielb1
-rw-r--r--src/librustc_typeck/check/_match.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 01d2986a53c..eaff8e7b8ac 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -410,6 +410,49 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // is problematic as the HIR is being scraped, but ref bindings may be
         // implicit after #42640. We need to make sure that pat_adjustments
         // (once introduced) is populated by the time we get here.
+        //
+        // arielb1 [writes here in this comment thread][c] that there
+        // is certainly *some* potential danger, e.g. for an example
+        // like:
+        //
+        // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
+        //
+        // ```
+        // let Foo(x) = f()[0];
+        // ```
+        //
+        // Then if the pattern matches by reference, we want to match
+        // `f()[0]` as a lexpr, so we can't allow it to be
+        // coerced. But if the pattern matches by value, `f()[0]` is
+        // still syntactically a lexpr, but we *do* want to allow
+        // coercions.
+        //
+        // However, *likely* we are ok with allowing coercions to
+        // happen if there are no explicit ref mut patterns - all
+        // implicit ref mut patterns must occur behind a reference, so
+        // they will have the "correct" variance and lifetime.
+        //
+        // This does mean that the following pattern would be legal:
+        //
+        // ```
+        // struct Foo(Bar);
+        // struct Bar(u32);
+        // impl Deref for Foo {
+        //     type Target = Bar;
+        //     fn deref(&self) -> &Bar { &self.0 }
+        // }
+        // impl DerefMut for Foo {
+        //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
+        // }
+        // fn foo(x: &mut Foo) {
+        //     {
+        //         let Bar(z): &mut Bar = x;
+        //         *z = 42;
+        //     }
+        //     assert_eq!(foo.0.0, 42);
+        // }
+        // ```
+
         let contains_ref_bindings = arms.iter()
                                         .filter_map(|a| a.contains_explicit_ref_binding())
                                         .max_by_key(|m| match *m {