Generate inference vars and obligations for projections in opaque types instead of trying to normalize them.
This commit is contained in:
parent
5fb1a65215
commit
34de78fd81
@ -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;
|
||||
@ -995,31 +994,37 @@ fn fold_opaque_ty(
|
||||
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);
|
||||
self.obligations.reserve(item_bounds.len());
|
||||
for (predicate, _) in item_bounds {
|
||||
debug!(?predicate);
|
||||
let predicate = predicate.subst(tcx, substs);
|
||||
debug!(?predicate);
|
||||
|
||||
debug!(?bounds);
|
||||
// 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`.
|
||||
@ -1029,7 +1034,7 @@ fn fold_opaque_ty(
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -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!()
|
||||
}
|
||||
|
||||
|
@ -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 `()`
|
||||
|
||||
Some errors have detailed explanations: E0433, E0720.
|
||||
For more information about an error, try `rustc --explain E0433`.
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0433, E0720.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user