Skip to content

Commit 706779c

Browse files
committed
adding changes for detecing named regions
1 parent a361a2c commit 706779c

File tree

3 files changed

+60
-22
lines changed

3 files changed

+60
-22
lines changed

src/librustc/infer/error_reporting/anon_anon_conflict.rs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
3939
// }
4040
// It will later be extended to trait objects.
4141
pub fn try_report_anon_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
42+
debug!("try_report_anon_anon_conflict");
4243
let (span, sub, sup) = match *error {
4344
ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
4445
_ => return false, // inapplicable
4546
};
4647

4748
// Determine whether the sub and sup consist of both anonymous (elided) regions.
4849
let (ty1, ty2, scope_def_id_1, scope_def_id_2, bregion1, bregion2) = if
49-
self.is_suitable_anonymous_region(sup, true).is_some() &&
50-
self.is_suitable_anonymous_region(sub, true).is_some() {
50+
self.is_suitable_region(sup, true).is_some() &&
51+
self.is_suitable_region(sub, true).is_some() {
5152
if let (Some(anon_reg1), Some(anon_reg2)) =
52-
(self.is_suitable_anonymous_region(sup, true),
53-
self.is_suitable_anonymous_region(sub, true)) {
53+
(self.is_suitable_region(sup, true),
54+
self.is_suitable_region(sub, true)) {
5455
let ((def_id1, br1), (def_id2, br2)) = (anon_reg1, anon_reg2);
5556
let found_arg1 = self.find_anon_type(sup, &br1);
5657
let found_arg2 = self.find_anon_type(sub, &br2);
@@ -133,6 +134,7 @@ pub struct FindNestedTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
133134
// The type where the anonymous lifetime appears
134135
// for e.g. Vec<`&u8`> and <`&u8`>
135136
pub found_type: Option<&'gcx hir::Ty>,
137+
//pub depth: u32,
136138
}
137139

138140
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
@@ -144,24 +146,52 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
144146
// Find the index of the anonymous region that was part of the
145147
// error. We will then search the function parameters for a bound
146148
// region at the right depth with the same index.
147-
let br_index = match self.bound_region {
148-
ty::BrAnon(index) => index,
149-
_ => return,
150-
};
151-
152149
match arg.node {
153150
hir::TyRptr(ref lifetime, _) => {
154151
match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) {
155152
// the lifetime of the TyRptr
156-
Some(&rl::Region::LateBoundAnon(debuijn_index, anon_index)) => {
157-
if debuijn_index.depth == 1 && anon_index == br_index {
153+
Some(&rl::Region::LateBoundAnon(debruijn_index, anon_index)) => {
154+
let br_index = match self.bound_region {
155+
ty::BrAnon(index) => index,
156+
_ => return,
157+
};
158+
debug!("LateBoundAnon depth = {:?} anon_index = {:?} br_index={:?}",debruijn_index.depth
159+
,anon_index,br_index);
160+
if debruijn_index.depth == 1 && anon_index == br_index {
158161
self.found_type = Some(arg);
159162
return; // we can stop visiting now
160163
}
161164
}
165+
Some(&rl::Region::EarlyBound(_, id)) => {
166+
let def_id = match self.bound_region {
167+
ty::BrNamed(def_id, _) => def_id,//def_id of hir::Lifetime
168+
_ => return,
169+
};
170+
debug!("EarlyBound self.infcx.tcx.hir.local_def_id(id) ={:?}
171+
def_id={:?}",
172+
self.infcx.tcx.hir.local_def_id(id), def_id);
173+
if self.infcx.tcx.hir.local_def_id(id) == def_id {
174+
self.found_type = Some(arg);
175+
return; // we can stop visiting now
176+
}
177+
178+
}
179+
180+
Some(&rl::Region::LateBound(debruijn_index, id)) => {
181+
let def_id = match self.bound_region {
182+
ty::BrNamed(def_id, _) => def_id,//def_id of hir::Lifetime
183+
_ => return,
184+
};
185+
debug!("LateBound depth = {:?} self.infcx.tcx.hir.local_def_id(id) ={:?}
186+
def_id={:?}",debruijn_index.depth
187+
,self.infcx.tcx.hir.local_def_id(id), def_id);
188+
if debruijn_index.depth == 1 && self.infcx.tcx.hir.local_def_id(id) == def_id{
189+
self.found_type = Some(arg);
190+
return; // we can stop visiting now
191+
}
192+
}
193+
162194
Some(&rl::Region::Static) |
163-
Some(&rl::Region::EarlyBound(_, _)) |
164-
Some(&rl::Region::LateBound(_, _)) |
165195
Some(&rl::Region::Free(_, _)) |
166196
None => {
167197
debug!("no arg found");

src/librustc/infer/error_reporting/named_anon_conflict.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
use infer::InferCtxt;
1414
use infer::region_inference::RegionResolutionError::*;
1515
use infer::region_inference::RegionResolutionError;
16+
use ty::{self};
1617

1718
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1819
// This method generates the error message for the case when
1920
// the function arguments consist of a named region and an anonymous
2021
// region and corresponds to `ConcreteFailure(..)`
2122
pub fn try_report_named_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
23+
debug!("try_report_named_anon_conflict");
2224
let (span, sub, sup) = match *error {
2325
ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
2426
_ => return false, // inapplicable
@@ -31,21 +33,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
3133
// version new_ty of its type where the anonymous region is replaced
3234
// with the named one.
3335
let (named, (arg, new_ty, br, is_first), (scope_def_id, _), anon) = if
34-
sub.is_named_region() && self.is_suitable_anonymous_region(sup, false).is_some() {
36+
sub.is_named_region() && self.is_suitable_region(sup, false).is_some() {
37+
debug!("1.1");
3538
(sub,
3639
self.find_arg_with_anonymous_region(sup, sub).unwrap(),
37-
self.is_suitable_anonymous_region(sup, false).unwrap(),
40+
self.is_suitable_region(sup, false).unwrap(),
3841
sup)
3942
} else if
40-
sup.is_named_region() && self.is_suitable_anonymous_region(sub, false).is_some() {
43+
sup.is_named_region() && self.is_suitable_region(sub, false).is_some() {
44+
debug!("1.2");
4145
(sup,
4246
self.find_arg_with_anonymous_region(sub, sup).unwrap(),
43-
self.is_suitable_anonymous_region(sub, false).unwrap(),
47+
self.is_suitable_region(sub, false).unwrap(),
4448
sub)
4549
} else {
50+
debug!("1.3");
4651
return false; // inapplicable
4752
};
4853

54+
match br
55+
{ ty::BrAnon(_) => {},
56+
_ => { /* not an anonymous region */ return false; } }
57+
4958
if self.is_return_type_anon(scope_def_id, br) || self.is_self_anon(is_first, scope_def_id) {
5059
return false;
5160
} else {

src/librustc/infer/error_reporting/util.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
5959
});
6060
if found_anon_region {
6161
let is_first = index == 0;
62+
debug!("arg={:?}",arg);
6263
Some((arg, new_arg_ty, free_region.bound_region, is_first))
6364
} else {
6465
None
@@ -79,14 +80,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
7980
}
8081
}
8182

82-
// This method returns whether the given Region is Anonymous
83+
// This method returns whether the given Region is Anonymous or Named
8384
// and returns the DefId and the BoundRegion corresponding to the given region
84-
pub fn is_suitable_anonymous_region(&self,
85+
pub fn is_suitable_region(&self,
8586
region: Region<'tcx>,
8687
is_anon_anon: bool)
8788
-> Option<(DefId, ty::BoundRegion)> {
8889
if let ty::ReFree(ref free_region) = *region {
89-
if let ty::BrAnon(..) = free_region.bound_region {
9090
let anonymous_region_binding_scope = free_region.scope;
9191
let node_id = self.tcx
9292
.hir
@@ -119,7 +119,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
119119
// we target only top-level functions
120120
}
121121
return Some((anonymous_region_binding_scope, free_region.bound_region));
122-
}
123122
}
124123
None
125124
}
@@ -176,7 +175,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
176175
/// The function returns the nested type corresponding to the anonymous region
177176
/// for e.g. `&u8` and Vec<`&u8`.
178177
pub fn find_anon_type(&self, region: Region<'tcx>, br: &ty::BoundRegion) -> Option<(&hir::Ty)> {
179-
if let Some(anon_reg) = self.is_suitable_anonymous_region(region, true) {
178+
if let Some(anon_reg) = self.is_suitable_region(region, true) {
180179
let (def_id, _) = anon_reg;
181180
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
182181
let ret_ty = self.tcx.type_of(def_id);

0 commit comments

Comments
 (0)