Skip to content

Commit

Permalink
Rollup merge of rust-lang#87107 - oli-obk:tait_double, r=nikomatsakis
Browse files Browse the repository at this point in the history
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 rust-lang#86410 anyway

r? ``@spastorino``

cc ``@nikomatsakis``
  • Loading branch information
GuillaumeGomez authored Jul 16, 2021
2 parents 2119976 + 587e8fd commit 8273567
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
10 changes: 6 additions & 4 deletions compiler/rustc_data_structures/src/vec_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
36 changes: 13 additions & 23 deletions compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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,
);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/type-alias-impl-trait/issue-85113.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
14 changes: 13 additions & 1 deletion src/test/ui/type-alias-impl-trait/issue-85113.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand Down Expand Up @@ -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`.

0 comments on commit 8273567

Please sign in to comment.