Skip to content

Commit 799ad7a

Browse files
committed
Overhaul ensure_ok.
`ensure_ok` provides a special, more efficient way of calling a query when its return value isn't needed. But there is a complication: if the query is marked with the `return_result_from_ensure_ok` modifier, then it will return `Result<(), ErrorGuaranteed`. This is clunky and feels tacked on. It's annoying to have to add a modifier to a query to declare information present in its return type, and it's confusing that queries called via `ensure_ok` have different return types depending on the modifier. This commit: - Eliminates the `return_result_from_ensure_ok` modifier. The proc macro now looks at the return type and detects if it matches `Result<_, ErrorGuarantee>`. If so, it adds the modifier `returns_result_with_error_guarantee`. (Aside: We need better terminology to distinguish modifiers written by the user in a `query` declaration (e.g. `cycle_delayed_bug`) from modifiers added by the proc macro (e.g. `cycle_error_handling`.)) - Introduces `ensure_result`, which replaces the use of `ensure_ok` for queries that return `Result<_, ErrorGuarantee>`. As a result, `ensure_ok` can now only be used for the "ignore the return value" case.
1 parent bea3803 commit 799ad7a

29 files changed

Lines changed: 142 additions & 142 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
294294

295295
// Avoid bogus move errors because of an incoherent `Copy` impl.
296296
self.infcx.type_implements_trait(copy_def_id, [ty], self.infcx.param_env).may_apply()
297-
&& self.infcx.tcx.ensure_ok().coherent_trait(copy_def_id).is_err()
297+
&& self.infcx.tcx.ensure_result().coherent_trait(copy_def_id).is_err()
298298
}
299299

300300
fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> {

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fn mir_borrowck(
123123
// We should eagerly check stalled coroutine obligations from HIR typeck.
124124
// Not doing so leads to silent normalization failures later, which will
125125
// fail to register opaque types in the next solver.
126-
tcx.ensure_ok().check_coroutine_obligations(def)?;
126+
tcx.ensure_result().check_coroutine_obligations(def)?;
127127

128128
let input_body: &Body<'_> = &input_body.borrow();
129129
if let Some(guar) = input_body.tainted_by_errors {

compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
334334
self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`");
335335
}
336336
if let Some(def_id) = def_id.as_local()
337-
&& let Err(guar) = self.tcx.ensure_ok().check_well_formed(hir::OwnerId { def_id })
337+
&& let Err(guar) = self.tcx.ensure_result().check_well_formed(hir::OwnerId { def_id })
338338
{
339339
self.error_emitted = Some(guar);
340340
}

compiler/rustc_hir_analysis/src/check/always_applicable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub(crate) fn check_drop_impl(
5252
}
5353
}
5454

55-
tcx.ensure_ok().orphan_check_impl(drop_impl_did)?;
55+
tcx.ensure_result().orphan_check_impl(drop_impl_did)?;
5656

5757
let self_ty = tcx.type_of(drop_impl_did).instantiate_identity();
5858

@@ -96,7 +96,7 @@ pub(crate) fn check_negative_auto_trait_impl<'tcx>(
9696
tcx.dcx().span_delayed_bug(tcx.def_span(impl_def_id), "default impl cannot be negative");
9797
}
9898

99-
tcx.ensure_ok().orphan_check_impl(impl_def_id)?;
99+
tcx.ensure_result().orphan_check_impl(impl_def_id)?;
100100

101101
match impl_trait_ref.self_ty().kind() {
102102
ty::Adt(adt_def, adt_to_impl_args) => {

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
807807
if of_trait {
808808
let impl_trait_header = tcx.impl_trait_header(def_id);
809809
res = res.and(
810-
tcx.ensure_ok()
810+
tcx.ensure_result()
811811
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id),
812812
);
813813

@@ -1238,8 +1238,7 @@ fn check_impl_items_against_trait<'tcx>(
12381238
Err(ErrorGuaranteed { .. }) => continue,
12391239
};
12401240

1241-
let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());
1242-
1241+
let res = tcx.ensure_result().compare_impl_item(impl_item.expect_local());
12431242
if res.is_ok() {
12441243
match ty_impl_item.kind {
12451244
ty::AssocKind::Fn { .. } => {

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2458,7 +2458,7 @@ pub(super) fn check_type_bounds<'tcx>(
24582458
) -> Result<(), ErrorGuaranteed> {
24592459
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
24602460
// other `Foo` impls are incoherent.
2461-
tcx.ensure_ok().coherent_trait(impl_trait_ref.def_id)?;
2461+
tcx.ensure_result().coherent_trait(impl_trait_ref.def_id)?;
24622462

24632463
let param_env = tcx.param_env(impl_ty.def_id);
24642464
debug!(?param_env);

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ pub(crate) fn check_associated_item(
935935

936936
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
937937
// other `Foo` impls are incoherent.
938-
tcx.ensure_ok().coherent_trait(tcx.parent(item.trait_item_or_self()?))?;
938+
tcx.ensure_result().coherent_trait(tcx.parent(item.trait_item_or_self()?))?;
939939

940940
let self_ty = match item.container {
941941
ty::AssocContainer::Trait => tcx.types.self_param,
@@ -1327,9 +1327,9 @@ fn check_impl<'tcx>(
13271327
// therefore don't need to be WF (the trait's `Self: Trait` predicate
13281328
// won't hold).
13291329
let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity();
1330-
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
1331-
// other `Foo` impls are incoherent.
1332-
tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
1330+
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in
1331+
// case other `Foo` impls are incoherent.
1332+
tcx.ensure_result().coherent_trait(trait_ref.def_id)?;
13331333
let trait_span = of_trait.trait_ref.path.span;
13341334
let trait_ref = wfcx.deeply_normalize(
13351335
trait_span,
@@ -2333,15 +2333,22 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
23332333

23342334
pub(super) fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
23352335
let items = tcx.hir_crate_items(());
2336-
let res = items
2337-
.par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))
2338-
.and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
2339-
.and(items.par_trait_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
2340-
.and(
2341-
items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)),
2342-
)
2343-
.and(items.par_nested_bodies(|item| tcx.ensure_ok().check_well_formed(item)))
2344-
.and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item)));
2336+
let res =
2337+
items
2338+
.par_items(|item| tcx.ensure_result().check_well_formed(item.owner_id.def_id))
2339+
.and(
2340+
items.par_impl_items(|item| {
2341+
tcx.ensure_result().check_well_formed(item.owner_id.def_id)
2342+
}),
2343+
)
2344+
.and(items.par_trait_items(|item| {
2345+
tcx.ensure_result().check_well_formed(item.owner_id.def_id)
2346+
}))
2347+
.and(items.par_foreign_items(|item| {
2348+
tcx.ensure_result().check_well_formed(item.owner_id.def_id)
2349+
}))
2350+
.and(items.par_nested_bodies(|item| tcx.ensure_result().check_well_formed(item)))
2351+
.and(items.par_opaques(|item| tcx.ensure_result().check_well_formed(item)));
23452352
super::entry::check_for_entry_fn(tcx);
23462353

23472354
res

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
226226
// Just compute this for the side-effects, in particular reporting
227227
// errors; other parts of the code may demand it for the info of
228228
// course.
229-
tcx.ensure_ok().coerce_unsized_info(impl_did)
229+
tcx.ensure_result().coerce_unsized_info(impl_did)
230230
}
231231

232232
fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
@@ -259,7 +259,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
259259
tcx.require_lang_item(LangItem::CoerceUnsized, span),
260260
source,
261261
|impl_def_id| {
262-
res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id));
262+
res = res.and(tcx.ensure_result().coerce_unsized_info(impl_def_id));
263263
},
264264
);
265265
res?;

compiler/rustc_hir_analysis/src/coherence/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
160160
}
161161
// Trigger building the specialization graph for the trait. This will detect and report any
162162
// overlap errors.
163-
let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
163+
let mut res = tcx.ensure_result().specialization_graph_of(def_id);
164164

165165
for &impl_def_id in impls {
166166
let impl_header = tcx.impl_trait_header(impl_def_id);
@@ -171,7 +171,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
171171
.and(check_impl(tcx, impl_def_id, trait_ref, trait_def, impl_header.polarity))
172172
.and(check_object_overlap(tcx, impl_def_id, trait_ref))
173173
.and(unsafety::check_item(tcx, impl_def_id, impl_header, trait_def))
174-
.and(tcx.ensure_ok().orphan_check_impl(impl_def_id))
174+
.and(tcx.ensure_result().orphan_check_impl(impl_def_id))
175175
.and(builtin::check_trait(tcx, def_id, impl_def_id, impl_header));
176176
}
177177

compiler/rustc_hir_analysis/src/impl_wf_check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub(crate) fn check_impl_wf(
6363
// Check that the args are constrained. We queryfied the check for ty/const params
6464
// since unconstrained type/const params cause ICEs in projection, so we want to
6565
// detect those specifically and project those to `TyKind::Error`.
66-
let mut res = tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
66+
let mut res = tcx.ensure_result().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
6767
res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id, of_trait));
6868

6969
if of_trait && tcx.features().min_specialization() {

0 commit comments

Comments
 (0)