Rust: Improve type inference for closures and function traits

This commit is contained in:
Simon Friis Vindum
2026-01-15 12:16:51 +01:00
parent 196f6e1931
commit dabc5d54c9
6 changed files with 121 additions and 61 deletions

View File

@@ -143,23 +143,46 @@ class FutureTrait extends Trait {
TypeAlias getOutputType() { result = this.(TraitItemNode).getAssocItem("Output") }
}
/** A function trait `FnOnce`, `FnMut`, or `Fn`. */
class AnyFnTrait extends Trait {
/** Gets the `Args` type parameter of this trait. */
TypeParam getTypeParam() { result = this.getGenericParamList().getGenericParam(0) }
}
/**
* The [`FnOnce` trait][1].
*
* [1]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html
*/
class FnOnceTrait extends Trait {
class FnOnceTrait extends AnyFnTrait {
pragma[nomagic]
FnOnceTrait() { this.getCanonicalPath() = "core::ops::function::FnOnce" }
/** Gets the type parameter of this trait. */
TypeParam getTypeParam() { result = this.getGenericParamList().getGenericParam(0) }
/** Gets the `Output` associated type. */
pragma[nomagic]
TypeAlias getOutputType() { result = this.(TraitItemNode).getAssocItem("Output") }
}
/**
* The [`FnMut` trait][1].
*
* [1]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
*/
class FnMutTrait extends AnyFnTrait {
pragma[nomagic]
FnMutTrait() { this.getCanonicalPath() = "core::ops::function::FnMut" }
}
/**
* The [`Fn` trait][1].
*
* [1]: https://doc.rust-lang.org/std/ops/trait.Fn.html
*/
class FnTrait extends AnyFnTrait {
pragma[nomagic]
FnTrait() { this.getCanonicalPath() = "core::ops::function::Fn" }
}
/**
* The [`Iterator` trait][1].
*

View File

@@ -3825,16 +3825,29 @@ private Type invokedClosureFnTypeAt(InvokedClosureExpr ce, TypePath path) {
_, path, result)
}
/**
* Gets the root type of a closure.
*
* We model closures as `dyn Fn` trait object types. A closure might implement
* only `Fn`, `FnMut`, or `FnOnce`. But since `Fn` is a subtrait of the others,
* giving closures the type `dyn Fn` works well in practice—even if not entirely
* accurate.
*/
private DynTraitType closureRootType() {
result = TDynTraitType(any(FnTrait t)) // always exists because of the mention in `builtins/mentions.rs`
}
/** Gets the path to a closure's return type. */
private TypePath closureReturnPath() {
result = TypePath::singleton(getDynTraitTypeParameter(any(FnOnceTrait t).getOutputType()))
result =
TypePath::singleton(TDynTraitTypeParameter(any(FnTrait t), any(FnOnceTrait t).getOutputType()))
}
/** Gets the path to a closure with arity `arity`s `index`th parameter type. */
pragma[nomagic]
private TypePath closureParameterPath(int arity, int index) {
result =
TypePath::cons(TDynTraitTypeParameter(_, any(FnOnceTrait t).getTypeParam()),
TypePath::cons(TDynTraitTypeParameter(_, any(FnTrait t).getTypeParam()),
TypePath::singleton(getTupleTypeParameter(arity, index)))
}
@@ -3872,9 +3885,7 @@ private Type inferDynamicCallExprType(Expr n, TypePath path) {
or
// _If_ the invoked expression has the type of a closure, then we propagate
// the surrounding types into the closure.
exists(int arity, TypePath path0 |
ce.getTypeAt(TypePath::nil()).(DynTraitType).getTrait() instanceof FnOnceTrait
|
exists(int arity, TypePath path0 | ce.getTypeAt(TypePath::nil()) = closureRootType() |
// Propagate the type of arguments to the parameter types of closure
exists(int index, ArgList args |
n = ce and
@@ -3898,10 +3909,10 @@ private Type inferClosureExprType(AstNode n, TypePath path) {
exists(ClosureExpr ce |
n = ce and
path.isEmpty() and
result = TDynTraitType(any(FnOnceTrait t)) // always exists because of the mention in `builtins/mentions.rs`
result = closureRootType()
or
n = ce and
path = TypePath::singleton(TDynTraitTypeParameter(_, any(FnOnceTrait t).getTypeParam())) and
path = TypePath::singleton(TDynTraitTypeParameter(_, any(FnTrait t).getTypeParam())) and
result.(TupleType).getArity() = ce.getNumberOfParams()
or
// Propagate return type annotation to body

View File

@@ -212,7 +212,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
// associated types of `Fn` and `FnMut` yet.
//
// [1]: https://doc.rust-lang.org/reference/paths.html#grammar-TypePathFn
exists(FnOnceTrait t, PathSegment s |
exists(AnyFnTrait t, PathSegment s |
t = resolved and
s = this.getSegment() and
s.hasParenthesizedArgList()
@@ -220,7 +220,7 @@ class NonAliasPathTypeMention extends PathTypeMention {
tp = TTypeParamTypeParameter(t.getTypeParam()) and
result = s.getParenthesizedArgList().(TypeMention).resolveTypeAt(path)
or
tp = TAssociatedTypeTypeParameter(t, t.getOutputType()) and
tp = TAssociatedTypeTypeParameter(t, any(FnOnceTrait tr).getOutputType()) and
(
result = s.getRetType().getTypeRepr().(TypeMention).resolveTypeAt(path)
or

View File

@@ -70,15 +70,15 @@ mod fn_once_trait {
mod fn_mut_trait {
fn return_type<F: FnMut(bool) -> i64>(mut f: F) {
let _return = f(true); // $ MISSING: type=_return:i64
let _return = f(true); // $ type=_return:i64
}
fn return_type_omitted<F: FnMut(bool)>(mut f: F) {
let _return = f(true); // $ MISSING: type=_return:()
let _return = f(true); // $ type=_return:()
}
fn argument_type<F: FnMut(bool) -> i64>(mut f: F) {
let arg = Default::default(); // $ MISSING: target=default type=arg:bool
let arg = Default::default(); // $ target=default type=arg:bool
f(arg);
}
@@ -98,7 +98,7 @@ mod fn_mut_trait {
0
}
};
let _r = apply(f, true); // $ target=apply MISSING: type=_r:i64
let _r = apply(f, true); // $ target=apply type=_r:i64
let f = |x| x + 1; // $ MISSING: type=x:i64 target=add
let _r2 = apply_two(f); // $ target=apply_two certainType=_r2:i64
@@ -107,15 +107,15 @@ mod fn_mut_trait {
mod fn_trait {
fn return_type<F: Fn(bool) -> i64>(f: F) {
let _return = f(true); // $ MISSING: type=_return:i64
let _return = f(true); // $ type=_return:i64
}
fn return_type_omitted<F: Fn(bool)>(f: F) {
let _return = f(true); // $ MISSING: type=_return:()
let _return = f(true); // $ type=_return:()
}
fn argument_type<F: Fn(bool) -> i64>(f: F) {
let arg = Default::default(); // $ MISSING: target=default type=arg:bool
let arg = Default::default(); // $ target=default type=arg:bool
f(arg);
}
@@ -135,7 +135,7 @@ mod fn_trait {
0
}
};
let _r = apply(f, true); // $ target=apply MISSING: type=_r:i64
let _r = apply(f, true); // $ target=apply type=_r:i64
let f = |x| x + 1; // $ MISSING: type=x:i64 target=add
let _r2 = apply_two(f); // $ target=apply_two certainType=_r2:i64

View File

@@ -5420,12 +5420,12 @@ inferType
| blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | | {EXTERNAL LOCATION} | & |
| blanket_impl.rs:299:47:299:67 | "SELECT * FROM users" | TRef | {EXTERNAL LOCATION} | str |
| closure.rs:4:19:31:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:6:13:6:22 | my_closure | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:6:13:6:22 | my_closure | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:6:13:6:22 | my_closure | dyn(Args) | {EXTERNAL LOCATION} | (T_2) |
| closure.rs:6:13:6:22 | my_closure | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:6:13:6:22 | my_closure | dyn(Args).T1 | {EXTERNAL LOCATION} | bool |
| closure.rs:6:13:6:22 | my_closure | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:6:26:6:38 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:6:26:6:38 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:6:26:6:38 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_2) |
| closure.rs:6:26:6:38 | \|...\| ... | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:6:26:6:38 | \|...\| ... | dyn(Args).T1 | {EXTERNAL LOCATION} | bool |
@@ -5437,11 +5437,11 @@ inferType
| closure.rs:6:38:6:38 | b | | {EXTERNAL LOCATION} | bool |
| closure.rs:8:13:8:13 | x | | {EXTERNAL LOCATION} | i64 |
| closure.rs:8:22:8:25 | 1i64 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:9:13:9:19 | add_one | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:9:13:9:19 | add_one | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:9:13:9:19 | add_one | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:9:13:9:19 | add_one | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:9:13:9:19 | add_one | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:9:23:9:34 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:9:23:9:34 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:9:23:9:34 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:9:23:9:34 | \|...\| ... | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:9:23:9:34 | \|...\| ... | dyn(Output) | {EXTERNAL LOCATION} | i64 |
@@ -5450,7 +5450,7 @@ inferType
| closure.rs:9:27:9:34 | ... + ... | | {EXTERNAL LOCATION} | i64 |
| closure.rs:9:31:9:34 | 1i64 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:10:13:10:14 | _y | | {EXTERNAL LOCATION} | i64 |
| closure.rs:10:18:10:24 | add_one | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:10:18:10:24 | add_one | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:10:18:10:24 | add_one | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:10:18:10:24 | add_one | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:10:18:10:24 | add_one | dyn(Output) | {EXTERNAL LOCATION} | i64 |
@@ -5458,55 +5458,55 @@ inferType
| closure.rs:10:26:10:26 | x | | {EXTERNAL LOCATION} | i64 |
| closure.rs:13:13:13:13 | x | | {EXTERNAL LOCATION} | i64 |
| closure.rs:13:17:13:34 | ...::default(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:14:13:14:20 | add_zero | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:14:13:14:20 | add_zero | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:14:13:14:20 | add_zero | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:14:13:14:20 | add_zero | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:14:13:14:20 | add_zero | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:14:24:14:33 | \|...\| n | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:14:24:14:33 | \|...\| n | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:14:24:14:33 | \|...\| n | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:14:24:14:33 | \|...\| n | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:14:24:14:33 | \|...\| n | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:14:25:14:25 | n | | {EXTERNAL LOCATION} | i64 |
| closure.rs:14:33:14:33 | n | | {EXTERNAL LOCATION} | i64 |
| closure.rs:15:13:15:14 | _y | | {EXTERNAL LOCATION} | i64 |
| closure.rs:15:18:15:25 | add_zero | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:15:18:15:25 | add_zero | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:15:18:15:25 | add_zero | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:15:18:15:25 | add_zero | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:15:18:15:25 | add_zero | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:15:18:15:28 | add_zero(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:15:27:15:27 | x | | {EXTERNAL LOCATION} | i64 |
| closure.rs:17:13:17:21 | _get_bool | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:17:13:17:21 | _get_bool | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:17:13:17:21 | _get_bool | dyn(Args) | {EXTERNAL LOCATION} | () |
| closure.rs:17:13:17:21 | _get_bool | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:17:25:21:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:17:25:21:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:17:25:21:9 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | () |
| closure.rs:17:25:21:9 | \|...\| ... | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:17:36:21:9 | { ... } | | {EXTERNAL LOCATION} | bool |
| closure.rs:19:17:19:17 | b | | {EXTERNAL LOCATION} | bool |
| closure.rs:19:21:19:38 | ...::default(...) | | {EXTERNAL LOCATION} | bool |
| closure.rs:20:13:20:13 | b | | {EXTERNAL LOCATION} | bool |
| closure.rs:24:13:24:14 | id | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:24:13:24:14 | id | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:24:13:24:14 | id | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:24:13:24:14 | id | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:24:13:24:14 | id | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:24:18:24:22 | \|...\| b | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:24:18:24:22 | \|...\| b | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:24:18:24:22 | \|...\| b | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:24:18:24:22 | \|...\| b | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:24:18:24:22 | \|...\| b | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:24:19:24:19 | b | | {EXTERNAL LOCATION} | bool |
| closure.rs:24:22:24:22 | b | | {EXTERNAL LOCATION} | bool |
| closure.rs:25:13:25:14 | _b | | {EXTERNAL LOCATION} | bool |
| closure.rs:25:18:25:19 | id | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:25:18:25:19 | id | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:25:18:25:19 | id | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:25:18:25:19 | id | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:25:18:25:19 | id | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:25:18:25:25 | id(...) | | {EXTERNAL LOCATION} | bool |
| closure.rs:25:21:25:24 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:28:13:28:15 | id2 | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:28:13:28:15 | id2 | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:28:13:28:15 | id2 | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:28:13:28:15 | id2 | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:28:13:28:15 | id2 | dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:28:19:28:23 | \|...\| b | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:28:19:28:23 | \|...\| b | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:28:19:28:23 | \|...\| b | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:28:19:28:23 | \|...\| b | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:28:19:28:23 | \|...\| b | dyn(Output) | {EXTERNAL LOCATION} | bool |
@@ -5515,7 +5515,7 @@ inferType
| closure.rs:29:13:29:15 | arg | | {EXTERNAL LOCATION} | bool |
| closure.rs:29:19:29:36 | ...::default(...) | | {EXTERNAL LOCATION} | bool |
| closure.rs:30:13:30:15 | _b2 | | {EXTERNAL LOCATION} | bool |
| closure.rs:30:25:30:27 | id2 | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:30:25:30:27 | id2 | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:30:25:30:27 | id2 | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:30:25:30:27 | id2 | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:30:25:30:27 | id2 | dyn(Output) | {EXTERNAL LOCATION} | bool |
@@ -5553,12 +5553,12 @@ inferType
| closure.rs:53:11:53:11 | 2 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:53:11:53:11 | 2 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:56:15:68:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:57:13:57:13 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:57:13:57:13 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:57:13:57:13 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:57:13:57:13 | f | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:57:13:57:13 | f | dyn(Output) | {EXTERNAL LOCATION} | i32 |
| closure.rs:57:13:57:13 | f | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:57:17:63:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:57:17:63:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:57:17:63:9 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:57:17:63:9 | \|...\| ... | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:57:17:63:9 | \|...\| ... | dyn(Output) | {EXTERNAL LOCATION} | i32 |
@@ -5581,32 +5581,40 @@ inferType
| closure.rs:64:13:64:14 | _r | | {EXTERNAL LOCATION} | i64 |
| closure.rs:64:18:64:31 | apply(...) | | {EXTERNAL LOCATION} | i32 |
| closure.rs:64:18:64:31 | apply(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:64:24:64:24 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:64:24:64:24 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:64:24:64:24 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:64:24:64:24 | f | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:64:24:64:24 | f | dyn(Output) | {EXTERNAL LOCATION} | i32 |
| closure.rs:64:24:64:24 | f | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:64:27:64:30 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:66:13:66:13 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:66:13:66:13 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:66:13:66:13 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:66:17:66:25 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:66:17:66:25 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:66:17:66:25 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:66:25:66:25 | 1 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:67:13:67:15 | _r2 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:67:19:67:30 | apply_two(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:67:29:67:29 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:67:29:67:29 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:67:29:67:29 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:72:47:72:47 | f | | closure.rs:72:20:72:40 | F |
| closure.rs:72:53:74:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:73:13:73:19 | _return | | {EXTERNAL LOCATION} | i64 |
| closure.rs:73:23:73:23 | f | | closure.rs:72:20:72:40 | F |
| closure.rs:73:23:73:29 | f(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:73:25:73:28 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:76:48:76:48 | f | | closure.rs:76:28:76:41 | F |
| closure.rs:76:54:78:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:77:13:77:19 | _return | | {EXTERNAL LOCATION} | () |
| closure.rs:77:23:77:23 | f | | closure.rs:76:28:76:41 | F |
| closure.rs:77:23:77:29 | f(...) | | {EXTERNAL LOCATION} | () |
| closure.rs:77:25:77:28 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:80:49:80:49 | f | | closure.rs:80:22:80:42 | F |
| closure.rs:80:55:83:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:81:13:81:15 | arg | | {EXTERNAL LOCATION} | bool |
| closure.rs:81:19:81:36 | ...::default(...) | | {EXTERNAL LOCATION} | bool |
| closure.rs:82:9:82:9 | f | | closure.rs:80:22:80:42 | F |
| closure.rs:82:9:82:14 | f(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:82:11:82:13 | arg | | {EXTERNAL LOCATION} | bool |
| closure.rs:85:42:85:42 | f | | closure.rs:85:20:85:35 | F |
| closure.rs:85:48:85:48 | a | | closure.rs:85:14:85:14 | A |
| closure.rs:85:59:87:5 | { ... } | | closure.rs:85:17:85:17 | B |
@@ -5618,13 +5626,14 @@ inferType
| closure.rs:90:9:90:9 | f | | closure.rs:89:25:89:46 | impl ... |
| closure.rs:90:9:90:12 | f(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:90:11:90:11 | 2 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:90:11:90:11 | 2 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:93:15:105:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:94:13:94:13 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:94:13:94:13 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:94:13:94:13 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:94:13:94:13 | f | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:94:13:94:13 | f | dyn(Output) | {EXTERNAL LOCATION} | i32 |
| closure.rs:94:13:94:13 | f | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:94:17:100:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:94:17:100:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:94:17:100:9 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:94:17:100:9 | \|...\| ... | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:94:17:100:9 | \|...\| ... | dyn(Output) | {EXTERNAL LOCATION} | i32 |
@@ -5643,32 +5652,44 @@ inferType
| closure.rs:97:20:99:13 | { ... } | | {EXTERNAL LOCATION} | i64 |
| closure.rs:98:17:98:17 | 0 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:98:17:98:17 | 0 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:101:24:101:24 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:101:13:101:14 | _r | | {EXTERNAL LOCATION} | i32 |
| closure.rs:101:13:101:14 | _r | | {EXTERNAL LOCATION} | i64 |
| closure.rs:101:18:101:31 | apply(...) | | {EXTERNAL LOCATION} | i32 |
| closure.rs:101:18:101:31 | apply(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:101:24:101:24 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:101:24:101:24 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:101:24:101:24 | f | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:101:24:101:24 | f | dyn(Output) | {EXTERNAL LOCATION} | i32 |
| closure.rs:101:24:101:24 | f | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:101:27:101:30 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:103:13:103:13 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:103:13:103:13 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:103:13:103:13 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:103:17:103:25 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:103:17:103:25 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:103:17:103:25 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:103:25:103:25 | 1 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:104:13:104:15 | _r2 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:104:19:104:30 | apply_two(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:104:29:104:29 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:104:29:104:29 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:104:29:104:29 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:109:40:109:40 | f | | closure.rs:109:20:109:37 | F |
| closure.rs:109:46:111:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:110:13:110:19 | _return | | {EXTERNAL LOCATION} | i64 |
| closure.rs:110:23:110:23 | f | | closure.rs:109:20:109:37 | F |
| closure.rs:110:23:110:29 | f(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:110:25:110:28 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:113:41:113:41 | f | | closure.rs:113:28:113:38 | F |
| closure.rs:113:47:115:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:114:13:114:19 | _return | | {EXTERNAL LOCATION} | () |
| closure.rs:114:23:114:23 | f | | closure.rs:113:28:113:38 | F |
| closure.rs:114:23:114:29 | f(...) | | {EXTERNAL LOCATION} | () |
| closure.rs:114:25:114:28 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:117:42:117:42 | f | | closure.rs:117:22:117:39 | F |
| closure.rs:117:48:120:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:118:13:118:15 | arg | | {EXTERNAL LOCATION} | bool |
| closure.rs:118:19:118:36 | ...::default(...) | | {EXTERNAL LOCATION} | bool |
| closure.rs:119:9:119:9 | f | | closure.rs:117:22:117:39 | F |
| closure.rs:119:9:119:14 | f(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:119:11:119:13 | arg | | {EXTERNAL LOCATION} | bool |
| closure.rs:122:35:122:35 | f | | closure.rs:122:20:122:32 | F |
| closure.rs:122:41:122:41 | a | | closure.rs:122:14:122:14 | A |
| closure.rs:122:52:124:5 | { ... } | | closure.rs:122:17:122:17 | B |
@@ -5680,13 +5701,14 @@ inferType
| closure.rs:127:9:127:9 | f | | closure.rs:126:21:126:39 | impl ... |
| closure.rs:127:9:127:12 | f(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:127:11:127:11 | 2 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:127:11:127:11 | 2 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:130:15:142:5 | { ... } | | {EXTERNAL LOCATION} | () |
| closure.rs:131:13:131:13 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:131:13:131:13 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:131:13:131:13 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:131:13:131:13 | f | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:131:13:131:13 | f | dyn(Output) | {EXTERNAL LOCATION} | i32 |
| closure.rs:131:13:131:13 | f | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:131:17:137:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:131:17:137:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:131:17:137:9 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:131:17:137:9 | \|...\| ... | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:131:17:137:9 | \|...\| ... | dyn(Output) | {EXTERNAL LOCATION} | i32 |
@@ -5705,20 +5727,24 @@ inferType
| closure.rs:134:20:136:13 | { ... } | | {EXTERNAL LOCATION} | i64 |
| closure.rs:135:17:135:17 | 0 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:135:17:135:17 | 0 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:138:24:138:24 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:138:13:138:14 | _r | | {EXTERNAL LOCATION} | i32 |
| closure.rs:138:13:138:14 | _r | | {EXTERNAL LOCATION} | i64 |
| closure.rs:138:18:138:31 | apply(...) | | {EXTERNAL LOCATION} | i32 |
| closure.rs:138:18:138:31 | apply(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:138:24:138:24 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:138:24:138:24 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:138:24:138:24 | f | dyn(Args).T0 | {EXTERNAL LOCATION} | bool |
| closure.rs:138:24:138:24 | f | dyn(Output) | {EXTERNAL LOCATION} | i32 |
| closure.rs:138:24:138:24 | f | dyn(Output) | {EXTERNAL LOCATION} | i64 |
| closure.rs:138:27:138:30 | true | | {EXTERNAL LOCATION} | bool |
| closure.rs:140:13:140:13 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:140:13:140:13 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:140:13:140:13 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:140:17:140:25 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:140:17:140:25 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:140:17:140:25 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:140:25:140:25 | 1 | | {EXTERNAL LOCATION} | i32 |
| closure.rs:141:13:141:15 | _r2 | | {EXTERNAL LOCATION} | i64 |
| closure.rs:141:19:141:30 | apply_two(...) | | {EXTERNAL LOCATION} | i64 |
| closure.rs:141:29:141:29 | f | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:141:29:141:29 | f | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:141:29:141:29 | f | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:146:54:146:54 | f | | {EXTERNAL LOCATION} | Box |
| closure.rs:146:54:146:54 | f | A | {EXTERNAL LOCATION} | Global |
@@ -5751,11 +5777,11 @@ inferType
| closure.rs:152:19:152:57 | apply_boxed(...) | | {EXTERNAL LOCATION} | bool |
| closure.rs:152:31:152:53 | ...::new(...) | | {EXTERNAL LOCATION} | Box |
| closure.rs:152:31:152:53 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
| closure.rs:152:31:152:53 | ...::new(...) | T | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:152:31:152:53 | ...::new(...) | T | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:152:31:152:53 | ...::new(...) | T.dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:152:31:152:53 | ...::new(...) | T.dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:152:31:152:53 | ...::new(...) | T.dyn(Output) | {EXTERNAL LOCATION} | bool |
| closure.rs:152:40:152:52 | \|...\| true | | {EXTERNAL LOCATION} | dyn FnOnce |
| closure.rs:152:40:152:52 | \|...\| true | | {EXTERNAL LOCATION} | dyn Fn |
| closure.rs:152:40:152:52 | \|...\| true | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| closure.rs:152:40:152:52 | \|...\| true | dyn(Args).T0 | {EXTERNAL LOCATION} | i64 |
| closure.rs:152:40:152:52 | \|...\| true | dyn(Output) | {EXTERNAL LOCATION} | bool |
@@ -9060,7 +9086,7 @@ inferType
| main.rs:1480:17:1480:18 | TryExpr | | {EXTERNAL LOCATION} | Result |
| main.rs:1480:17:1480:18 | TryExpr | T | main.rs:1454:5:1455:14 | S1 |
| main.rs:1480:17:1480:29 | ... .map(...) | | {EXTERNAL LOCATION} | Result |
| main.rs:1480:24:1480:28 | \|...\| s | | {EXTERNAL LOCATION} | dyn FnOnce |
| main.rs:1480:24:1480:28 | \|...\| s | | {EXTERNAL LOCATION} | dyn Fn |
| main.rs:1480:24:1480:28 | \|...\| s | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| main.rs:1481:9:1481:22 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result |
| main.rs:1481:9:1481:22 | ...::Ok(...) | E | main.rs:1457:5:1458:14 | S2 |
@@ -9083,7 +9109,7 @@ inferType
| main.rs:1488:22:1491:10 | ... .and_then(...) | | {EXTERNAL LOCATION} | Result |
| main.rs:1488:22:1491:10 | ... .and_then(...) | E | main.rs:1454:5:1455:14 | S1 |
| main.rs:1488:33:1488:37 | value | | main.rs:1486:20:1486:27 | T |
| main.rs:1488:49:1491:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| main.rs:1488:49:1491:9 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| main.rs:1488:49:1491:9 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| main.rs:1488:49:1491:9 | \|...\| ... | dyn(Output) | {EXTERNAL LOCATION} | Result |
| main.rs:1488:49:1491:9 | \|...\| ... | dyn(Output).E | main.rs:1454:5:1455:14 | S1 |
@@ -10648,7 +10674,7 @@ inferType
| main.rs:2399:19:2399:19 | 1 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2399:22:2399:22 | 2 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2399:25:2399:25 | 3 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2399:32:2399:40 | \|...\| ... | | {EXTERNAL LOCATION} | dyn FnOnce |
| main.rs:2399:32:2399:40 | \|...\| ... | | {EXTERNAL LOCATION} | dyn Fn |
| main.rs:2399:32:2399:40 | \|...\| ... | dyn(Args) | {EXTERNAL LOCATION} | (T_1) |
| main.rs:2399:40:2399:40 | 1 | | {EXTERNAL LOCATION} | i32 |
| main.rs:2399:43:2399:44 | { ... } | | {EXTERNAL LOCATION} | () |

View File

@@ -3,4 +3,4 @@
use std::future::Future;
fn mention_dyn_future<T>(f: &dyn Future<Output = T>) {}
fn mention_dyn_fn_once<F>(f: &dyn FnOnce() -> F) {}
fn mention_dyn_fn_once<F>(f: &dyn Fn() -> F) {}