mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-17 10:18:31 +00:00
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 <flodiebold@gmail.com>
This commit is contained in:
commit
80f193e3f8
6 changed files with 41 additions and 24 deletions
|
@ -183,7 +183,7 @@ impl TyExt for Ty {
|
|||
|
||||
fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
|
||||
match self.kind(&Interner) {
|
||||
TyKind::OpaqueType(opaque_ty_id, ..) => {
|
||||
TyKind::OpaqueType(opaque_ty_id, subst) => {
|
||||
match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
|
||||
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
|
||||
let krate = def.module(db.upcast()).krate();
|
||||
|
@ -206,7 +206,14 @@ impl TyExt for Ty {
|
|||
None
|
||||
}
|
||||
}
|
||||
ImplTraitId::ReturnTypeImplTrait(..) => None,
|
||||
ImplTraitId::ReturnTypeImplTrait(func, idx) => {
|
||||
db.return_type_impl_traits(func).map(|it| {
|
||||
let data = (*it)
|
||||
.as_ref()
|
||||
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
|
||||
data.substitute(&Interner, &subst).into_value_and_skipped_binders().0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
|
||||
|
|
|
@ -384,7 +384,8 @@ impl HirDisplay for Ty {
|
|||
&TyKind::Alias(AliasTy::Opaque(OpaqueTy {
|
||||
opaque_ty_id,
|
||||
substitution: ref parameters,
|
||||
})) => {
|
||||
}))
|
||||
| &TyKind::OpaqueType(opaque_ty_id, ref parameters) => {
|
||||
let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into());
|
||||
if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
|
||||
datas =
|
||||
|
|
|
@ -93,7 +93,13 @@ impl chalk_ir::interner::Interner for Interner {
|
|||
alias: &chalk_ir::AliasTy<Interner>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
|
||||
use std::fmt::Debug;
|
||||
match alias {
|
||||
chalk_ir::AliasTy::Projection(projection_ty) => {
|
||||
Interner::debug_projection_ty(projection_ty, fmt)
|
||||
}
|
||||
chalk_ir::AliasTy::Opaque(opaque_ty) => Some(opaque_ty.fmt(fmt)),
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_projection_ty(
|
||||
|
@ -114,7 +120,7 @@ impl chalk_ir::interner::Interner for Interner {
|
|||
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish())
|
||||
Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
|
||||
}
|
||||
|
||||
fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
|
|
|
@ -38,7 +38,7 @@ use crate::{
|
|||
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
|
||||
},
|
||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
|
||||
FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
|
||||
FnSubst, ImplTraitId, Interner, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
|
||||
QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
|
||||
TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
|
||||
};
|
||||
|
@ -250,11 +250,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
|
||||
let generics = generics(self.db.upcast(), func.into());
|
||||
let parameters = generics.bound_vars_subst(self.in_binders);
|
||||
TyKind::Alias(AliasTy::Opaque(OpaqueTy {
|
||||
opaque_ty_id,
|
||||
substitution: parameters,
|
||||
}))
|
||||
.intern(&Interner)
|
||||
TyKind::OpaqueType(opaque_ty_id, parameters).intern(&Interner)
|
||||
}
|
||||
ImplTraitLoweringMode::Param => {
|
||||
let idx = self.impl_trait_counter.get();
|
||||
|
|
|
@ -1058,3 +1058,22 @@ fn cfg_tail() {
|
|||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impl_trait_in_option_9530() {
|
||||
check_types(
|
||||
r#"
|
||||
struct Option<T>;
|
||||
impl<T> Option<T> {
|
||||
fn unwrap(self) -> T { loop {} }
|
||||
}
|
||||
fn make() -> Option<impl Copy> { Option }
|
||||
trait Copy {}
|
||||
fn test() {
|
||||
let o = make();
|
||||
o.unwrap();
|
||||
//^^^^^^^^^^ impl Copy
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! Implementation of Chalk debug helper functions using TLS.
|
||||
use std::fmt::{self, Debug};
|
||||
use std::fmt;
|
||||
|
||||
use chalk_ir::AliasTy;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{
|
||||
|
@ -53,17 +52,6 @@ impl DebugContext<'_> {
|
|||
write!(fmt, "{}::{}", trait_data.name, type_alias_data.name)
|
||||
}
|
||||
|
||||
pub(crate) fn debug_alias(
|
||||
&self,
|
||||
alias_ty: &AliasTy<Interner>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
match alias_ty {
|
||||
AliasTy::Projection(projection_ty) => self.debug_projection_ty(projection_ty, fmt),
|
||||
AliasTy::Opaque(opaque_ty) => opaque_ty.fmt(fmt),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn debug_projection_ty(
|
||||
&self,
|
||||
projection_ty: &chalk_ir::ProjectionTy<Interner>,
|
||||
|
|
Loading…
Reference in a new issue