Skip to content

Commit a4b11c8

Browse files
committed
Auto merge of #121394 - oli-obk:define_opaque_types, r=compiler-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 #117348
2 parents 0fd5712 + 4e8d2f0 commit a4b11c8

31 files changed

+522
-49
lines changed

compiler/rustc_hir_typeck/src/callee.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
918918

919919
let param = callee_args.const_at(host_effect_index);
920920
let cause = self.misc(span);
921-
match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
921+
// We know the type of `effect` to be `bool`, there will be no opaque type inference.
922+
match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::Yes, effect, param) {
922923
Ok(infer::InferOk { obligations, value: () }) => {
923924
self.register_predicates(obligations);
924925
}

compiler/rustc_hir_typeck/src/demand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
400400
// what our ideal rcvr ty would look like.
401401
let _ = self
402402
.at(&ObligationCause::dummy(), self.param_env)
403-
.eq(DefineOpaqueTypes::No, method.sig.inputs()[idx + 1], arg_ty)
403+
.eq(DefineOpaqueTypes::Yes, method.sig.inputs()[idx + 1], arg_ty)
404404
.ok()?;
405405
self.select_obligations_where_possible(|errs| {
406406
// Yeet the errors, we're already reporting errors.
@@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
479479
.and_then(|method| {
480480
let _ = self
481481
.at(&ObligationCause::dummy(), self.param_env)
482-
.eq(DefineOpaqueTypes::No, ideal_rcvr_ty, expected_ty)
482+
.eq(DefineOpaqueTypes::Yes, ideal_rcvr_ty, expected_ty)
483483
.ok()?;
484484
Some(method)
485485
});

compiler/rustc_hir_typeck/src/expr.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ use rustc_infer::infer::InferOk;
4444
use rustc_infer::traits::query::NoSolution;
4545
use rustc_infer::traits::ObligationCause;
4646
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
47-
use rustc_middle::ty::error::{
48-
ExpectedFound,
49-
TypeError::{FieldMisMatch, Sorts},
50-
};
47+
use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts};
5148
use rustc_middle::ty::GenericArgsRef;
5249
use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
5350
use rustc_session::errors::ExprParenthesesNeeded;
@@ -1811,24 +1808,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18111808
let target_ty = self.field_ty(base_expr.span, f, args);
18121809
let cause = self.misc(base_expr.span);
18131810
match self.at(&cause, self.param_env).sup(
1814-
DefineOpaqueTypes::No,
1811+
// We're already using inference variables for any params, and don't allow converting
1812+
// between different structs, so there is no way this ever actually defines an opaque type.
1813+
// Thus choosing `Yes` is fine.
1814+
DefineOpaqueTypes::Yes,
18151815
target_ty,
18161816
fru_ty,
18171817
) {
18181818
Ok(InferOk { obligations, value: () }) => {
18191819
self.register_predicates(obligations)
18201820
}
18211821
Err(_) => {
1822-
// This should never happen, since we're just subtyping the
1823-
// remaining_fields, but it's fine to emit this, I guess.
1824-
self.err_ctxt()
1825-
.report_mismatched_types(
1826-
&cause,
1827-
target_ty,
1828-
fru_ty,
1829-
FieldMisMatch(variant.name, ident.name),
1830-
)
1831-
.emit();
1822+
span_bug!(
1823+
cause.span(),
1824+
"subtyping remaining fields of type changing FRU failed: {target_ty} != {fru_ty}: {}::{}",
1825+
variant.name,
1826+
ident.name,
1827+
);
18321828
}
18331829
}
18341830
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
687687
// Using probe here, since we don't want this subtyping to affect inference.
688688
let subtyping_error = self.probe(|_| {
689689
self.at(&self.misc(arg_span), self.param_env)
690-
.sup(DefineOpaqueTypes::No, formal_input_ty, coerced_ty)
690+
.sup(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty)
691691
.err()
692692
});
693693

compiler/rustc_infer/src/infer/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,9 @@ impl<'tcx> InferCtxt<'tcx> {
843843
{
844844
let origin = &ObligationCause::dummy();
845845
self.probe(|_| {
846-
self.at(origin, param_env).sub(DefineOpaqueTypes::No, expected, actual).is_ok()
846+
// We're only answering whether there could be a subtyping relation, and with
847+
// opaque types, "there could be one", via registering a hidden type.
848+
self.at(origin, param_env).sub(DefineOpaqueTypes::Yes, expected, actual).is_ok()
847849
})
848850
}
849851

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

858862
#[instrument(skip(self), level = "debug")]

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
720720
) -> Result<(), NoSolution> {
721721
self.infcx
722722
.at(&ObligationCause::dummy(), param_env)
723-
.eq(DefineOpaqueTypes::No, lhs, rhs)
723+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
724+
.eq(DefineOpaqueTypes::Yes, lhs, rhs)
724725
.map(|InferOk { value: (), obligations }| {
725726
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
726727
})
@@ -759,7 +760,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
759760
) -> Result<(), NoSolution> {
760761
self.infcx
761762
.at(&ObligationCause::dummy(), param_env)
762-
.sub(DefineOpaqueTypes::No, sub, sup)
763+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
764+
.sub(DefineOpaqueTypes::Yes, sub, sup)
763765
.map(|InferOk { value: (), obligations }| {
764766
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
765767
})
@@ -779,7 +781,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
779781
) -> Result<(), NoSolution> {
780782
self.infcx
781783
.at(&ObligationCause::dummy(), param_env)
782-
.relate(DefineOpaqueTypes::No, lhs, variance, rhs)
784+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
785+
.relate(DefineOpaqueTypes::Yes, lhs, variance, rhs)
783786
.map(|InferOk { value: (), obligations }| {
784787
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
785788
})
@@ -803,7 +806,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
803806
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
804807
self.infcx
805808
.at(&ObligationCause::dummy(), param_env)
806-
.eq(DefineOpaqueTypes::No, lhs, rhs)
809+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
810+
.eq(DefineOpaqueTypes::Yes, lhs, rhs)
807811
.map(|InferOk { value: (), obligations }| {
808812
obligations.into_iter().map(|o| o.into()).collect()
809813
})

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ fn rematch_impl<'tcx>(
182182

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

@@ -257,7 +258,8 @@ fn rematch_unsize<'tcx>(
257258
nested.extend(
258259
infcx
259260
.at(&ObligationCause::dummy(), goal.param_env)
260-
.eq(DefineOpaqueTypes::No, a_elem_ty, b_elem_ty)
261+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
262+
.eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty)
261263
.expect("expected rematch to succeed")
262264
.into_obligations(),
263265
);
@@ -300,7 +302,8 @@ fn rematch_unsize<'tcx>(
300302
nested.extend(
301303
infcx
302304
.at(&ObligationCause::dummy(), goal.param_env)
303-
.eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
305+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
306+
.eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
304307
.expect("expected rematch to succeed")
305308
.into_obligations(),
306309
);
@@ -329,7 +332,8 @@ fn rematch_unsize<'tcx>(
329332
nested.extend(
330333
infcx
331334
.at(&ObligationCause::dummy(), goal.param_env)
332-
.eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
335+
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
336+
.eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
333337
.expect("expected rematch to succeed")
334338
.into_obligations(),
335339
);

compiler/rustc_trait_selection/src/traits/coherence.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,8 @@ fn plug_infer_with_placeholders<'tcx>(
477477
if ty.is_ty_var() {
478478
let Ok(InferOk { value: (), obligations }) =
479479
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
480-
DefineOpaqueTypes::No,
480+
// Comparing against a type variable never registers hidden types anyway
481+
DefineOpaqueTypes::Yes,
481482
ty,
482483
Ty::new_placeholder(
483484
self.infcx.tcx,
@@ -504,7 +505,9 @@ fn plug_infer_with_placeholders<'tcx>(
504505
if ct.is_ct_infer() {
505506
let Ok(InferOk { value: (), obligations }) =
506507
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
507-
DefineOpaqueTypes::No,
508+
// The types of the constants are the same, so there is no hidden type
509+
// registration happening anyway.
510+
DefineOpaqueTypes::Yes,
508511
ct,
509512
ty::Const::new_placeholder(
510513
self.infcx.tcx,
@@ -532,7 +535,8 @@ fn plug_infer_with_placeholders<'tcx>(
532535
if r.is_var() {
533536
let Ok(InferOk { value: (), obligations }) =
534537
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
535-
DefineOpaqueTypes::No,
538+
// Lifetimes don't contain opaque types (or any types for that matter).
539+
DefineOpaqueTypes::Yes,
536540
r,
537541
ty::Region::new_placeholder(
538542
self.infcx.tcx,

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -3842,7 +3842,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
38423842
self.probe(|_| {
38433843
match self
38443844
.at(&ObligationCause::misc(expr.span, body_id), param_env)
3845-
.eq(DefineOpaqueTypes::No, expected, actual)
3845+
// Doesn't actually matter if we define opaque types here, this is just used for
3846+
// diagnostics, and the result is never kept around.
3847+
.eq(DefineOpaqueTypes::Yes, expected, actual)
38463848
{
38473849
Ok(_) => (), // We ignore nested obligations here for now.
38483850
Err(err) => type_diffs.push(err),

compiler/rustc_trait_selection/src/traits/fulfill.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
429429
// as the cause of an overflow.
430430
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
431431
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
432-
DefineOpaqueTypes::No,
432+
// Only really excercised by generic_const_exprs
433+
DefineOpaqueTypes::Yes,
433434
ct.ty(),
434435
ty,
435436
) {
@@ -571,7 +572,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
571572
if let Ok(new_obligations) = infcx
572573
.at(&obligation.cause, obligation.param_env)
573574
.trace(c1, c2)
574-
.eq(DefineOpaqueTypes::No, a.args, b.args)
575+
// Can define opaque types as this is only reachable with
576+
// `generic_const_exprs`
577+
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
575578
{
576579
return ProcessResult::Changed(mk_pending(
577580
new_obligations.into_obligations(),
@@ -582,7 +585,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
582585
(_, _) => {
583586
if let Ok(new_obligations) = infcx
584587
.at(&obligation.cause, obligation.param_env)
585-
.eq(DefineOpaqueTypes::No, c1, c2)
588+
// Can define opaque types as this is only reachable with
589+
// `generic_const_exprs`
590+
.eq(DefineOpaqueTypes::Yes, c1, c2)
586591
{
587592
return ProcessResult::Changed(mk_pending(
588593
new_obligations.into_obligations(),
@@ -623,7 +628,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
623628
match (evaluate(c1), evaluate(c2)) {
624629
(Ok(c1), Ok(c2)) => {
625630
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
626-
DefineOpaqueTypes::No,
631+
// Can define opaque types as this is only reachable with
632+
// `generic_const_exprs`
633+
DefineOpaqueTypes::Yes,
627634
c1,
628635
c2,
629636
) {

compiler/rustc_trait_selection/src/traits/select/mod.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
906906
.infcx
907907
.at(&obligation.cause, obligation.param_env)
908908
.trace(c1, c2)
909-
.eq(DefineOpaqueTypes::No, a.args, b.args)
909+
// Can define opaque types as this is only reachable with
910+
// `generic_const_exprs`
911+
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
910912
{
911913
return self.evaluate_predicates_recursively(
912914
previous_stack,
@@ -919,7 +921,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
919921
if let Ok(InferOk { obligations, value: () }) = self
920922
.infcx
921923
.at(&obligation.cause, obligation.param_env)
922-
.eq(DefineOpaqueTypes::No, c1, c2)
924+
// Can define opaque types as this is only reachable with
925+
// `generic_const_exprs`
926+
.eq(DefineOpaqueTypes::Yes, c1, c2)
923927
{
924928
return self.evaluate_predicates_recursively(
925929
previous_stack,
@@ -949,7 +953,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
949953
match (evaluate(c1), evaluate(c2)) {
950954
(Ok(c1), Ok(c2)) => {
951955
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
952-
DefineOpaqueTypes::No,
956+
// Can define opaque types as this is only reachable with
957+
// `generic_const_exprs`
958+
DefineOpaqueTypes::Yes,
953959
c1,
954960
c2,
955961
) {
@@ -982,7 +988,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
982988
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
983989
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
984990
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
985-
DefineOpaqueTypes::No,
991+
// Only really excercised by generic_const_exprs
992+
DefineOpaqueTypes::Yes,
986993
ct.ty(),
987994
ty,
988995
) {

compiler/rustc_trait_selection/src/traits/specialize/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,12 @@ fn fulfill_implication<'tcx>(
247247
// do the impls unify? If not, no specialization.
248248
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
249249
.at(&ObligationCause::dummy(), param_env)
250-
.eq(DefineOpaqueTypes::No, source_trait, target_trait)
250+
// Ok to use `Yes`, as all the generic params are already replaced by inference variables,
251+
// which will match the opaque type no matter if it is defining or not.
252+
// Any concrete type that would match the opaque would already be handled by coherence rules,
253+
// and thus either be ok to match here and already have errored, or it won't match, in which
254+
// case there is no issue anyway.
255+
.eq(DefineOpaqueTypes::Yes, source_trait, target_trait)
251256
else {
252257
debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait);
253258
return Err(());

src/librustdoc/clean/blanket_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
4747
// Require the type the impl is implemented on to match
4848
// our type, and ignore the impl if there was a mismatch.
4949
let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq(
50-
DefineOpaqueTypes::No,
50+
DefineOpaqueTypes::Yes,
5151
impl_trait_ref.self_ty(),
5252
impl_ty,
5353
) else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(generic_const_exprs, type_alias_impl_trait)]
2+
#![allow(incomplete_features)]
3+
4+
type Foo = impl Sized;
5+
6+
fn with_bound<const N: usize>() -> Foo
7+
where
8+
[u8; (N / 2) as usize]: Sized,
9+
{
10+
let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
11+
//~^ ERROR mismatched types
12+
//~| ERROR non-primitive cast: `usize` as `Foo`
13+
todo!()
14+
}
15+
16+
fn main() {
17+
with_bound::<4>();
18+
}

0 commit comments

Comments
 (0)