@@ -19,12 +19,16 @@ use hir::def_id::DefId;
1919use hir:: def:: Def ;
2020use namespace:: Namespace ;
2121
22+ use rustc_data_structures:: sync:: Lrc ;
2223use rustc:: hir;
2324use rustc:: lint;
2425use rustc:: session:: config:: nightly_options;
2526use rustc:: ty:: subst:: { Subst , Substs } ;
2627use 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 } ;
2832use rustc:: ty:: GenericParamDefKind ;
2933use rustc:: infer:: type_variable:: TypeVariableOrigin ;
3034use rustc:: util:: nodemap:: FxHashSet ;
@@ -34,7 +38,7 @@ use rustc::infer::canonical::{OriginalQueryValues};
3438use rustc:: middle:: stability;
3539use syntax:: ast;
3640use 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 } ;
3842use std:: iter;
3943use std:: mem;
4044use std:: ops:: Deref ;
@@ -59,7 +63,7 @@ struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
5963 /// This is the OriginalQueryValues for the steps queries
6064 /// that are answered in steps.
6165 orig_steps_var_values : OriginalQueryValues < ' tcx > ,
62- steps : Rc < Vec < CandidateStep < ' gcx > > > ,
66+ steps : Lrc < Vec < CandidateStep < ' gcx > > > ,
6367
6468 inherent_candidates : Vec < Candidate < ' tcx > > ,
6569 extension_candidates : Vec < Candidate < ' tcx > > ,
@@ -90,19 +94,6 @@ impl<'a, 'gcx, 'tcx> Deref for ProbeContext<'a, 'gcx, 'tcx> {
9094 }
9195}
9296
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-
10697#[ derive( Debug ) ]
10798struct Candidate < ' tcx > {
10899 xform_self_ty : Ty < ' tcx > ,
@@ -260,11 +251,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
260251 {
261252 let mut orig_values = OriginalQueryValues :: default ( ) ;
262253 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) ;
264259
265- // FIXME: consider caching this "whole op" here.
266260 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)
268262 } else {
269263 self . infcx . probe ( |_| {
270264 // Mode::Path - the deref steps is "trivial". This turns
@@ -273,30 +267,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
273267 // special handling for this "trivial case" is a good idea.
274268
275269 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) =
277274 infcx. instantiate_canonical_with_fresh_inference_vars (
278275 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 {
282280 self_ty: self . make_query_response_with_obligations_pending(
283281 canonical_inference_vars, self_ty) ,
284282 autoderefs: 0 ,
285283 from_unsafe_deref: false ,
286284 unsize: false ,
287- } ] ,
285+ } ] ) ,
288286 opt_bad_ty : None
289287 }
290288 } )
291289 } ;
292290
293291 // If we encountered an `_` type or an error type during autoderef, this is
294292 // 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;
296295 if is_suggestion. 0 {
297296 // Ambiguity was encountered during a suggestion. Just keep going.
298297 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 {
300299 // this case used to be allowed by the compiler,
301300 // so we do a future-compat lint here for the 2015 edition
302301 // (see https://github.com/rust-lang/rust/issues/46906)
@@ -337,7 +336,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
337336 self . probe ( |_| {
338337 let mut probe_cx = ProbeContext :: new (
339338 self , span, mode, method_name, return_type, orig_values,
340- Rc :: new ( steps. steps ) , is_suggestion,
339+ steps. steps , is_suggestion,
341340 ) ;
342341
343342 probe_cx. assemble_inherent_candidates ( ) ;
@@ -352,27 +351,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
352351 }
353352}
354353
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;
365356}
366357
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 >
371361{
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)
376368 . include_raw_pointers ( ) ;
377369 let mut reached_raw_pointer = false ;
378370 let mut steps: Vec < _ > = autoderef. by_ref ( )
@@ -396,7 +388,7 @@ fn create_steps_inner<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
396388 let opt_bad_ty = match final_ty. sty {
397389 ty:: Infer ( ty:: TyVar ( _) ) |
398390 ty:: Error => {
399- Some ( CreateStepsBadTy {
391+ Some ( MethodAutoderefBadTy {
400392 reached_raw_pointer,
401393 ty : infcx. make_query_response_with_obligations_pending (
402394 inference_vars, final_ty)
@@ -420,9 +412,12 @@ fn create_steps_inner<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
420412 _ => None
421413 } ;
422414
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) ;
424416
425- CreateStepsResult { steps, opt_bad_ty }
417+ MethodAutoderefStepsResult {
418+ steps : Lrc :: new ( steps) ,
419+ opt_bad_ty : opt_bad_ty. map ( Lrc :: new)
420+ }
426421 } )
427422}
428423
0 commit comments