@@ -19,12 +19,16 @@ use hir::def_id::DefId;
19
19
use hir:: def:: Def ;
20
20
use namespace:: Namespace ;
21
21
22
+ use rustc_data_structures:: sync:: Lrc ;
22
23
use rustc:: hir;
23
24
use rustc:: lint;
24
25
use rustc:: session:: config:: nightly_options;
25
26
use rustc:: ty:: subst:: { Subst , Substs } ;
26
27
use rustc:: traits:: { self , ObligationCause } ;
27
- use rustc:: ty:: { self , ParamEnv , Ty , TyCtxt , ToPolyTraitRef , ToPredicate , TraitRef , TypeFoldable } ;
28
+ use rustc:: traits:: query:: { CanonicalTyGoal } ;
29
+ use rustc:: traits:: query:: method_autoderef:: { CandidateStep , MethodAutoderefStepsResult } ;
30
+ use rustc:: traits:: query:: method_autoderef:: { MethodAutoderefBadTy } ;
31
+ use rustc:: ty:: { self , ParamEnvAnd , Ty , TyCtxt , ToPolyTraitRef , ToPredicate , TraitRef , TypeFoldable } ;
28
32
use rustc:: ty:: GenericParamDefKind ;
29
33
use rustc:: infer:: type_variable:: TypeVariableOrigin ;
30
34
use rustc:: util:: nodemap:: FxHashSet ;
@@ -34,7 +38,7 @@ use rustc::infer::canonical::{OriginalQueryValues};
34
38
use rustc:: middle:: stability;
35
39
use syntax:: ast;
36
40
use syntax:: util:: lev_distance:: { lev_distance, find_best_match_for_name} ;
37
- use syntax_pos:: { Span , symbol:: Symbol } ;
41
+ use syntax_pos:: { DUMMY_SP , Span , symbol:: Symbol } ;
38
42
use std:: iter;
39
43
use std:: mem;
40
44
use std:: ops:: Deref ;
@@ -59,7 +63,7 @@ struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
59
63
/// This is the OriginalQueryValues for the steps queries
60
64
/// that are answered in steps.
61
65
orig_steps_var_values : OriginalQueryValues < ' tcx > ,
62
- steps : Rc < Vec < CandidateStep < ' gcx > > > ,
66
+ steps : Lrc < Vec < CandidateStep < ' gcx > > > ,
63
67
64
68
inherent_candidates : Vec < Candidate < ' tcx > > ,
65
69
extension_candidates : Vec < Candidate < ' tcx > > ,
@@ -90,19 +94,6 @@ impl<'a, 'gcx, 'tcx> Deref for ProbeContext<'a, 'gcx, 'tcx> {
90
94
}
91
95
}
92
96
93
- #[ derive( Debug ) ]
94
- struct CandidateStep < ' gcx > {
95
- self_ty : Canonical < ' gcx , QueryResponse < ' gcx , Ty < ' gcx > > > ,
96
- autoderefs : usize ,
97
- // true if the type results from a dereference of a raw pointer.
98
- // when assembling candidates, we include these steps, but not when
99
- // picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
100
- // `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
101
- // `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
102
- from_unsafe_deref : bool ,
103
- unsize : bool ,
104
- }
105
-
106
97
#[ derive( Debug ) ]
107
98
struct Candidate < ' tcx > {
108
99
xform_self_ty : Ty < ' tcx > ,
@@ -260,11 +251,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
260
251
{
261
252
let mut orig_values = OriginalQueryValues :: default ( ) ;
262
253
let param_env_and_self_ty =
263
- self . infcx . canonicalize_query ( & ( self . param_env , self_ty) , & mut orig_values) ;
254
+ self . infcx . canonicalize_query (
255
+ & ParamEnvAnd {
256
+ param_env : self . param_env ,
257
+ value : self_ty
258
+ } , & mut orig_values) ;
264
259
265
- // FIXME: consider caching this "whole op" here.
266
260
let steps = if mode == Mode :: MethodCall {
267
- create_steps_inner ( self . tcx . global_tcx ( ) , span , param_env_and_self_ty)
261
+ self . tcx . method_autoderef_steps ( param_env_and_self_ty)
268
262
} else {
269
263
self . infcx . probe ( |_| {
270
264
// Mode::Path - the deref steps is "trivial". This turns
@@ -273,30 +267,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
273
267
// special handling for this "trivial case" is a good idea.
274
268
275
269
let infcx = & self . infcx ;
276
- let ( ( _, self_ty) , canonical_inference_vars) =
270
+ let ( ParamEnvAnd {
271
+ param_env : _,
272
+ value : self_ty
273
+ } , canonical_inference_vars) =
277
274
infcx. instantiate_canonical_with_fresh_inference_vars (
278
275
span, & param_env_and_self_ty) ;
279
- debug ! ( "param_env_and_self_ty={:?} self_ty={:?}" , param_env_and_self_ty, self_ty) ;
280
- CreateStepsResult {
281
- steps : vec ! [ CandidateStep {
276
+ debug ! ( "probe_op: Mode::Path, param_env_and_self_ty={:?} self_ty={:?}" ,
277
+ param_env_and_self_ty, self_ty) ;
278
+ MethodAutoderefStepsResult {
279
+ steps : Lrc :: new ( vec ! [ CandidateStep {
282
280
self_ty: self . make_query_response_with_obligations_pending(
283
281
canonical_inference_vars, self_ty) ,
284
282
autoderefs: 0 ,
285
283
from_unsafe_deref: false ,
286
284
unsize: false ,
287
- } ] ,
285
+ } ] ) ,
288
286
opt_bad_ty : None
289
287
}
290
288
} )
291
289
} ;
292
290
293
291
// If we encountered an `_` type or an error type during autoderef, this is
294
292
// ambiguous.
295
- if let Some ( CreateStepsBadTy { reached_raw_pointer, ty } ) = & steps. opt_bad_ty {
293
+ if let Some ( autoderef_bad_ty) = & steps. opt_bad_ty {
294
+ let MethodAutoderefBadTy { reached_raw_pointer, ref ty } = * * autoderef_bad_ty;
296
295
if is_suggestion. 0 {
297
296
// Ambiguity was encountered during a suggestion. Just keep going.
298
297
debug ! ( "ProbeContext: encountered ambiguity in suggestion" ) ;
299
- } else if * reached_raw_pointer && !self . tcx . features ( ) . arbitrary_self_types {
298
+ } else if reached_raw_pointer && !self . tcx . features ( ) . arbitrary_self_types {
300
299
// this case used to be allowed by the compiler,
301
300
// so we do a future-compat lint here for the 2015 edition
302
301
// (see https://github.com/rust-lang/rust/issues/46906)
@@ -337,7 +336,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
337
336
self . probe ( |_| {
338
337
let mut probe_cx = ProbeContext :: new (
339
338
self , span, mode, method_name, return_type, orig_values,
340
- Rc :: new ( steps. steps ) , is_suggestion,
339
+ steps. steps , is_suggestion,
341
340
) ;
342
341
343
342
probe_cx. assemble_inherent_candidates ( ) ;
@@ -352,27 +351,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
352
351
}
353
352
}
354
353
355
- #[ derive( Debug ) ]
356
- struct CreateStepsResult < ' gcx > {
357
- steps : Vec < CandidateStep < ' gcx > > ,
358
- opt_bad_ty : Option < CreateStepsBadTy < ' gcx > >
359
- }
360
-
361
- #[ derive( Debug ) ]
362
- struct CreateStepsBadTy < ' gcx > {
363
- reached_raw_pointer : bool ,
364
- ty : Canonical < ' gcx , QueryResponse < ' gcx , Ty < ' gcx > > > ,
354
+ pub fn provide ( providers : & mut ty:: query:: Providers ) {
355
+ providers. method_autoderef_steps = method_autoderef_steps;
365
356
}
366
357
367
- fn create_steps_inner < ' a , ' gcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' gcx > ,
368
- span : Span ,
369
- pe_and_self_ty : Canonical < ' gcx , ( ParamEnv < ' gcx > , Ty < ' gcx > ) > )
370
- -> CreateStepsResult < ' gcx >
358
+ fn method_autoderef_steps < ' a , ' gcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' gcx > ,
359
+ goal : CanonicalTyGoal < ' tcx > )
360
+ -> MethodAutoderefStepsResult < ' gcx >
371
361
{
372
- tcx. infer_ctxt ( ) . enter ( |ref infcx| {
373
- let ( ( param_env, self_ty) , inference_vars) =
374
- infcx. instantiate_canonical_with_fresh_inference_vars ( span, & pe_and_self_ty) ;
375
- let mut autoderef = Autoderef :: new ( infcx, param_env, ast:: DUMMY_NODE_ID , span, self_ty)
362
+ debug ! ( "method_autoderef_steps({:?})" , goal) ;
363
+
364
+ tcx. infer_ctxt ( ) . enter_with_canonical ( DUMMY_SP , & goal, |ref infcx, goal, inference_vars| {
365
+ let ParamEnvAnd { param_env, value : self_ty } = goal;
366
+
367
+ let mut autoderef = Autoderef :: new ( infcx, param_env, ast:: DUMMY_NODE_ID , DUMMY_SP , self_ty)
376
368
. include_raw_pointers ( ) ;
377
369
let mut reached_raw_pointer = false ;
378
370
let mut steps: Vec < _ > = autoderef. by_ref ( )
@@ -396,7 +388,7 @@ fn create_steps_inner<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
396
388
let opt_bad_ty = match final_ty. sty {
397
389
ty:: Infer ( ty:: TyVar ( _) ) |
398
390
ty:: Error => {
399
- Some ( CreateStepsBadTy {
391
+ Some ( MethodAutoderefBadTy {
400
392
reached_raw_pointer,
401
393
ty : infcx. make_query_response_with_obligations_pending (
402
394
inference_vars, final_ty)
@@ -420,9 +412,12 @@ fn create_steps_inner<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
420
412
_ => None
421
413
} ;
422
414
423
- debug ! ( "create_steps : steps={:?} opt_bad_ty={:?}" , steps, opt_bad_ty) ;
415
+ debug ! ( "method_autoderef_steps : steps={:?} opt_bad_ty={:?}" , steps, opt_bad_ty) ;
424
416
425
- CreateStepsResult { steps, opt_bad_ty }
417
+ MethodAutoderefStepsResult {
418
+ steps : Lrc :: new ( steps) ,
419
+ opt_bad_ty : opt_bad_ty. map ( Lrc :: new)
420
+ }
426
421
} )
427
422
}
428
423
0 commit comments