Skip to content

Commit 34de78f

Browse files
committed
Generate inference vars and obligations for projections in opaque types instead of trying to normalize them.
1 parent 5fb1a65 commit 34de78f

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

compiler/rustc_trait_selection/src/opaque_types.rs

+24-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::infer::InferCtxtExt as _;
21
use crate::traits::{self, ObligationCause, PredicateObligation};
32
use rustc_data_structures::fx::FxHashMap;
43
use rustc_data_structures::sync::Lrc;
@@ -995,31 +994,37 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
995994
debug!("generated new type inference var {:?}", ty_var.kind());
996995

997996
let item_bounds = tcx.explicit_item_bounds(def_id);
998-
debug!(?item_bounds);
999-
let bounds: Vec<_> =
1000-
item_bounds.iter().map(|(bound, _)| bound.subst(tcx, substs)).collect();
1001-
1002-
let param_env = tcx.param_env(def_id);
1003-
let InferOk { value: bounds, obligations } = infcx.partially_normalize_associated_types_in(
1004-
ObligationCause::misc(self.value_span, self.body_id),
1005-
param_env,
1006-
bounds,
1007-
);
1008-
self.obligations.extend(obligations);
1009997

1010-
debug!(?bounds);
998+
self.obligations.reserve(item_bounds.len());
999+
for (predicate, _) in item_bounds {
1000+
debug!(?predicate);
1001+
let predicate = predicate.subst(tcx, substs);
1002+
debug!(?predicate);
1003+
1004+
// We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
1005+
let predicate = predicate.fold_with(&mut BottomUpFolder {
1006+
tcx,
1007+
ty_op: |ty| match ty.kind() {
1008+
ty::Projection(projection_ty) => infcx.infer_projection(
1009+
self.param_env,
1010+
*projection_ty,
1011+
ObligationCause::misc(self.value_span, self.body_id),
1012+
0,
1013+
&mut self.obligations,
1014+
),
1015+
_ => ty,
1016+
},
1017+
lt_op: |lt| lt,
1018+
ct_op: |ct| ct,
1019+
});
1020+
debug!(?predicate);
10111021

1012-
for predicate in &bounds {
10131022
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
10141023
if projection.ty.references_error() {
10151024
// No point on adding these obligations since there's a type error involved.
10161025
return ty_var;
10171026
}
10181027
}
1019-
}
1020-
1021-
self.obligations.reserve(bounds.len());
1022-
for predicate in bounds {
10231028
// Change the predicate to refer to the type variable,
10241029
// which will be the concrete type instead of the opaque type.
10251030
// This also instantiates nested instances of `impl Trait`.
@@ -1029,7 +1034,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
10291034
traits::ObligationCause::new(self.value_span, self.body_id, traits::OpaqueType);
10301035

10311036
// Require that the predicate holds for the concrete type.
1032-
debug!("instantiate_opaque_types: predicate={:?}", predicate);
1037+
debug!(?predicate);
10331038
self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate));
10341039
}
10351040

src/test/ui/impl-trait/issue-72911.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint>
1616

1717
fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
1818
//~^ ERROR: failed to resolve
19+
//~| ERROR: `()` is not an iterator
1920
unimplemented!()
2021
}
2122

src/test/ui/impl-trait/issue-72911.stderr

+11-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,15 @@ LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = L
2828
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
2929
| -------------------------------------- returning this opaque type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
3030

31-
error: aborting due to 3 previous errors
31+
error[E0277]: `()` is not an iterator
32+
--> $DIR/issue-72911.rs:17:20
33+
|
34+
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
36+
|
37+
= help: the trait `Iterator` is not implemented for `()`
38+
39+
error: aborting due to 4 previous errors
3240

33-
Some errors have detailed explanations: E0433, E0720.
34-
For more information about an error, try `rustc --explain E0433`.
41+
Some errors have detailed explanations: E0277, E0433, E0720.
42+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)