From 9c37acc0b83ae5aea300759086875ca64627242a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 26 Jan 2026 14:47:25 +0100 Subject: [PATCH 1/3] Rust: Fix context-based type inference explosion --- .../typeinference/FunctionOverloading.qll | 34 +++++++++++++++---- .../internal/typeinference/TypeInference.qll | 13 ++++--- .../PathResolutionConsistency.expected | 2 -- .../typeinference/internal/TypeInference.qll | 7 +++- 4 files changed, 39 insertions(+), 17 deletions(-) delete mode 100644 rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/PathResolutionConsistency.expected diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll index e1da3352d0cd..1426f7d76d6e 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll @@ -95,13 +95,8 @@ predicate traitTypeParameterOccurrence( tp = trait.(TraitTypeAbstraction).getATypeParameter() } -/** - * Holds if resolving the function `f` in `impl` with the name `functionName` - * requires inspecting the type of applied _arguments_ at position `pos` in - * order to determine whether it is the correct resolution. - */ pragma[nomagic] -predicate functionResolutionDependsOnArgument( +private predicate functionResolutionDependsOnArgument0( ImplItemNode impl, Function f, FunctionPosition pos, TypePath path, Type type ) { /* @@ -133,7 +128,32 @@ predicate functionResolutionDependsOnArgument( implHasSibling(impl, trait) and traitTypeParameterOccurrence(trait, _, functionName, pos, path, _) and type = getAssocFunctionTypeAt(f, impl, pos, path) and - f = impl.getASuccessor(functionName) and + f = impl.getASuccessor(functionName) + ) +} + +/** + * Holds if resolving the function `f` in `impl` requires inspecting the type + * of applied _arguments_ at position `pos` (including the return type) in + * order to determine whether it is the correct resolution. + */ +pragma[nomagic] +predicate functionResolutionDependsOnArgument( + ImplItemNode impl, Function f, FunctionPosition pos, TypePath path, Type type +) { + functionResolutionDependsOnArgument0(impl, f, pos, path, type) and + ( pos.isPosition() + or + // Only disambiguate based on return type when all other positions are trivially + // satisfied for all arguments. + pos.isReturn() and + forall(FunctionPosition pos0, TypePath path0, Type type0 | + pos0.isPosition() and + functionResolutionDependsOnArgument0(impl, f, pos0, path0, type0) + | + path0.isEmpty() and + type0.(TypeParamTypeParameter).getTypeParam() = any(TypeParam tp | not tp.hasTypeBound()) + ) ) } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index b051d60d8b4d..76155d329f48 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -1172,13 +1172,13 @@ private module ContextTyping { */ module CheckContextTyping { pragma[nomagic] - private Type inferCallTypeFromContextCand(AstNode n, TypePath path, TypePath prefix) { + private Type inferCallTypeFromContextCand(AstNode n, TypePath prefix, TypePath path) { result = inferCallType(n, false, path) and hasUnknownType(n) and prefix = path or exists(TypePath mid | - result = inferCallTypeFromContextCand(n, path, mid) and + result = inferCallTypeFromContextCand(n, mid, path) and mid.isSnoc(prefix, _) ) } @@ -1188,7 +1188,7 @@ private module ContextTyping { result = inferCallType(n, true, path) or exists(TypePath prefix | - result = inferCallTypeFromContextCand(n, path, prefix) and + result = inferCallTypeFromContextCand(n, prefix, path) and hasUnknownTypeAt(n, prefix) ) } @@ -2669,9 +2669,8 @@ private module NonMethodResolution { then // We only check that the context of the call provides relevant type information // when no argument can - not exists(FunctionPosition pos0 | - FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos0, _, _) and - not pos0.isReturn() + not exists(FunctionPosition pos0 | not pos0.isReturn() | + FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos0, _, _) or FunctionOverloading::functionResolutionDependsOnArgument(impl, implFunction, pos0, _, _) ) @@ -2837,7 +2836,7 @@ private module NonMethodResolution { NonMethodFunction resolveTraitFunctionViaPathResolution(TraitItemNode trait) { this.hasTrait() and result = this.getPathResolutionResolved() and - result = trait.getASuccessor(_) + result = trait.getAnAssocItem() } } diff --git a/rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/PathResolutionConsistency.expected deleted file mode 100644 index 580c9cd8202c..000000000000 --- a/rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/PathResolutionConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -multipleResolvedTargets -| test_storage.rs:36:45:36:57 | text.as_ref() | diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 654102ce2167..c33c49e7a168 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -980,6 +980,11 @@ module Make1 Input1> { not t = abs.getATypeParameter() } + pragma[nomagic] + private predicate hasTypeConstraint(HasTypeTree term, Type constraint) { + hasTypeConstraint(term, constraint, constraint) + } + /** * Holds if the type tree at `tt` satisfies the constraint `constraint` * with the type `t` at `path`. @@ -994,7 +999,7 @@ module Make1 Input1> { path = prefix0.append(suffix) ) or - hasTypeConstraint(tt, constraint, constraint) and + hasTypeConstraint(tt, constraint) and t = getTypeAt(tt, path) } From 063175bd2e8bf9e862576c24d730c85362e680db Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 26 Jan 2026 17:21:53 +0100 Subject: [PATCH 2/3] Rust: Merge `Input1` and `Input2` modules --- .../internal/typeinference/TypeInference.qll | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index 76155d329f48..c0dc5c07da96 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -30,7 +30,7 @@ private newtype TTypeArgumentPosition = } or TTypeParamTypeArgumentPosition(TypeParam tp) -private module Input1 implements InputSig1 { +private module Input implements InputSig1, InputSig2 { private import Type as T private import codeql.rust.elements.internal.generated.Raw private import codeql.rust.elements.internal.generated.Synth @@ -120,21 +120,7 @@ private module Input1 implements InputSig1 { } int getTypePathLimit() { result = 10 } -} - -private import Input1 - -private module M1 = Make1; - -import M1 - -predicate getTypePathLimit = Input1::getTypePathLimit/0; - -class TypePath = M1::TypePath; - -module TypePath = M1::TypePath; -private module Input2 implements InputSig2 { TypeMention getABaseTypeMention(Type t) { none() } Type getATypeParameterConstraint(TypeParameter tp, TypePath path) { @@ -208,7 +194,19 @@ private module Input2 implements InputSig2 { } } -private module M2 = Make2; +private import Input + +private module M1 = Make1; + +import M1 + +predicate getTypePathLimit = Input::getTypePathLimit/0; + +class TypePath = M1::TypePath; + +module TypePath = M1::TypePath; + +private module M2 = Make2; import M2 @@ -4151,7 +4149,7 @@ private module Debug { TypeAbstraction abs, TypeMention condition, TypeMention constraint, boolean transitive ) { abs = getRelevantLocatable() and - Input2::conditionSatisfiesConstraint(abs, condition, constraint, transitive) + Input::conditionSatisfiesConstraint(abs, condition, constraint, transitive) } predicate debugInferShorthandSelfType(ShorthandSelfParameterMention self, TypePath path, Type t) { From 50ce393a231072052fc5314fdc4f53728960867f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 26 Jan 2026 20:04:58 +0100 Subject: [PATCH 3/3] Rust: Add type inference regression test --- .../test/library-tests/type-inference/main.rs | 10 ++ .../type-inference/type-inference.expected | 170 +++++++++--------- 2 files changed, 98 insertions(+), 82 deletions(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index e72fecf32f1a..293863c8c60b 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2883,6 +2883,16 @@ mod literal_overlap { } } +mod from_default { + #[derive(Default)] + struct S; + + fn f() -> S { + let x = Default::default(); // $ target=default type=x:S + From::from(x) // $ target=from + } +} + mod associated_types; mod blanket_impl; mod closure; diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 36663b1dc4bf..95651e193b4c 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -3727,48 +3727,49 @@ inferCertainType | main.rs:2878:21:2878:21 | y | | {EXTERNAL LOCATION} | & | | main.rs:2881:13:2881:13 | y | | {EXTERNAL LOCATION} | usize | | main.rs:2882:23:2882:23 | y | | {EXTERNAL LOCATION} | usize | -| main.rs:2892:11:2927:1 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2893:5:2893:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2894:5:2894:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2895:5:2895:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2895:20:2895:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2895:41:2895:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2896:5:2896:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2897:5:2897:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2898:5:2898:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2899:5:2899:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2900:5:2900:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2901:5:2901:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2902:5:2902:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2903:5:2903:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2904:5:2904:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2905:5:2905:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2906:5:2906:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2907:5:2907:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2908:5:2908:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2909:5:2909:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2910:5:2910:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2911:5:2911:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | -| main.rs:2911:5:2911:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | -| main.rs:2912:5:2912:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2913:5:2913:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2914:5:2914:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2915:5:2915:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2916:5:2916:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2917:5:2917:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2918:5:2918:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2890:17:2893:5 | { ... } | | main.rs:2887:5:2888:13 | S | +| main.rs:2902:11:2937:1 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2903:5:2903:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2904:5:2904:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2905:5:2905:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2905:20:2905:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2905:41:2905:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2906:5:2906:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2907:5:2907:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2908:5:2908:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2909:5:2909:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2910:5:2910:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2911:5:2911:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2912:5:2912:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2913:5:2913:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2914:5:2914:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2915:5:2915:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2916:5:2916:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2917:5:2917:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2918:5:2918:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | | main.rs:2919:5:2919:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2920:5:2920:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2921:5:2921:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2922:5:2922:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2923:5:2923:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2924:5:2924:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2925:5:2925:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2925:5:2925:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2925:5:2925:20 | ...::f(...) | T | main.rs:2695:5:2697:5 | dyn MyTrait | -| main.rs:2925:5:2925:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | -| main.rs:2925:16:2925:19 | true | | {EXTERNAL LOCATION} | bool | -| main.rs:2926:5:2926:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2920:5:2920:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2921:5:2921:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | +| main.rs:2921:5:2921:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | +| main.rs:2922:5:2922:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2923:5:2923:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2924:5:2924:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2925:5:2925:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2926:5:2926:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2927:5:2927:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2928:5:2928:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2929:5:2929:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2930:5:2930:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2931:5:2931:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2932:5:2932:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2933:5:2933:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2934:5:2934:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2935:5:2935:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2935:5:2935:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2935:5:2935:20 | ...::f(...) | T | main.rs:2695:5:2697:5 | dyn MyTrait | +| main.rs:2935:5:2935:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | +| main.rs:2935:16:2935:19 | true | | {EXTERNAL LOCATION} | bool | +| main.rs:2936:5:2936:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | | pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:13:26:133:1 | { ... } | T | {EXTERNAL LOCATION} | () | | pattern_matching.rs:15:5:18:5 | if ... {...} | | {EXTERNAL LOCATION} | () | @@ -11891,48 +11892,53 @@ inferType | main.rs:2882:17:2882:17 | x | | {EXTERNAL LOCATION} | i32 | | main.rs:2882:17:2882:24 | x.max(...) | | {EXTERNAL LOCATION} | i32 | | main.rs:2882:23:2882:23 | y | | {EXTERNAL LOCATION} | usize | -| main.rs:2892:11:2927:1 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2893:5:2893:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2894:5:2894:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2895:5:2895:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2895:20:2895:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2895:41:2895:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2896:5:2896:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2897:5:2897:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2898:5:2898:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2899:5:2899:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2900:5:2900:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2901:5:2901:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2902:5:2902:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2903:5:2903:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2904:5:2904:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2905:5:2905:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2906:5:2906:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2907:5:2907:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2908:5:2908:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2909:5:2909:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2910:5:2910:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2911:5:2911:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | -| main.rs:2911:5:2911:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | -| main.rs:2912:5:2912:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2913:5:2913:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2914:5:2914:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2915:5:2915:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2916:5:2916:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2917:5:2917:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2918:5:2918:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2890:17:2893:5 | { ... } | | main.rs:2887:5:2888:13 | S | +| main.rs:2891:13:2891:13 | x | | main.rs:2887:5:2888:13 | S | +| main.rs:2891:17:2891:34 | ...::default(...) | | main.rs:2887:5:2888:13 | S | +| main.rs:2892:9:2892:21 | ...::from(...) | | main.rs:2887:5:2888:13 | S | +| main.rs:2892:20:2892:20 | x | | main.rs:2887:5:2888:13 | S | +| main.rs:2902:11:2937:1 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2903:5:2903:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2904:5:2904:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2905:5:2905:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2905:20:2905:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2905:41:2905:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2906:5:2906:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2907:5:2907:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2908:5:2908:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2909:5:2909:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2910:5:2910:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2911:5:2911:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2912:5:2912:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2913:5:2913:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2914:5:2914:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2915:5:2915:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2916:5:2916:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2917:5:2917:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2918:5:2918:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | | main.rs:2919:5:2919:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2920:5:2920:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2921:5:2921:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2922:5:2922:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2923:5:2923:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2924:5:2924:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2925:5:2925:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2925:5:2925:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2925:5:2925:20 | ...::f(...) | T | main.rs:2695:5:2697:5 | dyn MyTrait | -| main.rs:2925:5:2925:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | -| main.rs:2925:16:2925:19 | true | | {EXTERNAL LOCATION} | bool | -| main.rs:2926:5:2926:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2920:5:2920:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2921:5:2921:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | +| main.rs:2921:5:2921:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | +| main.rs:2922:5:2922:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2923:5:2923:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2924:5:2924:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2925:5:2925:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2926:5:2926:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2927:5:2927:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2928:5:2928:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2929:5:2929:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2930:5:2930:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2931:5:2931:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2932:5:2932:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2933:5:2933:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2934:5:2934:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2935:5:2935:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2935:5:2935:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2935:5:2935:20 | ...::f(...) | T | main.rs:2695:5:2697:5 | dyn MyTrait | +| main.rs:2935:5:2935:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | +| main.rs:2935:16:2935:19 | true | | {EXTERNAL LOCATION} | bool | +| main.rs:2936:5:2936:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | | pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:13:26:133:1 | { ... } | T | {EXTERNAL LOCATION} | () | | pattern_matching.rs:14:9:14:13 | value | | {EXTERNAL LOCATION} | Option |