@@ -256,6 +256,12 @@ pub struct Inherited<'a, 'tcx> {
256
256
/// not clear.
257
257
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
258
258
259
+ /// Maps each expression with a generic path
260
+ /// (e.g. `foo::<u8>()` to `InferredPath` containing
261
+ /// additional information used by `NeverCompatHandler`.
262
+ ///
263
+ /// Each entry in this map is gradually filled in during typecheck,
264
+ /// as the information we need is not available all at once.
259
265
inferred_paths : RefCell < FxHashMap < hir:: HirId , InferredPath < ' tcx > > > ,
260
266
261
267
body_id : Option < hir:: BodyId > ,
@@ -623,11 +629,45 @@ pub struct FnCtxt<'a, 'tcx> {
623
629
inh : & ' a Inherited < ' a , ' tcx > ,
624
630
}
625
631
632
+ /// Stores additional data about a generic path
633
+ /// containing inference variables (e.g. `my_method::<_, u8>(bar)`).
634
+ /// This is used by `NeverCompatHandler` to inspect
635
+ /// all method calls that contain inference variables.
636
+ ///
637
+ /// This struct is a little strange, in that its data
638
+ /// is filled in from two different places in typecheck.
639
+ /// Thw two `Option` fields are written by `check_argument_types`
640
+ /// and `instantiate_value_path`, since neither method
641
+ /// has all of the information it needs.
626
642
#[ derive( Clone , Debug ) ]
627
643
struct InferredPath < ' tcx > {
644
+ /// The span of the corresponding expression.
628
645
span : Span ,
646
+ /// The type of this path. For method calls,
647
+ /// this is a `ty::FnDef`
629
648
ty : Option < Ty < ' tcx > > ,
649
+ /// The types of the arguments (*not* generic substs)
650
+ /// provided to this path, if it represents a method
651
+ /// call. For example, `foo(true, 25)` would have
652
+ /// types `[bool, i32]`. If this path does not
653
+ /// correspond to a method, then this will be `None`
654
+ ///
655
+ /// This is a `Cow` rather than a `Vec` or slice
656
+ /// to accommodate `check_argument_types`, which may
657
+ /// be called with either an interned slice or a Vec.
658
+ /// A `Cow` lets us avoid unecessary interning
659
+ /// and Vec construction, since we just need to iterate
660
+ /// over this
630
661
args : Option < Cow < ' tcx , [ Ty < ' tcx > ] > > ,
662
+ /// The unresolved inference variables for each
663
+ /// generic substs. Each entry in the outer vec
664
+ /// corresponds to a generic substs in the function.
665
+ ///
666
+ /// For example, suppose we have the function
667
+ /// `fn foo<T, V> (){ ... }`.
668
+ ///
669
+ /// The method call `foo::<MyStruct<_#0t, #1t>, true>>()`
670
+ /// will have an `unresolved_vars` of `[[_#0t, _#1t], []]`
631
671
unresolved_vars : Vec < Vec < Ty < ' tcx > > > ,
632
672
}
633
673
@@ -3757,6 +3797,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3757
3797
) {
3758
3798
let fn_inputs = fn_inputs. into ( ) ;
3759
3799
debug ! ( "check_argument_types: storing arguments for expr {:?}" , expr) ;
3800
+ // We now have the arguments types available for this msthod call,
3801
+ // so store them in the `inferred_paths` entry for this method call.
3802
+ // We set `ty` as `None` if we are the first to access the entry
3803
+ // for this method, and leave it untouched otherwise.
3760
3804
match self . inferred_paths . borrow_mut ( ) . entry ( expr. hir_id ) {
3761
3805
Entry :: Vacant ( e) => {
3762
3806
debug ! ( "check_argument_types: making new entry for types {:?}" , fn_inputs) ;
@@ -3769,7 +3813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3769
3813
}
3770
3814
Entry :: Occupied ( mut e) => {
3771
3815
debug ! (
3772
- "check_argument_types: modifiying exsting entry {:?} with types {:?}" ,
3816
+ "check_argument_types: modifying existing {:?} with types {:?}" ,
3773
3817
e. get( ) ,
3774
3818
fn_inputs
3775
3819
) ;
@@ -5473,6 +5517,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5473
5517
match parent {
5474
5518
Node :: Expr ( hir:: Expr { span : p_span, kind : ExprKind :: Call ( ..) , .. } )
5475
5519
| Node :: Expr ( hir:: Expr { span : p_span, kind : ExprKind :: MethodCall ( ..) , .. } ) => {
5520
+ // Fill in the type for our parent expression. This might not be
5521
+ // a method call - if it is, the argumetns will be filled in by
5522
+ // `check_argument_types`
5476
5523
match self . inferred_paths . borrow_mut ( ) . entry ( parent_id) {
5477
5524
Entry :: Vacant ( e) => {
5478
5525
debug ! ( "instantiate_value_path: inserting new path" ) ;
0 commit comments