From 4f9fe856a25ab29345b90e7725509e9ee38a37be Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:41 +0200 Subject: Adding upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_hir_typeck/src/closure.rs | 92 ++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 40 deletions(-) (limited to 'compiler/rustc_hir_typeck/src/closure.rs') diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 12a2abfa7..d84fabb78 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -3,8 +3,8 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; use hir::def::DefKind; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::astconv::AstConv; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -12,9 +12,11 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, Ty, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Span; +use rustc_span::sym; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; use rustc_trait_selection::traits::error_reporting::ArgKind; @@ -80,7 +82,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?bound_sig, ?liberated_sig); - let mut fcx = FnCtxt::new(self, self.param_env.without_const(), body.value.hir_id); + let mut fcx = FnCtxt::new(self, self.param_env.without_const(), closure.def_id); let generator_types = check_fn( &mut fcx, liberated_sig, @@ -125,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the `closures` table. let sig = bound_sig.map_bound(|sig| { self.tcx.mk_fn_sig( - iter::once(self.tcx.intern_tup(sig.inputs())), + [self.tcx.mk_tup(sig.inputs())], sig.output(), sig.c_variadic, sig.unsafety, @@ -231,7 +233,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { struct MentionsTy<'tcx> { expected_ty: Ty<'tcx>, } - impl<'tcx> TypeVisitor<'tcx> for MentionsTy<'tcx> { + impl<'tcx> TypeVisitor> for MentionsTy<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { @@ -288,21 +290,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_def_id = projection.trait_def_id(tcx); let is_fn = tcx.is_fn_trait(trait_def_id); - let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span); - let is_gen = gen_trait == trait_def_id; + + let gen_trait = tcx.lang_items().gen_trait(); + let is_gen = gen_trait == Some(trait_def_id); + if !is_fn && !is_gen { debug!("not fn or generator"); return None; } - if is_gen { - // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return` - // 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"); - return None; - } + // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return` + // associated item and not yield. + if is_gen && self.tcx.associated_item(projection.projection_def_id()).name != sym::Return { + debug!("not `Return` assoc item of `Generator`"); + return None; } let input_tys = if is_fn { @@ -326,7 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?ret_param_ty); let sig = projection.rebind(self.tcx.mk_fn_sig( - input_tys.iter(), + input_tys, ret_param_ty, false, hir::Unsafety::Normal, @@ -488,17 +489,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let expected_span = expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id)); - self.report_arg_count_mismatch( - expected_span, - closure_span, - expected_args, - found_args, - true, - closure_arg_span, - ) - .emit(); - - let error_sig = self.error_sig_of_closure(decl); + let guar = self + .report_arg_count_mismatch( + expected_span, + closure_span, + expected_args, + found_args, + true, + closure_arg_span, + ) + .emit(); + + let error_sig = self.error_sig_of_closure(decl, guar); self.closure_sigs(expr_def_id, body, error_sig) } @@ -544,7 +546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .map(|(hir_ty, &supplied_ty)| { // Instantiate (this part of..) S to S', i.e., with fresh variables. - self.replace_bound_vars_with_fresh_vars( + self.instantiate_binder_with_fresh_vars( hir_ty.span, LateBoundRegionConversionTime::FnCall, // (*) binder moved to here @@ -561,12 +563,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { // Check that E' = S'. let cause = self.misc(hir_ty.span); - let InferOk { value: (), obligations } = - self.at(&cause, self.param_env).eq(*expected_ty, supplied_ty)?; + let InferOk { value: (), obligations } = self + .at(&cause, self.param_env) + .define_opaque_types(true) + .eq(*expected_ty, supplied_ty)?; all_obligations.extend(obligations); } - let supplied_output_ty = self.replace_bound_vars_with_fresh_vars( + let supplied_output_ty = self.instantiate_binder_with_fresh_vars( decl.output.span(), LateBoundRegionConversionTime::FnCall, supplied_sig.output(), @@ -574,6 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cause = &self.misc(decl.output.span()); let InferOk { value: (), obligations } = self .at(cause, self.param_env) + .define_opaque_types(true) .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?; all_obligations.extend(obligations); @@ -620,8 +625,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // function. Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => { debug!("closure is async fn body"); - self.deduce_future_output_from_obligations(expr_def_id, body.id().hir_id) - .unwrap_or_else(|| { + let def_id = self.tcx.hir().body_owner_def_id(body.id()); + self.deduce_future_output_from_obligations(expr_def_id, def_id).unwrap_or_else( + || { // AFAIK, deducing the future output // always succeeds *except* in error cases // like #65159. I'd like to return Error @@ -630,7 +636,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // *have* reported an // error. --nikomatsakis astconv.ty_infer(None, decl.output.span()) - }) + }, + ) } _ => astconv.ty_infer(None, decl.output.span()), @@ -665,7 +672,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn deduce_future_output_from_obligations( &self, expr_def_id: LocalDefId, - body_id: hir::HirId, + body_def_id: LocalDefId, ) -> Option> { 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") @@ -725,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let InferOk { value: output_ty, obligations } = self .replace_opaque_types_with_inference_vars( output_ty, - body_id, + body_def_id, self.tcx.def_span(expr_def_id), self.param_env, ); @@ -787,13 +794,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Converts the types that the user supplied, in case that doing /// so should yield an error, but returns back a signature where /// all parameters are of type `TyErr`. - fn error_sig_of_closure(&self, decl: &hir::FnDecl<'_>) -> ty::PolyFnSig<'tcx> { + fn error_sig_of_closure( + &self, + decl: &hir::FnDecl<'_>, + guar: ErrorGuaranteed, + ) -> ty::PolyFnSig<'tcx> { let astconv: &dyn AstConv<'_> = self; + let err_ty = self.tcx.ty_error(guar); let supplied_arguments = decl.inputs.iter().map(|a| { // Convert the types that the user supplied (if any), but ignore them. astconv.ast_ty_to_ty(a); - self.tcx.ty_error() + err_ty }); if let hir::FnRetTy::Return(ref output) = decl.output { @@ -802,7 +814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = ty::Binder::dummy(self.tcx.mk_fn_sig( supplied_arguments, - self.tcx.ty_error(), + err_ty, decl.c_variadic, hir::Unsafety::Normal, Abi::RustCall, -- cgit v1.2.3