..
} = self.type_var_origin(expected)? else { return None; };
- let sig = *self
- .typeck_results
- .borrow()
- .liberated_fn_sigs()
- .get(hir::HirId::make_owner(self.body_id.owner.def_id))?;
+ let sig = self.body_fn_sig()?;
let substs = sig.output().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
fn_id: hir::HirId,
body: &'tcx hir::Body<'tcx>,
can_be_generator: Option<hir::Movability>,
- return_type_pre_known: bool,
) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
// Create the function context. This is either derived from scratch or,
// in the case of closures, based on the outer context.
let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
- fcx.return_type_pre_known = return_type_pre_known;
let tcx = fcx.tcx;
let hir = tcx.hir();
decl.output.span(),
param_env,
));
- // If we replaced declared_ret_ty with infer vars, then we must be inferring
- // an opaque type, so set a flag so we can improve diagnostics.
- fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
debug!(?bound_sig, ?liberated_sig);
- let return_type_pre_known = !liberated_sig.output().is_ty_infer();
-
let generator_types = check_fn(
self,
self.param_env.without_const(),
expr.hir_id,
body,
gen,
- return_type_pre_known,
)
.1;
// may occur at the first return expression we see in the closure
// (if it conflicts with the declared return type). Skip adding a
// note in this case, since it would be incorrect.
- && !fcx.return_type_pre_known
+ && let Some(fn_sig) = fcx.body_fn_sig()
+ && fn_sig.output().is_ty_var()
{
err.span_note(
sp,
return_expr_ty,
);
- if self.return_type_has_opaque {
+ if let Some(fn_sig) = self.body_fn_sig()
+ && fn_sig.output().has_opaque_types()
+ {
// Point any obligations that were registered due to opaque type
// inference at the return expression.
self.select_obligations_where_possible(false, |errors| {
pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
pub(super) inh: &'a Inherited<'tcx>,
-
- /// True if the function or closure's return type is known before
- /// entering the function/closure, i.e. if the return type is
- /// either given explicitly or inferred from, say, an `Fn*` trait
- /// bound. Used for diagnostic purposes only.
- pub(super) return_type_pre_known: bool,
-
- /// True if the return type has an Opaque type
- pub(super) return_type_has_opaque: bool,
}
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
by_id: Default::default(),
}),
inh,
- return_type_pre_known: true,
- return_type_has_opaque: false,
}
}
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+ pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
+ self.typeck_results
+ .borrow()
+ .liberated_fn_sigs()
+ .get(self.tcx.hir().get_parent_node(self.body_id))
+ .copied()
+ }
+
pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) {
err.span_suggestion_short(
span.shrink_to_hi(),
param_env,
fn_sig,
);
- check_fn(&inh, param_env, fn_sig, decl, id, body, None, true).0
+ check_fn(&inh, param_env, fn_sig, decl, id, body, None).0
} else {
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
let expected_type = body_ty