Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Created May 5, 2017 21:49
Show Gist options
  • Save nikomatsakis/26a6cdecffc726c31e28a9b5901f9844 to your computer and use it in GitHub Desktop.
Save nikomatsakis/26a6cdecffc726c31e28a9b5901f9844 to your computer and use it in GitHub Desktop.
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index d1d5e9d..34fc383 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -1041,10 +1041,11 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
}
}
-fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, walk: F)
+/// Executes `walk` in a "cleared" context with no parents or
+/// anything.
+fn clear_cx<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, walk: F)
where F: FnOnce(&mut RegionResolutionVisitor<'a, 'tcx>)
{
- // Items create a new outer block scope as far as we're concerned.
let prev_cx = visitor.cx;
let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
visitor.cx = Context {
@@ -1160,15 +1161,28 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
}
fn visit_item(&mut self, i: &'tcx Item) {
- resolve_item_like(self, |this| intravisit::walk_item(this, i));
+ clear_cx(self, |this| intravisit::walk_item(this, i));
}
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
- resolve_item_like(self, |this| intravisit::walk_impl_item(this, ii));
+ clear_cx(self, |this| match ii.node {
+ hir::ImplItemKind::Const(_, body) => {
+ // Not a perfect fit, but it will do for now. In
+ // short, the "call site" for a constant is sort of
+ // place in which the result of evaluation will be
+ // used.
+ this.cx.parent = Some(this.new_code_extent(
+ CodeExtentData::CallSiteScope { fn_id: ii.id,
+ body_id: body.node_id }));
+
+ intravisit::walk_impl_item(this, ii);
+ }
+ _ => intravisit::walk_impl_item(this, ii)
+ });
}
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
- resolve_item_like(self, |this| intravisit::walk_trait_item(this, ti));
+ clear_cx(self, |this| intravisit::walk_trait_item(this, ti));
}
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx FnDecl,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index b65de56..cdc6fff 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1276,7 +1276,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
match tcx.hir.find(id) {
Some(hir_map::NodeImplItem(ref impl_item)) => {
match impl_item.node {
- hir::ImplItemKind::Type(_) | hir::ImplItemKind::Const(..) => {
+ hir::ImplItemKind::Type(_) => {
// associated types don't have their own entry (for some reason),
// so for now just grab environment for the impl
let impl_id = tcx.hir.get_parent(id);
@@ -1285,6 +1285,16 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
impl_def_id,
Some(tcx.item_extent(id)))
}
+ hir::ImplItemKind::Const(_, body) => {
+ // associated types don't have their own entry (for some reason),
+ // so for now just grab environment for the impl
+ let impl_id = tcx.hir.get_parent(id);
+ let impl_def_id = tcx.hir.local_def_id(impl_id);
+ let extent = tcx.call_site_extent(id, body.node_id);
+ tcx.construct_parameter_environment(impl_item.span,
+ impl_def_id,
+ Some(extent))
+ }
hir::ImplItemKind::Method(_, ref body) => {
tcx.construct_parameter_environment(
impl_item.span,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment