1use tracing::{debug, instrument};
2
3use self::combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys};
4use crate::data_structures::DelayedSet;
5use crate::relate::combine::combine_ty_args;
6pub use crate::relate::*;
7use crate::solve::{Goal, VisibleForLeakCheck};
8use crate::{self as ty, InferCtxtLike, Interner, Region};
9
10pub trait RelateExt: InferCtxtLike {
11 fn relate<T: Relate<Self::Interner>>(
12 &self,
13 param_env: <Self::Interner as Interner>::ParamEnv,
14 lhs: T,
15 variance: ty::Variance,
16 rhs: T,
17 span: <Self::Interner as Interner>::Span,
18 ) -> Result<
19 Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
20 TypeError<Self::Interner>,
21 >;
22}
23
24impl<Infcx: InferCtxtLike> RelateExt for Infcx {
25 fn relate<T: Relate<Self::Interner>>(
26 &self,
27 param_env: <Self::Interner as Interner>::ParamEnv,
28 lhs: T,
29 variance: ty::Variance,
30 rhs: T,
31 span: <Self::Interner as Interner>::Span,
32 ) -> Result<
33 Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
34 TypeError<Self::Interner>,
35 > {
36 let mut relate = SolverRelating::new(self, variance, param_env, span);
37 relate.relate(lhs, rhs)?;
38 Ok(relate.goals)
39 }
40}
41
42pub struct SolverRelating<'infcx, Infcx, I: Interner> {
44 infcx: &'infcx Infcx,
45 param_env: I::ParamEnv,
47 span: I::Span,
48 ambient_variance: ty::Variance,
50 goals: Vec<Goal<I, I::Predicate>>,
51 cache: DelayedSet<(ty::Variance, I::Ty, I::Ty)>,
74}
75
76impl<'infcx, Infcx, I> SolverRelating<'infcx, Infcx, I>
77where
78 Infcx: InferCtxtLike<Interner = I>,
79 I: Interner,
80{
81 pub fn new(
82 infcx: &'infcx Infcx,
83 ambient_variance: ty::Variance,
84 param_env: I::ParamEnv,
85 span: I::Span,
86 ) -> Self {
87 SolverRelating {
88 infcx,
89 span,
90 ambient_variance,
91 param_env,
92 goals: ::alloc::vec::Vec::new()vec![],
93 cache: Default::default(),
94 }
95 }
96}
97
98impl<Infcx, I> TypeRelation<I> for SolverRelating<'_, Infcx, I>
99where
100 Infcx: InferCtxtLike<Interner = I>,
101 I: Interner,
102{
103 fn cx(&self) -> I {
104 self.infcx.cx()
105 }
106
107 fn relate_ty_args(
108 &mut self,
109 a_ty: I::Ty,
110 b_ty: I::Ty,
111 def_id: I::DefId,
112 a_args: I::GenericArgs,
113 b_args: I::GenericArgs,
114 _: impl FnOnce(I::GenericArgs) -> I::Ty,
115 ) -> RelateResult<I, I::Ty> {
116 if self.ambient_variance == ty::Invariant {
117 relate_args_invariantly(self, a_args, b_args)?;
121 Ok(a_ty)
122 } else {
123 let variances = self.cx().variances_of(def_id);
124 combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, |_| a_ty)
125 }
126 }
127
128 fn relate_with_variance<T: Relate<I>>(
129 &mut self,
130 variance: ty::Variance,
131 _info: VarianceDiagInfo<I>,
132 a: T,
133 b: T,
134 ) -> RelateResult<I, T> {
135 let old_ambient_variance = self.ambient_variance;
136 self.ambient_variance = self.ambient_variance.xform(variance);
137 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/relate/solver_relating.rs:137",
"rustc_type_ir::relate::solver_relating",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/relate/solver_relating.rs"),
::tracing_core::__macro_support::Option::Some(137u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::relate::solver_relating"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("self.ambient_variance")
}> =
::tracing::__macro_support::FieldName::new("self.ambient_variance");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("new ambient variance")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&self.ambient_variance)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?self.ambient_variance, "new ambient variance");
138
139 let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) };
140
141 self.ambient_variance = old_ambient_variance;
142 r
143 }
144
145 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("tys",
"rustc_type_ir::relate::solver_relating",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/relate/solver_relating.rs"),
::tracing_core::__macro_support::Option::Some(145u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::relate::solver_relating"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("a")
}> =
::tracing::__macro_support::FieldName::new("a");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("b")
}> =
::tracing::__macro_support::FieldName::new("b");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<I, I::Ty> = loop {};
return __tracing_attr_fake_return;
}
{
if a == b { return Ok(a); }
let infcx = self.infcx;
let a = infcx.shallow_resolve(a);
let b = infcx.shallow_resolve(b);
if self.cache.contains(&(self.ambient_variance, a, b)) {
return Ok(a);
}
match (a.kind(), b.kind()) {
(ty::Infer(ty::TyVar(a_id)), ty::Infer(ty::TyVar(b_id))) => {
match self.ambient_variance {
ty::Covariant => {
self.goals.push(Goal::new(self.cx(), self.param_env,
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: true,
a,
b,
}))));
}
ty::Contravariant => {
self.goals.push(Goal::new(self.cx(), self.param_env,
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: false,
a: b,
b: a,
}))));
}
ty::Invariant => { infcx.equate_ty_vids_raw(a_id, b_id); }
ty::Bivariant => {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}
}
}
}
(ty::Alias(ty::IsRigid::No, alias), _) if
infcx.next_trait_solver() => {
let new_var = infcx.next_ty_infer();
self.goals.push(Goal::new(self.cx(), self.param_env,
ty::ProjectionPredicate {
projection_term: alias.into(),
term: new_var.into(),
}));
self.tys(new_var, b)?;
}
(_, ty::Alias(ty::IsRigid::No, alias)) if
infcx.next_trait_solver() => {
let new_var = infcx.next_ty_infer();
self.goals.push(Goal::new(self.cx(), self.param_env,
ty::ProjectionPredicate {
projection_term: alias.into(),
term: new_var.into(),
}));
self.tys(a, new_var)?;
}
(ty::Infer(ty::TyVar(a_vid)), _) => {
infcx.instantiate_ty_var(self, true, a_vid,
self.ambient_variance, b)?;
}
(_, ty::Infer(ty::TyVar(b_vid))) => {
infcx.instantiate_ty_var(self, false, b_vid,
self.ambient_variance.xform(ty::Contravariant), a)?;
}
_ => { super_combine_tys(self.infcx, self, a, b)?; }
}
if !self.cache.insert((self.ambient_variance, a, b)) {
::core::panicking::panic("assertion failed: self.cache.insert((self.ambient_variance, a, b))")
};
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
146 fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty> {
147 if a == b {
148 return Ok(a);
149 }
150
151 let infcx = self.infcx;
152 let a = infcx.shallow_resolve(a);
153 let b = infcx.shallow_resolve(b);
154
155 if self.cache.contains(&(self.ambient_variance, a, b)) {
156 return Ok(a);
157 }
158
159 match (a.kind(), b.kind()) {
160 (ty::Infer(ty::TyVar(a_id)), ty::Infer(ty::TyVar(b_id))) => {
161 match self.ambient_variance {
162 ty::Covariant => {
163 self.goals.push(Goal::new(
166 self.cx(),
167 self.param_env,
168 ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
169 a_is_expected: true,
170 a,
171 b,
172 })),
173 ));
174 }
175 ty::Contravariant => {
176 self.goals.push(Goal::new(
179 self.cx(),
180 self.param_env,
181 ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
182 a_is_expected: false,
183 a: b,
184 b: a,
185 })),
186 ));
187 }
188 ty::Invariant => {
189 infcx.equate_ty_vids_raw(a_id, b_id);
190 }
191 ty::Bivariant => {
192 unreachable!("Expected bivariance to be handled in relate_with_variance")
193 }
194 }
195 }
196
197 (ty::Alias(ty::IsRigid::No, alias), _) if infcx.next_trait_solver() => {
198 let new_var = infcx.next_ty_infer();
199 self.goals.push(Goal::new(
200 self.cx(),
201 self.param_env,
202 ty::ProjectionPredicate { projection_term: alias.into(), term: new_var.into() },
203 ));
204 self.tys(new_var, b)?;
205 }
206 (_, ty::Alias(ty::IsRigid::No, alias)) if infcx.next_trait_solver() => {
207 let new_var = infcx.next_ty_infer();
208 self.goals.push(Goal::new(
209 self.cx(),
210 self.param_env,
211 ty::ProjectionPredicate { projection_term: alias.into(), term: new_var.into() },
212 ));
213 self.tys(a, new_var)?;
214 }
215
216 (ty::Infer(ty::TyVar(a_vid)), _) => {
217 infcx.instantiate_ty_var(self, true, a_vid, self.ambient_variance, b)?;
218 }
219 (_, ty::Infer(ty::TyVar(b_vid))) => {
220 infcx.instantiate_ty_var(
221 self,
222 false,
223 b_vid,
224 self.ambient_variance.xform(ty::Contravariant),
225 a,
226 )?;
227 }
228
229 _ => {
230 super_combine_tys(self.infcx, self, a, b)?;
231 }
232 }
233
234 assert!(self.cache.insert((self.ambient_variance, a, b)));
235
236 Ok(a)
237 }
238
239 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("regions",
"rustc_type_ir::relate::solver_relating",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/relate/solver_relating.rs"),
::tracing_core::__macro_support::Option::Some(239u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::relate::solver_relating"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("a")
}> =
::tracing::__macro_support::FieldName::new("a");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("b")
}> =
::tracing::__macro_support::FieldName::new("b");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<I, Region<I>> =
loop {};
return __tracing_attr_fake_return;
}
{
match self.ambient_variance {
ty::Covariant =>
self.infcx.sub_regions(b, a, VisibleForLeakCheck::Yes,
self.span),
ty::Contravariant =>
self.infcx.sub_regions(a, b, VisibleForLeakCheck::Yes,
self.span),
ty::Invariant =>
self.infcx.equate_regions(a, b, VisibleForLeakCheck::Yes,
self.span),
ty::Bivariant => {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}
}
}
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
240 fn regions(&mut self, a: Region<I>, b: Region<I>) -> RelateResult<I, Region<I>> {
241 match self.ambient_variance {
242 ty::Covariant => self.infcx.sub_regions(b, a, VisibleForLeakCheck::Yes, self.span),
244 ty::Contravariant => self.infcx.sub_regions(a, b, VisibleForLeakCheck::Yes, self.span),
246 ty::Invariant => self.infcx.equate_regions(a, b, VisibleForLeakCheck::Yes, self.span),
247 ty::Bivariant => {
248 unreachable!("Expected bivariance to be handled in relate_with_variance")
249 }
250 }
251
252 Ok(a)
253 }
254
255 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("consts",
"rustc_type_ir::relate::solver_relating",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/relate/solver_relating.rs"),
::tracing_core::__macro_support::Option::Some(255u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::relate::solver_relating"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("a")
}> =
::tracing::__macro_support::FieldName::new("a");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("b")
}> =
::tracing::__macro_support::FieldName::new("b");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<I, I::Const> =
loop {};
return __tracing_attr_fake_return;
}
{ super_combine_consts(self.infcx, self, a, b) }
}
}#[instrument(skip(self), level = "trace")]
256 fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const> {
257 super_combine_consts(self.infcx, self, a, b)
258 }
259
260 fn binders<T>(
261 &mut self,
262 a: ty::Binder<I, T>,
263 b: ty::Binder<I, T>,
264 ) -> RelateResult<I, ty::Binder<I, T>>
265 where
266 T: Relate<I>,
267 {
268 if a == b {
270 return Ok(a);
271 }
272
273 if let Some(a_inner) = a.no_bound_vars()
275 && let Some(b_inner) = b.no_bound_vars()
276 {
277 self.relate(a_inner, b_inner)?;
278 return Ok(a);
279 }
280
281 match self.ambient_variance {
282 ty::Covariant => {
298 self.infcx.enter_forall_with_empty_assumptions(b, |b| {
299 let a = self.infcx.instantiate_binder_with_infer(a);
300 self.relate(a, b)
301 })?;
302 }
303 ty::Contravariant => {
304 self.infcx.enter_forall_with_empty_assumptions(a, |a| {
305 let b = self.infcx.instantiate_binder_with_infer(b);
306 self.relate(a, b)
307 })?;
308 }
309
310 ty::Invariant => {
321 self.infcx.enter_forall_with_empty_assumptions(b, |b| {
322 let a = self.infcx.instantiate_binder_with_infer(a);
323 self.relate(a, b)
324 })?;
325
326 self.infcx.enter_forall_with_empty_assumptions(a, |a| {
328 let b = self.infcx.instantiate_binder_with_infer(b);
329 self.relate(a, b)
330 })?;
331 }
332 ty::Bivariant => {
333 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}unreachable!("Expected bivariance to be handled in relate_with_variance")
334 }
335 }
336 Ok(a)
337 }
338}
339
340impl<Infcx, I> PredicateEmittingRelation<Infcx> for SolverRelating<'_, Infcx, I>
341where
342 Infcx: InferCtxtLike<Interner = I>,
343 I: Interner,
344{
345 fn span(&self) -> I::Span {
346 Span::dummy()
347 }
348
349 fn param_env(&self) -> I::ParamEnv {
350 self.param_env
351 }
352
353 fn register_predicates(
354 &mut self,
355 obligations: impl IntoIterator<Item: ty::Upcast<I, I::Predicate>>,
356 ) {
357 self.goals.extend(
358 obligations.into_iter().map(|pred| Goal::new(self.infcx.cx(), self.param_env, pred)),
359 );
360 }
361
362 fn register_goals(&mut self, obligations: impl IntoIterator<Item = Goal<I, I::Predicate>>) {
363 self.goals.extend(obligations);
364 }
365}