Rollup merge of #87107 - oli-obk:tait_double, r=nikomatsakis
Loop over all opaque types instead of looking at just the first one with the same DefId This exposed a bug in VecMap and is needed for https://github.com/rust-lang/rust/pull/86410 anyway r? ``@spastorino`` cc ``@nikomatsakis``
This commit is contained in:
commit
8273567a71
@ -127,13 +127,15 @@ impl<K, V> IntoIterator for VecMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Extend<(K, V)> for VecMap<K, V> {
|
||||
impl<K: PartialEq, V> Extend<(K, V)> for VecMap<K, V> {
|
||||
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
|
||||
self.0.extend(iter);
|
||||
for (k, v) in iter {
|
||||
self.insert(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
fn extend_one(&mut self, item: (K, V)) {
|
||||
self.0.extend_one(item);
|
||||
fn extend_one(&mut self, (k, v): (K, V)) {
|
||||
self.insert(k, v);
|
||||
}
|
||||
|
||||
fn extend_reserve(&mut self, additional: usize) {
|
||||
|
@ -509,11 +509,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||
use rustc_hir::{Expr, ImplItem, Item, TraitItem};
|
||||
|
||||
debug!("find_opaque_ty_constraints({:?})", def_id);
|
||||
|
||||
struct ConstraintLocator<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
@ -522,13 +521,11 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||
}
|
||||
|
||||
impl ConstraintLocator<'_> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn check(&mut self, def_id: LocalDefId) {
|
||||
// Don't try to check items that cannot possibly constrain the type.
|
||||
if !self.tcx.has_typeck_results(def_id) {
|
||||
debug!(
|
||||
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no typeck results",
|
||||
self.def_id, def_id,
|
||||
);
|
||||
debug!("no constraint: no typeck results");
|
||||
return;
|
||||
}
|
||||
// Calling `mir_borrowck` can lead to cycle errors through
|
||||
@ -540,21 +537,19 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||
.get_by(|(key, _)| key.def_id == self.def_id)
|
||||
.is_none()
|
||||
{
|
||||
debug!(
|
||||
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
|
||||
self.def_id, def_id,
|
||||
);
|
||||
debug!("no constraints in typeck results");
|
||||
return;
|
||||
}
|
||||
// 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);
|
||||
@ -603,7 +598,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||
|
||||
if let Some((prev_span, prev_ty)) = self.found {
|
||||
if *concrete_type != prev_ty {
|
||||
debug!("find_opaque_ty_constraints: span={:?}", span);
|
||||
debug!(?span);
|
||||
// Found different concrete types for the opaque type.
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
span,
|
||||
@ -619,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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user