Skip to content

Commit

Permalink
Generate inference vars and obligations for projections in opaque typ…
Browse files Browse the repository at this point in the history
…es instead of trying to normalize them.
  • Loading branch information
oli-obk committed Sep 20, 2021
1 parent 5fb1a65 commit 34de78f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 22 deletions.
43 changes: 24 additions & 19 deletions compiler/rustc_trait_selection/src/opaque_types.rs
@@ -1,4 +1,3 @@
use crate::infer::InferCtxtExt as _;
use crate::traits::{self, ObligationCause, PredicateObligation};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
Expand Down Expand Up @@ -995,31 +994,37 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
debug!("generated new type inference var {:?}", ty_var.kind());

let item_bounds = tcx.explicit_item_bounds(def_id);
debug!(?item_bounds);
let bounds: Vec<_> =
item_bounds.iter().map(|(bound, _)| bound.subst(tcx, substs)).collect();

let param_env = tcx.param_env(def_id);
let InferOk { value: bounds, obligations } = infcx.partially_normalize_associated_types_in(
ObligationCause::misc(self.value_span, self.body_id),
param_env,
bounds,
);
self.obligations.extend(obligations);

debug!(?bounds);
self.obligations.reserve(item_bounds.len());
for (predicate, _) in item_bounds {
debug!(?predicate);
let predicate = predicate.subst(tcx, substs);
debug!(?predicate);

// We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| match ty.kind() {
ty::Projection(projection_ty) => infcx.infer_projection(
self.param_env,
*projection_ty,
ObligationCause::misc(self.value_span, self.body_id),
0,
&mut self.obligations,
),
_ => ty,
},
lt_op: |lt| lt,
ct_op: |ct| ct,
});
debug!(?predicate);

for predicate in &bounds {
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
if projection.ty.references_error() {
// No point on adding these obligations since there's a type error involved.
return ty_var;
}
}
}

self.obligations.reserve(bounds.len());
for predicate in bounds {
// Change the predicate to refer to the type variable,
// which will be the concrete type instead of the opaque type.
// This also instantiates nested instances of `impl Trait`.
Expand All @@ -1029,7 +1034,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
traits::ObligationCause::new(self.value_span, self.body_id, traits::OpaqueType);

// Require that the predicate holds for the concrete type.
debug!("instantiate_opaque_types: predicate={:?}", predicate);
debug!(?predicate);
self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate));
}

Expand Down
1 change: 1 addition & 0 deletions src/test/ui/impl-trait/issue-72911.rs
Expand Up @@ -16,6 +16,7 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint>

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

Expand Down
14 changes: 11 additions & 3 deletions src/test/ui/impl-trait/issue-72911.stderr
Expand Up @@ -28,7 +28,15 @@ LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = L
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
| -------------------------------------- returning this opaque type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`

error: aborting due to 3 previous errors
error[E0277]: `()` is not an iterator
--> $DIR/issue-72911.rs:17:20
|
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`

error: aborting due to 4 previous errors

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

0 comments on commit 34de78f

Please sign in to comment.