Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call_expr.span,
ObligationCauseCode::WellFormed(WellFormedLoc::HirId(call_expr.hir_id)),
);
// FIXME: This needs to happen in a `probe` as the `sup`
// call can currently guide type inference.
if self
Comment thread
fallible-algebra marked this conversation as resolved.
.at(&cause, self.param_env)
.sup(DefineOpaqueTypes::Yes, formal_input_tys[0], adjusted_arg_type)
.sup_raw(
&cause,
self.param_env,
DefineOpaqueTypes::Yes,
formal_input_tys[0],
adjusted_arg_type,
)
.is_err()
{
return do_check();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
let res = if self.use_lub {
at.lub(b, a)
} else {
at.sup(DefineOpaqueTypes::Yes, b, a)
self.sup_raw(&self.cause, self.param_env, DefineOpaqueTypes::Yes, b, a)
.map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
};

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Result<(), Diag<'a>> {
self.at(cause, self.param_env)
.sup(DefineOpaqueTypes::Yes, expected, actual)
self.sup_raw(cause, self.param_env, DefineOpaqueTypes::Yes, expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
.map_err(|e| {
self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e)
Expand Down
27 changes: 5 additions & 22 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{ExprKind, HirId, QPath, is_range_literal};
use rustc_hir_analysis::diagnostics::{NoFieldOnType, NoVariantNamed};
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin};
use rustc_infer::infer::{self, RegionVariableOrigin};
use rustc_infer::traits::WellFormedLoc;
use rustc_infer::traits::query::NoSolution;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
Expand Down Expand Up @@ -2119,27 +2119,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(_) = remaining_fields.remove(&ident) {
let target_ty = self.field_ty(base_expr.span, f, args);
let cause = self.misc(base_expr.span);
match self.at(&cause, self.param_env).sup(
// We're already using inference variables for any params,
// and don't allow converting between different structs,
// so there is no way this ever actually defines an opaque
// type. Thus choosing `Yes` is fine.
DefineOpaqueTypes::Yes,
target_ty,
fru_ty,
) {
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations)
}
Err(_) => {
span_bug!(
cause.span,
"subtyping remaining fields of type changing FRU \
failed: {target_ty} != {fru_ty}: {}::{}",
variant.name,
ident.name,
);
}
if let Err(diag) =
self.demand_suptype_diag(cause.span, target_ty, fru_ty)
{
diag.delay_as_bug();
}
}
self.deeply_resolve_ignoring_regions(fru_ty)
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3263,9 +3263,14 @@ impl<'a, 'tcx> ArgMatchingCtxt<'a, 'tcx> {

// Using probe here, since we don't want this subtyping to affect inference.
let subtyping_error = self.probe(|_| {
self.at(&self.misc(arg_span), self.param_env)
.sup(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty)
.err()
self.sup_raw(
&self.misc(arg_span),
self.param_env,
DefineOpaqueTypes::Yes,
formal_input_ty,
coerced_ty,
)
.err()
});

// Same as above: if either the coerce type or the checked type is an error type,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
self_ty, method_self_ty, self.span, pick
);
let cause = self.cause(self.self_expr.span, ObligationCauseCode::Misc);
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) {
match self.sup_raw(&cause, self.param_env, DefineOpaqueTypes::Yes, method_self_ty, self_ty)

@lcnr lcnr Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

want to change this to use demand_suptype_diag instead?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure how to integrate this here, each way I try to brings up different failures in the test suite (wrt arbitrary self for the most part).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to leave this instance of sup_raw here for now.

{
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations);
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1971,7 +1971,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.xform_self_ty(candidate.item, trait_ref.self_ty(), trait_ref.args);
// Guide the trait selection to show impls that have methods whose type matches
// up with the `self` parameter of the method.
let _ = self.at(&ObligationCause::dummy(), self.param_env).sup(
let _ = self.sup_raw(
&ObligationCause::dummy(),
self.param_env,
DefineOpaqueTypes::Yes,
xform_self_ty,
self_ty,
Expand Down
70 changes: 29 additions & 41 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn sup_raw<T>(
self,
&self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
Expand All @@ -143,7 +143,27 @@ impl<'tcx> InferCtxt<'tcx> {
where
T: ToTrace<'tcx>,
{
self.at(cause, param_env).sup(define_opaque_types, expected, actual)
if self.next_trait_solver {
NextSolverRelate::relate(
self,
param_env,
expected,
ty::Contravariant,
actual,
cause.span,
)
.map(|goals| self.goals_to_obligations(cause, goals))
} else {
let mut op = TypeRelating::new(
&self,
ToTrace::to_trace(cause, expected, actual),
param_env,
define_opaque_types,
ty::Contravariant,
);
op.relate(expected, actual)?;
Ok(InferOk { value: (), obligations: op.into_obligations() })
}
}

/// Makes `expected <: actual`.
Expand Down Expand Up @@ -268,44 +288,6 @@ pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
}

impl<'a, 'tcx> At<'a, 'tcx> {
/// Makes `actual <: expected`. For example, if type-checking a
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
/// `sup(i32, x)`, since the "expected" type is the type that
/// appears in the signature.
///
/// FIXME: To be removed in favor of the [`InferCtxt::sup_raw`] method instead.
pub fn sup<T>(
self,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
if self.infcx.next_trait_solver {
NextSolverRelate::relate(
self.infcx,
self.param_env,
expected,
ty::Contravariant,
actual,
self.cause.span,
)
.map(|goals| self.goals_to_obligations(goals))
} else {
let mut op = TypeRelating::new(
self.infcx,
ToTrace::to_trace(self.cause, expected, actual),
self.param_env,
define_opaque_types,
ty::Contravariant,
);
op.relate(expected, actual)?;
Ok(InferOk { value: (), obligations: op.into_obligations() })
}
}

/// Makes `expected <: actual`.
///
/// FIXME: To be removed in favor of the [`InferCtxt::sub_raw`] method instead.
Expand Down Expand Up @@ -411,7 +393,13 @@ impl<'a, 'tcx> At<'a, 'tcx> {
match variance {
ty::Covariant => self.sub(define_opaque_types, expected, actual),
ty::Invariant => self.eq(define_opaque_types, expected, actual),
ty::Contravariant => self.sup(define_opaque_types, expected, actual),
ty::Contravariant => self.infcx.sup_raw(
self.cause,
self.param_env,
define_opaque_types,
expected,
actual,
),

// We could make this make sense but it's not readily
// exposed and I don't feel like dealing with it. Note
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ impl<'tcx> InferCtxt<'tcx> {
if a_is_expected {
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
} else {
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
Ok(self.sup_raw(cause, param_env, DefineOpaqueTypes::Yes, b, a))
}
})
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,7 @@ where
actual: T,
) -> Result<(), TypeError<'tcx>> {
self.infcx
.at(cause, param_env)
.sup(DefineOpaqueTypes::Yes, expected, actual)
.sup_raw(cause, param_env, DefineOpaqueTypes::Yes, expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1033,8 +1033,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// only the **lifetime bound** is changed.
let InferOk { mut obligations, .. } = self
.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::Yes, target, source_trait)
.sup_raw(
&obligation.cause,
obligation.param_env,
DefineOpaqueTypes::Yes,
target,
source_trait,
)
.map_err(|_| SelectionError::Unimplemented)?;

// Register one obligation for 'a: 'b.
Expand Down
Loading