about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-11-19 10:26:04 -0500
committerNiko Matsakis <niko@alum.mit.edu>2019-01-02 17:35:06 -0500
commitbc4404c0b501729cc5df05544e5f0784789f4215 (patch)
tree82de553fe5dd5c502c28d9e5f5714f17126d6198
parenta24e04dff6b9b92bbec791c61a69876401d10512 (diff)
downloadrust-bc4404c0b501729cc5df05544e5f0784789f4215.tar.gz
rust-bc4404c0b501729cc5df05544e5f0784789f4215.zip
improve handling for subtype
Still not great, but good enough to land this PR.
-rw-r--r--src/librustc/infer/error_reporting/mod.rs47
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs110
-rw-r--r--src/librustc/infer/error_reporting/note.rs20
-rw-r--r--src/librustc/infer/mod.rs2
-rw-r--r--src/librustc/ty/error.rs20
-rw-r--r--src/librustc/ty/structural_impls.rs10
-rw-r--r--src/librustc/ty/sty.rs7
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.bad.stderr22
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.good.stderr2
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.rs2
-rw-r--r--src/test/ui/closure-expected-type/expect-fn-supply-fn.rs2
-rw-r--r--src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr42
-rw-r--r--src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr13
-rw-r--r--src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr12
-rw-r--r--src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr13
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-fn.rs2
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-fn.stderr24
-rw-r--r--src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr4
-rw-r--r--src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs2
-rw-r--r--src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr50
-rw-r--r--src/test/ui/hrtb/hrtb-perfect-forwarding.rs2
-rw-r--r--src/test/ui/hrtb/hrtb-perfect-forwarding.stderr22
-rw-r--r--src/test/ui/issues/issue-40000.rs2
-rw-r--r--src/test/ui/issues/issue-40000.stderr26
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.rs2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.stderr15
-rw-r--r--src/test/ui/mismatched_types/closure-arg-type-mismatch.rs2
-rw-r--r--src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr48
-rw-r--r--src/test/ui/mismatched_types/closure-mismatch.rs2
-rw-r--r--src/test/ui/mismatched_types/closure-mismatch.stderr15
-rw-r--r--src/test/ui/regions-fn-subtyping-return-static-fail.stderr13
-rw-r--r--src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs2
-rw-r--r--src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr17
-rw-r--r--src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs2
-rw-r--r--src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr17
-rw-r--r--src/test/ui/regions/regions-lifetime-bounds-on-fns.rs2
-rw-r--r--src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr17
37 files changed, 233 insertions, 379 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index d0cb718f55a..4cce8343c02 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -132,12 +132,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
             ty::ReEmpty => ("the empty lifetime".to_owned(), None),
 
+            ty::RePlaceholder(_) => (format!("any other region"), None),
+
             // FIXME(#13998) RePlaceholder should probably print like
             // ReFree rather than dumping Debug output on the user.
             //
             // We shouldn't really be having unification failures with ReVar
             // and ReLateBound though.
-            ty::RePlaceholder(..) | ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
+            ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
                 (format!("lifetime {:?}", region), None)
             }
 
@@ -324,8 +326,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     // the error. If all of these fails, we fall back to a rather
                     // general bit of code that displays the error information
                     RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
-                        self.report_concrete_failure(region_scope_tree, origin, sub, sup)
-                            .emit();
+                        if sub.is_placeholder() || sup.is_placeholder() {
+                            self.report_placeholder_failure(region_scope_tree, origin, sub, sup)
+                                .emit();
+                        } else {
+                            self.report_concrete_failure(region_scope_tree, origin, sub, sup)
+                                .emit();
+                        }
                     }
 
                     RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => {
@@ -346,14 +353,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         sup_origin,
                         sup_r,
                     ) => {
-                        self.report_sub_sup_conflict(
-                            region_scope_tree,
-                            var_origin,
-                            sub_origin,
-                            sub_r,
-                            sup_origin,
-                            sup_r,
-                        );
+                        if sub_r.is_placeholder() {
+                            self.report_placeholder_failure(
+                                region_scope_tree,
+                                sub_origin,
+                                sub_r,
+                                sup_r,
+                            )
+                                .emit();
+                        } else if sup_r.is_placeholder() {
+                            self.report_placeholder_failure(
+                                region_scope_tree,
+                                sup_origin,
+                                sub_r,
+                                sup_r,
+                            )
+                                .emit();
+                        } else {
+                            self.report_sub_sup_conflict(
+                                region_scope_tree,
+                                var_origin,
+                                sub_origin,
+                                sub_r,
+                                sup_origin,
+                                sup_r,
+                            );
+                        }
                     }
                 }
             }
diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
index 07a61eb6d77..0dda636a9bd 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -14,9 +14,16 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
     /// an anonymous region, emit an descriptive diagnostic error.
     pub(super) fn try_report_placeholder_conflict(&self) -> Option<ErrorReported> {
-        // Check for the first case: relating two trait-refs, and we
-        // find a conflict between two placeholders.
         match &self.error {
+            ///////////////////////////////////////////////////////////////////////////
+            // NB. The ordering of cases in this match is very
+            // sensitive, because we are often matching against
+            // specific cases and then using an `_` to match all
+            // others.
+
+            ///////////////////////////////////////////////////////////////////////////
+            // Check for errors from comparing trait failures -- first
+            // with two placeholders, then with one.
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
@@ -27,8 +34,10 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                 sub_placeholder @ ty::RePlaceholder(_),
                 _,
                 sup_placeholder @ ty::RePlaceholder(_),
-            )) => if expected.def_id == found.def_id {
-                return Some(self.try_report_placeholders_trait(
+            ))
+                if expected.def_id == found.def_id =>
+            {
+                Some(self.try_report_placeholders_trait(
                     Some(self.tcx.mk_region(ty::ReVar(*vid))),
                     cause,
                     Some(sub_placeholder),
@@ -36,10 +45,8 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                     expected.def_id,
                     expected.substs,
                     found.substs,
-                ));
-            } else {
-                // I actually can't see why this would be the case ever.
-            },
+                ))
+            }
 
             Some(RegionResolutionError::SubSupConflict(
                 vid,
@@ -51,8 +58,10 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                 sub_placeholder @ ty::RePlaceholder(_),
                 _,
                 _,
-            )) => if expected.def_id == found.def_id {
-                return Some(self.try_report_placeholders_trait(
+            ))
+                if expected.def_id == found.def_id =>
+            {
+                Some(self.try_report_placeholders_trait(
                     Some(self.tcx.mk_region(ty::ReVar(*vid))),
                     cause,
                     Some(sub_placeholder),
@@ -60,10 +69,8 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                     expected.def_id,
                     expected.substs,
                     found.substs,
-                ));
-            } else {
-                // I actually can't see why this would be the case ever.
-            },
+                ))
+            }
 
             Some(RegionResolutionError::SubSupConflict(
                 vid,
@@ -75,8 +82,10 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                 _,
                 _,
                 sup_placeholder @ ty::RePlaceholder(_),
-            )) => if expected.def_id == found.def_id {
-                return Some(self.try_report_placeholders_trait(
+            ))
+                if expected.def_id == found.def_id =>
+            {
+                Some(self.try_report_placeholders_trait(
                     Some(self.tcx.mk_region(ty::ReVar(*vid))),
                     cause,
                     None,
@@ -84,17 +93,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                     expected.def_id,
                     expected.substs,
                     found.substs,
-                ));
-            } else {
-                // I actually can't see why this would be the case ever.
-            },
-
-            Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(TypeTrace { .. }),
-                ty::RePlaceholder(_),
-                ty::RePlaceholder(_),
-            )) => {
-                // I actually can't see why this would be the case ever.
+                ))
             }
 
             Some(RegionResolutionError::ConcreteFailure(
@@ -102,21 +101,21 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
-                sub_region,
+                sub_region @ ty::RePlaceholder(_),
                 sup_region @ ty::RePlaceholder(_),
-            )) => if expected.def_id == found.def_id {
-                return Some(self.try_report_placeholders_trait(
-                    Some(sub_region),
-                    cause,
+            ))
+                if expected.def_id == found.def_id =>
+            {
+                Some(self.try_report_placeholders_trait(
                     None,
+                    cause,
+                    Some(*sub_region),
                     Some(*sup_region),
                     expected.def_id,
                     expected.substs,
                     found.substs,
-                ));
-            } else {
-                // I actually can't see why this would be the case ever.
-            },
+                ))
+            }
 
             Some(RegionResolutionError::ConcreteFailure(
                 SubregionOrigin::Subtype(TypeTrace {
@@ -125,24 +124,43 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
                 }),
                 sub_region @ ty::RePlaceholder(_),
                 sup_region,
-            )) => if expected.def_id == found.def_id {
-                return Some(self.try_report_placeholders_trait(
+            ))
+                if expected.def_id == found.def_id =>
+            {
+                Some(self.try_report_placeholders_trait(
                     Some(sup_region),
                     cause,
-                    None,
                     Some(*sub_region),
+                    None,
                     expected.def_id,
                     expected.substs,
                     found.substs,
-                ));
-            } else {
-                // I actually can't see why this would be the case ever.
-            },
+                ))
+            }
 
-            _ => {}
-        }
+            Some(RegionResolutionError::ConcreteFailure(
+                SubregionOrigin::Subtype(TypeTrace {
+                    cause,
+                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
+                }),
+                sub_region,
+                sup_region @ ty::RePlaceholder(_),
+            ))
+                if expected.def_id == found.def_id =>
+            {
+                Some(self.try_report_placeholders_trait(
+                    Some(sub_region),
+                    cause,
+                    None,
+                    Some(*sup_region),
+                    expected.def_id,
+                    expected.substs,
+                    found.substs,
+                ))
+            }
 
-        None
+            _ => None,
+        }
     }
 
     // error[E0308]: implementation of `Foo` does not apply to enough lifetimes
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index 91da3197d3c..e45a4b17cdd 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -442,4 +442,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
         }
     }
+
+    pub(super) fn report_placeholder_failure(
+        &self,
+        region_scope_tree: &region::ScopeTree,
+        placeholder_origin: SubregionOrigin<'tcx>,
+        sub: Region<'tcx>,
+        sup: Region<'tcx>,
+    ) -> DiagnosticBuilder<'tcx> {
+        // I can't think how to do better than this right now. -nikomatsakis
+        match placeholder_origin {
+            infer::Subtype(trace) => {
+                let terr = TypeError::RegionsPlaceholderMismatch;
+                self.report_and_explain_type_error(trace, &terr)
+            }
+
+            _ => {
+                self.report_concrete_failure(region_scope_tree, placeholder_origin, sub, sup)
+            }
+        }
+    }
 }
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 3b9affa6ffb..461e09819d9 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -225,7 +225,7 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
 pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
 
 /// See `error_reporting` module for more details
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum ValuePairs<'tcx> {
     Types(ExpectedFound<Ty<'tcx>>),
     Regions(ExpectedFound<ty::Region<'tcx>>),
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 6b931e39a05..76e102d88d7 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -1,5 +1,5 @@
 use hir::def_id::DefId;
-use ty::{self, BoundRegion, Region, Ty, TyCtxt};
+use ty::{self, Region, Ty, TyCtxt};
 use std::borrow::Cow;
 use std::fmt;
 use rustc_target::spec::abi;
@@ -9,7 +9,7 @@ use syntax_pos::Span;
 
 use hir;
 
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub struct ExpectedFound<T> {
     pub expected: T,
     pub found: T,
@@ -27,8 +27,7 @@ pub enum TypeError<'tcx> {
     ArgCount,
 
     RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
-    RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>),
-    RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>),
+    RegionsPlaceholderMismatch,
 
     Sorts(ExpectedFound<Ty<'tcx>>),
     IntMismatch(ExpectedFound<ty::IntVarValue>),
@@ -102,17 +101,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             RegionsDoesNotOutlive(..) => {
                 write!(f, "lifetime mismatch")
             }
-            RegionsInsufficientlyPolymorphic(br, _) => {
-                write!(f,
-                       "expected bound lifetime parameter{}{}, found concrete lifetime",
-                       if br.is_named() { " " } else { "" },
-                       br)
-            }
-            RegionsOverlyPolymorphic(br, _) => {
-                write!(f,
-                       "expected concrete lifetime, found bound lifetime parameter{}{}",
-                       if br.is_named() { " " } else { "" },
-                       br)
+            RegionsPlaceholderMismatch => {
+                write!(f, "one type is more general than the other")
             }
             Sorts(values) => ty::tls::with(|tcx| {
                 report_maybe_different(f, &values.expected.sort_string(tcx),
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 4755adc4cd1..f9b43f42d52 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -434,12 +434,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             RegionsDoesNotOutlive(a, b) => {
                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
             }
-            RegionsInsufficientlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
-            }
-            RegionsOverlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
-            }
+            RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
             Traits(x) => Traits(x),
@@ -1006,8 +1001,7 @@ EnumTypeFoldableImpl! {
         (ty::error::TypeError::FixedArraySize)(x),
         (ty::error::TypeError::ArgCount),
         (ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
-        (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
-        (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
+        (ty::error::TypeError::RegionsPlaceholderMismatch),
         (ty::error::TypeError::IntMismatch)(x),
         (ty::error::TypeError::FloatMismatch)(x),
         (ty::error::TypeError::Traits)(x),
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index f7adb83f8eb..a2720bdf385 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1396,6 +1396,13 @@ impl RegionKind {
         }
     }
 
+    pub fn is_placeholder(&self) -> bool {
+        match *self {
+            ty::RePlaceholder(..) => true,
+            _ => false,
+        }
+    }
+
     pub fn bound_at_or_above_binder(&self, index: DebruijnIndex) -> bool {
         match *self {
             ty::ReLateBound(debruijn, _) => debruijn >= index,
diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
index b5355e60099..e4704494e14 100644
--- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
+++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
@@ -1,24 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/higher-ranked-projection.rs:25:5
    |
 LL |     foo(());
-   |     ^^^
+   |     ^^^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U2, name: BrNamed(crate0:DefIndex(1:12), 'a) })...
-   = note: ...so that the types are compatible:
-           expected Mirror
-              found Mirror
-note: but, the lifetime must be valid for the expression at 25:5...
-  --> $DIR/higher-ranked-projection.rs:25:5
-   |
-LL |     foo(());
-   |     ^^^
-note: ...so type `fn(()) {foo::<&(), ()>}` of expression is valid during the expression
-  --> $DIR/higher-ranked-projection.rs:25:5
-   |
-LL |     foo(());
-   |     ^^^
+   = note: expected type `Mirror`
+              found type `Mirror`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr
index a837df0cd24..db15ec51d87 100644
--- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr
+++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr
@@ -3,7 +3,7 @@ error: compilation successful
    |
 LL | / fn main() { //[good]~ ERROR compilation successful
 LL | |     foo(());
-LL | |     //[bad]~^ ERROR E0495
+LL | |     //[bad]~^ ERROR E0308
 LL | | }
    | |_^
 
diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs
index 2d2221c6c63..5b380c982f0 100644
--- a/src/test/ui/associated-types/higher-ranked-projection.rs
+++ b/src/test/ui/associated-types/higher-ranked-projection.rs
@@ -23,5 +23,5 @@ fn foo<U, T>(_t: T)
 #[rustc_error]
 fn main() { //[good]~ ERROR compilation successful
     foo(());
-    //[bad]~^ ERROR E0495
+    //[bad]~^ ERROR E0308
 }
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs
index 49f6565540b..6977fd47a2e 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs
@@ -44,7 +44,7 @@ fn expect_bound_supply_free_from_closure() {
     // the argument level.
     type Foo<'a> = fn(&'a u32);
     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-    //~^ ERROR cannot infer
+    //~^ ERROR mismatched types
     });
 }
 
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
index d140e9989a3..b1cfd6cef10 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -40,57 +40,29 @@ error[E0308]: mismatched types
   --> $DIR/expect-fn-supply-fn.rs:30:52
    |
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |                                                    ^^^^^^^^ lifetime mismatch
+   |                                                    ^^^^^^^^ one type is more general than the other
    |
    = note: expected type `fn(&u32)`
               found type `for<'r> fn(&'r u32)`
-   = note: lifetime RePlaceholder(Placeholder { universe: U2, name: BrAnon(0) })...
-note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 30:48
-  --> $DIR/expect-fn-supply-fn.rs:30:48
-   |
-LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |                                                ^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/expect-fn-supply-fn.rs:37:53
    |
 LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-   |                                                     ^^^^^^^^^^^ lifetime mismatch
+   |                                                     ^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected type `for<'r> fn(&'r u32)`
               found type `fn(&'x u32)`
-   = note: lifetime RePlaceholder(Placeholder { universe: U3, name: BrAnon(0) })...
-note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 34:37
-  --> $DIR/expect-fn-supply-fn.rs:34:37
-   |
-LL | fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
-   |                                     ^^
 
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/expect-fn-supply-fn.rs:46:53
    |
 LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |                                                     ^^^^^^^
-   |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U3, name: BrAnon(0) })...
-   = note: ...so that the types are compatible:
-           expected for<'r> fn(&'r u32)
-              found fn(&u32)
-note: but, the lifetime must be valid for the expression at 46:65...
-  --> $DIR/expect-fn-supply-fn.rs:46:65
+   |                                                     ^^^^^^^ one type is more general than the other
    |
-LL |       with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |  _________________________________________________________________^
-LL | |     //~^ ERROR cannot infer
-LL | |     });
-   | |_____^
-note: ...so that the type `fn(&u32)` will meet its required lifetime bounds
-  --> $DIR/expect-fn-supply-fn.rs:46:53
-   |
-LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |                                                     ^^^^^^^
+   = note: expected type `for<'r> fn(&'r u32)`
+              found type `fn(&u32)`
 
 error: aborting due to 5 previous errors
 
-Some errors occurred: E0308, E0495.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr
index 4069e3b25ad..bdfabdabbeb 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr
@@ -1,19 +1,16 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:39:26
    |
 LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^
+   |                            ^^^^^^^^^^^ one type is more general than the other
 ...
 LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32,
 LL | |                                             for<'a>    fn(&'a u32, &'a u32) -> &'a u32) }
    | |_________________________________________________________________________________________- in this macro invocation
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U1, name: BrNamed(crate0:DefIndex(1:26), 'b) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U1, name: BrNamed(crate0:DefIndex(1:25), 'a) })...
-   = note: ...so that the expression is assignable:
-           expected std::option::Option<for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32>
-              found std::option::Option<for<'a> fn(&'a u32, &'a u32) -> &'a u32>
+   = note: expected type `std::option::Option<for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32>`
+              found type `std::option::Option<for<'a> fn(&'a u32, &'a u32) -> &'a u32>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr
index bb1a828f3da..74b8c89b6e8 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:39:26
    |
 LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^ lifetime mismatch
+   |                            ^^^^^^^^^^^ one type is more general than the other
 ...
 LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
 LL | |                              fn(&'x u32)) }
@@ -10,16 +10,6 @@ LL | |                              fn(&'x u32)) }
    |
    = note: expected type `std::option::Option<for<'a> fn(&'a u32)>`
               found type `std::option::Option<fn(&'x u32)>`
-   = note: lifetime RePlaceholder(Placeholder { universe: U1, name: BrNamed(crate0:DefIndex(1:23), 'a) })...
-note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 38:22
-  --> $DIR/hr-subtype.rs:38:22
-   |
-LL |           fn supertype<'x,'y:'x,'z:'y>() {
-   |                        ^^
-...
-LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
-LL | |                              fn(&'x u32)) }
-   | |___________________________________________- in this macro invocation
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr
index 1a806bd2cb5..8168941e277 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr
@@ -1,19 +1,16 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:39:26
    |
 LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^
+   |                            ^^^^^^^^^^^ one type is more general than the other
 ...
 LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
 LL | |                                         for<'a>    fn(Inv<'a>, Inv<'a>)) }
    | |__________________________________________________________________________- in this macro invocation
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U1, name: BrNamed(crate0:DefIndex(1:25), 'a) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U1, name: BrNamed(crate0:DefIndex(1:26), 'b) })...
-   = note: ...so that the expression is assignable:
-           expected std::option::Option<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>
-              found std::option::Option<for<'a> fn(Inv<'a>, Inv<'a>)>
+   = note: expected type `std::option::Option<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>`
+              found type `std::option::Option<for<'a> fn(Inv<'a>, Inv<'a>)>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.rs b/src/test/ui/hrtb/hrtb-exists-forall-fn.rs
index bba1f4dfb86..24182d76b35 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-fn.rs
+++ b/src/test/ui/hrtb/hrtb-exists-forall-fn.rs
@@ -19,5 +19,5 @@ fn main() {
     //     yielding `fn(&!b u32)`, in a fresh universe U1
     //   - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
 
-    let _: for<'b> fn(&'b u32) = foo(); //~ ERROR cannot infer
+    let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types
 }
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr
index 75ba89f58da..4a2a619298c 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr
@@ -1,24 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/hrtb-exists-forall-fn.rs:22:34
    |
-LL |     let _: for<'b> fn(&'b u32) = foo(); //~ ERROR cannot infer
-   |                                  ^^^
+LL |     let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types
+   |                                  ^^^^^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U1, name: BrNamed(crate0:DefIndex(1:11), 'b) })...
-   = note: ...so that the expression is assignable:
-           expected for<'b> fn(&'b u32)
-              found fn(&u32)
-note: but, the lifetime must be valid for the call at 22:34...
-  --> $DIR/hrtb-exists-forall-fn.rs:22:34
-   |
-LL |     let _: for<'b> fn(&'b u32) = foo(); //~ ERROR cannot infer
-   |                                  ^^^^^
-note: ...so type `fn(&u32)` of expression is valid during the expression
-  --> $DIR/hrtb-exists-forall-fn.rs:22:34
-   |
-LL |     let _: for<'b> fn(&'b u32) = foo(); //~ ERROR cannot infer
-   |                                  ^^^^^
+   = note: expected type `for<'b> fn(&'b u32)`
+              found type `fn(&u32)`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
index b02764184fb..0d7b5cbf823 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -2,12 +2,10 @@ error[E0308]: mismatched types
   --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
    |
 LL |     want_bar_for_any_ccx(b); //~ ERROR
-   |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |     ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected type `for<'ccx> Bar<'ccx>`
               found type `Bar<'static>`
-   = note: lifetime RePlaceholder(Placeholder { universe: U4, name: BrNamed(crate0:DefIndex(1:16), 'ccx) })...
-   = note: ...does not necessarily outlive the static lifetime
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs
index 638587f428d..3d2d403462d 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs
@@ -16,7 +16,6 @@ fn want_foo_for_some_tcx<'x,F>(f: &'x F)
 {
     want_foo_for_some_tcx(f);
     want_foo_for_any_tcx(f); //~ ERROR E0308
-    //~^ ERROR E0308
 }
 
 fn want_foo_for_any_tcx<F>(f: &F)
@@ -34,7 +33,6 @@ fn want_bar_for_some_ccx<'x,B>(b: &B)
 
     want_bar_for_some_ccx(b);
     want_bar_for_any_ccx(b); //~ ERROR E0308
-    //~^ ERROR E0308
 }
 
 fn want_bar_for_any_ccx<B>(b: &B)
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
index 71ed59ce2ff..31dbeec2a55 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
@@ -2,62 +2,20 @@ error[E0308]: mismatched types
   --> $DIR/hrtb-higher-ranker-supertraits.rs:18:5
    |
 LL |     want_foo_for_any_tcx(f); //~ ERROR E0308
-   |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |     ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected type `for<'tcx> Foo<'tcx>`
               found type `Foo<'x>`
-   = note: lifetime RePlaceholder(Placeholder { universe: U4, name: BrNamed(crate0:DefIndex(1:15), 'tcx) })...
-note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 14:26
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:14:26
-   |
-LL | fn want_foo_for_some_tcx<'x,F>(f: &'x F)
-   |                          ^^
-
-error[E0308]: mismatched types
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:18:5
-   |
-LL |     want_foo_for_any_tcx(f); //~ ERROR E0308
-   |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
-   |
-   = note: expected type `for<'tcx> Foo<'tcx>`
-              found type `Foo<'x>`
-note: the lifetime 'x as defined on the function body at 14:26...
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:14:26
-   |
-LL | fn want_foo_for_some_tcx<'x,F>(f: &'x F)
-   |                          ^^
-   = note: ...does not necessarily outlive lifetime RePlaceholder(Placeholder { universe: U4, name: BrNamed(crate0:DefIndex(1:15), 'tcx) })
 
 error[E0308]: mismatched types
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:36:5
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:35:5
    |
 LL |     want_bar_for_any_ccx(b); //~ ERROR E0308
-   |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |     ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected type `for<'ccx> Bar<'ccx>`
               found type `Bar<'x>`
-   = note: lifetime RePlaceholder(Placeholder { universe: U8, name: BrNamed(crate0:DefIndex(1:19), 'ccx) })...
-note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 29:26
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:29:26
-   |
-LL | fn want_bar_for_some_ccx<'x,B>(b: &B)
-   |                          ^^
-
-error[E0308]: mismatched types
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:36:5
-   |
-LL |     want_bar_for_any_ccx(b); //~ ERROR E0308
-   |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
-   |
-   = note: expected type `for<'ccx> Bar<'ccx>`
-              found type `Bar<'x>`
-note: the lifetime 'x as defined on the function body at 29:26...
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:29:26
-   |
-LL | fn want_bar_for_some_ccx<'x,B>(b: &B)
-   |                          ^^
-   = note: ...does not necessarily outlive lifetime RePlaceholder(Placeholder { universe: U8, name: BrNamed(crate0:DefIndex(1:19), 'ccx) })
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
index 31dad39efc3..7bd89960e42 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
@@ -43,7 +43,7 @@ fn foo_hrtb_bar_not<'b,T>(mut t: T)
     // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
     // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
     // clause only specifies `T : Bar<&'b isize>`.
-    foo_hrtb_bar_not(&mut t); //~ ERROR E0495
+    foo_hrtb_bar_not(&mut t); //~ ERROR E0308
 }
 
 fn foo_hrtb_bar_hrtb<T>(mut t: T)
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
index 2de60a79a85..ec3bf8a1a1b 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
@@ -1,22 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/hrtb-perfect-forwarding.rs:46:5
    |
-LL |     foo_hrtb_bar_not(&mut t); //~ ERROR E0495
-   |     ^^^^^^^^^^^^^^^^
+LL |     foo_hrtb_bar_not(&mut t); //~ ERROR E0308
+   |     ^^^^^^^^^^^^^^^^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U2, name: BrNamed(crate0:DefIndex(1:23), 'a) })...
-   = note: ...so that the types are compatible:
-           expected Foo<&'a isize>
-              found Foo<&isize>
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 39:21...
-  --> $DIR/hrtb-perfect-forwarding.rs:39:21
-   |
-LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
-   |                     ^^
-   = note: ...so that the types are compatible:
-           expected Bar<&isize>
-              found Bar<&'b isize>
+   = note: expected type `Foo<&'a isize>`
+              found type `Foo<&isize>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-40000.rs b/src/test/ui/issues/issue-40000.rs
index c7d1900ada9..320992c0764 100644
--- a/src/test/ui/issues/issue-40000.rs
+++ b/src/test/ui/issues/issue-40000.rs
@@ -3,5 +3,5 @@ fn main() {
 
     fn foo(x: Box<Fn(&i32)>) {}
     let bar = Box::new(|x: &i32| {}) as Box<Fn(_)>;
-    foo(bar); //~ ERROR E0495
+    foo(bar); //~ ERROR E0308
 }
diff --git a/src/test/ui/issues/issue-40000.stderr b/src/test/ui/issues/issue-40000.stderr
index 3aa1da8680c..d7966cea52b 100644
--- a/src/test/ui/issues/issue-40000.stderr
+++ b/src/test/ui/issues/issue-40000.stderr
@@ -1,26 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/issue-40000.rs:6:9
    |
-LL |     foo(bar); //~ ERROR E0495
-   |         ^^^
+LL |     foo(bar); //~ ERROR E0308
+   |         ^^^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U8, name: BrAnon(0) })...
-   = note: ...so that the types are compatible:
-           expected dyn for<'r> std::ops::Fn(&'r i32)
-              found dyn std::ops::Fn(&i32)
-note: but, the lifetime must be valid for the block suffix following statement 2 at 5:5...
-  --> $DIR/issue-40000.rs:5:5
-   |
-LL | /     let bar = Box::new(|x: &i32| {}) as Box<Fn(_)>;
-LL | |     foo(bar); //~ ERROR E0495
-LL | | }
-   | |_^
-note: ...so that variable is valid at time of its declaration
-  --> $DIR/issue-40000.rs:5:9
-   |
-LL |     let bar = Box::new(|x: &i32| {}) as Box<Fn(_)>;
-   |         ^^^
+   = note: expected type `dyn for<'r> std::ops::Fn(&'r i32)`
+              found type `dyn std::ops::Fn(&i32)`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs
index 132df608af7..9be7a813603 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.rs
+++ b/src/test/ui/lub-glb/old-lub-glb-object.rs
@@ -7,7 +7,7 @@ fn foo(
     x: &for<'a, 'b> Foo<&'a u8, &'b u8>,
     y: &for<'a> Foo<&'a u8, &'a u8>,
 ) {
-    let z = match 22 { //~ ERROR cannot infer
+    let z = match 22 { //~ ERROR E0308
         0 => x,
         _ => y,
     };
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr
index 2ed180f25dc..17d3648156b 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.stderr
+++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr
@@ -1,19 +1,16 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/old-lub-glb-object.rs:10:13
    |
-LL |       let z = match 22 { //~ ERROR cannot infer
+LL |       let z = match 22 { //~ ERROR E0308
    |  _____________^
 LL | |         0 => x,
 LL | |         _ => y,
 LL | |     };
-   | |_____^
+   | |_____^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U5, name: BrNamed(crate0:DefIndex(1:11), 'a) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U5, name: BrNamed(crate0:DefIndex(1:12), 'b) })...
-   = note: ...so that the types are compatible:
-           expected dyn for<'a, 'b> Foo<&'a u8, &'b u8>
-              found dyn for<'a> Foo<&'a u8, &'a u8>
+   = note: expected type `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+              found type `dyn for<'a> Foo<&'a u8, &'a u8>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
index f71a1736d4d..437150666be 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
@@ -9,6 +9,4 @@ fn baz<F: Fn(*mut &u32)>(_: F) {}
 fn _test<'a>(f: fn(*mut &'a u32)) {
     baz(f); //~ ERROR mismatched types
      //~| ERROR mismatched types
-     //~| ERROR mismatched types
-     //~| ERROR mismatched types
 }
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index 2cd63099bb7..a6628006587 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -26,63 +26,21 @@ error[E0308]: mismatched types
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
 LL |     baz(f); //~ ERROR mismatched types
-   |     ^^^ lifetime mismatch
+   |     ^^^ one type is more general than the other
    |
    = note: expected type `for<'r> std::ops::Fn<(*mut &'r u32,)>`
               found type `std::ops::Fn<(*mut &'a u32,)>`
-   = note: lifetime RePlaceholder(Placeholder { universe: U2, name: BrAnon(0) })...
-note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 9:10
-  --> $DIR/closure-arg-type-mismatch.rs:9:10
-   |
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-   |          ^^
-
-error[E0308]: mismatched types
-  --> $DIR/closure-arg-type-mismatch.rs:10:5
-   |
-LL |     baz(f); //~ ERROR mismatched types
-   |     ^^^ lifetime mismatch
-   |
-   = note: expected type `std::ops::FnOnce<(*mut &u32,)>`
-              found type `std::ops::FnOnce<(*mut &'a u32,)>`
-   = note: lifetime RePlaceholder(Placeholder { universe: U3, name: BrAnon(0) })...
-note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 9:10
-  --> $DIR/closure-arg-type-mismatch.rs:9:10
-   |
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-   |          ^^
 
 error[E0308]: mismatched types
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
 LL |     baz(f); //~ ERROR mismatched types
-   |     ^^^ lifetime mismatch
-   |
-   = note: expected type `for<'r> std::ops::Fn<(*mut &'r u32,)>`
-              found type `std::ops::Fn<(*mut &'a u32,)>`
-note: the lifetime 'a as defined on the function body at 9:10...
-  --> $DIR/closure-arg-type-mismatch.rs:9:10
-   |
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-   |          ^^
-   = note: ...does not necessarily outlive lifetime RePlaceholder(Placeholder { universe: U2, name: BrAnon(0) })
-
-error[E0308]: mismatched types
-  --> $DIR/closure-arg-type-mismatch.rs:10:5
-   |
-LL |     baz(f); //~ ERROR mismatched types
-   |     ^^^ lifetime mismatch
+   |     ^^^ one type is more general than the other
    |
    = note: expected type `std::ops::FnOnce<(*mut &u32,)>`
               found type `std::ops::FnOnce<(*mut &'a u32,)>`
-note: the lifetime 'a as defined on the function body at 9:10...
-  --> $DIR/closure-arg-type-mismatch.rs:9:10
-   |
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-   |          ^^
-   = note: ...does not necessarily outlive lifetime RePlaceholder(Placeholder { universe: U3, name: BrAnon(0) })
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 Some errors occurred: E0308, E0631.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/closure-mismatch.rs b/src/test/ui/mismatched_types/closure-mismatch.rs
index 0f28e5dfd7e..152a5254937 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.rs
+++ b/src/test/ui/mismatched_types/closure-mismatch.rs
@@ -5,5 +5,5 @@ impl<T: Fn(&())> Foo for T {}
 fn baz<T: Foo>(_: T) {}
 
 fn main() {
-    baz(|_| ()); //~ ERROR E0495
+    baz(|_| ()); //~ ERROR E0308
 }
diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr
index f028817a935..0d87bc22875 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-mismatch.stderr
@@ -1,15 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/closure-mismatch.rs:8:5
    |
-LL |     baz(|_| ()); //~ ERROR E0495
-   |     ^^^
+LL |     baz(|_| ()); //~ ERROR E0308
+   |     ^^^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U6, name: BrAnon(0) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U6, name: BrAnon(0) })...
-   = note: ...so that the types are compatible:
-           expected for<'r> std::ops::Fn<(&'r (),)>
-              found std::ops::Fn<(&(),)>
+   = note: expected type `for<'r> std::ops::Fn<(&'r (),)>`
+              found type `std::ops::Fn<(&(),)>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr
index c9ccb9b6ded..a9234e43191 100644
--- a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr
+++ b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr
@@ -1,15 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12
    |
 LL |     want_G(baz); //~ ERROR
-   |            ^^^
+   |            ^^^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U3, name: BrNamed(crate0:DefIndex(1:11), 'cx) })...
-   = note: ...but the lifetime must also be valid for the static lifetime...
-   = note: ...so that the expression is assignable:
-           expected for<'cx> fn(&'cx S) -> &'static S
-              found for<'r> fn(&'r S) -> &'r S
+   = note: expected type `for<'cx> fn(&'cx S) -> &'static S`
+              found type `for<'r> fn(&'r S) -> &'r S`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs
index e5514d32c4e..ab4c6d9cf91 100644
--- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs
+++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs
@@ -17,7 +17,7 @@ fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
 fn d() {
     // 'a and 'b are early bound in the function `a` because they appear
     // inconstraints:
-    let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0495
+    let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types
 }
 
 fn e() {
diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
index 3824755fa06..47e1d0efdc7 100644
--- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
+++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
@@ -16,19 +16,16 @@ LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
 LL |     a(x, y); //~ ERROR lifetime mismatch [E0623]
    |       ^ ...but data from `y` flows into `x` here
 
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
    |
-LL |     let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0495
-   |                                           ^
+LL |     let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types
+   |                                           ^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U1, name: BrAnon(1) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U1, name: BrAnon(1) })...
-   = note: ...so that the expression is assignable:
-           expected for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)
-              found for<'r, 's> fn(&'r mut &isize, &'s mut &isize)
+   = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
+              found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
 
 error: aborting due to 3 previous errors
 
-Some errors occurred: E0495, E0623.
-For more information about an error, try `rustc --explain E0495`.
+Some errors occurred: E0308, E0623.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs
index 3e635300d7b..066522548ad 100644
--- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs
+++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs
@@ -19,7 +19,7 @@ fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
 fn d() {
     // 'a and 'b are early bound in the function `a` because they appear
     // inconstraints:
-    let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0495
+    let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0308
 }
 
 fn e() {
diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
index f694d312640..1e7b99053f7 100644
--- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
+++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
@@ -27,19 +27,16 @@ LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
 LL |     a(x, y, z); //~ ERROR lifetime mismatch [E0623]
    |       ^ ...but data from `y` flows into `x` here
 
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
    |
-LL |     let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0495
-   |                                                        ^
+LL |     let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0308
+   |                                                        ^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U1, name: BrAnon(1) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U1, name: BrAnon(1) })...
-   = note: ...so that the expression is assignable:
-           expected for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)
-              found for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)
+   = note: expected type `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)`
+              found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
 
 error: aborting due to 4 previous errors
 
-Some errors occurred: E0495, E0623.
-For more information about an error, try `rustc --explain E0495`.
+Some errors occurred: E0308, E0623.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs b/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs
index 6ebfc3f80d2..7d7f62e1979 100644
--- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs
+++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs
@@ -17,7 +17,7 @@ fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
 fn d() {
     // 'a and 'b are early bound in the function `a` because they appear
     // inconstraints:
-    let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0495
+    let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0308
 }
 
 fn e() {
diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr
index 20e28e8877f..a43ee7ec3ac 100644
--- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr
+++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr
@@ -16,19 +16,16 @@ LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
 LL |     a(x, y); //~ ERROR lifetime mismatch [E0623]
    |       ^ ...but data from `y` flows into `x` here
 
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+error[E0308]: mismatched types
   --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43
    |
-LL |     let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0495
-   |                                           ^
+LL |     let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0308
+   |                                           ^ one type is more general than the other
    |
-   = note: first, the lifetime cannot outlive lifetime RePlaceholder(Placeholder { universe: U1, name: BrAnon(1) })...
-   = note: ...but the lifetime must also be valid for lifetime RePlaceholder(Placeholder { universe: U1, name: BrAnon(1) })...
-   = note: ...so that the expression is assignable:
-           expected for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)
-              found for<'r, 's> fn(&'r mut &isize, &'s mut &isize)
+   = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
+              found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
 
 error: aborting due to 3 previous errors
 
-Some errors occurred: E0495, E0623.
-For more information about an error, try `rustc --explain E0495`.
+Some errors occurred: E0308, E0623.
+For more information about an error, try `rustc --explain E0308`.