mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 14:51:48 +00:00
Represent opaque types with TyKind::OpaqueType
... instead of using `AliasTy`. Chalk turns the alias type into the placeholder during unification anyway, which confuses our method resolution logic. Fixes #9530.
This commit is contained in:
parent
552b50de9e
commit
d674d7185d
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>> {
|
fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
|
||||||
match self.kind(&Interner) {
|
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()) {
|
match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
|
||||||
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
|
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
|
||||||
let krate = def.module(db.upcast()).krate();
|
let krate = def.module(db.upcast()).krate();
|
||||||
|
@ -206,7 +206,14 @@ impl TyExt for Ty {
|
||||||
None
|
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)) => {
|
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
|
||||||
|
|
|
@ -384,7 +384,8 @@ impl HirDisplay for Ty {
|
||||||
&TyKind::Alias(AliasTy::Opaque(OpaqueTy {
|
&TyKind::Alias(AliasTy::Opaque(OpaqueTy {
|
||||||
opaque_ty_id,
|
opaque_ty_id,
|
||||||
substitution: ref parameters,
|
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());
|
let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into());
|
||||||
if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
|
if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
|
||||||
datas =
|
datas =
|
||||||
|
|
|
@ -93,7 +93,13 @@ impl chalk_ir::interner::Interner for Interner {
|
||||||
alias: &chalk_ir::AliasTy<Interner>,
|
alias: &chalk_ir::AliasTy<Interner>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
) -> Option<fmt::Result> {
|
) -> 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(
|
fn debug_projection_ty(
|
||||||
|
@ -114,7 +120,7 @@ impl chalk_ir::interner::Interner for Interner {
|
||||||
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
|
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
|
||||||
fmt: &mut fmt::Formatter<'_>,
|
fmt: &mut fmt::Formatter<'_>,
|
||||||
) -> Option<fmt::Result> {
|
) -> 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> {
|
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,
|
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
|
||||||
},
|
},
|
||||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
|
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,
|
QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
|
||||||
TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
|
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 opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
|
||||||
let generics = generics(self.db.upcast(), func.into());
|
let generics = generics(self.db.upcast(), func.into());
|
||||||
let parameters = generics.bound_vars_subst(self.in_binders);
|
let parameters = generics.bound_vars_subst(self.in_binders);
|
||||||
TyKind::Alias(AliasTy::Opaque(OpaqueTy {
|
TyKind::OpaqueType(opaque_ty_id, parameters).intern(&Interner)
|
||||||
opaque_ty_id,
|
|
||||||
substitution: parameters,
|
|
||||||
}))
|
|
||||||
.intern(&Interner)
|
|
||||||
}
|
}
|
||||||
ImplTraitLoweringMode::Param => {
|
ImplTraitLoweringMode::Param => {
|
||||||
let idx = self.impl_trait_counter.get();
|
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.
|
//! Implementation of Chalk debug helper functions using TLS.
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt;
|
||||||
|
|
||||||
use chalk_ir::AliasTy;
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -53,17 +52,6 @@ impl DebugContext<'_> {
|
||||||
write!(fmt, "{}::{}", trait_data.name, type_alias_data.name)
|
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(
|
pub(crate) fn debug_projection_ty(
|
||||||
&self,
|
&self,
|
||||||
projection_ty: &chalk_ir::ProjectionTy<Interner>,
|
projection_ty: &chalk_ir::ProjectionTy<Interner>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue