From c7c2603e2c7440d4ef2e8ab5fc570d1dab2b0cbb Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 7 Nov 2017 13:18:14 -0500 Subject: [PATCH] factor out `free_region_binding_scope` helper --- src/librustc/infer/error_reporting/mod.rs | 8 +------ src/librustc/ty/sty.rs | 29 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 84baece77fe5..d22eb20e70a8 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -177,13 +177,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::ReEarlyBound(_) | ty::ReFree(_) => { - let scope = match *region { - ty::ReEarlyBound(ref br) => { - self.parent_def_id(br.def_id).unwrap() - } - ty::ReFree(ref fr) => fr.scope, - _ => bug!() - }; + let scope = region.free_region_binding_scope(self); let prefix = match *region { ty::ReEarlyBound(ref br) => { format!("the lifetime {} as defined on", br.name) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index c68907e689a6..65406c3d16cc 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1050,6 +1050,35 @@ impl RegionKind { flags } + + /// Given an early-bound or free region, returns the def-id where it was bound. + /// For example, consider the regions in this snippet of code: + /// + /// ``` + /// impl<'a> Foo { + /// ^^ -- early bound, declared on an impl + /// + /// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c + /// ^^ ^^ ^ anonymous, late-bound + /// | early-bound, appears in where-clauses + /// late-bound, appears only in fn args + /// {..} + /// } + /// ``` + /// + /// Here, `free_region_binding_scope('a)` would return the def-id + /// of the impl, and for all the other highlighted regions, it + /// would return the def-id of the function. In other cases (not shown), this + /// function might return the def-id of a closure. + pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_, '_>) -> DefId { + match self { + ty::ReEarlyBound(br) => { + tcx.parent_def_id(br.def_id).unwrap() + } + ty::ReFree(fr) => fr.scope, + _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), + } + } } /// Type utilities