Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit be72f25

Browse files
committedMay 26, 2023
Auto merge of rust-lang#111918 - compiler-errors:custom-type-ops-err, r=lcnr
Use `ErrorGuaranteed` more in MIR type ops Delay bugs more eagerly and pass them through type op infra instead of delaying them at all the usage-sites. Follow up to: rust-lang#111741 (comment) r? `@lcnr`
2 parents c86212f + 0a35db5 commit be72f25

File tree

21 files changed

+158
-159
lines changed

21 files changed

+158
-159
lines changed
 

‎compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::fmt;
22

3+
use rustc_errors::ErrorGuaranteed;
34
use rustc_infer::infer::canonical::Canonical;
45
use rustc_middle::mir::ConstraintCategory;
56
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
67
use rustc_span::def_id::DefId;
78
use rustc_span::Span;
89
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
9-
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
1010
use rustc_trait_selection::traits::ObligationCause;
1111

1212
use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
@@ -30,14 +30,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
3030
locations: Locations,
3131
category: ConstraintCategory<'tcx>,
3232
op: Op,
33-
) -> Fallible<R>
33+
) -> Result<R, ErrorGuaranteed>
3434
where
3535
Op: type_op::TypeOp<'tcx, Output = R>,
3636
Op::ErrorInfo: ToUniverseInfo<'tcx>,
3737
{
3838
let old_universe = self.infcx.universe();
3939

40-
let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?;
40+
let TypeOpOutput { output, constraints, error_info } =
41+
op.fully_perform(self.infcx, locations.span(self.body))?;
4142

4243
debug!(?output, ?constraints);
4344

@@ -135,14 +136,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
135136
) {
136137
let param_env = self.param_env;
137138
let predicate = predicate.to_predicate(self.tcx());
138-
self.fully_perform_op(
139+
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
139140
locations,
140141
category,
141142
param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)),
142-
)
143-
.unwrap_or_else(|NoSolution| {
144-
span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
145-
})
143+
);
146144
}
147145

148146
pub(super) fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
@@ -163,15 +161,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
163161
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
164162
{
165163
let param_env = self.param_env;
166-
self.fully_perform_op(
164+
let result: Result<_, ErrorGuaranteed> = self.fully_perform_op(
167165
location.to_locations(),
168166
category,
169167
param_env.and(type_op::normalize::Normalize::new(value)),
170-
)
171-
.unwrap_or_else(|NoSolution| {
172-
span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
173-
value
174-
})
168+
);
169+
result.unwrap_or(value)
175170
}
176171

177172
#[instrument(skip(self), level = "debug")]
@@ -181,18 +176,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
181176
user_ty: ty::UserType<'tcx>,
182177
span: Span,
183178
) {
184-
self.fully_perform_op(
179+
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
185180
Locations::All(span),
186181
ConstraintCategory::Boring,
187182
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(mir_ty, user_ty)),
188-
)
189-
.unwrap_or_else(|err| {
190-
span_mirbug!(
191-
self,
192-
span,
193-
"ascribe_user_type `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`",
194-
);
195-
});
183+
);
196184
}
197185

198186
/// *Incorrectly* skips the WF checks we normally do in `ascribe_user_type`.
@@ -219,7 +207,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
219207

220208
let cause = ObligationCause::dummy_with_span(span);
221209
let param_env = self.param_env;
222-
self.fully_perform_op(
210+
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
223211
Locations::All(span),
224212
ConstraintCategory::Boring,
225213
type_op::custom::CustomTypeOp::new(
@@ -230,13 +218,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
230218
},
231219
"ascribe_user_type_skip_wf",
232220
),
233-
)
234-
.unwrap_or_else(|err| {
235-
span_mirbug!(
236-
self,
237-
span,
238-
"ascribe_user_type_skip_wf `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`",
239-
);
240-
});
221+
);
241222
}
242223
}

‎compiler/rustc_borrowck/src/type_check/free_region_relations.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_infer::infer::InferCtxt;
88
use rustc_middle::mir::ConstraintCategory;
99
use rustc_middle::traits::query::OutlivesBound;
1010
use rustc_middle::ty::{self, RegionVid, Ty};
11-
use rustc_span::Span;
11+
use rustc_span::{Span, DUMMY_SP};
1212
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1313
use std::rc::Rc;
1414
use type_op::TypeOpOutput;
@@ -243,18 +243,11 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
243243
let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self
244244
.param_env
245245
.and(type_op::normalize::Normalize::new(ty))
246-
.fully_perform(self.infcx)
247-
.unwrap_or_else(|_| {
248-
let guar = self
249-
.infcx
250-
.tcx
251-
.sess
252-
.delay_span_bug(span, format!("failed to normalize {:?}", ty));
253-
TypeOpOutput {
254-
output: self.infcx.tcx.ty_error(guar),
255-
constraints: None,
256-
error_info: None,
257-
}
246+
.fully_perform(self.infcx, span)
247+
.unwrap_or_else(|guar| TypeOpOutput {
248+
output: self.infcx.tcx.ty_error(guar),
249+
constraints: None,
250+
error_info: None,
258251
});
259252
if let Some(c) = constraints_normalize {
260253
constraints.push(c)
@@ -324,7 +317,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
324317
let TypeOpOutput { output: bounds, constraints, .. } = self
325318
.param_env
326319
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
327-
.fully_perform(self.infcx)
320+
.fully_perform(self.infcx, DUMMY_SP)
328321
.unwrap_or_else(|_| bug!("failed to compute implied bounds {:?}", ty));
329322
debug!(?bounds, ?constraints);
330323
self.add_outlives_bounds(bounds);

‎compiler/rustc_borrowck/src/type_check/liveness/trace.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_index::interval::IntervalSet;
44
use rustc_infer::infer::canonical::QueryRegionConstraints;
55
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
66
use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
7+
use rustc_span::DUMMY_SP;
78
use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult;
89
use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
910
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
@@ -568,10 +569,15 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
568569
) -> DropData<'tcx> {
569570
debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);
570571

571-
let param_env = typeck.param_env;
572-
let TypeOpOutput { output, constraints, .. } =
573-
param_env.and(DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx).unwrap();
574-
575-
DropData { dropck_result: output, region_constraint_data: constraints }
572+
match typeck
573+
.param_env
574+
.and(DropckOutlives::new(dropped_ty))
575+
.fully_perform(typeck.infcx, DUMMY_SP)
576+
{
577+
Ok(TypeOpOutput { output, constraints, .. }) => {
578+
DropData { dropck_result: output, region_constraint_data: constraints }
579+
}
580+
Err(_) => DropData { dropck_result: Default::default(), region_constraint_data: None },
581+
}
576582
}
577583
}

‎compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use either::Either;
1010
use hir::OpaqueTyOrigin;
1111
use rustc_data_structures::frozen::Frozen;
1212
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
13+
use rustc_errors::ErrorGuaranteed;
1314
use rustc_hir as hir;
1415
use rustc_hir::def::DefKind;
1516
use rustc_hir::def_id::LocalDefId;
@@ -26,6 +27,7 @@ use rustc_middle::mir::tcx::PlaceTy;
2627
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
2728
use rustc_middle::mir::AssertKind;
2829
use rustc_middle::mir::*;
30+
use rustc_middle::traits::query::NoSolution;
2931
use rustc_middle::ty::adjustment::PointerCast;
3032
use rustc_middle::ty::cast::CastTy;
3133
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
@@ -41,7 +43,7 @@ use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
4143
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
4244
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
4345
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
44-
use rustc_trait_selection::traits::query::Fallible;
46+
4547
use rustc_trait_selection::traits::PredicateObligation;
4648

4749
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
@@ -216,24 +218,22 @@ pub(crate) fn type_check<'mir, 'tcx>(
216218
let opaque_type_values = opaque_type_values
217219
.into_iter()
218220
.map(|(opaque_type_key, decl)| {
219-
checker
220-
.fully_perform_op(
221-
Locations::All(body.span),
222-
ConstraintCategory::OpaqueType,
223-
CustomTypeOp::new(
224-
|ocx| {
225-
ocx.infcx.register_member_constraints(
226-
param_env,
227-
opaque_type_key,
228-
decl.hidden_type.ty,
229-
decl.hidden_type.span,
230-
);
231-
Ok(())
232-
},
233-
"opaque_type_map",
234-
),
235-
)
236-
.unwrap();
221+
let _: Result<_, ErrorGuaranteed> = checker.fully_perform_op(
222+
Locations::All(body.span),
223+
ConstraintCategory::OpaqueType,
224+
CustomTypeOp::new(
225+
|ocx| {
226+
ocx.infcx.register_member_constraints(
227+
param_env,
228+
opaque_type_key,
229+
decl.hidden_type.ty,
230+
decl.hidden_type.span,
231+
);
232+
Ok(())
233+
},
234+
"opaque_type_map",
235+
),
236+
);
237237
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
238238
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
239239
if hidden_type.has_non_region_infer() {
@@ -1134,7 +1134,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11341134
sup: Ty<'tcx>,
11351135
locations: Locations,
11361136
category: ConstraintCategory<'tcx>,
1137-
) -> Fallible<()> {
1137+
) -> Result<(), NoSolution> {
11381138
// Use this order of parameters because the sup type is usually the
11391139
// "expected" type in diagnostics.
11401140
self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category)
@@ -1147,7 +1147,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11471147
found: Ty<'tcx>,
11481148
locations: Locations,
11491149
category: ConstraintCategory<'tcx>,
1150-
) -> Fallible<()> {
1150+
) -> Result<(), NoSolution> {
11511151
self.relate_types(expected, ty::Variance::Invariant, found, locations, category)
11521152
}
11531153

@@ -1159,7 +1159,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11591159
user_ty: &UserTypeProjection,
11601160
locations: Locations,
11611161
category: ConstraintCategory<'tcx>,
1162-
) -> Fallible<()> {
1162+
) -> Result<(), NoSolution> {
11631163
let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
11641164
trace!(?annotated_type);
11651165
let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
@@ -2755,11 +2755,20 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
27552755
/// constraints in our `InferCtxt`
27562756
type ErrorInfo = InstantiateOpaqueType<'tcx>;
27572757

2758-
fn fully_perform(mut self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
2759-
let (mut output, region_constraints) = scrape_region_constraints(infcx, |ocx| {
2760-
ocx.register_obligations(self.obligations.clone());
2761-
Ok(())
2762-
})?;
2758+
fn fully_perform(
2759+
mut self,
2760+
infcx: &InferCtxt<'tcx>,
2761+
span: Span,
2762+
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
2763+
let (mut output, region_constraints) = scrape_region_constraints(
2764+
infcx,
2765+
|ocx| {
2766+
ocx.register_obligations(self.obligations.clone());
2767+
Ok(())
2768+
},
2769+
"InstantiateOpaqueType",
2770+
span,
2771+
)?;
27632772
self.region_constraints = Some(region_constraints);
27642773
output.error_info = Some(self);
27652774
Ok(output)

‎compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
use rustc_errors::ErrorGuaranteed;
12
use rustc_infer::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
23
use rustc_infer::infer::NllRegionVariableOrigin;
34
use rustc_infer::traits::PredicateObligations;
45
use rustc_middle::mir::ConstraintCategory;
6+
use rustc_middle::traits::query::NoSolution;
57
use rustc_middle::ty::relate::TypeRelation;
68
use rustc_middle::ty::{self, Ty};
79
use rustc_span::symbol::sym;
810
use rustc_span::{Span, Symbol};
9-
use rustc_trait_selection::traits::query::Fallible;
1011

1112
use crate::constraints::OutlivesConstraint;
1213
use crate::diagnostics::UniverseInfo;
@@ -30,7 +31,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
3031
b: Ty<'tcx>,
3132
locations: Locations,
3233
category: ConstraintCategory<'tcx>,
33-
) -> Fallible<()> {
34+
) -> Result<(), NoSolution> {
3435
TypeRelating::new(
3536
self.infcx,
3637
NllTypeRelatingDelegate::new(self, locations, category, UniverseInfo::relate(a, b)),
@@ -47,7 +48,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
4748
b: ty::SubstsRef<'tcx>,
4849
locations: Locations,
4950
category: ConstraintCategory<'tcx>,
50-
) -> Fallible<()> {
51+
) -> Result<(), NoSolution> {
5152
TypeRelating::new(
5253
self.infcx,
5354
NllTypeRelatingDelegate::new(self, locations, category, UniverseInfo::other()),
@@ -185,7 +186,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
185186
}
186187

187188
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
188-
match self.type_checker.fully_perform_op(
189+
let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op(
189190
self.locations,
190191
self.category,
191192
InstantiateOpaqueType {
@@ -194,16 +195,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
194195
base_universe: None,
195196
region_constraints: None,
196197
},
197-
) {
198-
Ok(()) => {}
199-
Err(_) => {
200-
// It's a bit redundant to delay a bug here, but I'd rather
201-
// delay more bugs than accidentally not delay a bug at all.
202-
self.type_checker.tcx().sess.delay_span_bug(
203-
self.locations.span(self.type_checker.body),
204-
"errors selecting obligation during MIR typeck",
205-
);
206-
}
207-
};
198+
);
208199
}
209200
}

‎compiler/rustc_infer/src/infer/canonical/query_response.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::infer::canonical::{
1515
use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
1616
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
1717
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
18-
use crate::traits::query::{Fallible, NoSolution};
18+
use crate::traits::query::NoSolution;
1919
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
2020
use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt};
2121
use rustc_data_structures::captures::Captures;
@@ -57,7 +57,7 @@ impl<'tcx> InferCtxt<'tcx> {
5757
inference_vars: CanonicalVarValues<'tcx>,
5858
answer: T,
5959
fulfill_cx: &mut dyn TraitEngine<'tcx>,
60-
) -> Fallible<CanonicalQueryResponse<'tcx, T>>
60+
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
6161
where
6262
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
6363
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,

‎compiler/rustc_middle/src/traits/query.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
9595
#[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)]
9696
pub struct NoSolution;
9797

98-
pub type Fallible<T> = Result<T, NoSolution>;
99-
10098
impl<'tcx> From<TypeError<'tcx>> for NoSolution {
10199
fn from(_: TypeError<'tcx>) -> NoSolution {
102100
NoSolution

‎compiler/rustc_trait_selection/src/infer.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
55
use rustc_hir::lang_items::LangItem;
66
use rustc_middle::arena::ArenaAllocatable;
77
use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
8-
use rustc_middle::traits::query::Fallible;
8+
use rustc_middle::traits::query::NoSolution;
99
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
1010
use rustc_middle::ty::{GenericArg, ToPredicate};
1111
use rustc_span::DUMMY_SP;
@@ -82,8 +82,8 @@ pub trait InferCtxtBuilderExt<'tcx> {
8282
fn enter_canonical_trait_query<K, R>(
8383
&mut self,
8484
canonical_key: &Canonical<'tcx, K>,
85-
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>,
86-
) -> Fallible<CanonicalQueryResponse<'tcx, R>>
85+
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
86+
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
8787
where
8888
K: TypeFoldable<TyCtxt<'tcx>>,
8989
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
@@ -110,8 +110,8 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
110110
fn enter_canonical_trait_query<K, R>(
111111
&mut self,
112112
canonical_key: &Canonical<'tcx, K>,
113-
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>,
114-
) -> Fallible<CanonicalQueryResponse<'tcx, R>>
113+
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
114+
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
115115
where
116116
K: TypeFoldable<TyCtxt<'tcx>>,
117117
R: Debug + TypeFoldable<TyCtxt<'tcx>>,

‎compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use rustc_infer::infer::canonical::{
1414
};
1515
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1616
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
17-
use rustc_infer::traits::query::Fallible;
1817
use rustc_infer::traits::{
1918
FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
2019
};
2120
use rustc_middle::arena::ArenaAllocatable;
21+
use rustc_middle::traits::query::NoSolution;
2222
use rustc_middle::ty::error::TypeError;
2323
use rustc_middle::ty::ToPredicate;
2424
use rustc_middle::ty::TypeFoldable;
@@ -235,7 +235,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
235235
&self,
236236
inference_vars: CanonicalVarValues<'tcx>,
237237
answer: T,
238-
) -> Fallible<CanonicalQueryResponse<'tcx, T>>
238+
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
239239
where
240240
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
241241
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,

‎compiler/rustc_trait_selection/src/traits/outlives_bounds.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::infer::InferCtxt;
22
use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
3-
use crate::traits::query::NoSolution;
43
use crate::traits::{ObligationCause, ObligationCtxt};
54
use rustc_data_structures::fx::FxIndexSet;
5+
use rustc_errors::ErrorGuaranteed;
66
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
77
use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt};
88
use rustc_span::def_id::LocalDefId;
@@ -69,16 +69,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
6969
}
7070

7171
let span = self.tcx.def_span(body_id);
72-
let result = param_env
72+
let result: Result<_, ErrorGuaranteed> = param_env
7373
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
74-
.fully_perform(self);
74+
.fully_perform(self, span);
7575
let result = match result {
7676
Ok(r) => r,
77-
Err(NoSolution) => {
78-
self.tcx.sess.delay_span_bug(
79-
span,
80-
"implied_outlives_bounds failed to solve all obligations",
81-
);
77+
Err(_) => {
8278
return vec![];
8379
}
8480
};

‎compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2-
use crate::traits::query::Fallible;
2+
use rustc_middle::traits::query::NoSolution;
33
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
44

55
pub use rustc_middle::traits::query::type_op::AscribeUserType;
@@ -17,7 +17,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
1717
fn perform_query(
1818
tcx: TyCtxt<'tcx>,
1919
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
20-
) -> Fallible<CanonicalQueryResponse<'tcx, ()>> {
20+
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
2121
tcx.type_op_ascribe_user_type(canonicalized)
2222
}
2323
}

‎compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::infer::canonical::query_response;
22
use crate::infer::InferCtxt;
33
use crate::traits::query::type_op::TypeOpOutput;
4-
use crate::traits::query::Fallible;
54
use crate::traits::ObligationCtxt;
5+
use rustc_errors::ErrorGuaranteed;
66
use rustc_infer::infer::region_constraints::RegionConstraintData;
77
use rustc_middle::traits::query::NoSolution;
88
use rustc_span::source_map::DUMMY_SP;
9+
use rustc_span::Span;
910

1011
use std::fmt;
1112

@@ -17,15 +18,15 @@ pub struct CustomTypeOp<F> {
1718
impl<F> CustomTypeOp<F> {
1819
pub fn new<'tcx, R>(closure: F, description: &'static str) -> Self
1920
where
20-
F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible<R>,
21+
F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
2122
{
2223
CustomTypeOp { closure, description }
2324
}
2425
}
2526

2627
impl<'tcx, F, R: fmt::Debug> super::TypeOp<'tcx> for CustomTypeOp<F>
2728
where
28-
F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible<R>,
29+
F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
2930
{
3031
type Output = R;
3132
/// We can't do any custom error reporting for `CustomTypeOp`, so
@@ -35,12 +36,16 @@ where
3536
/// Processes the operation and all resulting obligations,
3637
/// returning the final result along with any region constraints
3738
/// (they will be given over to the NLL region solver).
38-
fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
39+
fn fully_perform(
40+
self,
41+
infcx: &InferCtxt<'tcx>,
42+
span: Span,
43+
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
3944
if cfg!(debug_assertions) {
4045
info!("fully_perform({:?})", self);
4146
}
4247

43-
Ok(scrape_region_constraints(infcx, self.closure)?.0)
48+
Ok(scrape_region_constraints(infcx, self.closure, self.description, span)?.0)
4449
}
4550
}
4651

@@ -54,8 +59,10 @@ impl<F> fmt::Debug for CustomTypeOp<F> {
5459
/// constraints that result, creating query-region-constraints.
5560
pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
5661
infcx: &InferCtxt<'tcx>,
57-
op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible<R>,
58-
) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> {
62+
op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
63+
name: &'static str,
64+
span: Span,
65+
) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> {
5966
// During NLL, we expect that nobody will register region
6067
// obligations **except** as part of a custom type op (and, at the
6168
// end of each custom type op, we scrape out the region
@@ -70,16 +77,17 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
7077

7178
let value = infcx.commit_if_ok(|_| {
7279
let ocx = ObligationCtxt::new_in_snapshot(infcx);
73-
let value = op(&ocx)?;
80+
let value = op(&ocx).map_err(|_| {
81+
infcx.tcx.sess.delay_span_bug(span, format!("error performing operation: {name}"))
82+
})?;
7483
let errors = ocx.select_all_or_error();
7584
if errors.is_empty() {
7685
Ok(value)
7786
} else {
78-
infcx.tcx.sess.delay_span_bug(
87+
Err(infcx.tcx.sess.delay_span_bug(
7988
DUMMY_SP,
8089
format!("errors selecting obligation during MIR typeck: {:?}", errors),
81-
);
82-
Err(NoSolution)
90+
))
8391
}
8492
})?;
8593

‎compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2-
use crate::traits::query::Fallible;
2+
use rustc_middle::traits::query::NoSolution;
33
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
44

55
pub use rustc_middle::traits::query::type_op::Eq;
@@ -17,7 +17,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
1717
fn perform_query(
1818
tcx: TyCtxt<'tcx>,
1919
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
20-
) -> Fallible<CanonicalQueryResponse<'tcx, ()>> {
20+
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
2121
tcx.type_op_eq(canonicalized)
2222
}
2323
}

‎compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2-
use crate::traits::query::Fallible;
32
use rustc_infer::traits::query::OutlivesBound;
3+
use rustc_middle::traits::query::NoSolution;
44
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt};
55

66
#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
@@ -28,7 +28,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
2828
fn perform_query(
2929
tcx: TyCtxt<'tcx>,
3030
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
31-
) -> Fallible<CanonicalQueryResponse<'tcx, Self::QueryResponse>> {
31+
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
3232
// FIXME this `unchecked_map` is only necessary because the
3333
// query is defined as taking a `ParamEnvAnd<Ty>`; it should
3434
// take an `ImpliedOutlivesBounds` instead

‎compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ use crate::infer::canonical::{
22
Canonical, CanonicalQueryResponse, OriginalQueryValues, QueryRegionConstraints,
33
};
44
use crate::infer::{InferCtxt, InferOk};
5-
use crate::traits::query::Fallible;
65
use crate::traits::ObligationCause;
6+
use rustc_errors::ErrorGuaranteed;
77
use rustc_infer::infer::canonical::Certainty;
8-
use rustc_infer::traits::query::NoSolution;
98
use rustc_infer::traits::PredicateObligations;
9+
use rustc_middle::traits::query::NoSolution;
1010
use rustc_middle::ty::fold::TypeFoldable;
1111
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
12+
use rustc_span::Span;
1213
use std::fmt;
1314

1415
pub mod ascribe_user_type;
@@ -32,7 +33,11 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
3233
/// Processes the operation and all resulting obligations,
3334
/// returning the final result along with any region constraints
3435
/// (they will be given over to the NLL region solver).
35-
fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>>;
36+
fn fully_perform(
37+
self,
38+
infcx: &InferCtxt<'tcx>,
39+
span: Span,
40+
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed>;
3641
}
3742

3843
/// The output from performing a type op
@@ -74,18 +79,21 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
7479
fn perform_query(
7580
tcx: TyCtxt<'tcx>,
7681
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
77-
) -> Fallible<CanonicalQueryResponse<'tcx, Self::QueryResponse>>;
82+
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution>;
7883

7984
fn fully_perform_into(
8085
query_key: ParamEnvAnd<'tcx, Self>,
8186
infcx: &InferCtxt<'tcx>,
8287
output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
83-
) -> Fallible<(
84-
Self::QueryResponse,
85-
Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>,
86-
PredicateObligations<'tcx>,
87-
Certainty,
88-
)> {
88+
) -> Result<
89+
(
90+
Self::QueryResponse,
91+
Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>,
92+
PredicateObligations<'tcx>,
93+
Certainty,
94+
),
95+
NoSolution,
96+
> {
8997
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
9098
return Ok((result, None, vec![], Certainty::Proven));
9199
}
@@ -120,10 +128,16 @@ where
120128
type Output = Q::QueryResponse;
121129
type ErrorInfo = Canonical<'tcx, ParamEnvAnd<'tcx, Q>>;
122130

123-
fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
131+
fn fully_perform(
132+
self,
133+
infcx: &InferCtxt<'tcx>,
134+
span: Span,
135+
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
124136
let mut region_constraints = QueryRegionConstraints::default();
125137
let (output, error_info, mut obligations, _) =
126-
Q::fully_perform_into(self, infcx, &mut region_constraints)?;
138+
Q::fully_perform_into(self, infcx, &mut region_constraints).map_err(|_| {
139+
infcx.tcx.sess.delay_span_bug(span, format!("error performing {self:?}"))
140+
})?;
127141

128142
// Typically, instantiating NLL query results does not
129143
// create obligations. However, in some cases there
@@ -151,7 +165,10 @@ where
151165
}
152166
}
153167
if !progress {
154-
return Err(NoSolution);
168+
return Err(infcx.tcx.sess.delay_span_bug(
169+
span,
170+
format!("ambiguity processing {obligations:?} from {self:?}"),
171+
));
155172
}
156173
}
157174

‎compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2-
use crate::traits::query::Fallible;
2+
use rustc_middle::traits::query::NoSolution;
33
use rustc_middle::ty::fold::TypeFoldable;
44
use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
55
use std::fmt;
@@ -19,7 +19,7 @@ where
1919
fn perform_query(
2020
tcx: TyCtxt<'tcx>,
2121
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
22-
) -> Fallible<CanonicalQueryResponse<'tcx, Self::QueryResponse>> {
22+
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
2323
T::type_op_method(tcx, canonicalized)
2424
}
2525
}
@@ -28,14 +28,14 @@ pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tc
2828
fn type_op_method(
2929
tcx: TyCtxt<'tcx>,
3030
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
31-
) -> Fallible<CanonicalQueryResponse<'tcx, Self>>;
31+
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>;
3232
}
3333

3434
impl<'tcx> Normalizable<'tcx> for Ty<'tcx> {
3535
fn type_op_method(
3636
tcx: TyCtxt<'tcx>,
3737
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
38-
) -> Fallible<CanonicalQueryResponse<'tcx, Self>> {
38+
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
3939
tcx.type_op_normalize_ty(canonicalized)
4040
}
4141
}
@@ -44,7 +44,7 @@ impl<'tcx> Normalizable<'tcx> for ty::Predicate<'tcx> {
4444
fn type_op_method(
4545
tcx: TyCtxt<'tcx>,
4646
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
47-
) -> Fallible<CanonicalQueryResponse<'tcx, Self>> {
47+
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
4848
tcx.type_op_normalize_predicate(canonicalized)
4949
}
5050
}
@@ -53,7 +53,7 @@ impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
5353
fn type_op_method(
5454
tcx: TyCtxt<'tcx>,
5555
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
56-
) -> Fallible<CanonicalQueryResponse<'tcx, Self>> {
56+
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
5757
tcx.type_op_normalize_poly_fn_sig(canonicalized)
5858
}
5959
}
@@ -62,7 +62,7 @@ impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
6262
fn type_op_method(
6363
tcx: TyCtxt<'tcx>,
6464
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
65-
) -> Fallible<CanonicalQueryResponse<'tcx, Self>> {
65+
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
6666
tcx.type_op_normalize_fn_sig(canonicalized)
6767
}
6868
}

‎compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
22
use crate::traits::query::dropck_outlives::{trivial_dropck_outlives, DropckOutlivesResult};
3-
use crate::traits::query::Fallible;
3+
use rustc_middle::traits::query::NoSolution;
44
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
55

66
#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
@@ -27,7 +27,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
2727
fn perform_query(
2828
tcx: TyCtxt<'tcx>,
2929
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
30-
) -> Fallible<CanonicalQueryResponse<'tcx, Self::QueryResponse>> {
30+
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
3131
// Subtle: note that we are not invoking
3232
// `infcx.at(...).dropck_outlives(...)` here, but rather the
3333
// underlying `dropck_outlives` query. This same underlying

‎compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2-
use crate::traits::query::Fallible;
2+
use rustc_middle::traits::query::NoSolution;
33
use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt};
44

55
pub use rustc_middle::traits::query::type_op::ProvePredicate;
@@ -33,7 +33,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
3333
fn perform_query(
3434
tcx: TyCtxt<'tcx>,
3535
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
36-
) -> Fallible<CanonicalQueryResponse<'tcx, ()>> {
36+
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
3737
tcx.type_op_prove_predicate(canonicalized)
3838
}
3939
}

‎compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2-
use crate::traits::query::Fallible;
2+
use rustc_middle::traits::query::NoSolution;
33
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
44

55
pub use rustc_middle::traits::query::type_op::Subtype;
@@ -14,7 +14,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
1414
fn perform_query(
1515
tcx: TyCtxt<'tcx>,
1616
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
17-
) -> Fallible<CanonicalQueryResponse<'tcx, ()>> {
17+
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
1818
tcx.type_op_subtype(canonicalized)
1919
}
2020
}

‎compiler/rustc_traits/src/implied_outlives_bounds.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
1111
use rustc_span::def_id::CRATE_DEF_ID;
1212
use rustc_span::source_map::DUMMY_SP;
1313
use rustc_trait_selection::infer::InferCtxtBuilderExt;
14-
use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution};
14+
use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution};
1515
use rustc_trait_selection::traits::wf;
1616
use rustc_trait_selection::traits::ObligationCtxt;
1717
use smallvec::{smallvec, SmallVec};
@@ -37,7 +37,7 @@ fn compute_implied_outlives_bounds<'tcx>(
3737
ocx: &ObligationCtxt<'_, 'tcx>,
3838
param_env: ty::ParamEnv<'tcx>,
3939
ty: Ty<'tcx>,
40-
) -> Fallible<Vec<OutlivesBound<'tcx>>> {
40+
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
4141
let tcx = ocx.infcx.tcx;
4242

4343
// Sometimes when we ask what it takes for T: WF, we get back that

‎compiler/rustc_traits/src/type_op.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_hir as hir;
22
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
33
use rustc_infer::infer::TyCtxtInferExt;
44
use rustc_middle::query::Providers;
5+
use rustc_middle::traits::query::NoSolution;
56
use rustc_middle::traits::{DefiningAnchor, ObligationCauseCode};
67
use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
78
use rustc_middle::ty::{ParamEnvAnd, Predicate};
@@ -15,7 +16,6 @@ use rustc_trait_selection::traits::query::type_op::eq::Eq;
1516
use rustc_trait_selection::traits::query::type_op::normalize::Normalize;
1617
use rustc_trait_selection::traits::query::type_op::prove_predicate::ProvePredicate;
1718
use rustc_trait_selection::traits::query::type_op::subtype::Subtype;
18-
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
1919
use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt};
2020
use std::fmt;
2121

@@ -160,7 +160,7 @@ fn type_op_eq<'tcx>(
160160
fn type_op_normalize<'tcx, T>(
161161
ocx: &ObligationCtxt<'_, 'tcx>,
162162
key: ParamEnvAnd<'tcx, Normalize<T>>,
163-
) -> Fallible<T>
163+
) -> Result<T, NoSolution>
164164
where
165165
T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>,
166166
{

0 commit comments

Comments
 (0)
Please sign in to comment.