Auto merge of #126581 - GuillaumeGomez:rollup-dx4fadn, r=GuillaumeGomez
Rollup of 3 pull requests Successful merges: - #126226 (Make suggestion to change `Fn` to `FnMut` work with methods as well) - #126570 (Convert a `span_bug` to a `span_delayed_bug`.) - #126580 (Add `run-make/const_fn_mir` missing test annotation) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
3baa20b783
@ -937,24 +937,50 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
let node = self.infcx.tcx.hir_node(fn_call_id);
|
let node = self.infcx.tcx.hir_node(fn_call_id);
|
||||||
let def_id = hir.enclosing_body_owner(fn_call_id);
|
let def_id = hir.enclosing_body_owner(fn_call_id);
|
||||||
let mut look_at_return = true;
|
let mut look_at_return = true;
|
||||||
// If we can detect the expression to be an `fn` call where the closure was an argument,
|
|
||||||
// we point at the `fn` definition argument...
|
// If the HIR node is a function or method call gets the def ID
|
||||||
if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) = node {
|
// of the called function or method and the span and args of the call expr
|
||||||
let arg_pos = args
|
let get_call_details = || {
|
||||||
|
let hir::Node::Expr(hir::Expr { hir_id, kind, .. }) = node else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let typeck_results = self.infcx.tcx.typeck(def_id);
|
||||||
|
|
||||||
|
match kind {
|
||||||
|
hir::ExprKind::Call(expr, args) => {
|
||||||
|
if let Some(ty::FnDef(def_id, _)) =
|
||||||
|
typeck_results.node_type_opt(expr.hir_id).as_ref().map(|ty| ty.kind())
|
||||||
|
{
|
||||||
|
Some((*def_id, expr.span, *args))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hir::ExprKind::MethodCall(_, _, args, span) => {
|
||||||
|
if let Some(def_id) = typeck_results.type_dependent_def_id(*hir_id) {
|
||||||
|
Some((def_id, *span, *args))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// If we can detect the expression to be an function or method call where the closure was an argument,
|
||||||
|
// we point at the function or method definition argument...
|
||||||
|
if let Some((callee_def_id, call_span, call_args)) = get_call_details() {
|
||||||
|
let arg_pos = call_args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, arg)| arg.hir_id == closure_id)
|
.filter(|(_, arg)| arg.hir_id == closure_id)
|
||||||
.map(|(pos, _)| pos)
|
.map(|(pos, _)| pos)
|
||||||
.next();
|
.next();
|
||||||
let tables = self.infcx.tcx.typeck(def_id);
|
|
||||||
if let Some(ty::FnDef(def_id, _)) =
|
let arg = match hir.get_if_local(callee_def_id) {
|
||||||
tables.node_type_opt(func.hir_id).as_ref().map(|ty| ty.kind())
|
|
||||||
{
|
|
||||||
let arg = match hir.get_if_local(*def_id) {
|
|
||||||
Some(
|
Some(
|
||||||
hir::Node::Item(hir::Item {
|
hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. })
|
||||||
ident, kind: hir::ItemKind::Fn(sig, ..), ..
|
|
||||||
})
|
|
||||||
| hir::Node::TraitItem(hir::TraitItem {
|
| hir::Node::TraitItem(hir::TraitItem {
|
||||||
ident,
|
ident,
|
||||||
kind: hir::TraitItemKind::Fn(sig, _),
|
kind: hir::TraitItemKind::Fn(sig, _),
|
||||||
@ -983,12 +1009,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
if let Some(span) = arg {
|
if let Some(span) = arg {
|
||||||
err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
|
err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
|
||||||
err.span_label(func.span, "expects `Fn` instead of `FnMut`");
|
err.span_label(call_span, "expects `Fn` instead of `FnMut`");
|
||||||
err.span_label(closure_span, "in this closure");
|
err.span_label(closure_span, "in this closure");
|
||||||
look_at_return = false;
|
look_at_return = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if look_at_return && hir.get_fn_id_for_return_block(closure_id).is_some() {
|
if look_at_return && hir.get_fn_id_for_return_block(closure_id).is_some() {
|
||||||
// ...otherwise we are probably in the tail expression of the function, point at the
|
// ...otherwise we are probably in the tail expression of the function, point at the
|
||||||
|
@ -628,9 +628,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
| GenericArgKind::Const(_),
|
| GenericArgKind::Const(_),
|
||||||
_,
|
_,
|
||||||
) => {
|
) => {
|
||||||
// This was previously a `span_delayed_bug` and could be
|
self.dcx().span_delayed_bug(
|
||||||
// reached by the test for #82126, but no longer.
|
|
||||||
self.dcx().span_bug(
|
|
||||||
hir_arg.span(),
|
hir_arg.span(),
|
||||||
format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
|
format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
|
||||||
);
|
);
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
//@ known-bug: rust-lang/rust#126385
|
|
||||||
pub struct MyStruct<'field> {
|
|
||||||
field: &'_ [u32],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MyStruct<'_> {
|
|
||||||
pub fn _<'a>(field: &'a[u32]) -> Self<new> {
|
|
||||||
Self{field}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
// The `needs-unwind -Cpanic=abort` gives a different MIR output.
|
// The `needs-unwind -Cpanic=abort` gives a different MIR output.
|
||||||
|
|
||||||
|
//@ needs-unwind
|
||||||
|
|
||||||
use run_make_support::{cwd, diff, rustc};
|
use run_make_support::{cwd, diff, rustc};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
14
tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.rs
Normal file
14
tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// This test was triggering a `span_bug` crash, which was then fixed by
|
||||||
|
// downgrading it to a `span_delayed_bug`.
|
||||||
|
|
||||||
|
pub struct MyStruct<'field> {
|
||||||
|
field: &'field [u32],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MyStruct<'_> {
|
||||||
|
pub fn f(field: &[u32]) -> Self<u32> { //~ ERROR type arguments are not allowed on self type
|
||||||
|
Self { field } //~ ERROR lifetime may not live long enough
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,34 @@
|
|||||||
|
error[E0109]: type arguments are not allowed on self type
|
||||||
|
--> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:9:37
|
||||||
|
|
|
||||||
|
LL | pub fn f(field: &[u32]) -> Self<u32> {
|
||||||
|
| ---- ^^^ type argument not allowed
|
||||||
|
| |
|
||||||
|
| not allowed on self type
|
||||||
|
|
|
||||||
|
note: `Self` is of type `MyStruct<'_>`
|
||||||
|
--> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:4:12
|
||||||
|
|
|
||||||
|
LL | pub struct MyStruct<'field> {
|
||||||
|
| ^^^^^^^^ `Self` corresponds to this type
|
||||||
|
...
|
||||||
|
LL | impl MyStruct<'_> {
|
||||||
|
| ----------------- `Self` is on type `MyStruct` in this `impl`
|
||||||
|
help: the `Self` type doesn't accept type parameters, use the concrete type's name `MyStruct` instead if you want to specify its type parameters
|
||||||
|
|
|
||||||
|
LL | pub fn f(field: &[u32]) -> MyStruct<u32> {
|
||||||
|
| ~~~~~~~~
|
||||||
|
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:10:9
|
||||||
|
|
|
||||||
|
LL | pub fn f(field: &[u32]) -> Self<u32> {
|
||||||
|
| - --------- return type is MyStruct<'2>
|
||||||
|
| |
|
||||||
|
| let's call the lifetime of this reference `'1`
|
||||||
|
LL | Self { field }
|
||||||
|
| ^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0109`.
|
29
tests/ui/closures/wrong-closure-arg-suggestion-125325.rs
Normal file
29
tests/ui/closures/wrong-closure-arg-suggestion-125325.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Regression test for #125325
|
||||||
|
|
||||||
|
// Tests that we suggest changing an `impl Fn` param
|
||||||
|
// to `impl FnMut` when the provided closure arg
|
||||||
|
// is trying to mutate the closure env.
|
||||||
|
// Ensures that it works that way for both
|
||||||
|
// functions and methods
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn assoc_func(&self, _f: impl Fn()) -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn func(_f: impl Fn()) -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_func(s: &S) -> usize {
|
||||||
|
let mut x = ();
|
||||||
|
s.assoc_func(|| x = ());
|
||||||
|
//~^ cannot assign to `x`, as it is a captured variable in a `Fn` closure
|
||||||
|
func(|| x = ())
|
||||||
|
//~^ cannot assign to `x`, as it is a captured variable in a `Fn` closure
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
28
tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr
Normal file
28
tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
|
||||||
|
--> $DIR/wrong-closure-arg-suggestion-125325.rs:23:21
|
||||||
|
|
|
||||||
|
LL | fn assoc_func(&self, _f: impl Fn()) -> usize {
|
||||||
|
| --------- change this to accept `FnMut` instead of `Fn`
|
||||||
|
...
|
||||||
|
LL | s.assoc_func(|| x = ());
|
||||||
|
| --------------^^^^^^-
|
||||||
|
| | | |
|
||||||
|
| | | cannot assign
|
||||||
|
| | in this closure
|
||||||
|
| expects `Fn` instead of `FnMut`
|
||||||
|
|
||||||
|
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
|
||||||
|
--> $DIR/wrong-closure-arg-suggestion-125325.rs:25:13
|
||||||
|
|
|
||||||
|
LL | fn func(_f: impl Fn()) -> usize {
|
||||||
|
| --------- change this to accept `FnMut` instead of `Fn`
|
||||||
|
...
|
||||||
|
LL | func(|| x = ())
|
||||||
|
| ---- -- ^^^^^^ cannot assign
|
||||||
|
| | |
|
||||||
|
| | in this closure
|
||||||
|
| expects `Fn` instead of `FnMut`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0594`.
|
Loading…
x
Reference in New Issue
Block a user