Skip to content

Commit be72f25

Browse files
committed
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

+13-32
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

+7-14
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

+11-5
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

+36-27
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

+6-15
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

+2-2
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

-2
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

0 commit comments

Comments
 (0)