fix: panicking_unwrap FP on field access with implicit deref
(cherry picked from commit c905503474)
This commit is contained in:
parent
feb759bb79
commit
9c13ace16d
2 changed files with 26 additions and 2 deletions
|
|
@ -180,14 +180,19 @@ impl Local {
|
||||||
field_indices,
|
field_indices,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let field_projections = place
|
||||||
|
.projections
|
||||||
|
.iter()
|
||||||
|
.filter(|proj| matches!(proj.kind, ProjectionKind::Field(_, _)))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
is_potentially_local_place(*local_id, place)
|
is_potentially_local_place(*local_id, place)
|
||||||
// If there were projections other than field projections, err on the side of caution and say that they
|
// If there were projections other than field projections, err on the side of caution and say that they
|
||||||
// _might_ be mutating something.
|
// _might_ be mutating something.
|
||||||
//
|
//
|
||||||
// The reason we use `<=` and not `==` is that a mutation of `struct` or `struct.field1` should count as
|
// The reason we use `<=` and not `==` is that a mutation of `struct` or `struct.field1` should count as
|
||||||
// mutation of the child fields such as `struct.field1.field2`
|
// mutation of the child fields such as `struct.field1.field2`
|
||||||
&& place.projections.len() <= field_indices.len()
|
&& field_projections.len() <= field_indices.len()
|
||||||
&& iter::zip(&place.projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| {
|
&& iter::zip(&field_projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| {
|
||||||
match proj.kind {
|
match proj.kind {
|
||||||
ProjectionKind::Field(f_idx, _) => f_idx == field_idx,
|
ProjectionKind::Field(f_idx, _) => f_idx == field_idx,
|
||||||
// If this is a projection we don't expect, it _might_ be mutating something
|
// If this is a projection we don't expect, it _might_ be mutating something
|
||||||
|
|
|
||||||
|
|
@ -472,3 +472,22 @@ fn issue15321() {
|
||||||
//~^ unnecessary_unwrap
|
//~^ unnecessary_unwrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod issue16188 {
|
||||||
|
struct Foo {
|
||||||
|
value: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
pub fn bar(&mut self) {
|
||||||
|
let print_value = |v: i32| {
|
||||||
|
println!("{}", v);
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.value.is_none() {
|
||||||
|
self.value = Some(10);
|
||||||
|
print_value(self.value.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue