about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs111
1 files changed, 44 insertions, 67 deletions
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index c4f2cf62ddd..7328241dfbc 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -4,7 +4,6 @@ use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, Subdiag
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{symbol::kw, Span};
 
-#[derive(Default)]
 struct DescriptionCtx<'a> {
     span: Option<Span>,
     kind: &'a str,
@@ -17,96 +16,74 @@ impl<'a> DescriptionCtx<'a> {
         region: ty::Region<'tcx>,
         alt_span: Option<Span>,
     ) -> Option<Self> {
-        let mut me = DescriptionCtx::default();
-        me.span = alt_span;
-        match *region {
-            ty::ReEarlyBound(_) | ty::ReFree(_) => {
-                return Self::from_early_bound_and_free_regions(tcx, region);
-            }
-            ty::ReStatic => {
-                me.kind = "restatic";
-            }
-
-            ty::RePlaceholder(_) => return None,
-
-            ty::ReError(_) => return 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::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
-                me.kind = "revar";
-                me.arg = format!("{:?}", region);
-            }
-        };
-        Some(me)
-    }
-
-    fn from_early_bound_and_free_regions<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        region: ty::Region<'tcx>,
-    ) -> Option<Self> {
-        let mut me = DescriptionCtx::default();
-        let scope = region.free_region_binding_scope(tcx).expect_local();
-        match *region {
+        let (span, kind, arg) = match *region {
             ty::ReEarlyBound(ref br) => {
-                let mut sp = tcx.def_span(scope);
-                if let Some(param) =
+                let scope = region.free_region_binding_scope(tcx).expect_local();
+                let span = if let Some(param) =
                     tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
                 {
-                    sp = param.span;
-                }
-                if br.has_name() {
-                    me.kind = "as_defined";
-                    me.arg = br.name.to_string();
+                    param.span
                 } else {
-                    me.kind = "as_defined_anon";
+                    tcx.def_span(scope)
                 };
-                me.span = Some(sp)
+                if br.has_name() {
+                    (Some(span), "as_defined", br.name.to_string())
+                } else {
+                    (Some(span), "as_defined_anon", String::new())
+                }
             }
             ty::ReFree(ref fr) => {
                 if !fr.bound_region.is_named()
                     && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
                 {
-                    me.kind = "defined_here";
-                    me.span = Some(ty.span);
+                    (Some(ty.span), "defined_here", String::new())
                 } else {
+                    let scope = region.free_region_binding_scope(tcx).expect_local();
                     match fr.bound_region {
                         ty::BoundRegionKind::BrNamed(_, name) => {
-                            let mut sp = tcx.def_span(scope);
-                            if let Some(param) =
-                                tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
+                            let span = if let Some(param) = tcx
+                                .hir()
+                                .get_generics(scope)
+                                .and_then(|generics| generics.get_named(name))
                             {
-                                sp = param.span;
-                            }
-                            if name == kw::UnderscoreLifetime {
-                                me.kind = "as_defined_anon";
+                                param.span
                             } else {
-                                me.kind = "as_defined";
-                                me.arg = name.to_string();
+                                tcx.def_span(scope)
                             };
-                            me.span = Some(sp);
+                            if name == kw::UnderscoreLifetime {
+                                (Some(span), "as_defined_anon", String::new())
+                            } else {
+                                (Some(span), "as_defined", name.to_string())
+                            }
                         }
                         ty::BrAnon(span) => {
-                            me.kind = "defined_here";
-                            me.span = match span {
+                            let span = match span {
                                 Some(_) => span,
                                 None => Some(tcx.def_span(scope)),
-                            }
-                        },
+                            };
+                            (span, "defined_here", String::new())
+                        }
                         _ => {
-                            me.kind = "defined_here_reg";
-                            me.arg = region.to_string();
-                            me.span = Some(tcx.def_span(scope));
-                        },
+                            (Some(tcx.def_span(scope)), "defined_here_reg", region.to_string())
+                        }
                     }
                 }
             }
-            _ => bug!(),
-        }
-        Some(me)
+
+            ty::ReStatic => (alt_span, "restatic", String::new()),
+
+            ty::RePlaceholder(_) | ty::ReError(_) => return 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::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
+                (alt_span, "revar", format!("{:?}", region))
+            }
+        };
+        Some(DescriptionCtx { span, kind, arg })
     }
 }