Skip to content

Commit b4e9aad

Browse files
Rename can_coerce to may_coerce
1 parent e7c0d27 commit b4e9aad

File tree

8 files changed

+46
-43
lines changed

8 files changed

+46
-43
lines changed

compiler/rustc_hir_typeck/src/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
235235
Some(ret_coercion) => {
236236
let ret_ty = ret_coercion.borrow().expected_ty();
237237
let ret_ty = self.infcx.shallow_resolve(ret_ty);
238-
self.can_coerce(arm_ty, ret_ty)
239-
&& prior_arm.is_none_or(|(_, ty, _)| self.can_coerce(ty, ret_ty))
238+
self.may_coerce(arm_ty, ret_ty)
239+
&& prior_arm.is_none_or(|(_, ty, _)| self.may_coerce(ty, ret_ty))
240240
// The match arms need to unify for the case of `impl Trait`.
241241
&& !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..))
242242
}

compiler/rustc_hir_typeck/src/cast.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
409409
let mut sugg_mutref = false;
410410
if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
411411
if let ty::RawPtr(expr_ty, _) = *self.expr_ty.kind()
412-
&& fcx.can_coerce(
412+
&& fcx.may_coerce(
413413
Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, expr_ty, mutbl),
414414
self.cast_ty,
415415
)
@@ -418,22 +418,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
418418
} else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind()
419419
&& expr_mutbl == Mutability::Not
420420
&& mutbl == Mutability::Mut
421-
&& fcx.can_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty)
421+
&& fcx.may_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty)
422422
{
423423
sugg_mutref = true;
424424
}
425425

426426
if !sugg_mutref
427427
&& sugg == None
428-
&& fcx.can_coerce(
428+
&& fcx.may_coerce(
429429
Ty::new_ref(fcx.tcx, reg, self.expr_ty, mutbl),
430430
self.cast_ty,
431431
)
432432
{
433433
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
434434
}
435435
} else if let ty::RawPtr(_, mutbl) = *self.cast_ty.kind()
436-
&& fcx.can_coerce(
436+
&& fcx.may_coerce(
437437
Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, self.expr_ty, mutbl),
438438
self.cast_ty,
439439
)

compiler/rustc_hir_typeck/src/coercion.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -1083,21 +1083,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10831083
})
10841084
}
10851085

1086-
/// Same as `coerce()`, but without side-effects.
1086+
/// Probe whether `expr_ty` can be coerced to `target_ty`. This has no side-effects,
1087+
/// and may return false positives if types are not yet fully constrained by inference.
10871088
///
1088-
/// Returns false if the coercion creates any obligations that result in
1089-
/// errors.
1090-
pub(crate) fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
1089+
/// Returns false if the coercion is not possible, or if the coercion creates any
1090+
/// sub-obligations that result in errors.
1091+
///
1092+
/// This should only be used for diagnostics.
1093+
pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool {
10911094
// FIXME(-Znext-solver): We need to structurally resolve both types here.
10921095
let source = self.resolve_vars_with_obligations(expr_ty);
1093-
debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
1096+
debug!("coercion::can_with_predicates({:?} -> {:?})", source, target_ty);
10941097

10951098
let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable);
10961099
// We don't ever need two-phase here since we throw out the result of the coercion.
10971100
// We also just always set `coerce_never` to true, since this is a heuristic.
10981101
let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true);
10991102
self.probe(|_| {
1100-
let Ok(ok) = coerce.coerce(source, target) else {
1103+
let Ok(ok) = coerce.coerce(source, target_ty) else {
11011104
return false;
11021105
};
11031106
let ocx = ObligationCtxt::new(self);
@@ -1369,7 +1372,7 @@ pub fn can_coerce<'tcx>(
13691372
) -> bool {
13701373
let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id);
13711374
let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id);
1372-
fn_ctxt.can_coerce(ty, output_ty)
1375+
fn_ctxt.may_coerce(ty, output_ty)
13731376
}
13741377

13751378
/// CoerceMany encapsulates the pattern you should use when you have

compiler/rustc_hir_typeck/src/expr.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1330,9 +1330,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13301330
let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| {
13311331
let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs());
13321332
let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs());
1333-
self.can_coerce(rhs, lhs)
1333+
self.may_coerce(rhs, lhs)
13341334
};
1335-
let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
1335+
let (applicability, eq) = if self.may_coerce(rhs_ty, lhs_ty) {
13361336
(Applicability::MachineApplicable, true)
13371337
} else if refs_can_coerce(rhs_ty, lhs_ty) {
13381338
// The lhs and rhs are likely missing some references in either side. Subsequent
@@ -1349,7 +1349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13491349
let actual_lhs_ty = self.check_expr(rhs_expr);
13501350
(
13511351
Applicability::MaybeIncorrect,
1352-
self.can_coerce(rhs_ty, actual_lhs_ty)
1352+
self.may_coerce(rhs_ty, actual_lhs_ty)
13531353
|| refs_can_coerce(rhs_ty, actual_lhs_ty),
13541354
)
13551355
} else if let ExprKind::Binary(
@@ -1363,7 +1363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13631363
let actual_rhs_ty = self.check_expr(lhs_expr);
13641364
(
13651365
Applicability::MaybeIncorrect,
1366-
self.can_coerce(actual_rhs_ty, lhs_ty)
1366+
self.may_coerce(actual_rhs_ty, lhs_ty)
13671367
|| refs_can_coerce(actual_rhs_ty, lhs_ty),
13681368
)
13691369
} else {
@@ -1414,7 +1414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14141414
self.param_env,
14151415
)
14161416
.may_apply();
1417-
if lhs_deref_ty_is_sized && self.can_coerce(rhs_ty, lhs_deref_ty) {
1417+
if lhs_deref_ty_is_sized && self.may_coerce(rhs_ty, lhs_deref_ty) {
14181418
err.span_suggestion_verbose(
14191419
lhs.span.shrink_to_lo(),
14201420
"consider dereferencing here to assign to the mutably borrowed value",

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
658658
&& fn_sig.inputs()[1..]
659659
.iter()
660660
.zip(input_types.iter())
661-
.all(|(expected, found)| self.can_coerce(*expected, *found))
661+
.all(|(expected, found)| self.may_coerce(*expected, *found))
662662
&& fn_sig.inputs()[1..].len() == input_types.len()
663663
{
664664
err.span_suggestion_verbose(
@@ -722,7 +722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
722722

723723
let expectation = Expectation::rvalue_hint(self, expected_input_ty);
724724
let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
725-
let can_coerce = self.can_coerce(arg_ty, coerced_ty);
725+
let can_coerce = self.may_coerce(arg_ty, coerced_ty);
726726
if !can_coerce {
727727
return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
728728
ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
@@ -802,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
802802
provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx + tys.len()),
803803
),
804804
) {
805-
if !self.can_coerce(provided_ty, *expected_ty) {
805+
if !self.may_coerce(provided_ty, *expected_ty) {
806806
satisfied = false;
807807
break;
808808
}
@@ -1023,7 +1023,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10231023
std::iter::zip(formal_and_expected_inputs.iter(), removed_arg_tys.iter()).all(
10241024
|((expected_ty, _), (provided_ty, _))| {
10251025
!provided_ty.references_error()
1026-
&& self.can_coerce(*provided_ty, *expected_ty)
1026+
&& self.may_coerce(*provided_ty, *expected_ty)
10271027
},
10281028
)
10291029
};
@@ -2124,7 +2124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21242124
let expr_ty = self.typeck_results.borrow().expr_ty(expr);
21252125
let return_ty = fn_sig.output();
21262126
if !matches!(expr.kind, hir::ExprKind::Ret(..))
2127-
&& self.can_coerce(expr_ty, return_ty)
2127+
&& self.may_coerce(expr_ty, return_ty)
21282128
{
21292129
found_semi = true;
21302130
}

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
261261
if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) =
262262
expr.kind
263263
&& let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr)
264-
&& self.can_coerce(recv_ty, expected)
264+
&& self.may_coerce(recv_ty, expected)
265265
&& let name = method.name.as_str()
266266
&& (name.starts_with("to_") || name.starts_with("as_") || name == "into")
267267
{
@@ -349,7 +349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
349349
return true;
350350
}
351351

352-
if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected))
352+
if self.suggest_fn_call(err, expr, found, |output| self.may_coerce(output, expected))
353353
&& let ty::FnDef(def_id, ..) = *found.kind()
354354
&& let Some(sp) = self.tcx.hir().span_if_local(def_id)
355355
{
@@ -568,7 +568,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
568568
if self.tcx.hir().is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() {
569569
return false;
570570
}
571-
if self.can_coerce(Ty::new_box(self.tcx, found), expected) {
571+
if self.may_coerce(Ty::new_box(self.tcx, found), expected) {
572572
let suggest_boxing = match found.kind() {
573573
ty::Tuple(tuple) if tuple.is_empty() => {
574574
errors::SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span }
@@ -663,7 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663663
};
664664
match expected.kind() {
665665
ty::Adt(def, _) if Some(def.did()) == pin_did => {
666-
if self.can_coerce(pin_box_found, expected) {
666+
if self.may_coerce(pin_box_found, expected) {
667667
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
668668
match found.kind() {
669669
ty::Adt(def, _) if def.is_box() => {
@@ -689,7 +689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
689689
}
690690
}
691691
true
692-
} else if self.can_coerce(pin_found, expected) {
692+
} else if self.may_coerce(pin_found, expected) {
693693
match found.kind() {
694694
ty::Adt(def, _) if def.is_box() => {
695695
err.help("use `Box::pin`");
@@ -701,7 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
701701
false
702702
}
703703
}
704-
ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => {
704+
ty::Adt(def, _) if def.is_box() && self.may_coerce(box_found, expected) => {
705705
// Check if the parent expression is a call to Pin::new. If it
706706
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
707707
// can suggest Box::pin.
@@ -884,7 +884,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
884884
let ty = Binder::bind_with_vars(ty, bound_vars);
885885
let ty = self.normalize(hir_ty.span, ty);
886886
let ty = self.tcx.instantiate_bound_regions_with_erased(ty);
887-
if self.can_coerce(expected, ty) {
887+
if self.may_coerce(expected, ty) {
888888
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other {
889889
span: hir_ty.span,
890890
expected,
@@ -1141,12 +1141,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11411141
ty::Asyncness::No => ty,
11421142
};
11431143
let ty = self.normalize(expr.span, ty);
1144-
self.can_coerce(found, ty)
1144+
self.may_coerce(found, ty)
11451145
}
11461146
hir::FnRetTy::DefaultReturn(_) if in_closure => {
11471147
self.ret_coercion.as_ref().map_or(false, |ret| {
11481148
let ret_ty = ret.borrow().expected_ty();
1149-
self.can_coerce(found, ret_ty)
1149+
self.may_coerce(found, ret_ty)
11501150
})
11511151
}
11521152
_ => false,
@@ -1510,7 +1510,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15101510
provided_ty
15111511
};
15121512

1513-
if !self.can_coerce(expected_ty, dummy_ty) {
1513+
if !self.may_coerce(expected_ty, dummy_ty) {
15141514
return;
15151515
}
15161516
let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`");
@@ -1534,7 +1534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15341534
expected_ty: Ty<'tcx>,
15351535
) {
15361536
if let ty::Slice(elem_ty) | ty::Array(elem_ty, _) = expected_ty.kind() {
1537-
if self.can_coerce(blk_ty, *elem_ty)
1537+
if self.may_coerce(blk_ty, *elem_ty)
15381538
&& blk.stmts.is_empty()
15391539
&& blk.rules == hir::BlockCheckMode::DefaultBlock
15401540
{
@@ -1744,7 +1744,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17441744
if item_ty.has_param() {
17451745
return false;
17461746
}
1747-
if self.can_coerce(item_ty, expected_ty) {
1747+
if self.may_coerce(item_ty, expected_ty) {
17481748
err.span_suggestion_verbose(
17491749
segment.ident.span,
17501750
format!("try referring to the associated const `{capitalized_name}` instead",),
@@ -1804,7 +1804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18041804
// diagnostic in cases where we have `(&&T).clone()` and we expect `T`).
18051805
&& !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..)))
18061806
// Check that we're in fact trying to clone into the expected type
1807-
&& self.can_coerce(*pointee_ty, expected_ty)
1807+
&& self.may_coerce(*pointee_ty, expected_ty)
18081808
&& let trait_ref = ty::TraitRef::new(self.tcx, clone_trait_did, [expected_ty])
18091809
// And the expected type doesn't implement `Clone`
18101810
&& !self.predicate_must_hold_considering_regions(&traits::Obligation::new(
@@ -2022,7 +2022,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20222022
} else {
20232023
return false;
20242024
};
2025-
if is_ctor || !self.can_coerce(args.type_at(0), expected) {
2025+
if is_ctor || !self.may_coerce(args.type_at(0), expected) {
20262026
return false;
20272027
}
20282028

@@ -2293,7 +2293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22932293
.then(|| " (its field is private, but it's local to this crate and its privacy can be changed)".to_string());
22942294

22952295
let sole_field_ty = sole_field.ty(self.tcx, args);
2296-
if self.can_coerce(expr_ty, sole_field_ty) {
2296+
if self.may_coerce(expr_ty, sole_field_ty) {
22972297
let variant_path =
22982298
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
22992299
// FIXME #56861: DRYer prelude filtering
@@ -2401,7 +2401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24012401
}
24022402

24032403
let int_type = args.type_at(0);
2404-
if !self.can_coerce(expr_ty, int_type) {
2404+
if !self.may_coerce(expr_ty, int_type) {
24052405
return false;
24062406
}
24072407

@@ -2585,7 +2585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25852585
Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, checked_ty)
25862586
}
25872587
};
2588-
if self.can_coerce(ref_ty, expected) {
2588+
if self.may_coerce(ref_ty, expected) {
25892589
let mut sugg_sp = sp;
25902590
if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind {
25912591
let clone_trait =

compiler/rustc_hir_typeck/src/method/suggest.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1934,7 +1934,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19341934
&& fn_sig.inputs()[1..]
19351935
.iter()
19361936
.zip(args.into_iter())
1937-
.all(|(expected, found)| self.can_coerce(*expected, *found))
1937+
.all(|(expected, found)| self.may_coerce(*expected, *found))
19381938
&& fn_sig.inputs()[1..].len() == args.len()
19391939
{
19401940
err.span_suggestion_verbose(
@@ -4148,7 +4148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
41484148
return false;
41494149
};
41504150

4151-
if !self.can_coerce(output, expected) {
4151+
if !self.may_coerce(output, expected) {
41524152
return false;
41534153
}
41544154

compiler/rustc_hir_typeck/src/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17671767
} else if inexistent_fields.len() == 1 {
17681768
match pat_field.pat.kind {
17691769
PatKind::Lit(expr)
1770-
if !self.can_coerce(
1770+
if !self.may_coerce(
17711771
self.typeck_results.borrow().expr_ty(expr),
17721772
self.field_ty(field.span, field_def, args),
17731773
) => {}

0 commit comments

Comments
 (0)