Auto merge of #44516 - gaurikholkar:fns, r=arielb1
Extend E0623 for fn items This fixes #44516 The below example now gives ``` error[E0623]: lifetime mismatch --> gg.rs:3:10 | 2 | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { | --- --- these two types are declared with different lifetimes... 3 | y.push(z); | ^ ...but data from `z` flows into `y` here error: aborting due to previous error ``` r? @nikomatsakis cc @arielb1
This commit is contained in:
commit
94211416bc
8
fn.rs
Normal file
8
fn.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
fn foo(x: fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
|
||||||
|
// Debruijn 1 1 1 1
|
||||||
|
// Anon-Index 0 1 0 1
|
||||||
|
// ------
|
||||||
|
// debruijn indices are shifted by 1 in here
|
||||||
|
y.push(z); // index will be zero or one
|
||||||
|
}
|
@ -173,6 +173,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
hir_map: &self.tcx.hir,
|
hir_map: &self.tcx.hir,
|
||||||
bound_region: *br,
|
bound_region: *br,
|
||||||
found_type: None,
|
found_type: None,
|
||||||
|
depth: 1,
|
||||||
};
|
};
|
||||||
nested_visitor.visit_ty(arg);
|
nested_visitor.visit_ty(arg);
|
||||||
nested_visitor.found_type
|
nested_visitor.found_type
|
||||||
@ -195,6 +196,7 @@ struct FindNestedTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
|||||||
// The type where the anonymous lifetime appears
|
// The type where the anonymous lifetime appears
|
||||||
// for e.g. Vec<`&u8`> and <`&u8`>
|
// for e.g. Vec<`&u8`> and <`&u8`>
|
||||||
found_type: Option<&'gcx hir::Ty>,
|
found_type: Option<&'gcx hir::Ty>,
|
||||||
|
depth: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
|
||||||
@ -204,6 +206,21 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
|
fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
|
||||||
match arg.node {
|
match arg.node {
|
||||||
|
hir::TyBareFn(_) => {
|
||||||
|
self.depth += 1;
|
||||||
|
intravisit::walk_ty(self, arg);
|
||||||
|
self.depth -= 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hir::TyTraitObject(ref bounds, _) => {
|
||||||
|
for bound in bounds {
|
||||||
|
self.depth += 1;
|
||||||
|
self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
|
||||||
|
self.depth -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hir::TyRptr(ref lifetime, _) => {
|
hir::TyRptr(ref lifetime, _) => {
|
||||||
// the lifetime of the TyRptr
|
// the lifetime of the TyRptr
|
||||||
let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id);
|
let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id);
|
||||||
@ -217,7 +234,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
|
|||||||
debruijn_index.depth,
|
debruijn_index.depth,
|
||||||
anon_index,
|
anon_index,
|
||||||
br_index);
|
br_index);
|
||||||
if debruijn_index.depth == 1 && anon_index == br_index {
|
if debruijn_index.depth == self.depth && anon_index == br_index {
|
||||||
self.found_type = Some(arg);
|
self.found_type = Some(arg);
|
||||||
return; // we can stop visiting now
|
return; // we can stop visiting now
|
||||||
}
|
}
|
||||||
@ -246,7 +263,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
|
|||||||
debug!("self.infcx.tcx.hir.local_def_id(id)={:?}",
|
debug!("self.infcx.tcx.hir.local_def_id(id)={:?}",
|
||||||
self.infcx.tcx.hir.local_def_id(id));
|
self.infcx.tcx.hir.local_def_id(id));
|
||||||
debug!("def_id={:?}", def_id);
|
debug!("def_id={:?}", def_id);
|
||||||
if debruijn_index.depth == 1 &&
|
if debruijn_index.depth == self.depth &&
|
||||||
self.infcx.tcx.hir.local_def_id(id) == def_id {
|
self.infcx.tcx.hir.local_def_id(id) == def_id {
|
||||||
self.found_type = Some(arg);
|
self.found_type = Some(arg);
|
||||||
return; // we can stop visiting now
|
return; // we can stop visiting now
|
||||||
|
18
src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr
Normal file
18
src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/ex3-both-anon-regions-4.rs:12:13
|
||||||
|
|
|
||||||
|
11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||||
|
| --- --- these references are declared with different lifetimes...
|
||||||
|
12 | z.push((x,y));
|
||||||
|
| ^ ...but data flows into `z` here
|
||||||
|
|
||||||
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/ex3-both-anon-regions-4.rs:12:15
|
||||||
|
|
|
||||||
|
11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||||
|
| --- --- these references are declared with different lifetimes...
|
||||||
|
12 | z.push((x,y));
|
||||||
|
| ^ ...but data flows into `z` here
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
struct Ref<'a, 'b> {
|
||||||
|
a: &'a u32,
|
||||||
|
b: &'b u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(mut x: Ref) {
|
||||||
|
x.a = x.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/ex3-both-anon-regions-both-are-structs-4.rs:16:11
|
||||||
|
|
|
||||||
|
15 | fn foo(mut x: Ref) {
|
||||||
|
| ---
|
||||||
|
| |
|
||||||
|
| this type was declared with multiple lifetimes...
|
||||||
|
16 | x.a = x.b;
|
||||||
|
| ^^^ ...but data with one lifetime flows into the other here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
|
||||||
|
|
||||||
|
fn foo(mut y: Ref, x: &u32) {
|
||||||
|
y.b = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
@ -0,0 +1,10 @@
|
|||||||
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:14:11
|
||||||
|
|
|
||||||
|
13 | fn foo(mut y: Ref, x: &u32) {
|
||||||
|
| --- ---- these two types are declared with different lifetimes...
|
||||||
|
14 | y.b = x;
|
||||||
|
| ^ ...but data from `x` flows into `y` here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
|
||||||
|
y.push(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
@ -0,0 +1,10 @@
|
|||||||
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/ex3-both-anon-regions-using-fn-items.rs:11:10
|
||||||
|
|
|
||||||
|
10 | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
|
||||||
|
| --- --- these two types are declared with different lifetimes...
|
||||||
|
11 | y.push(z);
|
||||||
|
| ^ ...but data from `z` flows into `y` here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
|
||||||
|
y.push(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
@ -0,0 +1,10 @@
|
|||||||
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/ex3-both-anon-regions-using-trait-objects.rs:11:10
|
||||||
|
|
|
||||||
|
10 | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
|
||||||
|
| --- --- these two types are declared with different lifetimes...
|
||||||
|
11 | y.push(z);
|
||||||
|
| ^ ...but data from `z` flows into `y` here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Reference in New Issue
Block a user