@@ -359,7 +359,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
359359
360360 let obligation = traits:: Obligation :: new (
361361 self . tcx ,
362- cause,
362+ cause. clone ( ) ,
363363 self . param_env ,
364364 ty:: TraitRef :: new_from_args ( self . tcx , trait_def_id, args) ,
365365 ) ;
@@ -385,6 +385,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
385385
386386 debug ! ( "lookup_in_trait_adjusted: method_item={:?}" , method_item) ;
387387 let mut obligations = PredicateObligations :: new ( ) ;
388+ // Register the operator's obligation first to constrain the "rhs" argument (or inputs
389+ // for a fn-like operator). This would happen coincidentally as part of normalizing the
390+ // signature below if the output type is constrained but a param-env predicate, but for
391+ // `AsyncFn*`, the output type doesn't actually show up in the signature, so we end up
392+ // trying to prove other WF predicates first which incompletely constrains the type.
393+ obligations. push ( obligation) ;
388394
389395 // Instantiate late-bound regions and instantiate the trait
390396 // parameters into the method type to get the actual method type.
@@ -393,11 +399,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
393399 // function signature so that normalization does not need to deal
394400 // with bound regions.
395401 let fn_sig = tcx. fn_sig ( def_id) . instantiate ( self . tcx , args) ;
396- let fn_sig =
397- self . instantiate_binder_with_fresh_vars ( obligation. cause . span , infer:: FnCall , fn_sig) ;
402+ let fn_sig = self . instantiate_binder_with_fresh_vars ( cause. span , infer:: FnCall , fn_sig) ;
398403
399404 let InferOk { value : fn_sig, obligations : o } =
400- self . at ( & obligation . cause , self . param_env ) . normalize ( fn_sig) ;
405+ self . at ( & cause, self . param_env ) . normalize ( fn_sig) ;
401406 obligations. extend ( o) ;
402407
403408 // Register obligations for the parameters. This will include the
@@ -411,26 +416,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
411416 let bounds = self . tcx . predicates_of ( def_id) . instantiate ( self . tcx , args) ;
412417
413418 let InferOk { value : bounds, obligations : o } =
414- self . at ( & obligation . cause , self . param_env ) . normalize ( bounds) ;
419+ self . at ( & cause, self . param_env ) . normalize ( bounds) ;
415420 obligations. extend ( o) ;
416421 assert ! ( !bounds. has_escaping_bound_vars( ) ) ;
417422
418- let predicates_cause = obligation. cause . clone ( ) ;
419423 obligations. extend ( traits:: predicates_for_generics (
420- move |_, _| predicates_cause . clone ( ) ,
424+ |_, _| cause . clone ( ) ,
421425 self . param_env ,
422426 bounds,
423427 ) ) ;
424428
425429 // Also add an obligation for the method type being well-formed.
426430 let method_ty = Ty :: new_fn_ptr ( tcx, ty:: Binder :: dummy ( fn_sig) ) ;
427- debug ! (
428- "lookup_method_in_trait: matched method method_ty={:?} obligation={:?}" ,
429- method_ty, obligation
430- ) ;
431+ debug ! ( "lookup_method_in_trait: matched method method_ty={:?}" , method_ty) ;
432+
431433 obligations. push ( traits:: Obligation :: new (
432434 tcx,
433- obligation . cause ,
435+ cause. clone ( ) ,
434436 self . param_env ,
435437 ty:: Binder :: dummy ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed (
436438 method_ty. into ( ) ,
0 commit comments