Skip to content

Commit

Permalink
Auto merge of rust-lang#121394 - oli-obk:define_opaque_types, r=compi…
Browse files Browse the repository at this point in the history
…ler-errors

some smaller DefiningOpaqueTypes::No -> Yes switches

r? `@compiler-errors`

These are some easy cases, so let's get them out of the way first.
I added tests exercising the specialization code paths that I believe weren't tested so far.

follow-up to rust-lang#117348
  • Loading branch information
bors committed Apr 4, 2024
2 parents 0fd5712 + 4e8d2f0 commit a4b11c8
Show file tree
Hide file tree
Showing 31 changed files with 522 additions and 49 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let param = callee_args.const_at(host_effect_index);
let cause = self.misc(span);
match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
// We know the type of `effect` to be `bool`, there will be no opaque type inference.
match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::Yes, effect, param) {
Ok(infer::InferOk { obligations, value: () }) => {
self.register_predicates(obligations);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// what our ideal rcvr ty would look like.
let _ = self
.at(&ObligationCause::dummy(), self.param_env)
.eq(DefineOpaqueTypes::No, method.sig.inputs()[idx + 1], arg_ty)
.eq(DefineOpaqueTypes::Yes, method.sig.inputs()[idx + 1], arg_ty)
.ok()?;
self.select_obligations_where_possible(|errs| {
// Yeet the errors, we're already reporting errors.
Expand Down Expand Up @@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.and_then(|method| {
let _ = self
.at(&ObligationCause::dummy(), self.param_env)
.eq(DefineOpaqueTypes::No, ideal_rcvr_ty, expected_ty)
.eq(DefineOpaqueTypes::Yes, ideal_rcvr_ty, expected_ty)
.ok()?;
Some(method)
});
Expand Down
26 changes: 11 additions & 15 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ use rustc_infer::infer::InferOk;
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
use rustc_middle::ty::error::{
ExpectedFound,
TypeError::{FieldMisMatch, Sorts},
};
use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts};
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
use rustc_session::errors::ExprParenthesesNeeded;
Expand Down Expand Up @@ -1811,24 +1808,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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(
DefineOpaqueTypes::No,
// 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(_) => {
// This should never happen, since we're just subtyping the
// remaining_fields, but it's fine to emit this, I guess.
self.err_ctxt()
.report_mismatched_types(
&cause,
target_ty,
fru_ty,
FieldMisMatch(variant.name, ident.name),
)
.emit();
span_bug!(
cause.span(),
"subtyping remaining fields of type changing FRU failed: {target_ty} != {fru_ty}: {}::{}",
variant.name,
ident.name,
);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ impl<'a, 'tcx> FnCtxt<'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::No, formal_input_ty, coerced_ty)
.sup(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty)
.err()
});

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,9 @@ impl<'tcx> InferCtxt<'tcx> {
{
let origin = &ObligationCause::dummy();
self.probe(|_| {
self.at(origin, param_env).sub(DefineOpaqueTypes::No, expected, actual).is_ok()
// We're only answering whether there could be a subtyping relation, and with
// opaque types, "there could be one", via registering a hidden type.
self.at(origin, param_env).sub(DefineOpaqueTypes::Yes, expected, actual).is_ok()
})
}

Expand All @@ -852,7 +854,9 @@ impl<'tcx> InferCtxt<'tcx> {
T: at::ToTrace<'tcx>,
{
let origin = &ObligationCause::dummy();
self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::No, a, b).is_ok())
// We're only answering whether the types could be the same, and with
// opaque types, "they can be the same", via registering a hidden type.
self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::Yes, a, b).is_ok())
}

#[instrument(skip(self), level = "debug")]
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> Result<(), NoSolution> {
self.infcx
.at(&ObligationCause::dummy(), param_env)
.eq(DefineOpaqueTypes::No, lhs, rhs)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.eq(DefineOpaqueTypes::Yes, lhs, rhs)
.map(|InferOk { value: (), obligations }| {
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
})
Expand Down Expand Up @@ -759,7 +760,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> Result<(), NoSolution> {
self.infcx
.at(&ObligationCause::dummy(), param_env)
.sub(DefineOpaqueTypes::No, sub, sup)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.sub(DefineOpaqueTypes::Yes, sub, sup)
.map(|InferOk { value: (), obligations }| {
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
})
Expand All @@ -779,7 +781,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> Result<(), NoSolution> {
self.infcx
.at(&ObligationCause::dummy(), param_env)
.relate(DefineOpaqueTypes::No, lhs, variance, rhs)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.relate(DefineOpaqueTypes::Yes, lhs, variance, rhs)
.map(|InferOk { value: (), obligations }| {
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
})
Expand All @@ -803,7 +806,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.infcx
.at(&ObligationCause::dummy(), param_env)
.eq(DefineOpaqueTypes::No, lhs, rhs)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.eq(DefineOpaqueTypes::Yes, lhs, rhs)
.map(|InferOk { value: (), obligations }| {
obligations.into_iter().map(|o| o.into()).collect()
})
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ fn rematch_impl<'tcx>(

let mut nested = infcx
.at(&ObligationCause::dummy(), goal.param_env)
.eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.eq(DefineOpaqueTypes::Yes, goal.predicate.trait_ref, impl_trait_ref)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations();

Expand Down Expand Up @@ -257,7 +258,8 @@ fn rematch_unsize<'tcx>(
nested.extend(
infcx
.at(&ObligationCause::dummy(), goal.param_env)
.eq(DefineOpaqueTypes::No, a_elem_ty, b_elem_ty)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty)
.expect("expected rematch to succeed")
.into_obligations(),
);
Expand Down Expand Up @@ -300,7 +302,8 @@ fn rematch_unsize<'tcx>(
nested.extend(
infcx
.at(&ObligationCause::dummy(), goal.param_env)
.eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
.expect("expected rematch to succeed")
.into_obligations(),
);
Expand Down Expand Up @@ -329,7 +332,8 @@ fn rematch_unsize<'tcx>(
nested.extend(
infcx
.at(&ObligationCause::dummy(), goal.param_env)
.eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
.eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
.expect("expected rematch to succeed")
.into_obligations(),
);
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ fn plug_infer_with_placeholders<'tcx>(
if ty.is_ty_var() {
let Ok(InferOk { value: (), obligations }) =
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
DefineOpaqueTypes::No,
// Comparing against a type variable never registers hidden types anyway
DefineOpaqueTypes::Yes,
ty,
Ty::new_placeholder(
self.infcx.tcx,
Expand All @@ -504,7 +505,9 @@ fn plug_infer_with_placeholders<'tcx>(
if ct.is_ct_infer() {
let Ok(InferOk { value: (), obligations }) =
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
DefineOpaqueTypes::No,
// The types of the constants are the same, so there is no hidden type
// registration happening anyway.
DefineOpaqueTypes::Yes,
ct,
ty::Const::new_placeholder(
self.infcx.tcx,
Expand Down Expand Up @@ -532,7 +535,8 @@ fn plug_infer_with_placeholders<'tcx>(
if r.is_var() {
let Ok(InferOk { value: (), obligations }) =
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
DefineOpaqueTypes::No,
// Lifetimes don't contain opaque types (or any types for that matter).
DefineOpaqueTypes::Yes,
r,
ty::Region::new_placeholder(
self.infcx.tcx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3842,7 +3842,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.probe(|_| {
match self
.at(&ObligationCause::misc(expr.span, body_id), param_env)
.eq(DefineOpaqueTypes::No, expected, actual)
// Doesn't actually matter if we define opaque types here, this is just used for
// diagnostics, and the result is never kept around.
.eq(DefineOpaqueTypes::Yes, expected, actual)
{
Ok(_) => (), // We ignore nested obligations here for now.
Err(err) => type_diffs.push(err),
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
// as the cause of an overflow.
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
DefineOpaqueTypes::No,
// Only really excercised by generic_const_exprs
DefineOpaqueTypes::Yes,
ct.ty(),
ty,
) {
Expand Down Expand Up @@ -571,7 +572,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
if let Ok(new_obligations) = infcx
.at(&obligation.cause, obligation.param_env)
.trace(c1, c2)
.eq(DefineOpaqueTypes::No, a.args, b.args)
// Can define opaque types as this is only reachable with
// `generic_const_exprs`
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
{
return ProcessResult::Changed(mk_pending(
new_obligations.into_obligations(),
Expand All @@ -582,7 +585,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
(_, _) => {
if let Ok(new_obligations) = infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, c1, c2)
// Can define opaque types as this is only reachable with
// `generic_const_exprs`
.eq(DefineOpaqueTypes::Yes, c1, c2)
{
return ProcessResult::Changed(mk_pending(
new_obligations.into_obligations(),
Expand Down Expand Up @@ -623,7 +628,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
match (evaluate(c1), evaluate(c2)) {
(Ok(c1), Ok(c2)) => {
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
DefineOpaqueTypes::No,
// Can define opaque types as this is only reachable with
// `generic_const_exprs`
DefineOpaqueTypes::Yes,
c1,
c2,
) {
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.infcx
.at(&obligation.cause, obligation.param_env)
.trace(c1, c2)
.eq(DefineOpaqueTypes::No, a.args, b.args)
// Can define opaque types as this is only reachable with
// `generic_const_exprs`
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
{
return self.evaluate_predicates_recursively(
previous_stack,
Expand All @@ -919,7 +921,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let Ok(InferOk { obligations, value: () }) = self
.infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, c1, c2)
// Can define opaque types as this is only reachable with
// `generic_const_exprs`
.eq(DefineOpaqueTypes::Yes, c1, c2)
{
return self.evaluate_predicates_recursively(
previous_stack,
Expand Down Expand Up @@ -949,7 +953,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
match (evaluate(c1), evaluate(c2)) {
(Ok(c1), Ok(c2)) => {
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
DefineOpaqueTypes::No,
// Can define opaque types as this is only reachable with
// `generic_const_exprs`
DefineOpaqueTypes::Yes,
c1,
c2,
) {
Expand Down Expand Up @@ -982,7 +988,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
DefineOpaqueTypes::No,
// Only really excercised by generic_const_exprs
DefineOpaqueTypes::Yes,
ct.ty(),
ty,
) {
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_trait_selection/src/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,12 @@ fn fulfill_implication<'tcx>(
// do the impls unify? If not, no specialization.
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
.at(&ObligationCause::dummy(), param_env)
.eq(DefineOpaqueTypes::No, source_trait, target_trait)
// Ok to use `Yes`, as all the generic params are already replaced by inference variables,
// which will match the opaque type no matter if it is defining or not.
// Any concrete type that would match the opaque would already be handled by coherence rules,
// and thus either be ok to match here and already have errored, or it won't match, in which
// case there is no issue anyway.
.eq(DefineOpaqueTypes::Yes, source_trait, target_trait)
else {
debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait);
return Err(());
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/blanket_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
// Require the type the impl is implemented on to match
// our type, and ignore the impl if there was a mismatch.
let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq(
DefineOpaqueTypes::No,
DefineOpaqueTypes::Yes,
impl_trait_ref.self_ty(),
impl_ty,
) else {
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/opaque_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![feature(generic_const_exprs, type_alias_impl_trait)]
#![allow(incomplete_features)]

type Foo = impl Sized;

fn with_bound<const N: usize>() -> Foo
where
[u8; (N / 2) as usize]: Sized,
{
let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
//~^ ERROR mismatched types
//~| ERROR non-primitive cast: `usize` as `Foo`
todo!()
}

fn main() {
with_bound::<4>();
}

0 comments on commit a4b11c8

Please sign in to comment.