Skip to content

Commit 9a309c7

Browse files
committed
support revealing uses in borrowck
1 parent 3c7b20c commit 9a309c7

File tree

8 files changed

+73
-37
lines changed

8 files changed

+73
-37
lines changed

compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,31 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
2828
if errors.is_empty() {
2929
return;
3030
}
31+
32+
let infcx = self.infcx;
3133
let mut guar = None;
3234
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
3335
None;
3436
for error in errors {
3537
guar = Some(match error {
36-
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(self.infcx),
38+
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(infcx),
3739
DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(err) => {
38-
self.infcx.dcx().emit_err(err)
40+
infcx.dcx().emit_err(err)
3941
}
4042
DeferredOpaqueTypeError::UnexpectedHiddenRegion {
4143
opaque_type_key,
4244
hidden_type,
4345
member_region,
4446
} => {
45-
let named_ty = self
46-
.regioncx
47-
.name_regions_for_member_constraint(self.infcx.tcx, hidden_type.ty);
47+
let named_ty =
48+
self.regioncx.name_regions_for_member_constraint(infcx.tcx, hidden_type.ty);
4849
let named_key = self
4950
.regioncx
50-
.name_regions_for_member_constraint(self.infcx.tcx, opaque_type_key);
51-
let named_region = self
52-
.regioncx
53-
.name_regions_for_member_constraint(self.infcx.tcx, member_region);
51+
.name_regions_for_member_constraint(infcx.tcx, opaque_type_key);
52+
let named_region =
53+
self.regioncx.name_regions_for_member_constraint(infcx.tcx, member_region);
5454
let diag = unexpected_hidden_region_diagnostic(
55-
self.infcx,
55+
infcx,
5656
self.mir_def_id(),
5757
hidden_type.span,
5858
named_ty,
@@ -69,6 +69,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
6969
diag.delay_as_bug()
7070
}
7171
}
72+
DeferredOpaqueTypeError::NonDefiningUseInDefiningScope {
73+
span,
74+
opaque_type_key,
75+
} => infcx.dcx().span_err(
76+
span,
77+
format!(
78+
"non-defining use of `{}` in the defining scope",
79+
Ty::new_opaque(
80+
infcx.tcx,
81+
opaque_type_key.def_id.to_def_id(),
82+
opaque_type_key.args
83+
)
84+
),
85+
),
7286
});
7387
}
7488
let guar = guar.unwrap();

compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_macros::extension;
1111
use rustc_middle::mir::{Body, ConstraintCategory};
1212
use rustc_middle::ty::{
1313
self, DefiningScopeKind, FallibleTypeFolder, GenericArg, GenericArgsRef, OpaqueHiddenType,
14-
OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
14+
OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
1515
TypeVisitableExt, fold_regions,
1616
};
1717
use rustc_mir_dataflow::points::DenseLocationMap;
@@ -49,6 +49,10 @@ pub(crate) enum DeferredOpaqueTypeError<'tcx> {
4949
/// The unexpected region.
5050
member_region: Region<'tcx>,
5151
},
52+
NonDefiningUseInDefiningScope {
53+
span: Span,
54+
opaque_type_key: OpaqueTypeKey<'tcx>,
55+
},
5256
}
5357

5458
pub(crate) fn handle_opaque_type_uses<'tcx>(
@@ -99,7 +103,7 @@ pub(crate) fn handle_opaque_type_uses<'tcx>(
99103
return errors;
100104
}
101105

102-
apply_defining_uses(
106+
let errors = apply_defining_uses(
103107
root_cx,
104108
infcx,
105109
body,
@@ -123,7 +127,7 @@ pub(crate) fn handle_opaque_type_uses<'tcx>(
123127

124128
let _ = infcx.take_opaque_types();
125129

126-
Vec::new()
130+
errors
127131
}
128132

129133
#[derive(Debug)]
@@ -149,21 +153,26 @@ fn collect_defining_uses<'tcx>(
149153
let mut errors = vec![];
150154
for &(opaque_type_key, hidden_type) in opaque_types {
151155
let non_nll_opaque_type_key = opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |r| {
152-
nll_var_to_universal_region(&rcx, r.as_var()).unwrap_or_else(|| {
153-
ty::Region::new_error_with_message(
154-
infcx.tcx,
155-
hidden_type.span,
156-
"opaque type with non-universal region args",
157-
)
158-
})
156+
nll_var_to_universal_region(&rcx, r.as_var()).unwrap_or(r)
159157
});
160158
if let Err(err) = check_opaque_type_parameter_valid(
161159
infcx,
162160
non_nll_opaque_type_key,
163161
hidden_type.span,
164162
DefiningScopeKind::MirBorrowck,
165163
) {
166-
errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
164+
if tcx.use_typing_mode_borrowck() {
165+
match err {
166+
InvalidOpaqueTypeArgs::AlreadyReported(guar) => root_cx
167+
.add_concrete_opaque_type(
168+
opaque_type_key.def_id,
169+
OpaqueHiddenType::new_error(tcx, guar),
170+
),
171+
_ => debug!(?non_nll_opaque_type_key, ?err, "ignoring non-defining use"),
172+
}
173+
} else {
174+
errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
175+
}
167176
continue;
168177
}
169178

@@ -439,16 +448,25 @@ fn apply_defining_uses<'tcx>(
439448
known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>],
440449
constraints: &mut MirTypeckRegionConstraints<'tcx>,
441450
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
442-
) {
451+
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
443452
let tcx = infcx.tcx;
453+
let mut errors = Vec::new();
444454
for &(key, hidden_type) in opaque_types {
445455
let Some(expected) = root_cx.get_concrete_opaque_type(key.def_id) else {
446-
let guar = tcx
447-
.dcx()
448-
.span_delayed_bug(hidden_type.span, "non-defining use in the defining scope");
449-
root_cx.add_concrete_opaque_type(key.def_id, OpaqueHiddenType::new_error(tcx, guar));
450-
infcx.set_tainted_by_errors(guar);
451-
continue;
456+
if tcx.use_typing_mode_borrowck() {
457+
errors.push(DeferredOpaqueTypeError::NonDefiningUseInDefiningScope {
458+
span: hidden_type.span,
459+
opaque_type_key: key,
460+
});
461+
let guar = tcx
462+
.dcx()
463+
.span_delayed_bug(hidden_type.span, "non-defining use in the defining scope");
464+
root_cx
465+
.add_concrete_opaque_type(key.def_id, OpaqueHiddenType::new_error(tcx, guar));
466+
continue;
467+
} else {
468+
unreachable!()
469+
}
452470
};
453471

454472
let expected = ty::fold_regions(tcx, expected.instantiate(tcx, key.args), |re, _dbi| {
@@ -487,6 +505,7 @@ fn apply_defining_uses<'tcx>(
487505
root_cx.add_concrete_opaque_type(key.def_id, OpaqueHiddenType::new_error(tcx, guar));
488506
}
489507
}
508+
errors
490509
}
491510

492511
impl<'tcx> RegionInferenceContext<'tcx> {

compiler/rustc_trait_selection/src/opaque_types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::errors::NonGenericOpaqueTypeParam;
1313
use crate::regions::OutlivesEnvironmentBuildExt;
1414
use crate::traits::ObligationCtxt;
1515

16+
#[derive(Debug)]
1617
pub enum InvalidOpaqueTypeArgs<'tcx> {
1718
AlreadyReported(ErrorGuaranteed),
1819
NotAParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_index: usize, span: Span },

tests/ui/impl-trait/member-constraints/apply_member_constraint-no-req-eq.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//@ check-pass
2-
// FIXME(-Znext-solver): enable this test
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
35

46
trait Id {
57
type This;

tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Nested impl-traits can impose different member constraints on the same region variable.
22

33
//@ check-pass
4-
// FIXME(-Znext-solver): enable this test
4+
//@ revisions: current next
5+
//@ ignore-compare-mode-next-solver (explicit revisions)
6+
//@[next] compile-flags: -Znext-solver
57

68
trait Cap<'a> {}
79
impl<T> Cap<'_> for T {}

tests/ui/impl-trait/no-anonymize-regions.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//@ check-pass
2-
// FIXME(-Znext-solver): enable this test
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
35

46
// A regression test for an error in `redis` while working on #139587.
57
//
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
error[E0792]: expected generic lifetime parameter, found `'_`
1+
error: non-defining use of `impl Sized + '_` in the defining scope
22
--> $DIR/as-projection-term.rs:14:19
33
|
4-
LL | fn recur<'a>() -> impl Sized + 'a {
5-
| -- this generic parameter must be used with a generic lifetime parameter
6-
...
74
LL | prove_proj(|| recur());
85
| ^^^^^^^
96

107
error: aborting due to 1 previous error
118

12-
For more information about this error, try `rustc --explain E0792`.

tests/ui/impl-trait/non-defining-uses/as-projection-term.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ fn recur<'a>() -> impl Sized + 'a {
1212
// inference variable at this point, we unify it with `opaque<'1>` and
1313
// end up ignoring that defining use as the hidden type is equal to its key.
1414
prove_proj(|| recur());
15-
//[next]~^ ERROR expected generic lifetime parameter, found `'_`
15+
//[next]~^ ERROR non-defining use of `impl Sized + '_` in the defining scope
1616
}
1717
fn main() {}

0 commit comments

Comments
 (0)