Skip to content

Commit f0205d5

Browse files
authored
Rollup merge of rust-lang#109166 - lcnr:define_opaque_types-explicit, r=oli-obk
make `define_opaque_types` fully explicit based on the idea of rust-lang#108389. Moved `define_opaque_types` into the actual operations, e.g. `eq`, instead of `infcx.at` because normalization doesn't use `define_opaque_types` and even creates it's own `At` with a different `define_opaque_types` internally. Somewhat surprisingly, coherence actually relies on `DefineOpaqueTypes::Yes` for soundness which was revealed because I've incorrectly used `DefineOpaqueTypes::No` in `equate_impl_headers`. It feels concerning that even though this is the case, we still sometimes use `DefineOpaqueTypes::No` in coherence. I did not look into this as part of this PR as it is purely changing the structure of the code without changing behavior in any way. r? ```@oli-obk```
2 parents 36b8237 + d2b7604 commit f0205d5

File tree

33 files changed

+307
-224
lines changed

33 files changed

+307
-224
lines changed

Diff for: compiler/rustc_hir_analysis/src/coherence/builtin.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
99
use rustc_hir::lang_items::LangItem;
1010
use rustc_hir::ItemKind;
1111
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
12-
use rustc_infer::infer::TyCtxtInferExt;
1312
use rustc_infer::infer::{self, RegionResolutionError};
13+
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
1414
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
1515
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
1616
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
@@ -235,7 +235,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
235235
use rustc_type_ir::sty::TyKind::*;
236236
match (source.kind(), target.kind()) {
237237
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b))
238-
if infcx.at(&cause, param_env).eq(r_a, *r_b).is_ok() && mutbl_a == *mutbl_b => {}
238+
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
239+
&& mutbl_a == *mutbl_b => {}
239240
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
240241
(&Adt(def_a, substs_a), &Adt(def_b, substs_b))
241242
if def_a.is_struct() && def_b.is_struct() =>
@@ -278,7 +279,9 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
278279
}
279280
}
280281

281-
if let Ok(ok) = infcx.at(&cause, param_env).eq(ty_a, ty_b) {
282+
if let Ok(ok) =
283+
infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b)
284+
{
282285
if ok.obligations.is_empty() {
283286
create_err(
284287
"the trait `DispatchFromDyn` may only be implemented \
@@ -504,7 +507,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
504507
// we may have to evaluate constraint
505508
// expressions in the course of execution.)
506509
// See e.g., #41936.
507-
if let Ok(ok) = infcx.at(&cause, param_env).eq(a, b) {
510+
if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) {
508511
if ok.obligations.is_empty() {
509512
return None;
510513
}

Diff for: compiler/rustc_hir_analysis/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ use rustc_errors::ErrorGuaranteed;
102102
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
103103
use rustc_hir as hir;
104104
use rustc_hir::Node;
105-
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
105+
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
106106
use rustc_macros::fluent_messages;
107107
use rustc_middle::middle;
108108
use rustc_middle::ty::query::Providers;
@@ -165,7 +165,7 @@ fn require_same_types<'tcx>(
165165
) -> bool {
166166
let infcx = &tcx.infer_ctxt().build();
167167
let param_env = ty::ParamEnv::empty();
168-
let errors = match infcx.at(cause, param_env).eq(expected, actual) {
168+
let errors = match infcx.at(cause, param_env).eq(DefineOpaqueTypes::No, expected, actual) {
169169
Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
170170
Err(err) => {
171171
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();

Diff for: compiler/rustc_hir_typeck/src/closure.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir as hir;
88
use rustc_hir::lang_items::LangItem;
99
use rustc_hir_analysis::astconv::AstConv;
1010
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
11-
use rustc_infer::infer::LateBoundRegionConversionTime;
11+
use rustc_infer::infer::{DefineOpaqueTypes, LateBoundRegionConversionTime};
1212
use rustc_infer::infer::{InferOk, InferResult};
1313
use rustc_macros::{TypeFoldable, TypeVisitable};
1414
use rustc_middle::ty::subst::InternalSubsts;
@@ -563,10 +563,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
563563
) {
564564
// Check that E' = S'.
565565
let cause = self.misc(hir_ty.span);
566-
let InferOk { value: (), obligations } = self
567-
.at(&cause, self.param_env)
568-
.define_opaque_types(true)
569-
.eq(*expected_ty, supplied_ty)?;
566+
let InferOk { value: (), obligations } = self.at(&cause, self.param_env).eq(
567+
DefineOpaqueTypes::Yes,
568+
*expected_ty,
569+
supplied_ty,
570+
)?;
570571
all_obligations.extend(obligations);
571572
}
572573

@@ -576,10 +577,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
576577
supplied_sig.output(),
577578
);
578579
let cause = &self.misc(decl.output.span());
579-
let InferOk { value: (), obligations } = self
580-
.at(cause, self.param_env)
581-
.define_opaque_types(true)
582-
.eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
580+
let InferOk { value: (), obligations } = self.at(cause, self.param_env).eq(
581+
DefineOpaqueTypes::Yes,
582+
expected_sigs.liberated_sig.output(),
583+
supplied_output_ty,
584+
)?;
583585
all_obligations.extend(obligations);
584586

585587
let inputs = inputs.into_iter().map(|ty| self.resolve_vars_if_possible(ty));

Diff for: compiler/rustc_hir_typeck/src/coercion.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc_hir::intravisit::{self, Visitor};
4545
use rustc_hir::Expr;
4646
use rustc_hir_analysis::astconv::AstConv;
4747
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
48-
use rustc_infer::infer::{Coercion, InferOk, InferResult};
48+
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
4949
use rustc_infer::traits::Obligation;
5050
use rustc_middle::lint::in_external_macro;
5151
use rustc_middle::ty::adjustment::{
@@ -143,11 +143,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
143143
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
144144
debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
145145
self.commit_if_ok(|_| {
146-
let at = self.at(&self.cause, self.fcx.param_env).define_opaque_types(true);
146+
let at = self.at(&self.cause, self.fcx.param_env);
147147
if self.use_lub {
148-
at.lub(b, a)
148+
at.lub(DefineOpaqueTypes::Yes, b, a)
149149
} else {
150-
at.sup(b, a)
150+
at.sup(DefineOpaqueTypes::Yes, b, a)
151151
.map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
152152
}
153153
})
@@ -175,7 +175,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
175175
// so this will have the side-effect of making sure we have no ambiguities
176176
// due to `[type error]` and `_` not coercing together.
177177
let _ = self.commit_if_ok(|_| {
178-
self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b)
178+
self.at(&self.cause, self.param_env).eq(DefineOpaqueTypes::Yes, a, b)
179179
});
180180
return success(vec![], self.fcx.tcx.ty_error(guar), vec![]);
181181
}
@@ -1101,9 +1101,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11011101
(ty::FnDef(..), ty::FnDef(..)) => {
11021102
// Don't reify if the function types have a LUB, i.e., they
11031103
// are the same function and their parameters have a LUB.
1104-
match self
1105-
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
1106-
{
1104+
match self.commit_if_ok(|_| {
1105+
self.at(cause, self.param_env).lub(
1106+
DefineOpaqueTypes::No,
1107+
prev_ty,
1108+
new_ty,
1109+
)
1110+
}) {
11071111
// We have a LUB of prev_ty and new_ty, just return it.
11081112
Ok(ok) => return Ok(self.register_infer_ok_obligations(ok)),
11091113
Err(_) => {
@@ -1153,7 +1157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11531157
let sig = self
11541158
.at(cause, self.param_env)
11551159
.trace(prev_ty, new_ty)
1156-
.lub(a_sig, b_sig)
1160+
.lub(DefineOpaqueTypes::No, a_sig, b_sig)
11571161
.map(|ok| self.register_infer_ok_obligations(ok))?;
11581162

11591163
// Reify both sides and return the reified fn pointer type.
@@ -1237,7 +1241,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12371241
);
12381242

12391243
return self
1240-
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
1244+
.commit_if_ok(|_| {
1245+
self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
1246+
})
12411247
.map(|ok| self.register_infer_ok_obligations(ok));
12421248
}
12431249
}
@@ -1248,8 +1254,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12481254
if let Some(e) = first_error {
12491255
Err(e)
12501256
} else {
1251-
self.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
1252-
.map(|ok| self.register_infer_ok_obligations(ok))
1257+
self.commit_if_ok(|_| {
1258+
self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
1259+
})
1260+
.map(|ok| self.register_infer_ok_obligations(ok))
12531261
}
12541262
}
12551263
Ok(ok) => {
@@ -1487,8 +1495,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
14871495
assert!(expression_ty.is_unit(), "if let hack without unit type");
14881496
fcx.at(cause, fcx.param_env)
14891497
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
1490-
.define_opaque_types(true)
1491-
.eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
1498+
.eq_exp(
1499+
DefineOpaqueTypes::Yes,
1500+
label_expression_as_expected,
1501+
expression_ty,
1502+
self.merged_ty(),
1503+
)
14921504
.map(|infer_ok| {
14931505
fcx.register_infer_ok_obligations(infer_ok);
14941506
expression_ty

Diff for: compiler/rustc_hir_typeck/src/demand.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::def::CtorKind;
88
use rustc_hir::intravisit::Visitor;
99
use rustc_hir::lang_items::LangItem;
1010
use rustc_hir::{is_range_literal, Node};
11-
use rustc_infer::infer::InferOk;
11+
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
1212
use rustc_middle::lint::in_external_macro;
1313
use rustc_middle::middle::stability::EvalResult;
1414
use rustc_middle::ty::adjustment::AllowTwoPhase;
@@ -113,7 +113,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
113113
expected: Ty<'tcx>,
114114
actual: Ty<'tcx>,
115115
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
116-
match self.at(cause, self.param_env).define_opaque_types(true).sup(expected, actual) {
116+
match self.at(cause, self.param_env).sup(DefineOpaqueTypes::Yes, expected, actual) {
117117
Ok(InferOk { obligations, value: () }) => {
118118
self.register_predicates(obligations);
119119
None
@@ -143,7 +143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
143143
expected: Ty<'tcx>,
144144
actual: Ty<'tcx>,
145145
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
146-
match self.at(cause, self.param_env).define_opaque_types(true).eq(expected, actual) {
146+
match self.at(cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, actual) {
147147
Ok(InferOk { obligations, value: () }) => {
148148
self.register_predicates(obligations);
149149
None

Diff for: compiler/rustc_hir_typeck/src/expr.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use rustc_hir_analysis::astconv::AstConv as _;
3636
use rustc_hir_analysis::check::ty_kind_suggestion;
3737
use rustc_infer::infer;
3838
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
39+
use rustc_infer::infer::DefineOpaqueTypes;
3940
use rustc_infer::infer::InferOk;
4041
use rustc_infer::traits::ObligationCause;
4142
use rustc_middle::middle::stability;
@@ -1683,7 +1684,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16831684
if let Some(_) = remaining_fields.remove(&ident) {
16841685
let target_ty = self.field_ty(base_expr.span, f, substs);
16851686
let cause = self.misc(base_expr.span);
1686-
match self.at(&cause, self.param_env).sup(target_ty, fru_ty) {
1687+
match self.at(&cause, self.param_env).sup(
1688+
DefineOpaqueTypes::No,
1689+
target_ty,
1690+
fru_ty,
1691+
) {
16871692
Ok(InferOk { obligations, value: () }) => {
16881693
self.register_predicates(obligations)
16891694
}

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_hir_analysis::astconv::{
1919
};
2020
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
2121
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
22-
use rustc_infer::infer::InferResult;
22+
use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
2323
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
2424
use rustc_middle::ty::error::TypeError;
2525
use rustc_middle::ty::fold::TypeFoldable;
@@ -558,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
558558
let span = self.tcx.hir().body(body_id).value.span;
559559
let ok = self
560560
.at(&self.misc(span), self.param_env)
561-
.eq(interior, witness)
561+
.eq(DefineOpaqueTypes::No, interior, witness)
562562
.expect("Failed to unify generator interior type");
563563
let mut obligations = ok.obligations;
564564

@@ -1341,7 +1341,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13411341
// This also occurs for an enum variant on a type alias.
13421342
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).subst(tcx, substs));
13431343
let self_ty = self.normalize(span, self_ty);
1344-
match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) {
1344+
match self.at(&self.misc(span), self.param_env).eq(
1345+
DefineOpaqueTypes::No,
1346+
impl_ty,
1347+
self_ty,
1348+
) {
13451349
Ok(ok) => self.register_infer_ok_obligations(ok),
13461350
Err(_) => {
13471351
self.tcx.sess.delay_span_bug(

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use rustc_hir_analysis::structured_errors::StructuredDiagnostic;
2424
use rustc_index::vec::IndexVec;
2525
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
2626
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
27-
use rustc_infer::infer::InferOk;
2827
use rustc_infer::infer::TypeTrace;
28+
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
2929
use rustc_middle::ty::adjustment::AllowTwoPhase;
3030
use rustc_middle::ty::visit::TypeVisitableExt;
3131
use rustc_middle::ty::{self, IsSuggestable, Ty};
@@ -301,9 +301,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
301301

302302
// 3. Check if the formal type is a supertype of the checked one
303303
// and register any such obligations for future type checks
304-
let supertype_error = self
305-
.at(&self.misc(provided_arg.span), self.param_env)
306-
.sup(formal_input_ty, coerced_ty);
304+
let supertype_error = self.at(&self.misc(provided_arg.span), self.param_env).sup(
305+
DefineOpaqueTypes::No,
306+
formal_input_ty,
307+
coerced_ty,
308+
);
307309
let subtyping_error = match supertype_error {
308310
Ok(InferOk { obligations, value: () }) => {
309311
self.register_predicates(obligations);
@@ -585,7 +587,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
585587

586588
// Using probe here, since we don't want this subtyping to affect inference.
587589
let subtyping_error = self.probe(|_| {
588-
self.at(&self.misc(arg_span), self.param_env).sup(formal_input_ty, coerced_ty).err()
590+
self.at(&self.misc(arg_span), self.param_env)
591+
.sup(DefineOpaqueTypes::No, formal_input_ty, coerced_ty)
592+
.err()
589593
});
590594

591595
// Same as above: if either the coerce type or the checked type is an error type,

Diff for: compiler/rustc_hir_typeck/src/generator_interior/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::def_id::DefId;
1313
use rustc_hir::hir_id::HirIdSet;
1414
use rustc_hir::intravisit::{self, Visitor};
1515
use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind};
16-
use rustc_infer::infer::RegionVariableOrigin;
16+
use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin};
1717
use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
1818
use rustc_middle::ty::fold::FnMutDelegate;
1919
use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitableExt};
@@ -327,7 +327,11 @@ pub fn resolve_interior<'a, 'tcx>(
327327
);
328328

329329
// Unify the type variable inside the generator with the new witness
330-
match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(interior, witness) {
330+
match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(
331+
DefineOpaqueTypes::No,
332+
interior,
333+
witness,
334+
) {
331335
Ok(ok) => fcx.register_infer_ok_obligations(ok),
332336
_ => bug!("failed to relate {interior} and {witness}"),
333337
}

Diff for: compiler/rustc_hir_typeck/src/method/confirm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir_analysis::astconv::generics::{
88
check_generic_arg_count_for_call, create_substs_for_generic_args,
99
};
1010
use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall};
11-
use rustc_infer::infer::{self, InferOk};
11+
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
1212
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
1313
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
1414
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -478,7 +478,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
478478
substs,
479479
})),
480480
);
481-
match self.at(&cause, self.param_env).sup(method_self_ty, self_ty) {
481+
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) {
482482
Ok(InferOk { obligations, value: () }) => {
483483
self.register_predicates(obligations);
484484
}

0 commit comments

Comments
 (0)