Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Created September 5, 2017 14:38
Show Gist options
  • Save nikomatsakis/fb82e83de936ca8ae002d3d241e3d109 to your computer and use it in GitHub Desktop.
Save nikomatsakis/fb82e83de936ca8ae002d3d241e3d109 to your computer and use it in GitHub Desktop.
@@ -121,31 +124,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// This method returns the DefId and the BoundRegion corresponding to the given region.
pub fn is_suitable_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
- if let ty::ReFree(ref free_region) = *region {
- let suitable_region_binding_scope = free_region.scope;
- let node_id = self.tcx
- .hir
- .as_local_node_id(suitable_region_binding_scope)
- .unwrap();
- let mut is_impl_item = false;
- match self.tcx.hir.find(node_id) {
-
- Some(hir_map::NodeItem(..)) |
- Some(hir_map::NodeTraitItem(..)) => {
- // Success -- proceed to return Some below
- }
- Some(hir_map::NodeImplItem(..)) => {
- is_impl_item = self.is_bound_region_in_impl_item(suitable_region_binding_scope);
- }
- _ => return None,
+ // Find the def-id where this free region is bound. So, for
+ // example, if we have something like `fn foo<'a>(x: &'a i32)`
+ // where `'a` is early bound, then the binding def-id would be the
+ // def-id of `foo`.
+ let (binding_scope_def_id, bound_region) = match *region {
+ ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
+ ty::ReEarlyBound(ref ebr) => {
+ (
+ self.tcx.parent_def_id(ebr.def_id).unwrap(),
+ ty::BoundRegion::BrNamed(ebr.def_id, ebr.name),
+ )
+ }
+ _ => return None, // not a free region
+ };
+ let node_id = self.tcx.hir.as_local_node_id(binding_scope_def_id).unwrap();
+ let mut is_impl_item = false;
+ match self.tcx.hir.find(node_id) {
+ Some(hir_map::NodeItem(..)) |
+ Some(hir_map::NodeTraitItem(..)) => {
+ // Success -- proceed to return Some below
+ }
+ Some(hir_map::NodeImplItem(..)) => {
+ is_impl_item = self.is_bound_region_in_impl_item(binding_scope_def_id);
}
- return Some(FreeRegionInfo {
- def_id: suitable_region_binding_scope,
- boundregion: free_region.bound_region,
- is_impl_item: is_impl_item,
- });
+ _ => return None,
}
- None
+ return Some(FreeRegionInfo {
+ def_id: binding_scope_def_id,
+ boundregion: bound_region,
+ is_impl_item: is_impl_item,
+ });
}
// Here, we check for the case where the anonymous region
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment