diff --git a/compiler/rustc_hir_analysis/src/check/expectation.rs b/compiler/rustc_hir_analysis/src/check/expectation.rs
index e9e810344776b..d017ded103f15 100644
--- a/compiler/rustc_hir_analysis/src/check/expectation.rs
+++ b/compiler/rustc_hir_analysis/src/check/expectation.rs
@@ -18,9 +18,13 @@ pub enum Expectation<'tcx> {
     /// This expression will be cast to the `Ty`.
     ExpectCastableToType(Ty<'tcx>),
 
-    /// This rvalue expression will be wrapped in `&` or `Box` and coerced
-    /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
-    ExpectRvalueLikeUnsized(Ty<'tcx>),
+    /// This rvalue expression will be deref'd to the type Ty.
+    ///
+    /// Given, for example, if you have let x: &Ty = &<foo>, this
+    /// hint would be given when type-checking <foo>. It is
+    /// not required that foo has the type Ty, but it must have some
+    /// type that derefs to Ty for the program to be legal.
+    ExpectRvalueDeref(Ty<'tcx>),
 
     IsLast(Span),
 }
@@ -48,7 +52,7 @@ impl<'a, 'tcx> Expectation<'tcx> {
                 let ety = fcx.shallow_resolve(ety);
                 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
             }
-            ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
+            ExpectRvalueDeref(ety) => ExpectRvalueDeref(ety),
             _ => NoExpectation,
         }
     }
@@ -74,7 +78,7 @@ impl<'a, 'tcx> Expectation<'tcx> {
     /// for examples of where this comes up,.
     pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
         match fcx.tcx.struct_tail_without_normalization(ty).kind() {
-            ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
+            ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueDeref(ty),
             _ => ExpectHasType(ty),
         }
     }
@@ -87,7 +91,7 @@ impl<'a, 'tcx> Expectation<'tcx> {
             NoExpectation => NoExpectation,
             ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(t)),
             ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(t)),
-            ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(t)),
+            ExpectRvalueDeref(t) => ExpectRvalueDeref(fcx.resolve_vars_if_possible(t)),
             IsLast(sp) => IsLast(sp),
         }
     }
@@ -95,7 +99,7 @@ impl<'a, 'tcx> Expectation<'tcx> {
     pub(super) fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
         match self.resolve(fcx) {
             NoExpectation | IsLast(_) => None,
-            ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
+            ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueDeref(ty) => Some(ty),
         }
     }
 
@@ -106,9 +110,7 @@ impl<'a, 'tcx> Expectation<'tcx> {
     pub(super) fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
         match self {
             ExpectHasType(ty) => Some(fcx.resolve_vars_if_possible(ty)),
-            NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) | IsLast(_) => {
-                None
-            }
+            NoExpectation | ExpectCastableToType(_) | ExpectRvalueDeref(_) | IsLast(_) => None,
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs
index 71c6da862c94b..30be33a6bbcf9 100644
--- a/compiler/rustc_hir_analysis/src/check/expr.rs
+++ b/compiler/rustc_hir_analysis/src/check/expr.rs
@@ -7,7 +7,9 @@ use crate::check::cast;
 use crate::check::coercion::CoerceMany;
 use crate::check::fatally_break_rust;
 use crate::check::method::SelfSource;
-use crate::check::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
+use crate::check::Expectation::{
+    self, ExpectCastableToType, ExpectHasType, ExpectRvalueDeref, NoExpectation,
+};
 use crate::check::{
     report_unexpected_variant_res, BreakableCtxt, Diverges, DynamicCoerceMany, FnCtxt, Needs,
     TupleArgumentsFlag::DontTupleArguments,
@@ -437,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // the last field of a struct can be unsized.
                         ExpectHasType(*ty)
                     } else {
-                        Expectation::rvalue_hint(self, *ty)
+                        ExpectRvalueDeref(*ty)
                     }
                 }
                 _ => NoExpectation,
diff --git a/src/test/ui/coercion/coerce-block-tail-26978.rs b/src/test/ui/coercion/coerce-block-tail-26978.rs
new file mode 100644
index 0000000000000..a9c19c78b1f29
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-26978.rs
@@ -0,0 +1,10 @@
+// check-pass
+fn f(_: &i32) {}
+
+fn main() {
+    let x = Box::new(1i32);
+
+    f(&x);
+    f(&(x));
+    f(&{x});
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-57749.rs b/src/test/ui/coercion/coerce-block-tail-57749.rs
new file mode 100644
index 0000000000000..632dd2e3ca6db
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-57749.rs
@@ -0,0 +1,34 @@
+// check-pass
+use std::ops::Deref;
+
+fn main() {
+    fn save(who: &str) {
+        println!("I'll save you, {}!", who);
+    }
+
+    struct Madoka;
+
+    impl Deref for Madoka {
+        type Target = str;
+        fn deref(&self) -> &Self::Target {
+            "Madoka"
+        }
+    }
+
+    save(&{ Madoka });
+
+    fn reset(how: &u32) {
+        println!("Reset {} times", how);
+    }
+
+    struct Homura;
+
+    impl Deref for Homura {
+        type Target = u32;
+        fn deref(&self) -> &Self::Target {
+            &42
+        }
+    }
+
+    reset(&{ Homura });
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-83783.rs b/src/test/ui/coercion/coerce-block-tail-83783.rs
new file mode 100644
index 0000000000000..d70dfd92fceab
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83783.rs
@@ -0,0 +1,12 @@
+// check-pass
+// edition:2018
+fn _consume_reference<T: ?Sized>(_: &T) {}
+
+async fn _foo() {
+    _consume_reference::<i32>(&Box::new(7_i32));
+    _consume_reference::<i32>(&async { Box::new(7_i32) }.await);
+    _consume_reference::<[i32]>(&vec![7_i32]);
+    _consume_reference::<[i32]>(&async { vec![7_i32] }.await);
+}
+
+fn main() { }
diff --git a/src/test/ui/coercion/coerce-block-tail-83850.rs b/src/test/ui/coercion/coerce-block-tail-83850.rs
new file mode 100644
index 0000000000000..77fdf99983332
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83850.rs
@@ -0,0 +1,7 @@
+// check-fail
+fn f(_: &[i32]) {}
+
+fn main() {
+    f(&Box::new([1, 2]));
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-83850.stderr b/src/test/ui/coercion/coerce-block-tail-83850.stderr
new file mode 100644
index 0000000000000..bbf6075437043
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83850.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-block-tail-83850.rs:5:7
+   |
+LL |     f(&Box::new([1, 2]));
+   |     - ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found struct `Box`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected reference `&[i32]`
+              found reference `&Box<[{integer}; 2]>`
+note: function defined here
+  --> $DIR/coerce-block-tail-83850.rs:2:4
+   |
+LL | fn f(_: &[i32]) {}
+   |    ^ ---------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail.rs b/src/test/ui/coercion/coerce-block-tail.rs
new file mode 100644
index 0000000000000..442660efe2606
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail.rs
@@ -0,0 +1,5 @@
+// check-pass
+fn main() {
+    let _: &str = & { String::from("hahah")};
+    let _: &i32 = & { Box::new(1i32) };
+}
diff --git a/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr b/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr
index 6ded03e45b55e..a06726c8b82e2 100644
--- a/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr
+++ b/src/test/ui/did_you_mean/brackets-to-braces-single-element.stderr
@@ -23,11 +23,13 @@ LL | const B: &[u32] = &[ 1 ];
    |                    ~   ~
 
 error[E0308]: mismatched types
-  --> $DIR/brackets-to-braces-single-element.rs:7:27
+  --> $DIR/brackets-to-braces-single-element.rs:7:23
    |
 LL | const C: &&[u32; 1] = &&{ 1 };
-   |                           ^ expected array `[u32; 1]`, found integer
+   |                       ^^^^^^^ expected array `[u32; 1]`, found integer
    |
+   = note: expected reference `&'static &'static [u32; 1]`
+              found reference `&&{integer}`
 help: to create an array, use square brackets instead of curly braces
    |
 LL | const C: &&[u32; 1] = &&[ 1 ];