Skip to content

Commit 672977a

Browse files
authored
Merge pull request #20592 from hvitved/rust/type-inference-branch-propagation
Rust: Non-symmetric type propagation for lub coercions
2 parents 74411ff + ff31f0e commit 672977a

File tree

3 files changed

+263
-20
lines changed

3 files changed

+263
-20
lines changed

‎rust/ql/lib/codeql/rust/internal/TypeInference.qll‎

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,14 @@ private Struct getRangeType(RangeExpr re) {
524524
result instanceof RangeToInclusiveStruct
525525
}
526526

527+
private predicate bodyReturns(Expr body, Expr e) {
528+
exists(ReturnExpr re, Callable c |
529+
e = re.getExpr() and
530+
c = re.getEnclosingCallable() and
531+
body = c.getBody()
532+
)
533+
}
534+
527535
/**
528536
* Holds if the type tree of `n1` at `prefix1` should be equal to the type tree
529537
* of `n2` at `prefix2` and type information should propagate in both directions
@@ -540,9 +548,11 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
540548
let.getInitializer() = n2
541549
)
542550
or
543-
n1 = n2.(IfExpr).getABranch()
544-
or
545-
n1 = n2.(MatchExpr).getAnArm().getExpr()
551+
n2 =
552+
any(MatchExpr me |
553+
n1 = me.getAnArm().getExpr() and
554+
me.getNumberOfArms() = 1
555+
)
546556
or
547557
exists(LetExpr let |
548558
n1 = let.getScrutinee() and
@@ -573,6 +583,9 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
573583
n1 = n2.(MacroExpr).getMacroCall().getMacroCallExpansion()
574584
or
575585
n1 = n2.(MacroPat).getMacroCall().getMacroCallExpansion()
586+
or
587+
bodyReturns(n1, n2) and
588+
strictcount(Expr e | bodyReturns(n1, e)) = 1
576589
)
577590
or
578591
(
@@ -606,8 +619,12 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
606619
)
607620
)
608621
or
609-
// an array list expression (`[1, 2, 3]`) has the type of the first (any) element
610-
n1.(ArrayListExpr).getExpr(_) = n2 and
622+
// an array list expression with only one element (such as `[1]`) has type from that element
623+
n1 =
624+
any(ArrayListExpr ale |
625+
ale.getAnExpr() = n2 and
626+
ale.getNumberOfExprs() = 1
627+
) and
611628
prefix1 = TypePath::singleton(TArrayTypeParameter()) and
612629
prefix2.isEmpty()
613630
or
@@ -635,6 +652,61 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat
635652
prefix2.isEmpty()
636653
}
637654

655+
/**
656+
* Holds if `child` is a child of `parent`, and the Rust compiler applies [least
657+
* upper bound (LUB) coercion](1) to infer the type of `parent` from the type of
658+
* `child`.
659+
*
660+
* In this case, we want type information to only flow from `child` to `parent`,
661+
* to avoid (a) either having to model LUB coercions, or (b) risk combinatorial
662+
* explosion in inferred types.
663+
*
664+
* [1]: https://doc.rust-lang.org/reference/type-coercions.html#r-coerce.least-upper-bound
665+
*/
666+
private predicate lubCoercion(AstNode parent, AstNode child, TypePath prefix) {
667+
child = parent.(IfExpr).getABranch() and
668+
prefix.isEmpty()
669+
or
670+
parent =
671+
any(MatchExpr me |
672+
child = me.getAnArm().getExpr() and
673+
me.getNumberOfArms() > 1
674+
) and
675+
prefix.isEmpty()
676+
or
677+
parent =
678+
any(ArrayListExpr ale |
679+
child = ale.getAnExpr() and
680+
ale.getNumberOfExprs() > 1
681+
) and
682+
prefix = TypePath::singleton(TArrayTypeParameter())
683+
or
684+
bodyReturns(parent, child) and
685+
strictcount(Expr e | bodyReturns(parent, e)) > 1 and
686+
prefix.isEmpty()
687+
}
688+
689+
/**
690+
* Holds if the type tree of `n1` at `prefix1` should be equal to the type tree
691+
* of `n2` at `prefix2`, but type information should only propagate from `n1` to
692+
* `n2`.
693+
*/
694+
private predicate typeEqualityNonSymmetric(
695+
AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2
696+
) {
697+
lubCoercion(n2, n1, prefix2) and
698+
prefix1.isEmpty()
699+
or
700+
exists(AstNode mid, TypePath prefixMid, TypePath suffix |
701+
typeEquality(n1, prefixMid, mid, prefix2) or
702+
typeEquality(mid, prefix2, n1, prefixMid)
703+
|
704+
lubCoercion(mid, n2, suffix) and
705+
not lubCoercion(mid, n1, _) and
706+
prefix1 = prefixMid.append(suffix)
707+
)
708+
}
709+
638710
pragma[nomagic]
639711
private Type inferTypeEquality(AstNode n, TypePath path) {
640712
exists(TypePath prefix1, AstNode n2, TypePath prefix2, TypePath suffix |
@@ -644,6 +716,8 @@ private Type inferTypeEquality(AstNode n, TypePath path) {
644716
typeEquality(n, prefix1, n2, prefix2)
645717
or
646718
typeEquality(n2, prefix2, n, prefix1)
719+
or
720+
typeEqualityNonSymmetric(n2, prefix2, n, prefix1)
647721
)
648722
}
649723

‎rust/ql/test/library-tests/type-inference/main.rs‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,6 +2696,52 @@ pub mod path_buf {
26962696
}
26972697
}
26982698

2699+
mod if_expr {
2700+
pub trait MyTrait<T: Sized> {
2701+
fn m(&self) -> T;
2702+
}
2703+
2704+
#[derive(Default)]
2705+
struct S<T>(T);
2706+
2707+
impl MyTrait<i32> for S<i32> {
2708+
fn m(&self) -> i32 {
2709+
self.0 // $ fieldof=S
2710+
}
2711+
}
2712+
2713+
impl MyTrait<i32> for S<S<i32>> {
2714+
fn m(&self) -> i32 {
2715+
self.0 .0 // $ fieldof=S
2716+
}
2717+
}
2718+
2719+
impl<T: Copy> S<T> {
2720+
fn m2(&self) -> S<S<T>> {
2721+
S(S(self.0)) // $ fieldof=S
2722+
}
2723+
}
2724+
2725+
pub fn f(b: bool) -> Box<dyn MyTrait<i32>> {
2726+
let x = if b {
2727+
let y = Default::default(); // $ target=default
2728+
y // $ type=y:T.i32
2729+
} else {
2730+
S(2)
2731+
};
2732+
2733+
// This code would result in an explosion in type inference, if type information was
2734+
// propagated between branches.
2735+
let x = S(1);
2736+
if b {
2737+
let x = x.m2(); // $ target=m2
2738+
Box::new(x) // $ target=new
2739+
} else {
2740+
Box::new(x) // $ target=new
2741+
}
2742+
}
2743+
}
2744+
26992745
mod blanket_impl;
27002746
mod closure;
27012747
mod dereference;
@@ -2733,4 +2779,5 @@ fn main() {
27332779
pattern_matching::test_all_patterns(); // $ target=test_all_patterns
27342780
pattern_matching_experimental::box_patterns(); // $ target=box_patterns
27352781
dyn_type::test(); // $ target=test
2782+
if_expr::f(true); // $ target=f
27362783
}

‎rust/ql/test/library-tests/type-inference/type-inference.expected‎

Lines changed: 137 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,9 +5064,7 @@ inferType
50645064
| main.rs:2479:32:2479:52 | ... .to_vec() | T | {EXTERNAL LOCATION} | u16 |
50655065
| main.rs:2479:33:2479:36 | 1u16 | | {EXTERNAL LOCATION} | u16 |
50665066
| main.rs:2479:39:2479:39 | 2 | | {EXTERNAL LOCATION} | i32 |
5067-
| main.rs:2479:39:2479:39 | 2 | | {EXTERNAL LOCATION} | u16 |
50685067
| main.rs:2479:42:2479:42 | 3 | | {EXTERNAL LOCATION} | i32 |
5069-
| main.rs:2479:42:2479:42 | 3 | | {EXTERNAL LOCATION} | u16 |
50705068
| main.rs:2480:13:2480:13 | u | | {EXTERNAL LOCATION} | u16 |
50715069
| main.rs:2480:13:2480:13 | u | | file://:0:0:0:0 | & |
50725070
| main.rs:2480:18:2480:23 | vals4a | | {EXTERNAL LOCATION} | Vec |
@@ -5077,9 +5075,7 @@ inferType
50775075
| main.rs:2482:22:2482:33 | [...] | [T;...] | {EXTERNAL LOCATION} | u16 |
50785076
| main.rs:2482:23:2482:26 | 1u16 | | {EXTERNAL LOCATION} | u16 |
50795077
| main.rs:2482:29:2482:29 | 2 | | {EXTERNAL LOCATION} | i32 |
5080-
| main.rs:2482:29:2482:29 | 2 | | {EXTERNAL LOCATION} | u16 |
50815078
| main.rs:2482:32:2482:32 | 3 | | {EXTERNAL LOCATION} | i32 |
5082-
| main.rs:2482:32:2482:32 | 3 | | {EXTERNAL LOCATION} | u16 |
50835079
| main.rs:2485:13:2485:17 | vals5 | | {EXTERNAL LOCATION} | Vec |
50845080
| main.rs:2485:13:2485:17 | vals5 | A | {EXTERNAL LOCATION} | Global |
50855081
| main.rs:2485:13:2485:17 | vals5 | T | {EXTERNAL LOCATION} | i32 |
@@ -5093,9 +5089,7 @@ inferType
50935089
| main.rs:2485:31:2485:42 | [...] | [T;...] | {EXTERNAL LOCATION} | u32 |
50945090
| main.rs:2485:32:2485:35 | 1u32 | | {EXTERNAL LOCATION} | u32 |
50955091
| main.rs:2485:38:2485:38 | 2 | | {EXTERNAL LOCATION} | i32 |
5096-
| main.rs:2485:38:2485:38 | 2 | | {EXTERNAL LOCATION} | u32 |
50975092
| main.rs:2485:41:2485:41 | 3 | | {EXTERNAL LOCATION} | i32 |
5098-
| main.rs:2485:41:2485:41 | 3 | | {EXTERNAL LOCATION} | u32 |
50995093
| main.rs:2486:13:2486:13 | u | | {EXTERNAL LOCATION} | i32 |
51005094
| main.rs:2486:13:2486:13 | u | | {EXTERNAL LOCATION} | u32 |
51015095
| main.rs:2486:13:2486:13 | u | | file://:0:0:0:0 | & |
@@ -5116,9 +5110,7 @@ inferType
51165110
| main.rs:2488:32:2488:60 | ... .collect() | T.&T | {EXTERNAL LOCATION} | u64 |
51175111
| main.rs:2488:33:2488:36 | 1u64 | | {EXTERNAL LOCATION} | u64 |
51185112
| main.rs:2488:39:2488:39 | 2 | | {EXTERNAL LOCATION} | i32 |
5119-
| main.rs:2488:39:2488:39 | 2 | | {EXTERNAL LOCATION} | u64 |
51205113
| main.rs:2488:42:2488:42 | 3 | | {EXTERNAL LOCATION} | i32 |
5121-
| main.rs:2488:42:2488:42 | 3 | | {EXTERNAL LOCATION} | u64 |
51225114
| main.rs:2489:13:2489:13 | u | | file://:0:0:0:0 | & |
51235115
| main.rs:2489:13:2489:13 | u | &T | {EXTERNAL LOCATION} | u64 |
51245116
| main.rs:2489:18:2489:22 | vals6 | | {EXTERNAL LOCATION} | Vec |
@@ -5618,11 +5610,143 @@ inferType
56185610
| main.rs:2693:13:2693:20 | pathbuf1 | | main.rs:2668:5:2668:25 | PathBuf |
56195611
| main.rs:2693:24:2693:37 | ...::new(...) | | main.rs:2668:5:2668:25 | PathBuf |
56205612
| main.rs:2694:24:2694:31 | pathbuf1 | | main.rs:2668:5:2668:25 | PathBuf |
5621-
| main.rs:2706:5:2706:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo |
5622-
| main.rs:2707:5:2707:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo |
5623-
| main.rs:2707:20:2707:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
5624-
| main.rs:2707:41:2707:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
5625-
| main.rs:2723:5:2723:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future |
5613+
| main.rs:2701:14:2701:18 | SelfParam | | file://:0:0:0:0 | & |
5614+
| main.rs:2701:14:2701:18 | SelfParam | &T | main.rs:2700:5:2702:5 | Self [trait MyTrait] |
5615+
| main.rs:2708:14:2708:18 | SelfParam | | file://:0:0:0:0 | & |
5616+
| main.rs:2708:14:2708:18 | SelfParam | &T | main.rs:2704:5:2705:19 | S |
5617+
| main.rs:2708:14:2708:18 | SelfParam | &T.T | {EXTERNAL LOCATION} | i32 |
5618+
| main.rs:2708:28:2710:9 | { ... } | | {EXTERNAL LOCATION} | i32 |
5619+
| main.rs:2709:13:2709:16 | self | | file://:0:0:0:0 | & |
5620+
| main.rs:2709:13:2709:16 | self | &T | main.rs:2704:5:2705:19 | S |
5621+
| main.rs:2709:13:2709:16 | self | &T.T | {EXTERNAL LOCATION} | i32 |
5622+
| main.rs:2709:13:2709:18 | self.0 | | {EXTERNAL LOCATION} | i32 |
5623+
| main.rs:2714:14:2714:18 | SelfParam | | file://:0:0:0:0 | & |
5624+
| main.rs:2714:14:2714:18 | SelfParam | &T | main.rs:2704:5:2705:19 | S |
5625+
| main.rs:2714:14:2714:18 | SelfParam | &T.T | main.rs:2704:5:2705:19 | S |
5626+
| main.rs:2714:14:2714:18 | SelfParam | &T.T.T | {EXTERNAL LOCATION} | i32 |
5627+
| main.rs:2714:28:2716:9 | { ... } | | {EXTERNAL LOCATION} | i32 |
5628+
| main.rs:2715:13:2715:16 | self | | file://:0:0:0:0 | & |
5629+
| main.rs:2715:13:2715:16 | self | &T | main.rs:2704:5:2705:19 | S |
5630+
| main.rs:2715:13:2715:16 | self | &T.T | main.rs:2704:5:2705:19 | S |
5631+
| main.rs:2715:13:2715:16 | self | &T.T.T | {EXTERNAL LOCATION} | i32 |
5632+
| main.rs:2715:13:2715:18 | self.0 | | main.rs:2704:5:2705:19 | S |
5633+
| main.rs:2715:13:2715:18 | self.0 | T | {EXTERNAL LOCATION} | i32 |
5634+
| main.rs:2715:13:2715:21 | ... .0 | | {EXTERNAL LOCATION} | i32 |
5635+
| main.rs:2720:15:2720:19 | SelfParam | | file://:0:0:0:0 | & |
5636+
| main.rs:2720:15:2720:19 | SelfParam | &T | main.rs:2704:5:2705:19 | S |
5637+
| main.rs:2720:15:2720:19 | SelfParam | &T.T | main.rs:2719:10:2719:16 | T |
5638+
| main.rs:2720:33:2722:9 | { ... } | | main.rs:2704:5:2705:19 | S |
5639+
| main.rs:2720:33:2722:9 | { ... } | T | main.rs:2704:5:2705:19 | S |
5640+
| main.rs:2720:33:2722:9 | { ... } | T.T | main.rs:2719:10:2719:16 | T |
5641+
| main.rs:2721:13:2721:24 | S(...) | | main.rs:2704:5:2705:19 | S |
5642+
| main.rs:2721:13:2721:24 | S(...) | T | main.rs:2704:5:2705:19 | S |
5643+
| main.rs:2721:13:2721:24 | S(...) | T.T | main.rs:2719:10:2719:16 | T |
5644+
| main.rs:2721:15:2721:23 | S(...) | | main.rs:2704:5:2705:19 | S |
5645+
| main.rs:2721:15:2721:23 | S(...) | T | main.rs:2719:10:2719:16 | T |
5646+
| main.rs:2721:17:2721:20 | self | | file://:0:0:0:0 | & |
5647+
| main.rs:2721:17:2721:20 | self | &T | main.rs:2704:5:2705:19 | S |
5648+
| main.rs:2721:17:2721:20 | self | &T.T | main.rs:2719:10:2719:16 | T |
5649+
| main.rs:2721:17:2721:22 | self.0 | | main.rs:2719:10:2719:16 | T |
5650+
| main.rs:2725:14:2725:14 | b | | {EXTERNAL LOCATION} | bool |
5651+
| main.rs:2725:48:2742:5 | { ... } | | {EXTERNAL LOCATION} | Box |
5652+
| main.rs:2725:48:2742:5 | { ... } | A | {EXTERNAL LOCATION} | Global |
5653+
| main.rs:2725:48:2742:5 | { ... } | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5654+
| main.rs:2725:48:2742:5 | { ... } | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5655+
| main.rs:2726:13:2726:13 | x | | main.rs:2704:5:2705:19 | S |
5656+
| main.rs:2726:13:2726:13 | x | T | {EXTERNAL LOCATION} | i32 |
5657+
| main.rs:2726:17:2731:9 | if b {...} else {...} | | main.rs:2704:5:2705:19 | S |
5658+
| main.rs:2726:17:2731:9 | if b {...} else {...} | T | {EXTERNAL LOCATION} | i32 |
5659+
| main.rs:2726:20:2726:20 | b | | {EXTERNAL LOCATION} | bool |
5660+
| main.rs:2726:22:2729:9 | { ... } | | main.rs:2704:5:2705:19 | S |
5661+
| main.rs:2726:22:2729:9 | { ... } | T | {EXTERNAL LOCATION} | i32 |
5662+
| main.rs:2727:17:2727:17 | y | | main.rs:2704:5:2705:19 | S |
5663+
| main.rs:2727:17:2727:17 | y | T | {EXTERNAL LOCATION} | i32 |
5664+
| main.rs:2727:21:2727:38 | ...::default(...) | | main.rs:2704:5:2705:19 | S |
5665+
| main.rs:2727:21:2727:38 | ...::default(...) | T | {EXTERNAL LOCATION} | i32 |
5666+
| main.rs:2728:13:2728:13 | y | | main.rs:2704:5:2705:19 | S |
5667+
| main.rs:2728:13:2728:13 | y | T | {EXTERNAL LOCATION} | i32 |
5668+
| main.rs:2729:16:2731:9 | { ... } | | main.rs:2704:5:2705:19 | S |
5669+
| main.rs:2729:16:2731:9 | { ... } | T | {EXTERNAL LOCATION} | i32 |
5670+
| main.rs:2730:13:2730:16 | S(...) | | main.rs:2704:5:2705:19 | S |
5671+
| main.rs:2730:13:2730:16 | S(...) | T | {EXTERNAL LOCATION} | i32 |
5672+
| main.rs:2730:15:2730:15 | 2 | | {EXTERNAL LOCATION} | i32 |
5673+
| main.rs:2735:13:2735:13 | x | | main.rs:2700:5:2702:5 | dyn MyTrait |
5674+
| main.rs:2735:13:2735:13 | x | | main.rs:2704:5:2705:19 | S |
5675+
| main.rs:2735:13:2735:13 | x | T | {EXTERNAL LOCATION} | i32 |
5676+
| main.rs:2735:13:2735:13 | x | dyn(T) | {EXTERNAL LOCATION} | i32 |
5677+
| main.rs:2735:17:2735:20 | S(...) | | main.rs:2700:5:2702:5 | dyn MyTrait |
5678+
| main.rs:2735:17:2735:20 | S(...) | | main.rs:2704:5:2705:19 | S |
5679+
| main.rs:2735:17:2735:20 | S(...) | T | {EXTERNAL LOCATION} | i32 |
5680+
| main.rs:2735:17:2735:20 | S(...) | dyn(T) | {EXTERNAL LOCATION} | i32 |
5681+
| main.rs:2735:19:2735:19 | 1 | | {EXTERNAL LOCATION} | i32 |
5682+
| main.rs:2736:9:2741:9 | if b {...} else {...} | | {EXTERNAL LOCATION} | Box |
5683+
| main.rs:2736:9:2741:9 | if b {...} else {...} | A | {EXTERNAL LOCATION} | Global |
5684+
| main.rs:2736:9:2741:9 | if b {...} else {...} | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5685+
| main.rs:2736:9:2741:9 | if b {...} else {...} | T | main.rs:2704:5:2705:19 | S |
5686+
| main.rs:2736:9:2741:9 | if b {...} else {...} | T.T | {EXTERNAL LOCATION} | i32 |
5687+
| main.rs:2736:9:2741:9 | if b {...} else {...} | T.T | main.rs:2704:5:2705:19 | S |
5688+
| main.rs:2736:9:2741:9 | if b {...} else {...} | T.T.T | {EXTERNAL LOCATION} | i32 |
5689+
| main.rs:2736:9:2741:9 | if b {...} else {...} | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5690+
| main.rs:2736:12:2736:12 | b | | {EXTERNAL LOCATION} | bool |
5691+
| main.rs:2736:14:2739:9 | { ... } | | {EXTERNAL LOCATION} | Box |
5692+
| main.rs:2736:14:2739:9 | { ... } | A | {EXTERNAL LOCATION} | Global |
5693+
| main.rs:2736:14:2739:9 | { ... } | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5694+
| main.rs:2736:14:2739:9 | { ... } | T | main.rs:2704:5:2705:19 | S |
5695+
| main.rs:2736:14:2739:9 | { ... } | T.T | main.rs:2704:5:2705:19 | S |
5696+
| main.rs:2736:14:2739:9 | { ... } | T.T.T | {EXTERNAL LOCATION} | i32 |
5697+
| main.rs:2736:14:2739:9 | { ... } | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5698+
| main.rs:2737:17:2737:17 | x | | main.rs:2700:5:2702:5 | dyn MyTrait |
5699+
| main.rs:2737:17:2737:17 | x | | main.rs:2704:5:2705:19 | S |
5700+
| main.rs:2737:17:2737:17 | x | T | main.rs:2704:5:2705:19 | S |
5701+
| main.rs:2737:17:2737:17 | x | T.T | {EXTERNAL LOCATION} | i32 |
5702+
| main.rs:2737:17:2737:17 | x | dyn(T) | {EXTERNAL LOCATION} | i32 |
5703+
| main.rs:2737:21:2737:21 | x | | main.rs:2700:5:2702:5 | dyn MyTrait |
5704+
| main.rs:2737:21:2737:21 | x | | main.rs:2704:5:2705:19 | S |
5705+
| main.rs:2737:21:2737:21 | x | T | {EXTERNAL LOCATION} | i32 |
5706+
| main.rs:2737:21:2737:21 | x | dyn(T) | {EXTERNAL LOCATION} | i32 |
5707+
| main.rs:2737:21:2737:26 | x.m2() | | main.rs:2700:5:2702:5 | dyn MyTrait |
5708+
| main.rs:2737:21:2737:26 | x.m2() | | main.rs:2704:5:2705:19 | S |
5709+
| main.rs:2737:21:2737:26 | x.m2() | T | main.rs:2704:5:2705:19 | S |
5710+
| main.rs:2737:21:2737:26 | x.m2() | T.T | {EXTERNAL LOCATION} | i32 |
5711+
| main.rs:2737:21:2737:26 | x.m2() | dyn(T) | {EXTERNAL LOCATION} | i32 |
5712+
| main.rs:2738:13:2738:23 | ...::new(...) | | {EXTERNAL LOCATION} | Box |
5713+
| main.rs:2738:13:2738:23 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
5714+
| main.rs:2738:13:2738:23 | ...::new(...) | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5715+
| main.rs:2738:13:2738:23 | ...::new(...) | T | main.rs:2704:5:2705:19 | S |
5716+
| main.rs:2738:13:2738:23 | ...::new(...) | T.T | main.rs:2704:5:2705:19 | S |
5717+
| main.rs:2738:13:2738:23 | ...::new(...) | T.T.T | {EXTERNAL LOCATION} | i32 |
5718+
| main.rs:2738:13:2738:23 | ...::new(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5719+
| main.rs:2738:22:2738:22 | x | | main.rs:2700:5:2702:5 | dyn MyTrait |
5720+
| main.rs:2738:22:2738:22 | x | | main.rs:2704:5:2705:19 | S |
5721+
| main.rs:2738:22:2738:22 | x | T | main.rs:2704:5:2705:19 | S |
5722+
| main.rs:2738:22:2738:22 | x | T.T | {EXTERNAL LOCATION} | i32 |
5723+
| main.rs:2738:22:2738:22 | x | dyn(T) | {EXTERNAL LOCATION} | i32 |
5724+
| main.rs:2739:16:2741:9 | { ... } | | {EXTERNAL LOCATION} | Box |
5725+
| main.rs:2739:16:2741:9 | { ... } | A | {EXTERNAL LOCATION} | Global |
5726+
| main.rs:2739:16:2741:9 | { ... } | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5727+
| main.rs:2739:16:2741:9 | { ... } | T | main.rs:2704:5:2705:19 | S |
5728+
| main.rs:2739:16:2741:9 | { ... } | T.T | {EXTERNAL LOCATION} | i32 |
5729+
| main.rs:2739:16:2741:9 | { ... } | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5730+
| main.rs:2740:13:2740:23 | ...::new(...) | | {EXTERNAL LOCATION} | Box |
5731+
| main.rs:2740:13:2740:23 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
5732+
| main.rs:2740:13:2740:23 | ...::new(...) | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5733+
| main.rs:2740:13:2740:23 | ...::new(...) | T | main.rs:2704:5:2705:19 | S |
5734+
| main.rs:2740:13:2740:23 | ...::new(...) | T.T | {EXTERNAL LOCATION} | i32 |
5735+
| main.rs:2740:13:2740:23 | ...::new(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5736+
| main.rs:2740:22:2740:22 | x | | main.rs:2700:5:2702:5 | dyn MyTrait |
5737+
| main.rs:2740:22:2740:22 | x | | main.rs:2704:5:2705:19 | S |
5738+
| main.rs:2740:22:2740:22 | x | T | {EXTERNAL LOCATION} | i32 |
5739+
| main.rs:2740:22:2740:22 | x | dyn(T) | {EXTERNAL LOCATION} | i32 |
5740+
| main.rs:2752:5:2752:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo |
5741+
| main.rs:2753:5:2753:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo |
5742+
| main.rs:2753:20:2753:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
5743+
| main.rs:2753:41:2753:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
5744+
| main.rs:2769:5:2769:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future |
5745+
| main.rs:2782:5:2782:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box |
5746+
| main.rs:2782:5:2782:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global |
5747+
| main.rs:2782:5:2782:20 | ...::f(...) | T | main.rs:2700:5:2702:5 | dyn MyTrait |
5748+
| main.rs:2782:5:2782:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
5749+
| main.rs:2782:16:2782:19 | true | | {EXTERNAL LOCATION} | bool |
56265750
| pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option |
56275751
| pattern_matching.rs:13:26:133:1 | { ... } | T | file://:0:0:0:0 | () |
56285752
| pattern_matching.rs:14:9:14:13 | value | | {EXTERNAL LOCATION} | Option |
@@ -5648,7 +5772,6 @@ inferType
56485772
| pattern_matching.rs:20:9:20:18 | Some(...) | | {EXTERNAL LOCATION} | Option |
56495773
| pattern_matching.rs:20:9:20:18 | Some(...) | T | {EXTERNAL LOCATION} | i32 |
56505774
| pattern_matching.rs:20:14:20:17 | mesg | | {EXTERNAL LOCATION} | i32 |
5651-
| pattern_matching.rs:20:23:23:9 | { ... } | | file://:0:0:0:0 | () |
56525775
| pattern_matching.rs:21:17:21:20 | mesg | | {EXTERNAL LOCATION} | i32 |
56535776
| pattern_matching.rs:21:24:21:27 | mesg | | {EXTERNAL LOCATION} | i32 |
56545777
| pattern_matching.rs:22:22:22:29 | "{mesg}\\n" | | file://:0:0:0:0 | & |
@@ -5861,7 +5984,6 @@ inferType
58615984
| pattern_matching.rs:99:25:99:25 | x | | {EXTERNAL LOCATION} | i32 |
58625985
| pattern_matching.rs:100:25:100:25 | y | | file://:0:0:0:0 | & |
58635986
| pattern_matching.rs:100:25:100:25 | y | &T | {EXTERNAL LOCATION} | str |
5864-
| pattern_matching.rs:102:14:107:9 | { ... } | | file://:0:0:0:0 | () |
58655987
| pattern_matching.rs:103:17:103:17 | a | | {EXTERNAL LOCATION} | bool |
58665988
| pattern_matching.rs:103:21:103:26 | value1 | | {EXTERNAL LOCATION} | bool |
58675989
| pattern_matching.rs:104:17:104:17 | b | | {EXTERNAL LOCATION} | i32 |

0 commit comments

Comments
 (0)