Skip to content

Commit 80f193e

Browse files
Merge #9536
9536: Represent opaque types with TyKind::OpaqueType r=flodiebold a=flodiebold ... instead of using `AliasTy`. Chalk turns the alias type into the placeholder during unification anyway, which confuses our method resolution logic. Fixes #9530. Co-authored-by: Florian Diebold <[email protected]>
2 parents 552b50d + d674d71 commit 80f193e

File tree

6 files changed

+41
-24
lines changed

6 files changed

+41
-24
lines changed

crates/hir_ty/src/chalk_ext.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl TyExt for Ty {
183183

184184
fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
185185
match self.kind(&Interner) {
186-
TyKind::OpaqueType(opaque_ty_id, ..) => {
186+
TyKind::OpaqueType(opaque_ty_id, subst) => {
187187
match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
188188
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
189189
let krate = def.module(db.upcast()).krate();
@@ -206,7 +206,14 @@ impl TyExt for Ty {
206206
None
207207
}
208208
}
209-
ImplTraitId::ReturnTypeImplTrait(..) => None,
209+
ImplTraitId::ReturnTypeImplTrait(func, idx) => {
210+
db.return_type_impl_traits(func).map(|it| {
211+
let data = (*it)
212+
.as_ref()
213+
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
214+
data.substitute(&Interner, &subst).into_value_and_skipped_binders().0
215+
})
216+
}
210217
}
211218
}
212219
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {

crates/hir_ty/src/display.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ impl HirDisplay for Ty {
384384
&TyKind::Alias(AliasTy::Opaque(OpaqueTy {
385385
opaque_ty_id,
386386
substitution: ref parameters,
387-
})) => {
387+
}))
388+
| &TyKind::OpaqueType(opaque_ty_id, ref parameters) => {
388389
let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into());
389390
if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
390391
datas =

crates/hir_ty/src/interner.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ impl chalk_ir::interner::Interner for Interner {
9393
alias: &chalk_ir::AliasTy<Interner>,
9494
fmt: &mut fmt::Formatter<'_>,
9595
) -> Option<fmt::Result> {
96-
tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
96+
use std::fmt::Debug;
97+
match alias {
98+
chalk_ir::AliasTy::Projection(projection_ty) => {
99+
Interner::debug_projection_ty(projection_ty, fmt)
100+
}
101+
chalk_ir::AliasTy::Opaque(opaque_ty) => Some(opaque_ty.fmt(fmt)),
102+
}
97103
}
98104

99105
fn debug_projection_ty(
@@ -114,7 +120,7 @@ impl chalk_ir::interner::Interner for Interner {
114120
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
115121
fmt: &mut fmt::Formatter<'_>,
116122
) -> Option<fmt::Result> {
117-
Some(fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish())
123+
Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
118124
}
119125

120126
fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {

crates/hir_ty/src/lower.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use crate::{
3838
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
3939
},
4040
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
41-
FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
41+
FnSubst, ImplTraitId, Interner, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
4242
QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
4343
TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
4444
};
@@ -250,11 +250,7 @@ impl<'a> TyLoweringContext<'a> {
250250
let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
251251
let generics = generics(self.db.upcast(), func.into());
252252
let parameters = generics.bound_vars_subst(self.in_binders);
253-
TyKind::Alias(AliasTy::Opaque(OpaqueTy {
254-
opaque_ty_id,
255-
substitution: parameters,
256-
}))
257-
.intern(&Interner)
253+
TyKind::OpaqueType(opaque_ty_id, parameters).intern(&Interner)
258254
}
259255
ImplTraitLoweringMode::Param => {
260256
let idx = self.impl_trait_counter.get();

crates/hir_ty/src/tests/regression.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,3 +1058,22 @@ fn cfg_tail() {
10581058
"#]],
10591059
)
10601060
}
1061+
1062+
#[test]
1063+
fn impl_trait_in_option_9530() {
1064+
check_types(
1065+
r#"
1066+
struct Option<T>;
1067+
impl<T> Option<T> {
1068+
fn unwrap(self) -> T { loop {} }
1069+
}
1070+
fn make() -> Option<impl Copy> { Option }
1071+
trait Copy {}
1072+
fn test() {
1073+
let o = make();
1074+
o.unwrap();
1075+
//^^^^^^^^^^ impl Copy
1076+
}
1077+
"#,
1078+
)
1079+
}

crates/hir_ty/src/tls.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Implementation of Chalk debug helper functions using TLS.
2-
use std::fmt::{self, Debug};
2+
use std::fmt;
33

4-
use chalk_ir::AliasTy;
54
use itertools::Itertools;
65

76
use crate::{
@@ -53,17 +52,6 @@ impl DebugContext<'_> {
5352
write!(fmt, "{}::{}", trait_data.name, type_alias_data.name)
5453
}
5554

56-
pub(crate) fn debug_alias(
57-
&self,
58-
alias_ty: &AliasTy<Interner>,
59-
fmt: &mut fmt::Formatter<'_>,
60-
) -> Result<(), fmt::Error> {
61-
match alias_ty {
62-
AliasTy::Projection(projection_ty) => self.debug_projection_ty(projection_ty, fmt),
63-
AliasTy::Opaque(opaque_ty) => opaque_ty.fmt(fmt),
64-
}
65-
}
66-
6755
pub(crate) fn debug_projection_ty(
6856
&self,
6957
projection_ty: &chalk_ir::ProjectionTy<Interner>,

0 commit comments

Comments
 (0)