Loop over all opaque types instead of looking at just the first one with the same DefId

This commit is contained in:
Oli Scherer 2021-07-13 15:19:35 +00:00
parent 95f296db63
commit 587e8fd112
3 changed files with 22 additions and 13 deletions

View File

@ -542,13 +542,14 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
}
// Use borrowck to get the type with unerased regions.
let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
if let Some((opaque_type_key, concrete_type)) =
concrete_opaque_types.iter().find(|(key, _)| key.def_id == self.def_id)
{
debug!(
"find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
self.def_id, def_id, concrete_type,
);
debug!(?concrete_opaque_types);
for (opaque_type_key, concrete_type) in concrete_opaque_types {
if opaque_type_key.def_id != self.def_id {
// Ignore constraints for other opaque types.
continue;
}
debug!(?concrete_type, ?opaque_type_key.substs, "found constraint");
// FIXME(oli-obk): trace the actual span from inference to improve errors.
let span = self.tcx.def_span(def_id);
@ -613,11 +614,6 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
} else {
self.found = Some((span, concrete_type));
}
} else {
debug!(
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
self.def_id, def_id,
);
}
}
}

View File

@ -12,6 +12,7 @@ trait Output<'a> {}
impl<'a> Output<'a> for &'a str {}
fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
//~^ ERROR: concrete type differs from previous defining opaque type use
let out: OpaqueOutputImpl<'a> = arg;
arg
}

View File

@ -10,6 +10,18 @@ note: hidden type `&'<empty> str` captures lifetime smaller than the function bo
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^^^^^^^^^^^^^^^^^^^
error: concrete type differs from previous defining opaque type use
--> $DIR/issue-85113.rs:14:1
|
LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'<empty> str`, got `&'a str`
|
note: previous use here
--> $DIR/issue-85113.rs:14:1
|
LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0477]: the type `&'<empty> str` does not fulfill the required lifetime
--> $DIR/issue-85113.rs:5:29
|
@ -42,7 +54,7 @@ LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
= note: expected `Output<'a>`
found `Output<'_>`
error: aborting due to 3 previous errors
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0477, E0495, E0700.
For more information about an error, try `rustc --explain E0477`.