Skip to content

Commit 90ab9d9

Browse files
committed
code review fixes
1 parent 2ff1734 commit 90ab9d9

10 files changed

+73
-126
lines changed

src/librustc/infer/error_reporting/anon_anon_conflict.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
4848
// Determine whether the sub and sup consist of both anonymous (elided) regions.
4949
let (ty_sup, ty_sub, scope_def_id_sup, scope_def_id_sub, bregion_sup, bregion_sub) =
5050
if let (Some(anon_reg_sup), Some(anon_reg_sub)) =
51-
(self.is_suitable_anonymous_region(sup, true),
52-
self.is_suitable_anonymous_region(sub, true)) {
51+
(self.is_suitable_anonymous_region(sup), self.is_suitable_anonymous_region(sub)) {
5352
let (def_id_sup, br_sup, def_id_sub, br_sub) = (anon_reg_sup.def_id,
5453
anon_reg_sup.boundregion,
5554
anon_reg_sub.def_id,
@@ -64,7 +63,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
6463
return false;
6564
};
6665

67-
let (label1, label2) = if let (Some(sup_arg), Some(sub_arg)) =
66+
let (main_label, label1, label2) = if let (Some(sup_arg), Some(sub_arg)) =
6867
(self.find_arg_with_anonymous_region(sup, sup),
6968
self.find_arg_with_anonymous_region(sub, sub)) {
7069

@@ -81,7 +80,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
8180
}
8281

8382
if anon_arg_sup == anon_arg_sub {
84-
(format!(" with one lifetime"), format!(" into the other"))
83+
(format!("this type was declared with multiple lifetimes..."),
84+
format!(" with one lifetime"),
85+
format!(" into the other"))
8586
} else {
8687
let span_label_var1 = if let Some(simple_name) = anon_arg_sup.pat.simple_name() {
8788
format!(" from `{}`", simple_name)
@@ -95,15 +96,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
9596
format!("")
9697
};
9798

98-
(span_label_var1, span_label_var2)
99+
let span_label =
100+
format!("these two types are declared with different lifetimes...",);
101+
102+
(span_label, span_label_var1, span_label_var2)
99103
}
100104
} else {
101105
return false;
102106
};
103107

108+
104109
struct_span_err!(self.tcx.sess, span, E0623, "lifetime mismatch")
105-
.span_label(ty_sup.span,
106-
format!("these two types are declared with different lifetimes..."))
110+
.span_label(ty_sup.span, main_label)
107111
.span_label(ty_sub.span, format!(""))
108112
.span_label(span, format!("...but data{} flows{} here", label1, label2))
109113
.emit();
@@ -126,7 +130,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
126130
/// The function returns the nested type corresponding to the anonymous region
127131
/// for e.g. `&u8` and Vec<`&u8`.
128132
pub fn find_anon_type(&self, region: Region<'tcx>, br: &ty::BoundRegion) -> Option<&hir::Ty> {
129-
if let Some(anon_reg) = self.is_suitable_anonymous_region(region, true) {
133+
if let Some(anon_reg) = self.is_suitable_anonymous_region(region) {
130134
let def_id = anon_reg.def_id;
131135
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
132136
let ret_ty = self.tcx.type_of(def_id);

src/librustc/infer/error_reporting/named_anon_conflict.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
3131
// version new_ty of its type where the anonymous region is replaced
3232
// with the named one.//scope_def_id
3333
let (named, anon_arg_info, region_info) =
34-
if sub.is_named_region() && self.is_suitable_anonymous_region(sup, false).is_some() {
34+
if sub.is_named_region() && self.is_suitable_anonymous_region(sup).is_some() {
3535
(sub,
3636
self.find_arg_with_anonymous_region(sup, sub).unwrap(),
37-
self.is_suitable_anonymous_region(sup, false).unwrap())
38-
} else if sup.is_named_region() &&
39-
self.is_suitable_anonymous_region(sub, false).is_some() {
37+
self.is_suitable_anonymous_region(sup).unwrap())
38+
} else if sup.is_named_region() && self.is_suitable_anonymous_region(sub).is_some() {
4039
(sup,
4140
self.find_arg_with_anonymous_region(sub, sup).unwrap(),
42-
self.is_suitable_anonymous_region(sub, false).unwrap())
41+
self.is_suitable_anonymous_region(sub).unwrap())
4342
} else {
4443
return false; // inapplicable
4544
};
4645

47-
let (arg, new_ty, br, is_first, scope_def_id) = (anon_arg_info.arg,
48-
anon_arg_info.arg_ty,
49-
anon_arg_info.bound_region,
50-
anon_arg_info.is_first,
51-
region_info.def_id);
46+
let (arg, new_ty, br, is_first, scope_def_id, is_impl_item) = (anon_arg_info.arg,
47+
anon_arg_info.arg_ty,
48+
anon_arg_info.bound_region,
49+
anon_arg_info.is_first,
50+
region_info.def_id,
51+
region_info.is_impl_item);
52+
if is_impl_item {
53+
return false;
54+
}
55+
5256
if self.is_return_type_anon(scope_def_id, br) || self.is_self_anon(is_first, scope_def_id) {
5357
return false;
5458
} else {

src/librustc/infer/error_reporting/util.rs

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ pub struct FreeRegionInfo {
3737
pub def_id: DefId,
3838
// the bound region corresponding to FreeRegion
3939
pub boundregion: ty::BoundRegion,
40+
// checks if bound region is in Impl Item
41+
pub is_impl_item: bool,
4042
}
4143

4244
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
@@ -106,48 +108,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
106108

107109
// This method returns whether the given Region is Anonymous
108110
// and returns the DefId and the BoundRegion corresponding to the given region.
109-
// The is_anon_anon is set true when we are dealing with cases where
110-
// both the regions are anonymous i.e. E0623.
111-
pub fn is_suitable_anonymous_region(&self,
112-
region: Region<'tcx>,
113-
is_anon_anon: bool)
114-
-> Option<FreeRegionInfo> {
111+
pub fn is_suitable_anonymous_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
115112
if let ty::ReFree(ref free_region) = *region {
116113
if let ty::BrAnon(..) = free_region.bound_region {
117114
let anonymous_region_binding_scope = free_region.scope;
118-
let node_id = self.tcx
119-
.hir
120-
.as_local_node_id(anonymous_region_binding_scope)
121-
.unwrap();
122-
match self.tcx.hir.find(node_id) {
123-
Some(hir_map::NodeItem(..)) |
124-
Some(hir_map::NodeTraitItem(..)) => {
125-
// Success -- proceed to return Some below
126-
}
127-
Some(hir_map::NodeImplItem(..)) => {
128-
if !is_anon_anon {
129-
let container_id = self.tcx
130-
.associated_item(anonymous_region_binding_scope)
131-
.container
132-
.id();
133-
if self.tcx.impl_trait_ref(container_id).is_some() {
134-
// For now, we do not try to target impls of traits. This is
135-
// because this message is going to suggest that the user
136-
// change the fn signature, but they may not be free to do so,
137-
// since the signature must match the trait.
138-
//
139-
// FIXME(#42706) -- in some cases, we could do better here.
140-
return None;
141-
}
142-
} else {
143-
}
144-
}
145-
_ => return None, // inapplicable
146-
// we target only top-level functions
147-
}
148115
return Some(FreeRegionInfo {
149116
def_id: anonymous_region_binding_scope,
150117
boundregion: free_region.bound_region,
118+
is_impl_item:
119+
self.is_bound_region_in_impl_item(anonymous_region_binding_scope),
151120
});
152121
}
153122
}
@@ -177,12 +146,42 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
177146
// FIXME(#42700) - Need to format self properly to
178147
// enable E0621 for it.
179148
pub fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool {
180-
if is_first &&
181-
self.tcx
182-
.opt_associated_item(scope_def_id)
183-
.map(|i| i.method_has_self_argument)
184-
.unwrap_or(false) {
185-
return true;
149+
is_first &&
150+
self.tcx
151+
.opt_associated_item(scope_def_id)
152+
.map(|i| i.method_has_self_argument) == Some(true)
153+
}
154+
155+
// Here we check if the bound region is in Impl Item.
156+
pub fn is_bound_region_in_impl_item(&self, anonymous_region_binding_scope: DefId) -> bool {
157+
let node_id = self.tcx
158+
.hir
159+
.as_local_node_id(anonymous_region_binding_scope)
160+
.unwrap();
161+
match self.tcx.hir.find(node_id) {
162+
163+
Some(hir_map::NodeItem(..)) |
164+
Some(hir_map::NodeTraitItem(..)) => {
165+
// Success -- proceed to return Some below
166+
}
167+
Some(hir_map::NodeImplItem(..)) => {
168+
let container_id = self.tcx
169+
.associated_item(anonymous_region_binding_scope)
170+
.container
171+
.id();
172+
if self.tcx.impl_trait_ref(container_id).is_some() {
173+
// For now, we do not try to target impls of traits. This is
174+
// because this message is going to suggest that the user
175+
// change the fn signature, but they may not be free to do so,
176+
// since the signature must match the trait.
177+
//
178+
// FIXME(#42706) -- in some cases, we could do better here.
179+
return true;
180+
}
181+
}
182+
_ => {
183+
return false;
184+
}
186185
}
187186
false
188187
}

src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0623]: lifetime mismatch
44
15 | fn foo(mut x: Ref) {
55
| ---
66
| |
7-
| these two types are declared with different lifetimes...
7+
| this type was declared with multiple lifetimes...
88
16 | x.a = x.b;
99
| ^^^ ...but data with one lifetime flows into the other here
1010

src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.rs

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
1212

1313
fn foo(mut y: Ref, x: &u32) {
14-
x = y.b;
14+
y.b = x;
1515
}
1616

1717
fn main() { }
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
error[E0623]: lifetime mismatch
2-
--> $DIR/ex3-both-anon-regions-one-is-struct-3.rs:14:9
2+
--> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:14:11
33
|
44
13 | fn foo(mut y: Ref, x: &u32) {
5-
| --- ----
6-
| |
7-
| these two types are declared with different lifetimes...
8-
14 | x = y.b;
9-
| ^^^ ...but data from `y` flows into `x` here
5+
| --- ---- these two types are declared with different lifetimes...
6+
14 | y.b = x;
7+
| ^ ...but data from `x` flows into `y` here
108

119
error: aborting due to previous error
1210

src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)