Skip to content

Commit 9f8c5ca

Browse files
Try not to make obligations in handle_opaque_type
1 parent a80542c commit 9f8c5ca

File tree

6 files changed

+76
-91
lines changed

6 files changed

+76
-91
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
154154
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
155155
),
156156
};
157-
let cause = ObligationCause::dummy_with_span(self.span());
158-
self.register_goals(
159-
infcx
160-
.handle_opaque_type(a, b, &cause, self.param_env())?
161-
.obligations
162-
.into_iter()
163-
.map(Goal::from),
164-
);
157+
self.register_goals(infcx.handle_opaque_type(a, b, self.span(), self.param_env())?);
165158
Ok(())
166159
}
167160

compiler/rustc_infer/src/infer/opaque_types/mod.rs

+55-54
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
use super::{DefineOpaqueTypes, InferResult};
21
use crate::errors::OpaqueHiddenTypeDiag;
32
use crate::infer::{InferCtxt, InferOk};
4-
use crate::traits::{self, PredicateObligation};
3+
use crate::traits::{self, Obligation};
54
use hir::def_id::{DefId, LocalDefId};
65
use rustc_data_structures::fx::FxIndexMap;
76
use rustc_data_structures::sync::Lrc;
87
use rustc_hir as hir;
8+
use rustc_middle::traits::solve::Goal;
99
use rustc_middle::traits::ObligationCause;
1010
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1111
use rustc_middle::ty::fold::BottomUpFolder;
12+
use rustc_middle::ty::relate::TypeRelation;
1213
use rustc_middle::ty::GenericArgKind;
1314
use rustc_middle::ty::{
1415
self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
@@ -21,6 +22,9 @@ mod table;
2122
pub type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
2223
pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
2324

25+
use super::at::ToTrace;
26+
use super::{CombineFields, DefineOpaqueTypes, StructurallyRelateAliases};
27+
2428
/// Information about the opaque types whose values we
2529
/// are inferring in this function (these are the `impl Trait` that
2630
/// appear in the return type).
@@ -62,11 +66,23 @@ impl<'tcx> InferCtxt<'tcx> {
6266
{
6367
let def_span = self.tcx.def_span(def_id);
6468
let span = if span.contains(def_span) { def_span } else { span };
65-
let code = traits::ObligationCauseCode::OpaqueReturnType(None);
66-
let cause = ObligationCause::new(span, body_id, code);
6769
let ty_var = self.next_ty_var(span);
6870
obligations.extend(
69-
self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations,
71+
self.handle_opaque_type(ty, ty_var, span, param_env)
72+
.unwrap()
73+
.into_iter()
74+
.map(|goal| {
75+
Obligation::new(
76+
self.tcx,
77+
ObligationCause::new(
78+
span,
79+
body_id,
80+
traits::ObligationCauseCode::OpaqueReturnType(None),
81+
),
82+
goal.param_env,
83+
goal.predicate,
84+
)
85+
}),
7086
);
7187
ty_var
7288
}
@@ -80,17 +96,17 @@ impl<'tcx> InferCtxt<'tcx> {
8096
&self,
8197
a: Ty<'tcx>,
8298
b: Ty<'tcx>,
83-
cause: &ObligationCause<'tcx>,
99+
span: Span,
84100
param_env: ty::ParamEnv<'tcx>,
85-
) -> InferResult<'tcx, ()> {
101+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
86102
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
87103
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
88104
let def_id = def_id.expect_local();
89105
if self.intercrate {
90106
// See comment on `insert_hidden_type` for why this is sufficient in coherence
91107
return Some(self.register_hidden_type(
92108
OpaqueTypeKey { def_id, args },
93-
cause.clone(),
109+
span,
94110
param_env,
95111
b,
96112
));
@@ -143,18 +159,13 @@ impl<'tcx> InferCtxt<'tcx> {
143159
&& self.tcx.is_type_alias_impl_trait(b_def_id)
144160
{
145161
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
146-
span: cause.span,
162+
span,
147163
hidden_type: self.tcx.def_span(b_def_id),
148164
opaque_type: self.tcx.def_span(def_id),
149165
});
150166
}
151167
}
152-
Some(self.register_hidden_type(
153-
OpaqueTypeKey { def_id, args },
154-
cause.clone(),
155-
param_env,
156-
b,
157-
))
168+
Some(self.register_hidden_type(OpaqueTypeKey { def_id, args }, span, param_env, b))
158169
}
159170
_ => None,
160171
};
@@ -464,24 +475,23 @@ impl<'tcx> InferCtxt<'tcx> {
464475
fn register_hidden_type(
465476
&self,
466477
opaque_type_key: OpaqueTypeKey<'tcx>,
467-
cause: ObligationCause<'tcx>,
478+
span: Span,
468479
param_env: ty::ParamEnv<'tcx>,
469480
hidden_ty: Ty<'tcx>,
470-
) -> InferResult<'tcx, ()> {
471-
let mut obligations = Vec::new();
481+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
482+
let mut goals = Vec::new();
472483

473-
self.insert_hidden_type(opaque_type_key, &cause, param_env, hidden_ty, &mut obligations)?;
484+
self.insert_hidden_type(opaque_type_key, span, param_env, hidden_ty, &mut goals)?;
474485

475486
self.add_item_bounds_for_hidden_type(
476487
opaque_type_key.def_id.to_def_id(),
477488
opaque_type_key.args,
478-
cause,
479489
param_env,
480490
hidden_ty,
481-
&mut obligations,
491+
&mut goals,
482492
);
483493

484-
Ok(InferOk { value: (), obligations })
494+
Ok(goals)
485495
}
486496

487497
/// Insert a hidden type into the opaque type storage, making sure
@@ -507,38 +517,35 @@ impl<'tcx> InferCtxt<'tcx> {
507517
pub fn insert_hidden_type(
508518
&self,
509519
opaque_type_key: OpaqueTypeKey<'tcx>,
510-
cause: &ObligationCause<'tcx>,
520+
span: Span,
511521
param_env: ty::ParamEnv<'tcx>,
512522
hidden_ty: Ty<'tcx>,
513-
obligations: &mut Vec<PredicateObligation<'tcx>>,
523+
goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
514524
) -> Result<(), TypeError<'tcx>> {
515525
// Ideally, we'd get the span where *this specific `ty` came
516526
// from*, but right now we just use the span from the overall
517527
// value being folded. In simple cases like `-> impl Foo`,
518528
// these are the same span, but not in cases like `-> (impl
519529
// Foo, impl Bar)`.
520-
let span = cause.span;
521530
if self.intercrate {
522531
// During intercrate we do not define opaque types but instead always
523532
// force ambiguity unless the hidden type is known to not implement
524533
// our trait.
525-
obligations.push(traits::Obligation::new(
526-
self.tcx,
527-
cause.clone(),
528-
param_env,
529-
ty::PredicateKind::Ambiguous,
530-
))
534+
goals.push(Goal::new(self.tcx, param_env, ty::PredicateKind::Ambiguous))
531535
} else {
532536
let prev = self
533537
.inner
534538
.borrow_mut()
535539
.opaque_types()
536540
.register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
537541
if let Some(prev) = prev {
538-
obligations.extend(
539-
self.at(cause, param_env)
542+
goals.extend(
543+
self.at(&ObligationCause::dummy_with_span(span), param_env)
540544
.eq(DefineOpaqueTypes::Yes, prev, hidden_ty)?
541-
.obligations,
545+
.obligations
546+
.into_iter()
547+
// FIXME: Shuttling between obligations and goals is awkward.
548+
.map(Goal::from),
542549
);
543550
}
544551
};
@@ -550,10 +557,9 @@ impl<'tcx> InferCtxt<'tcx> {
550557
&self,
551558
def_id: DefId,
552559
args: ty::GenericArgsRef<'tcx>,
553-
cause: ObligationCause<'tcx>,
554560
param_env: ty::ParamEnv<'tcx>,
555561
hidden_ty: Ty<'tcx>,
556-
obligations: &mut Vec<PredicateObligation<'tcx>>,
562+
goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
557563
) {
558564
let tcx = self.tcx;
559565
// Require that the hidden type is well-formed. We have to
@@ -567,12 +573,7 @@ impl<'tcx> InferCtxt<'tcx> {
567573
// type during MIR borrowck, causing us to infer the wrong
568574
// lifetime for its member constraints which then results in
569575
// unexpected region errors.
570-
obligations.push(traits::Obligation::new(
571-
tcx,
572-
cause.clone(),
573-
param_env,
574-
ty::ClauseKind::WellFormed(hidden_ty.into()),
575-
));
576+
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
576577

577578
let item_bounds = tcx.explicit_item_bounds(def_id);
578579
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
@@ -588,13 +589,18 @@ impl<'tcx> InferCtxt<'tcx> {
588589
&& !tcx.is_impl_trait_in_trait(projection_ty.def_id)
589590
&& !self.next_trait_solver() =>
590591
{
591-
self.projection_ty_to_infer(
592+
let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
593+
goals.push(Goal::new(
594+
self.tcx,
592595
param_env,
593-
projection_ty,
594-
cause.clone(),
595-
0,
596-
obligations,
597-
)
596+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(
597+
ty::ProjectionPredicate {
598+
projection_term: projection_ty.into(),
599+
term: ty_var.into(),
600+
},
601+
)),
602+
));
603+
ty_var
598604
}
599605
// Replace all other mentions of the same opaque type with the hidden type,
600606
// as the bounds must hold on the hidden type after all.
@@ -611,12 +617,7 @@ impl<'tcx> InferCtxt<'tcx> {
611617

612618
// Require that the predicate holds for the concrete type.
613619
debug!(?predicate);
614-
obligations.push(traits::Obligation::new(
615-
self.tcx,
616-
cause.clone(),
617-
param_env,
618-
predicate,
619-
));
620+
goals.push(Goal::new(self.tcx, param_env, predicate));
620621
}
621622
}
622623
}

compiler/rustc_infer/src/infer/projection.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ impl<'tcx> InferCtxt<'tcx> {
2121
obligations: &mut Vec<PredicateObligation<'tcx>>,
2222
) -> Ty<'tcx> {
2323
debug_assert!(!self.next_trait_solver());
24-
let def_id = projection_ty.def_id;
25-
let ty_var = self.next_ty_var(self.tcx.def_span(def_id));
26-
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection(
27-
ty::ProjectionPredicate { projection_term: projection_ty.into(), term: ty_var.into() },
28-
)));
24+
let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
25+
let projection =
26+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
27+
projection_term: projection_ty.into(),
28+
term: ty_var.into(),
29+
}));
2930
let obligation =
3031
Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
3132
obligations.push(obligation);

compiler/rustc_infer/src/infer/relate/lattice.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use super::combine::PredicateEmittingRelation;
2121
use crate::infer::{DefineOpaqueTypes, InferCtxt};
2222
use crate::traits::ObligationCause;
2323

24-
use rustc_middle::traits::solve::Goal;
2524
use rustc_middle::ty::relate::RelateResult;
2625
use rustc_middle::ty::TyVar;
2726
use rustc_middle::ty::{self, Ty};
@@ -109,13 +108,7 @@ where
109108
&& def_id.is_local()
110109
&& !this.infcx().next_trait_solver() =>
111110
{
112-
this.register_goals(
113-
infcx
114-
.handle_opaque_type(a, b, this.cause(), this.param_env())?
115-
.obligations
116-
.into_iter()
117-
.map(Goal::from),
118-
);
111+
this.register_goals(infcx.handle_opaque_type(a, b, this.span(), this.param_env())?);
119112
Ok(a)
120113
}
121114

compiler/rustc_infer/src/infer/relate/type_relating.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
150150
&& def_id.is_local()
151151
&& !infcx.next_trait_solver() =>
152152
{
153-
// FIXME: Don't shuttle between Goal and Obligation
154-
self.fields.goals.extend(
155-
infcx
156-
.handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())?
157-
.obligations
158-
.into_iter()
159-
.map(Goal::from),
160-
);
153+
self.fields.goals.extend(infcx.handle_opaque_type(
154+
a,
155+
b,
156+
self.fields.trace.cause.span,
157+
self.param_env(),
158+
)?);
161159
}
162160

163161
_ => {

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

+7-8
Original file line numberDiff line numberDiff line change
@@ -961,15 +961,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
961961
param_env: ty::ParamEnv<'tcx>,
962962
hidden_ty: Ty<'tcx>,
963963
) -> Result<(), NoSolution> {
964-
let mut obligations = Vec::new();
964+
let mut goals = Vec::new();
965965
self.infcx.insert_hidden_type(
966966
opaque_type_key,
967-
&ObligationCause::dummy(),
967+
DUMMY_SP,
968968
param_env,
969969
hidden_ty,
970-
&mut obligations,
970+
&mut goals,
971971
)?;
972-
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
972+
self.add_goals(GoalSource::Misc, goals);
973973
Ok(())
974974
}
975975

@@ -980,16 +980,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
980980
param_env: ty::ParamEnv<'tcx>,
981981
hidden_ty: Ty<'tcx>,
982982
) {
983-
let mut obligations = Vec::new();
983+
let mut goals = Vec::new();
984984
self.infcx.add_item_bounds_for_hidden_type(
985985
opaque_def_id,
986986
opaque_args,
987-
ObligationCause::dummy(),
988987
param_env,
989988
hidden_ty,
990-
&mut obligations,
989+
&mut goals,
991990
);
992-
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
991+
self.add_goals(GoalSource::Misc, goals);
993992
}
994993

995994
// Do something for each opaque/hidden pair defined with `def_id` in the

0 commit comments

Comments
 (0)