]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_typeck/src/check/closure.rs
Rollup merge of #94023 - krasimirgg:head-llvm-use-llvm-nm, r=Mark-Simulacrum
[rust.git] / compiler / rustc_typeck / src / check / closure.rs
index c3deab0938d3b5beabd9851d2bb851f8fc7bb490..3c626837ef1a327b73cf74c2e7e31a27236932a5 100644 (file)
@@ -3,20 +3,16 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
-use crate::rustc_middle::ty::subst::Subst;
-use hir::OpaqueTyOrigin;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
-use rustc_infer::traits::ObligationCause;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::source_map::Span;
-use rustc_span::DUMMY_SP;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::error_reporting::ArgKind;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
@@ -176,29 +172,6 @@ fn deduce_expectations_from_expected_type(
         expected_ty: Ty<'tcx>,
     ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
         match *expected_ty.kind() {
-            ty::Opaque(def_id, substs) => {
-                let bounds = self.tcx.explicit_item_bounds(def_id);
-                let sig = bounds.iter().find_map(|(pred, span)| match pred.kind().skip_binder() {
-                    ty::PredicateKind::Projection(proj_predicate) => self
-                        .deduce_sig_from_projection(
-                            Some(*span),
-                            pred.kind().rebind(proj_predicate.subst(self.tcx, substs)),
-                        ),
-                    _ => None,
-                });
-
-                let kind = bounds
-                    .iter()
-                    .filter_map(|(pred, _)| match pred.kind().skip_binder() {
-                        ty::PredicateKind::Trait(tp) => {
-                            self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
-                        }
-                        _ => None,
-                    })
-                    .fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur))));
-                trace!(?sig, ?kind);
-                (sig, kind)
-            }
             ty::Dynamic(ref object_type, ..) => {
                 let sig = object_type.projection_bounds().find_map(|pb| {
                     let pb = pb.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self);
@@ -224,7 +197,10 @@ fn deduce_expectations_from_obligations(
     ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
         let expected_sig =
             self.obligations_for_self_ty(expected_vid).find_map(|(_, obligation)| {
-                debug!(?obligation.predicate);
+                debug!(
+                    "deduce_expectations_from_obligations: obligation.predicate={:?}",
+                    obligation.predicate
+                );
 
                 let bound_predicate = obligation.predicate.kind();
                 if let ty::PredicateKind::Projection(proj_predicate) =
@@ -259,7 +235,6 @@ fn deduce_expectations_from_obligations(
     /// The `cause_span` should be the span that caused us to
     /// have this expected signature, or `None` if we can't readily
     /// know that.
-    #[instrument(level = "debug", skip(self, cause_span))]
     fn deduce_sig_from_projection(
         &self,
         cause_span: Option<Span>,
@@ -267,13 +242,15 @@ fn deduce_sig_from_projection(
     ) -> Option<ExpectedSig<'tcx>> {
         let tcx = self.tcx;
 
+        debug!("deduce_sig_from_projection({:?})", projection);
+
         let trait_def_id = projection.trait_def_id(tcx);
 
         let is_fn = tcx.fn_trait_kind_from_lang_item(trait_def_id).is_some();
         let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span);
         let is_gen = gen_trait == trait_def_id;
         if !is_fn && !is_gen {
-            debug!("not fn or generator");
+            debug!("deduce_sig_from_projection: not fn or generator");
             return None;
         }
 
@@ -282,7 +259,7 @@ fn deduce_sig_from_projection(
             // associated item and not yield.
             let return_assoc_item = self.tcx.associated_item_def_ids(gen_trait)[1];
             if return_assoc_item != projection.projection_def_id() {
-                debug!("not return assoc item of generator");
+                debug!("deduce_sig_from_projection: not return assoc item of generator");
                 return None;
             }
         }
@@ -290,7 +267,7 @@ fn deduce_sig_from_projection(
         let input_tys = if is_fn {
             let arg_param_ty = projection.skip_binder().projection_ty.substs.type_at(1);
             let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty);
-            debug!(?arg_param_ty);
+            debug!("deduce_sig_from_projection: arg_param_ty={:?}", arg_param_ty);
 
             match arg_param_ty.kind() {
                 ty::Tuple(tys) => tys.into_iter().map(|k| k.expect_ty()).collect::<Vec<_>>(),
@@ -305,7 +282,7 @@ fn deduce_sig_from_projection(
         // Since this is a return parameter type it is safe to unwrap.
         let ret_param_ty = projection.skip_binder().term.ty().unwrap();
         let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty);
-        debug!(?ret_param_ty);
+        debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
 
         let sig = projection.rebind(self.tcx.mk_fn_sig(
             input_tys.iter(),
@@ -314,7 +291,7 @@ fn deduce_sig_from_projection(
             hir::Unsafety::Normal,
             Abi::Rust,
         ));
-        debug!(?sig);
+        debug!("deduce_sig_from_projection: sig={:?}", sig);
 
         Some(ExpectedSig { cause_span, sig })
     }
@@ -424,14 +401,9 @@ fn sig_of_closure_with_expectation(
         // in this binder we are creating.
         assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST));
         let bound_sig = expected_sig.sig.map_bound(|sig| {
-            let output = self.hide_parent_opaque_types(
-                sig.output(),
-                expected_sig.cause_span.unwrap_or(DUMMY_SP),
-                body.id().hir_id,
-            );
             self.tcx.mk_fn_sig(
                 sig.inputs().iter().cloned(),
-                output,
+                sig.output(),
                 sig.c_variadic,
                 hir::Unsafety::Normal,
                 Abi::RustCall,
@@ -478,7 +450,7 @@ fn sig_of_closure_with_mismatched_number_of_arguments(
             .skip_binder()
             .inputs()
             .iter()
-            .map(|ty| ArgKind::from_expected_ty(ty, None))
+            .map(|ty| ArgKind::from_expected_ty(*ty, None))
             .collect();
         let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
             Some((sp, args)) => (Some(sp), args),
@@ -618,8 +590,6 @@ fn supplied_sig_of_closure(
                 _ => astconv.ty_infer(None, decl.output.span()),
             },
         };
-        let supplied_return =
-            self.hide_parent_opaque_types(supplied_return, decl.output.span(), body.id().hir_id);
 
         let result = ty::Binder::bind_with_vars(
             self.tcx.mk_fn_sig(
@@ -640,57 +610,27 @@ fn supplied_sig_of_closure(
         result
     }
 
-    fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
-        ty.fold_with(&mut ty::fold::BottomUpFolder {
-            tcx: self.infcx.tcx,
-            lt_op: |lt| lt,
-            ct_op: |ct| ct,
-            ty_op: |ty| match *ty.kind() {
-                // Closures can't create hidden types for opaque types of their parent, as they
-                // do not have all the outlives information available. Also `type_of` looks for
-                // hidden types in the owner (so the closure's parent), so it would not find these
-                // definitions.
-                ty::Opaque(def_id, _substs)
-                    if matches!(
-                        self.infcx.opaque_type_origin(def_id, DUMMY_SP),
-                        Some(OpaqueTyOrigin::FnReturn(..))
-                    ) =>
-                {
-                    let ty_var = self.next_ty_var(TypeVariableOrigin {
-                        kind: TypeVariableOriginKind::TypeInference,
-                        span,
-                    });
-                    let cause = ObligationCause::misc(span, body_id);
-                    self.register_predicates(vec![self.infcx.opaque_ty_obligation(
-                        ty,
-                        ty_var,
-                        true,
-                        self.param_env,
-                        cause,
-                    )]);
-                    ty_var
-                }
-                _ => ty,
-            },
-        })
-    }
-
     /// Invoked when we are translating the generator that results
     /// from desugaring an `async fn`. Returns the "sugared" return
     /// type of the `async fn` -- that is, the return type that the
     /// user specified. The "desugared" return type is an `impl
     /// Future<Output = T>`, so we do this by searching through the
     /// obligations to extract the `T`.
-    #[instrument(skip(self), level = "debug")]
     fn deduce_future_output_from_obligations(&self, expr_def_id: DefId) -> Option<Ty<'tcx>> {
+        debug!("deduce_future_output_from_obligations(expr_def_id={:?})", expr_def_id);
+
         let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
             span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn")
         });
 
+        // In practice, the return type of the surrounding function is
+        // always a (not yet resolved) inference variable, because it
+        // is the hidden type for an `impl Trait` that we are going to
+        // be inferring.
         let ret_ty = ret_coercion.borrow().expected_ty();
         let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
-        let (def_id, substs) = match *ret_ty.kind() {
-            ty::Opaque(def_id, substs) => (def_id, substs),
+        let ret_vid = match *ret_ty.kind() {
+            ty::Infer(ty::TyVar(ret_vid)) => ret_vid,
             ty::Error(_) => return None,
             _ => span_bug!(
                 self.tcx.def_span(expr_def_id),
@@ -698,19 +638,17 @@ fn deduce_future_output_from_obligations(&self, expr_def_id: DefId) -> Option<Ty
             ),
         };
 
-        let item_bounds = self.tcx.explicit_item_bounds(def_id);
-
         // Search for a pending obligation like
         //
         // `<R as Future>::Output = T`
         //
         // where R is the return type we are expecting. This type `T`
         // will be our output.
-        let output_ty = item_bounds.iter().find_map(|&(predicate, span)| {
-            let bound_predicate = predicate.subst(self.tcx, substs).kind();
+        let output_ty = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| {
+            let bound_predicate = obligation.predicate.kind();
             if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() {
                 self.deduce_future_output_from_projection(
-                    span,
+                    obligation.cause.span,
                     bound_predicate.rebind(proj_predicate),
                 )
             } else {