Skip to content

Commit 7bce50c

Browse files
committed
Register member constraints on the final merged hidden type
Previously we did this per hidden type candiate, which didn't always have all the information available.
1 parent 9110911 commit 7bce50c

File tree

13 files changed

+62
-96
lines changed

13 files changed

+62
-96
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,16 @@ pub(crate) fn type_check<'mir, 'tcx>(
203203
ConstraintCategory::OpaqueType,
204204
CustomTypeOp::new(
205205
|infcx| {
206-
Ok(decl
206+
let res = decl
207207
.hidden_type(infcx, &cause, param_env)
208-
.map_err(|e| e.0)?)
208+
.map_err(|e| e.0)?;
209+
infcx.register_member_constraints(
210+
param_env,
211+
opaque_type_key,
212+
res.value.ty,
213+
res.value.span,
214+
);
215+
Ok(res)
209216
},
210217
|| "opaque_type_map".to_string(),
211218
),

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
2-
use rustc_infer::infer::NllRegionVariableOrigin;
2+
use rustc_infer::infer::{InferOk, NllRegionVariableOrigin};
33
use rustc_infer::traits::ObligationCause;
44
use rustc_middle::mir::ConstraintCategory;
55
use rustc_middle::ty::relate::TypeRelation;
@@ -136,7 +136,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
136136
true
137137
}
138138

139-
fn constrain_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
139+
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
140140
let param_env = self.param_env();
141141
let span = self.span();
142142
let def_id = self.type_checker.body.source.def_id().expect_local();
@@ -148,39 +148,18 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
148148
self.category,
149149
CustomTypeOp::new(
150150
|infcx| {
151-
let (concrete_ty, opaque_type_key) =
152-
match (a.kind(), b.kind(), a_is_expected) {
153-
(ty::Opaque(..), ty::Opaque(..), true) => {
154-
(b, a.expect_opaque_type())
155-
}
156-
(ty::Opaque(..), ty::Opaque(..), false) => {
157-
(a, b.expect_opaque_type())
158-
}
159-
(ty::Opaque(..), _, _) => (b, a.expect_opaque_type()),
160-
(_, ty::Opaque(..), _) => (a, b.expect_opaque_type()),
161-
_ => span_bug!(
162-
span,
163-
"no opaque types in constrain_opaque_type {:?}, {:?}",
164-
a,
165-
b
166-
),
167-
};
168-
let mut result = self.type_checker.infcx.constrain_opaque_type(
169-
param_env,
170-
opaque_type_key,
171-
concrete_ty,
172-
span,
173-
)?;
174-
result.obligations.push(infcx.opaque_ty_obligation(
175-
a,
176-
b,
177-
a_is_expected,
178-
param_env,
179-
cause,
180-
));
181-
Ok(result)
151+
Ok(InferOk {
152+
value: (),
153+
obligations: vec![infcx.opaque_ty_obligation(
154+
a,
155+
b,
156+
a_is_expected,
157+
param_env,
158+
cause,
159+
)],
160+
})
182161
},
183-
|| "constrain_opaque_type".to_string(),
162+
|| "register_opaque_type".to_string(),
184163
),
185164
)
186165
.unwrap();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
723723
true
724724
}
725725

726-
fn constrain_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
726+
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
727727
self.obligations.push(self.infcx.opaque_ty_obligation(
728728
a,
729729
b,

compiler/rustc_infer/src/infer/nll_relate/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub trait TypeRelatingDelegate<'tcx> {
9090
info: ty::VarianceDiagInfo<'tcx>,
9191
);
9292

93-
fn constrain_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool);
93+
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool);
9494

9595
fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
9696

@@ -591,7 +591,7 @@ where
591591
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
592592
_ => unreachable!(),
593593
};
594-
self.delegate.constrain_opaque_type(a, b, true);
594+
self.delegate.register_opaque_type(a, b, true);
595595
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
596596
Ok(a)
597597
}

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2-
use crate::infer::{InferCtxt, InferOk, InferResult};
2+
use crate::infer::{InferCtxt, InferOk};
33
use crate::traits::{self, PredicateObligation, PredicateObligations};
44
use hir::def_id::{DefId, LocalDefId};
55
use hir::OpaqueTyOrigin;
@@ -379,13 +379,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
379379
/// - `free_region_relations` -- something that can be used to relate
380380
/// the free regions (`'a`) that appear in the impl trait.
381381
#[instrument(level = "debug", skip(self))]
382-
pub fn constrain_opaque_type(
382+
pub fn register_member_constraints(
383383
&self,
384384
param_env: ty::ParamEnv<'tcx>,
385385
opaque_type_key: OpaqueTypeKey<'tcx>,
386386
concrete_ty: Ty<'tcx>,
387387
span: Span,
388-
) -> InferResult<'tcx, ()> {
388+
) {
389389
let def_id = opaque_type_key.def_id;
390390

391391
let tcx = self.tcx;
@@ -445,7 +445,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
445445
)
446446
},
447447
});
448-
Ok(InferOk { value: (), obligations: vec![] })
449448
}
450449

451450
pub fn opaque_ty_obligation(

compiler/rustc_trait_selection/src/opaque_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
3333
/// purpose of this function is to do that translation.
3434
///
3535
/// (*) C1 and C2 were introduced in the comments on
36-
/// `constrain_opaque_type`. Read that comment for more context.
36+
/// `register_member_constraints`. Read that comment for more context.
3737
///
3838
/// # Parameters
3939
///

src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ LL | | }
1414
= help: consider adding the following bound: `'a: 'b`
1515

1616
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
17-
--> $DIR/ret-impl-trait-one.rs:16:65
17+
--> $DIR/ret-impl-trait-one.rs:16:80
1818
|
19-
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
20-
| ^^^^^^^^^^^^^^
19+
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
20+
| ____________________________________--__________________________________________^
21+
| | |
22+
| | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here
23+
LL | |
24+
LL | | (a, b)
25+
LL | | }
26+
| |_^
2127
|
22-
note: hidden type `(&'a u8, &'<empty> u8)` captures lifetime smaller than the function body
23-
--> $DIR/ret-impl-trait-one.rs:16:65
28+
help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound
2429
|
25-
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
26-
| ^^^^^^^^^^^^^^
30+
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
31+
| ++++
2732

2833
error: aborting due to 2 previous errors
2934

src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,21 @@ LL | | }
1111
| |_^ ...but data from `a` is returned here
1212

1313
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
14-
--> $DIR/ret-impl-trait-one.rs:16:65
14+
--> $DIR/ret-impl-trait-one.rs:16:80
1515
|
16-
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
17-
| ^^^^^^^^^^^^^^
16+
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
17+
| ____________________________________--__________________________________________^
18+
| | |
19+
| | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here
20+
LL | |
21+
LL | | (a, b)
22+
LL | | }
23+
| |_^
1824
|
19-
note: hidden type `(&'a u8, &'<empty> u8)` captures lifetime smaller than the function body
20-
--> $DIR/ret-impl-trait-one.rs:16:65
25+
help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound
2126
|
22-
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
23-
| ^^^^^^^^^^^^^^
27+
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
28+
| ++++
2429

2530
error: aborting due to 2 previous errors
2631

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ where
2727
// ```
2828
if condition() { a } else { b }
2929
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
30-
//~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
3130
}
3231

3332
fn condition() -> bool {

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,6 @@ help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'
1212
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b
1313
| ++++
1414

15-
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
16-
--> $DIR/ordinary-bounds-unrelated.rs:28:33
17-
|
18-
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
19-
| -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
20-
...
21-
LL | if condition() { a } else { b }
22-
| ^
23-
|
24-
help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound
25-
|
26-
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b
27-
| ++++
28-
29-
error: aborting due to 2 previous errors
15+
error: aborting due to previous error
3016

3117
For more information about this error, try `rustc --explain E0700`.

0 commit comments

Comments
 (0)