mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Auto merge of #16996 - Veykril:lt-err, r=Veykril
internal: Lower outlive goals, respect them in display impls
This commit is contained in:
commit
c3b8c2a254
23 changed files with 303 additions and 122 deletions
|
@ -30,6 +30,8 @@ pub fn find_path(
|
||||||
find_path_inner(FindPathCtx { db, prefixed: None, prefer_no_std, prefer_prelude }, item, from)
|
find_path_inner(FindPathCtx { db, prefixed: None, prefer_no_std, prefer_prelude }, item, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find a path that can be used to refer to a certain item. This can depend on
|
||||||
|
/// *from where* you're referring to the item, hence the `from` parameter.
|
||||||
pub fn find_path_prefixed(
|
pub fn find_path_prefixed(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
item: ItemInNs,
|
item: ItemInNs,
|
||||||
|
@ -255,7 +257,7 @@ fn find_in_scope(
|
||||||
item: ItemInNs,
|
item: ItemInNs,
|
||||||
) -> Option<Name> {
|
) -> Option<Name> {
|
||||||
def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| {
|
def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| {
|
||||||
def_map[local_id].scope.name_of(item).map(|(name, _, _)| name.clone())
|
def_map[local_id].scope.names_of(item, |name, _, _| Some(name.clone()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ use crate::{
|
||||||
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct TypeParamData {
|
pub struct TypeParamData {
|
||||||
|
/// [`None`] only if the type ref is an [`TypeRef::ImplTrait`]. FIXME: Might be better to just
|
||||||
|
/// make it always be a value, giving impl trait a special name.
|
||||||
pub name: Option<Name>,
|
pub name: Option<Name>,
|
||||||
pub default: Option<Interned<TypeRef>>,
|
pub default: Option<Interned<TypeRef>>,
|
||||||
pub provenance: TypeParamProvenance,
|
pub provenance: TypeParamProvenance,
|
||||||
|
|
|
@ -277,13 +277,43 @@ impl ItemScope {
|
||||||
ItemInNs::Types(def) => self.types.iter().find_map(|(name, &(other_def, vis, i))| {
|
ItemInNs::Types(def) => self.types.iter().find_map(|(name, &(other_def, vis, i))| {
|
||||||
(other_def == def).then_some((name, vis, i.is_none()))
|
(other_def == def).then_some((name, vis, i.is_none()))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
ItemInNs::Values(def) => self.values.iter().find_map(|(name, &(other_def, vis, i))| {
|
ItemInNs::Values(def) => self.values.iter().find_map(|(name, &(other_def, vis, i))| {
|
||||||
(other_def == def).then_some((name, vis, i.is_none()))
|
(other_def == def).then_some((name, vis, i.is_none()))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// XXX: this is O(N) rather than O(1), try to not introduce new usages.
|
||||||
|
pub(crate) fn names_of<T>(
|
||||||
|
&self,
|
||||||
|
item: ItemInNs,
|
||||||
|
mut cb: impl FnMut(&Name, Visibility, bool) -> Option<T>,
|
||||||
|
) -> Option<T> {
|
||||||
|
match item {
|
||||||
|
ItemInNs::Macros(def) => self
|
||||||
|
.macros
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(name, &(other_def, vis, i))| {
|
||||||
|
(other_def == def).then_some((name, vis, i.is_none()))
|
||||||
|
})
|
||||||
|
.find_map(|(a, b, c)| cb(a, b, c)),
|
||||||
|
ItemInNs::Types(def) => self
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(name, &(other_def, vis, i))| {
|
||||||
|
(other_def == def).then_some((name, vis, i.is_none()))
|
||||||
|
})
|
||||||
|
.find_map(|(a, b, c)| cb(a, b, c)),
|
||||||
|
ItemInNs::Values(def) => self
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(name, &(other_def, vis, i))| {
|
||||||
|
(other_def == def).then_some((name, vis, i.is_none()))
|
||||||
|
})
|
||||||
|
.find_map(|(a, b, c)| cb(a, b, c)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
|
pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
|
||||||
self.types
|
self.types
|
||||||
.values()
|
.values()
|
||||||
|
|
|
@ -422,6 +422,10 @@ impl ModuleId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn crate_def_map(self, db: &dyn DefDatabase) -> Arc<DefMap> {
|
||||||
|
db.crate_def_map(self.krate)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn krate(self) -> CrateId {
|
pub fn krate(self) -> CrateId {
|
||||||
self.krate
|
self.krate
|
||||||
}
|
}
|
||||||
|
@ -438,6 +442,8 @@ impl ModuleId {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing
|
||||||
|
/// the block, if `self` corresponds to a block expression.
|
||||||
pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
|
pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
|
||||||
self.def_map(db).containing_module(self.local_id)
|
self.def_map(db).containing_module(self.local_id)
|
||||||
}
|
}
|
||||||
|
@ -929,6 +935,18 @@ impl GenericDefId {
|
||||||
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
|
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assoc_trait_container(self, db: &dyn DefDatabase) -> Option<TraitId> {
|
||||||
|
match match self {
|
||||||
|
GenericDefId::FunctionId(f) => f.lookup(db).container,
|
||||||
|
GenericDefId::TypeAliasId(t) => t.lookup(db).container,
|
||||||
|
GenericDefId::ConstId(c) => c.lookup(db).container,
|
||||||
|
_ => return None,
|
||||||
|
} {
|
||||||
|
ItemContainerId::TraitId(trait_) => Some(trait_),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AssocItemId> for GenericDefId {
|
impl From<AssocItemId> for GenericDefId {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Various extensions traits for Chalk types.
|
//! Various extensions traits for Chalk types.
|
||||||
|
|
||||||
use chalk_ir::{cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy};
|
use chalk_ir::{
|
||||||
|
cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, TypeOutlives, UintTy,
|
||||||
|
};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
|
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
|
||||||
generics::TypeOrConstParamData,
|
generics::TypeOrConstParamData,
|
||||||
|
@ -312,7 +314,7 @@ impl TyExt for Ty {
|
||||||
.generic_predicates(id.parent)
|
.generic_predicates(id.parent)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pred| pred.clone().substitute(Interner, &substs))
|
.map(|pred| pred.clone().substitute(Interner, &substs))
|
||||||
.filter(|wc| match &wc.skip_binders() {
|
.filter(|wc| match wc.skip_binders() {
|
||||||
WhereClause::Implemented(tr) => {
|
WhereClause::Implemented(tr) => {
|
||||||
&tr.self_type_parameter(Interner) == self
|
&tr.self_type_parameter(Interner) == self
|
||||||
}
|
}
|
||||||
|
@ -320,6 +322,9 @@ impl TyExt for Ty {
|
||||||
alias: AliasTy::Projection(proj),
|
alias: AliasTy::Projection(proj),
|
||||||
ty: _,
|
ty: _,
|
||||||
}) => &proj.self_type_parameter(db) == self,
|
}) => &proj.self_type_parameter(db) == self,
|
||||||
|
WhereClause::TypeOutlives(TypeOutlives { ty, lifetime: _ }) => {
|
||||||
|
ty == self
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
|
@ -9,6 +9,7 @@ use std::{
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use chalk_ir::{BoundVar, Safety, TyKind};
|
use chalk_ir::{BoundVar, Safety, TyKind};
|
||||||
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
data::adt::VariantData,
|
data::adt::VariantData,
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
|
@ -1072,6 +1073,7 @@ impl HirDisplay for Ty {
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
f,
|
f,
|
||||||
"impl",
|
"impl",
|
||||||
|
Either::Left(self),
|
||||||
bounds.skip_binders(),
|
bounds.skip_binders(),
|
||||||
SizedByDefault::Sized { anchor: krate },
|
SizedByDefault::Sized { anchor: krate },
|
||||||
)?;
|
)?;
|
||||||
|
@ -1087,6 +1089,7 @@ impl HirDisplay for Ty {
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
f,
|
f,
|
||||||
"impl",
|
"impl",
|
||||||
|
Either::Left(self),
|
||||||
bounds.skip_binders(),
|
bounds.skip_binders(),
|
||||||
SizedByDefault::Sized { anchor: krate },
|
SizedByDefault::Sized { anchor: krate },
|
||||||
)?;
|
)?;
|
||||||
|
@ -1189,21 +1192,24 @@ impl HirDisplay for Ty {
|
||||||
.generic_predicates(id.parent)
|
.generic_predicates(id.parent)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pred| pred.clone().substitute(Interner, &substs))
|
.map(|pred| pred.clone().substitute(Interner, &substs))
|
||||||
.filter(|wc| match &wc.skip_binders() {
|
.filter(|wc| match wc.skip_binders() {
|
||||||
WhereClause::Implemented(tr) => {
|
WhereClause::Implemented(tr) => {
|
||||||
&tr.self_type_parameter(Interner) == self
|
tr.self_type_parameter(Interner) == *self
|
||||||
}
|
}
|
||||||
WhereClause::AliasEq(AliasEq {
|
WhereClause::AliasEq(AliasEq {
|
||||||
alias: AliasTy::Projection(proj),
|
alias: AliasTy::Projection(proj),
|
||||||
ty: _,
|
ty: _,
|
||||||
}) => &proj.self_type_parameter(db) == self,
|
}) => proj.self_type_parameter(db) == *self,
|
||||||
_ => false,
|
WhereClause::AliasEq(_) => false,
|
||||||
|
WhereClause::TypeOutlives(to) => to.ty == *self,
|
||||||
|
WhereClause::LifetimeOutlives(_) => false,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let krate = id.parent.module(db.upcast()).krate();
|
let krate = id.parent.module(db.upcast()).krate();
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
f,
|
f,
|
||||||
"impl",
|
"impl",
|
||||||
|
Either::Left(self),
|
||||||
&bounds,
|
&bounds,
|
||||||
SizedByDefault::Sized { anchor: krate },
|
SizedByDefault::Sized { anchor: krate },
|
||||||
)?;
|
)?;
|
||||||
|
@ -1229,6 +1235,7 @@ impl HirDisplay for Ty {
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
f,
|
f,
|
||||||
"dyn",
|
"dyn",
|
||||||
|
Either::Left(self),
|
||||||
&bounds,
|
&bounds,
|
||||||
SizedByDefault::NotSized,
|
SizedByDefault::NotSized,
|
||||||
)?;
|
)?;
|
||||||
|
@ -1252,6 +1259,7 @@ impl HirDisplay for Ty {
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
f,
|
f,
|
||||||
"impl",
|
"impl",
|
||||||
|
Either::Left(self),
|
||||||
bounds.skip_binders(),
|
bounds.skip_binders(),
|
||||||
SizedByDefault::Sized { anchor: krate },
|
SizedByDefault::Sized { anchor: krate },
|
||||||
)?;
|
)?;
|
||||||
|
@ -1266,6 +1274,7 @@ impl HirDisplay for Ty {
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
f,
|
f,
|
||||||
"impl",
|
"impl",
|
||||||
|
Either::Left(self),
|
||||||
bounds.skip_binders(),
|
bounds.skip_binders(),
|
||||||
SizedByDefault::Sized { anchor: krate },
|
SizedByDefault::Sized { anchor: krate },
|
||||||
)?;
|
)?;
|
||||||
|
@ -1468,6 +1477,7 @@ impl SizedByDefault {
|
||||||
pub fn write_bounds_like_dyn_trait_with_prefix(
|
pub fn write_bounds_like_dyn_trait_with_prefix(
|
||||||
f: &mut HirFormatter<'_>,
|
f: &mut HirFormatter<'_>,
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
|
this: Either<&Ty, &Lifetime>,
|
||||||
predicates: &[QuantifiedWhereClause],
|
predicates: &[QuantifiedWhereClause],
|
||||||
default_sized: SizedByDefault,
|
default_sized: SizedByDefault,
|
||||||
) -> Result<(), HirDisplayError> {
|
) -> Result<(), HirDisplayError> {
|
||||||
|
@ -1476,7 +1486,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
|
||||||
|| predicates.is_empty() && matches!(default_sized, SizedByDefault::Sized { .. })
|
|| predicates.is_empty() && matches!(default_sized, SizedByDefault::Sized { .. })
|
||||||
{
|
{
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
write_bounds_like_dyn_trait(f, predicates, default_sized)
|
write_bounds_like_dyn_trait(f, this, predicates, default_sized)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1484,6 +1494,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
|
||||||
|
|
||||||
fn write_bounds_like_dyn_trait(
|
fn write_bounds_like_dyn_trait(
|
||||||
f: &mut HirFormatter<'_>,
|
f: &mut HirFormatter<'_>,
|
||||||
|
this: Either<&Ty, &Lifetime>,
|
||||||
predicates: &[QuantifiedWhereClause],
|
predicates: &[QuantifiedWhereClause],
|
||||||
default_sized: SizedByDefault,
|
default_sized: SizedByDefault,
|
||||||
) -> Result<(), HirDisplayError> {
|
) -> Result<(), HirDisplayError> {
|
||||||
|
@ -1541,6 +1552,28 @@ fn write_bounds_like_dyn_trait(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
WhereClause::TypeOutlives(to) if Either::Left(&to.ty) == this => {
|
||||||
|
if !is_fn_trait && angle_open {
|
||||||
|
write!(f, ">")?;
|
||||||
|
angle_open = false;
|
||||||
|
}
|
||||||
|
if !first {
|
||||||
|
write!(f, " + ")?;
|
||||||
|
}
|
||||||
|
to.lifetime.hir_fmt(f)?;
|
||||||
|
}
|
||||||
|
WhereClause::TypeOutlives(_) => {}
|
||||||
|
WhereClause::LifetimeOutlives(lo) if Either::Right(&lo.a) == this => {
|
||||||
|
if !is_fn_trait && angle_open {
|
||||||
|
write!(f, ">")?;
|
||||||
|
angle_open = false;
|
||||||
|
}
|
||||||
|
if !first {
|
||||||
|
write!(f, " + ")?;
|
||||||
|
}
|
||||||
|
lo.b.hir_fmt(f)?;
|
||||||
|
}
|
||||||
|
WhereClause::LifetimeOutlives(_) => {}
|
||||||
WhereClause::AliasEq(alias_eq) if is_fn_trait => {
|
WhereClause::AliasEq(alias_eq) if is_fn_trait => {
|
||||||
is_fn_trait = false;
|
is_fn_trait = false;
|
||||||
if !alias_eq.ty.is_unit() {
|
if !alias_eq.ty.is_unit() {
|
||||||
|
@ -1577,10 +1610,6 @@ fn write_bounds_like_dyn_trait(
|
||||||
}
|
}
|
||||||
ty.hir_fmt(f)?;
|
ty.hir_fmt(f)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME implement these
|
|
||||||
WhereClause::LifetimeOutlives(_) => {}
|
|
||||||
WhereClause::TypeOutlives(_) => {}
|
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,10 @@ use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
fold_tys,
|
error_lifetime, fold_tys,
|
||||||
infer::{coerce::CoerceMany, unify::InferenceTable},
|
infer::{coerce::CoerceMany, unify::InferenceTable},
|
||||||
lower::ImplTraitLoweringMode,
|
lower::ImplTraitLoweringMode,
|
||||||
static_lifetime, to_assoc_type_id,
|
to_assoc_type_id,
|
||||||
traits::FnTrait,
|
traits::FnTrait,
|
||||||
utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
|
utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
|
||||||
AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
|
AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
|
||||||
|
@ -326,7 +326,7 @@ pub struct Adjustment {
|
||||||
|
|
||||||
impl Adjustment {
|
impl Adjustment {
|
||||||
pub fn borrow(m: Mutability, ty: Ty) -> Self {
|
pub fn borrow(m: Mutability, ty: Ty) -> Self {
|
||||||
let ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
|
let ty = TyKind::Ref(m, error_lifetime(), ty).intern(Interner);
|
||||||
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty }
|
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,9 @@ use stdx::never;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::{HirDatabase, InternedClosure},
|
db::{HirDatabase, InternedClosure},
|
||||||
from_chalk_trait_id, from_placeholder_idx, make_binders,
|
error_lifetime, from_chalk_trait_id, from_placeholder_idx, make_binders,
|
||||||
mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
|
mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
|
||||||
static_lifetime, to_chalk_trait_id,
|
to_chalk_trait_id,
|
||||||
traits::FnTrait,
|
traits::FnTrait,
|
||||||
utils::{self, elaborate_clause_supertraits, generics, Generics},
|
utils::{self, elaborate_clause_supertraits, generics, Generics},
|
||||||
Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy,
|
Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy,
|
||||||
|
@ -324,7 +324,7 @@ impl CapturedItemWithoutTy {
|
||||||
BorrowKind::Mut { .. } => Mutability::Mut,
|
BorrowKind::Mut { .. } => Mutability::Mut,
|
||||||
_ => Mutability::Not,
|
_ => Mutability::Not,
|
||||||
};
|
};
|
||||||
TyKind::Ref(m, static_lifetime(), ty).intern(Interner)
|
TyKind::Ref(m, error_lifetime(), ty).intern(Interner)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return CapturedItem {
|
return CapturedItem {
|
||||||
|
|
|
@ -18,11 +18,11 @@ use triomphe::Arc;
|
||||||
use crate::{
|
use crate::{
|
||||||
autoderef::{Autoderef, AutoderefKind},
|
autoderef::{Autoderef, AutoderefKind},
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
|
error_lifetime,
|
||||||
infer::{
|
infer::{
|
||||||
Adjust, Adjustment, AutoBorrow, InferOk, InferenceContext, OverloadedDeref, PointerCast,
|
Adjust, Adjustment, AutoBorrow, InferOk, InferenceContext, OverloadedDeref, PointerCast,
|
||||||
TypeError, TypeMismatch,
|
TypeError, TypeMismatch,
|
||||||
},
|
},
|
||||||
static_lifetime,
|
|
||||||
utils::ClosureSubst,
|
utils::ClosureSubst,
|
||||||
Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
|
Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
|
||||||
Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
|
Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
|
||||||
|
@ -427,7 +427,7 @@ impl InferenceTable<'_> {
|
||||||
// compare those. Note that this means we use the target
|
// compare those. Note that this means we use the target
|
||||||
// mutability [1], since it may be that we are coercing
|
// mutability [1], since it may be that we are coercing
|
||||||
// from `&mut T` to `&U`.
|
// from `&mut T` to `&U`.
|
||||||
let lt = static_lifetime(); // FIXME: handle lifetimes correctly, see rustc
|
let lt = error_lifetime(); // FIXME: handle lifetimes correctly, see rustc
|
||||||
let derefd_from_ty = TyKind::Ref(to_mt, lt, referent_ty).intern(Interner);
|
let derefd_from_ty = TyKind::Ref(to_mt, lt, referent_ty).intern(Interner);
|
||||||
match autoderef.table.try_unify(&derefd_from_ty, to_ty) {
|
match autoderef.table.try_unify(&derefd_from_ty, to_ty) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
|
@ -621,7 +621,7 @@ impl InferenceTable<'_> {
|
||||||
(TyKind::Ref(from_mt, _, from_inner), &TyKind::Ref(to_mt, _, _)) => {
|
(TyKind::Ref(from_mt, _, from_inner), &TyKind::Ref(to_mt, _, _)) => {
|
||||||
coerce_mutabilities(*from_mt, to_mt)?;
|
coerce_mutabilities(*from_mt, to_mt)?;
|
||||||
|
|
||||||
let lt = static_lifetime();
|
let lt = error_lifetime();
|
||||||
Some((
|
Some((
|
||||||
Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() },
|
Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() },
|
||||||
Adjustment {
|
Adjustment {
|
||||||
|
|
|
@ -23,6 +23,7 @@ use crate::{
|
||||||
autoderef::{builtin_deref, deref_by_trait, Autoderef},
|
autoderef::{builtin_deref, deref_by_trait, Autoderef},
|
||||||
consteval,
|
consteval,
|
||||||
db::{InternedClosure, InternedCoroutine},
|
db::{InternedClosure, InternedCoroutine},
|
||||||
|
error_lifetime,
|
||||||
infer::{
|
infer::{
|
||||||
coerce::{CoerceMany, CoercionCause},
|
coerce::{CoerceMany, CoercionCause},
|
||||||
find_continuable,
|
find_continuable,
|
||||||
|
@ -630,7 +631,7 @@ impl InferenceContext<'_> {
|
||||||
let inner_ty = self.infer_expr_inner(*expr, &expectation);
|
let inner_ty = self.infer_expr_inner(*expr, &expectation);
|
||||||
match rawness {
|
match rawness {
|
||||||
Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
|
Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
|
||||||
Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
|
Rawness::Ref => TyKind::Ref(mutability, error_lifetime(), inner_ty),
|
||||||
}
|
}
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use hir_expand::name::Name;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consteval::{try_const_usize, usize_const},
|
consteval::{try_const_usize, usize_const},
|
||||||
|
error_lifetime,
|
||||||
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
|
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
|
||||||
lower::lower_to_chalk_mutability,
|
lower::lower_to_chalk_mutability,
|
||||||
primitive::UintTy,
|
primitive::UintTy,
|
||||||
|
@ -396,14 +397,14 @@ impl InferenceContext<'_> {
|
||||||
None => {
|
None => {
|
||||||
let inner_ty = self.table.new_type_var();
|
let inner_ty = self.table.new_type_var();
|
||||||
let ref_ty =
|
let ref_ty =
|
||||||
TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner);
|
TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner);
|
||||||
// Unification failure will be reported by the caller.
|
// Unification failure will be reported by the caller.
|
||||||
self.unify(&ref_ty, expected);
|
self.unify(&ref_ty, expected);
|
||||||
inner_ty
|
inner_ty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let subty = self.infer_pat(inner_pat, &expectation, default_bm);
|
let subty = self.infer_pat(inner_pat, &expectation, default_bm);
|
||||||
TyKind::Ref(mutability, static_lifetime(), subty).intern(Interner)
|
TyKind::Ref(mutability, error_lifetime(), subty).intern(Interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_bind_pat(
|
fn infer_bind_pat(
|
||||||
|
@ -430,7 +431,7 @@ impl InferenceContext<'_> {
|
||||||
|
|
||||||
let bound_ty = match mode {
|
let bound_ty = match mode {
|
||||||
BindingMode::Ref(mutability) => {
|
BindingMode::Ref(mutability) => {
|
||||||
TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner)
|
TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner)
|
||||||
}
|
}
|
||||||
BindingMode::Move => inner_ty.clone(),
|
BindingMode::Move => inner_ty.clone(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,8 +16,8 @@ use triomphe::Arc;
|
||||||
|
|
||||||
use super::{InferOk, InferResult, InferenceContext, TypeError};
|
use super::{InferOk, InferResult, InferenceContext, TypeError};
|
||||||
use crate::{
|
use crate::{
|
||||||
consteval::unknown_const, db::HirDatabase, fold_generic_args, fold_tys_and_consts,
|
consteval::unknown_const, db::HirDatabase, error_lifetime, fold_generic_args,
|
||||||
static_lifetime, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical,
|
fold_tys_and_consts, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical,
|
||||||
Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData,
|
Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData,
|
||||||
Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy,
|
Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy,
|
||||||
ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
|
ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
|
||||||
|
@ -43,40 +43,21 @@ impl InferenceContext<'_> {
|
||||||
let obligations = pending_obligations
|
let obligations = pending_obligations
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|obligation| match obligation.value.value.goal.data(Interner) {
|
.filter_map(|obligation| match obligation.value.value.goal.data(Interner) {
|
||||||
GoalData::DomainGoal(DomainGoal::Holds(
|
GoalData::DomainGoal(DomainGoal::Holds(clause)) => {
|
||||||
clause @ WhereClause::AliasEq(AliasEq {
|
let ty = match clause {
|
||||||
alias: AliasTy::Projection(projection),
|
WhereClause::AliasEq(AliasEq {
|
||||||
..
|
alias: AliasTy::Projection(projection),
|
||||||
}),
|
..
|
||||||
)) => {
|
}) => projection.self_type_parameter(self.db),
|
||||||
let projection_self = projection.self_type_parameter(self.db);
|
WhereClause::Implemented(trait_ref) => {
|
||||||
let uncanonical = chalk_ir::Substitute::apply(
|
trait_ref.self_type_parameter(Interner)
|
||||||
&obligation.free_vars,
|
}
|
||||||
projection_self,
|
WhereClause::TypeOutlives(to) => to.ty.clone(),
|
||||||
Interner,
|
_ => return None,
|
||||||
);
|
};
|
||||||
if matches!(
|
|
||||||
self.resolve_ty_shallow(&uncanonical).kind(Interner),
|
let uncanonical =
|
||||||
TyKind::InferenceVar(iv, TyVariableKind::General) if *iv == root,
|
chalk_ir::Substitute::apply(&obligation.free_vars, ty, Interner);
|
||||||
) {
|
|
||||||
Some(chalk_ir::Substitute::apply(
|
|
||||||
&obligation.free_vars,
|
|
||||||
clause.clone(),
|
|
||||||
Interner,
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GoalData::DomainGoal(DomainGoal::Holds(
|
|
||||||
clause @ WhereClause::Implemented(trait_ref),
|
|
||||||
)) => {
|
|
||||||
let trait_ref_self = trait_ref.self_type_parameter(Interner);
|
|
||||||
let uncanonical = chalk_ir::Substitute::apply(
|
|
||||||
&obligation.free_vars,
|
|
||||||
trait_ref_self,
|
|
||||||
Interner,
|
|
||||||
);
|
|
||||||
if matches!(
|
if matches!(
|
||||||
self.resolve_ty_shallow(&uncanonical).kind(Interner),
|
self.resolve_ty_shallow(&uncanonical).kind(Interner),
|
||||||
TyKind::InferenceVar(iv, TyVariableKind::General) if *iv == root,
|
TyKind::InferenceVar(iv, TyVariableKind::General) if *iv == root,
|
||||||
|
@ -121,8 +102,9 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
|
||||||
VariableKind::Ty(TyVariableKind::General) => ctx.new_type_var().cast(Interner),
|
VariableKind::Ty(TyVariableKind::General) => ctx.new_type_var().cast(Interner),
|
||||||
VariableKind::Ty(TyVariableKind::Integer) => ctx.new_integer_var().cast(Interner),
|
VariableKind::Ty(TyVariableKind::Integer) => ctx.new_integer_var().cast(Interner),
|
||||||
VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(Interner),
|
VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(Interner),
|
||||||
// Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
|
// Chalk can sometimes return new lifetime variables. We just replace them by errors
|
||||||
VariableKind::Lifetime => static_lifetime().cast(Interner),
|
// for now.
|
||||||
|
VariableKind::Lifetime => error_lifetime().cast(Interner),
|
||||||
VariableKind::Const(ty) => ctx.new_const_var(ty.clone()).cast(Interner),
|
VariableKind::Const(ty) => ctx.new_const_var(ty.clone()).cast(Interner),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -1020,11 +1002,11 @@ mod resolve {
|
||||||
_var: InferenceVar,
|
_var: InferenceVar,
|
||||||
_outer_binder: DebruijnIndex,
|
_outer_binder: DebruijnIndex,
|
||||||
) -> Lifetime {
|
) -> Lifetime {
|
||||||
// fall back all lifetimes to 'static -- currently we don't deal
|
// fall back all lifetimes to 'error -- currently we don't deal
|
||||||
// with any lifetimes, but we can sometimes get some lifetime
|
// with any lifetimes, but we can sometimes get some lifetime
|
||||||
// variables through Chalk's unification, and this at least makes
|
// variables through Chalk's unification, and this at least makes
|
||||||
// sure we don't leak them outside of inference
|
// sure we don't leak them outside of inference
|
||||||
crate::static_lifetime()
|
crate::error_lifetime()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -622,7 +622,7 @@ pub fn static_lifetime() -> Lifetime {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error_lifetime() -> Lifetime {
|
pub fn error_lifetime() -> Lifetime {
|
||||||
static_lifetime()
|
LifetimeData::Static.intern(Interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
|
pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
|
||||||
|
@ -861,7 +861,7 @@ where
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
Err(NoSolution)
|
Err(NoSolution)
|
||||||
} else {
|
} else {
|
||||||
Ok(static_lifetime())
|
Ok(error_lifetime())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,7 +873,7 @@ where
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
Err(NoSolution)
|
Err(NoSolution)
|
||||||
} else {
|
} else {
|
||||||
Ok(static_lifetime())
|
Ok(error_lifetime())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,10 @@ use base_db::{
|
||||||
CrateId,
|
CrateId,
|
||||||
};
|
};
|
||||||
use chalk_ir::{
|
use chalk_ir::{
|
||||||
cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
|
cast::Cast,
|
||||||
|
fold::{Shift, TypeFoldable},
|
||||||
|
interner::HasInterner,
|
||||||
|
Mutability, Safety, TypeOutlives,
|
||||||
};
|
};
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
@ -64,7 +67,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
|
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
|
||||||
FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
|
FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
|
||||||
LifetimeData, ParamKind, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
|
LifetimeData, LifetimeOutlives, ParamKind, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
|
||||||
QuantifiedWhereClauses, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder,
|
QuantifiedWhereClauses, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder,
|
||||||
TyKind, WhereClause,
|
TyKind, WhereClause,
|
||||||
};
|
};
|
||||||
|
@ -282,7 +285,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
let inner_ty = self.lower_ty(inner);
|
let inner_ty = self.lower_ty(inner);
|
||||||
// FIXME: It should infer the eldided lifetimes instead of stubbing with static
|
// FIXME: It should infer the eldided lifetimes instead of stubbing with static
|
||||||
let lifetime =
|
let lifetime =
|
||||||
lifetime.as_ref().map_or_else(static_lifetime, |lr| self.lower_lifetime(lr));
|
lifetime.as_ref().map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
|
||||||
TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
|
TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1051,13 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
WherePredicate::Lifetime { .. } => vec![].into_iter(),
|
WherePredicate::Lifetime { bound, target } => {
|
||||||
|
vec![crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
|
||||||
|
a: self.lower_lifetime(bound),
|
||||||
|
b: self.lower_lifetime(target),
|
||||||
|
}))]
|
||||||
|
.into_iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1101,7 +1110,13 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
|
bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
|
||||||
bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
||||||
}
|
}
|
||||||
TypeBound::Lifetime(_) => None,
|
TypeBound::Lifetime(l) => {
|
||||||
|
let lifetime = self.lower_lifetime(l);
|
||||||
|
Some(crate::wrap_empty_binders(WhereClause::TypeOutlives(TypeOutlives {
|
||||||
|
ty: self_ty,
|
||||||
|
lifetime,
|
||||||
|
})))
|
||||||
|
}
|
||||||
TypeBound::Error => None,
|
TypeBound::Error => None,
|
||||||
};
|
};
|
||||||
trait_ref.into_iter().chain(
|
trait_ref.into_iter().chain(
|
||||||
|
@ -1264,10 +1279,19 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
// bounds in the input.
|
// bounds in the input.
|
||||||
// INVARIANT: If this function returns `DynTy`, there should be at least one trait bound.
|
// INVARIANT: If this function returns `DynTy`, there should be at least one trait bound.
|
||||||
// These invariants are utilized by `TyExt::dyn_trait()` and chalk.
|
// These invariants are utilized by `TyExt::dyn_trait()` and chalk.
|
||||||
|
let mut lifetime = None;
|
||||||
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||||
let mut bounds: Vec<_> = bounds
|
let mut bounds: Vec<_> = bounds
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
|
.flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
|
||||||
|
.filter(|b| match b.skip_binders() {
|
||||||
|
WhereClause::Implemented(_) | WhereClause::AliasEq(_) => true,
|
||||||
|
WhereClause::LifetimeOutlives(_) => false,
|
||||||
|
WhereClause::TypeOutlives(t) => {
|
||||||
|
lifetime = Some(t.lifetime.clone());
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut multiple_regular_traits = false;
|
let mut multiple_regular_traits = false;
|
||||||
|
@ -1305,7 +1329,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We don't produce `WhereClause::{TypeOutlives, LifetimeOutlives}` yet.
|
// `WhereClause::{TypeOutlives, LifetimeOutlives}` have been filtered out
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1325,7 +1349,21 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
|
|
||||||
if let Some(bounds) = bounds {
|
if let Some(bounds) = bounds {
|
||||||
let bounds = crate::make_single_type_binders(bounds);
|
let bounds = crate::make_single_type_binders(bounds);
|
||||||
TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
|
TyKind::Dyn(DynTy {
|
||||||
|
bounds,
|
||||||
|
lifetime: match lifetime {
|
||||||
|
Some(it) => match it.bound_var(Interner) {
|
||||||
|
Some(bound_var) => LifetimeData::BoundVar(BoundVar::new(
|
||||||
|
DebruijnIndex::INNERMOST,
|
||||||
|
bound_var.index,
|
||||||
|
))
|
||||||
|
.intern(Interner),
|
||||||
|
None => it,
|
||||||
|
},
|
||||||
|
None => static_lifetime(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.intern(Interner)
|
||||||
} else {
|
} else {
|
||||||
// FIXME: report error
|
// FIXME: report error
|
||||||
// (additional non-auto traits, associated type rebound, or no resolved trait)
|
// (additional non-auto traits, associated type rebound, or no resolved trait)
|
||||||
|
@ -1657,18 +1695,7 @@ pub(crate) fn trait_environment_query(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let container: Option<ItemContainerId> = match def {
|
if let Some(trait_id) = def.assoc_trait_container(db.upcast()) {
|
||||||
// FIXME: is there a function for this?
|
|
||||||
GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
|
|
||||||
GenericDefId::AdtId(_) => None,
|
|
||||||
GenericDefId::TraitId(_) => None,
|
|
||||||
GenericDefId::TraitAliasId(_) => None,
|
|
||||||
GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
|
|
||||||
GenericDefId::ImplId(_) => None,
|
|
||||||
GenericDefId::EnumVariantId(_) => None,
|
|
||||||
GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
|
|
||||||
};
|
|
||||||
if let Some(ItemContainerId::TraitId(trait_id)) = container {
|
|
||||||
// add `Self: Trait<T1, T2, ...>` to the environment in trait
|
// add `Self: Trait<T1, T2, ...>` to the environment in trait
|
||||||
// function default implementations (and speculative code
|
// function default implementations (and speculative code
|
||||||
// inside consts or type aliases)
|
// inside consts or type aliases)
|
||||||
|
@ -1796,8 +1823,7 @@ pub(crate) fn generic_defaults_query(
|
||||||
make_binders(db, &generic_params, val)
|
make_binders(db, &generic_params, val)
|
||||||
}
|
}
|
||||||
GenericParamDataRef::LifetimeParamData(_) => {
|
GenericParamDataRef::LifetimeParamData(_) => {
|
||||||
// using static because it requires defaults
|
make_binders(db, &generic_params, error_lifetime().cast(Interner))
|
||||||
make_binders(db, &generic_params, static_lifetime().cast(Interner))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1817,7 +1843,7 @@ pub(crate) fn generic_defaults_recover(
|
||||||
let val = match id {
|
let val = match id {
|
||||||
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
|
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
|
||||||
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
|
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
|
||||||
GenericParamId::LifetimeParamId(_) => static_lifetime().cast(Interner),
|
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
|
||||||
};
|
};
|
||||||
crate::make_binders(db, &generic_params, val)
|
crate::make_binders(db, &generic_params, val)
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -22,10 +22,10 @@ use triomphe::Arc;
|
||||||
use crate::{
|
use crate::{
|
||||||
autoderef::{self, AutoderefKind},
|
autoderef::{self, AutoderefKind},
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
from_chalk_trait_id, from_foreign_def_id,
|
error_lifetime, from_chalk_trait_id, from_foreign_def_id,
|
||||||
infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast},
|
infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast},
|
||||||
primitive::{FloatTy, IntTy, UintTy},
|
primitive::{FloatTy, IntTy, UintTy},
|
||||||
static_lifetime, to_chalk_trait_id,
|
to_chalk_trait_id,
|
||||||
utils::all_super_traits,
|
utils::all_super_traits,
|
||||||
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
|
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
|
||||||
InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
|
InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
|
||||||
|
@ -1035,7 +1035,7 @@ fn iterate_method_candidates_with_autoref(
|
||||||
iterate_method_candidates_by_receiver(receiver_ty.clone(), maybe_reborrowed)?;
|
iterate_method_candidates_by_receiver(receiver_ty.clone(), maybe_reborrowed)?;
|
||||||
|
|
||||||
let refed = Canonical {
|
let refed = Canonical {
|
||||||
value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone())
|
value: TyKind::Ref(Mutability::Not, error_lifetime(), receiver_ty.value.clone())
|
||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
binders: receiver_ty.binders.clone(),
|
binders: receiver_ty.binders.clone(),
|
||||||
};
|
};
|
||||||
|
@ -1043,7 +1043,7 @@ fn iterate_method_candidates_with_autoref(
|
||||||
iterate_method_candidates_by_receiver(refed, first_adjustment.with_autoref(Mutability::Not))?;
|
iterate_method_candidates_by_receiver(refed, first_adjustment.with_autoref(Mutability::Not))?;
|
||||||
|
|
||||||
let ref_muted = Canonical {
|
let ref_muted = Canonical {
|
||||||
value: TyKind::Ref(Mutability::Mut, static_lifetime(), receiver_ty.value.clone())
|
value: TyKind::Ref(Mutability::Mut, error_lifetime(), receiver_ty.value.clone())
|
||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
binders: receiver_ty.binders,
|
binders: receiver_ty.binders,
|
||||||
};
|
};
|
||||||
|
@ -1369,6 +1369,7 @@ pub(crate) fn resolve_indexing_op(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Replace this with a `Try` impl once stable
|
||||||
macro_rules! check_that {
|
macro_rules! check_that {
|
||||||
($cond:expr) => {
|
($cond:expr) => {
|
||||||
if !$cond {
|
if !$cond {
|
||||||
|
@ -1377,6 +1378,7 @@ macro_rules! check_that {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum IsValidCandidate {
|
enum IsValidCandidate {
|
||||||
Yes,
|
Yes,
|
||||||
No,
|
No,
|
||||||
|
|
|
@ -9,11 +9,14 @@ use hir_def::{
|
||||||
resolver::HasResolver,
|
resolver::HasResolver,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::mir::eval::{
|
use crate::{
|
||||||
name, pad16, static_lifetime, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId,
|
error_lifetime,
|
||||||
HasModule, HirDisplay, Interned, InternedClosure, Interner, Interval, IntervalAndTy,
|
mir::eval::{
|
||||||
IntervalOrOwned, ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan,
|
name, pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule,
|
||||||
Mutability, Result, Substitution, Ty, TyBuilder, TyExt,
|
HirDisplay, Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned,
|
||||||
|
ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability,
|
||||||
|
Result, Substitution, Ty, TyBuilder, TyExt,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod simd;
|
mod simd;
|
||||||
|
@ -247,7 +250,7 @@ impl Evaluator<'_> {
|
||||||
let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
|
let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
|
||||||
let arg = IntervalAndTy {
|
let arg = IntervalAndTy {
|
||||||
interval: Interval { addr: tmp, size: self.ptr_size() },
|
interval: Interval { addr: tmp, size: self.ptr_size() },
|
||||||
ty: TyKind::Ref(Mutability::Not, static_lifetime(), ty.clone()).intern(Interner),
|
ty: TyKind::Ref(Mutability::Not, error_lifetime(), ty.clone()).intern(Interner),
|
||||||
};
|
};
|
||||||
let offset = layout.fields.offset(i).bytes_usize();
|
let offset = layout.fields.offset(i).bytes_usize();
|
||||||
self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
|
self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
|
||||||
|
|
|
@ -27,6 +27,7 @@ use crate::{
|
||||||
consteval::ConstEvalError,
|
consteval::ConstEvalError,
|
||||||
db::{HirDatabase, InternedClosure},
|
db::{HirDatabase, InternedClosure},
|
||||||
display::HirDisplay,
|
display::HirDisplay,
|
||||||
|
error_lifetime,
|
||||||
infer::{CaptureKind, CapturedItem, TypeMismatch},
|
infer::{CaptureKind, CapturedItem, TypeMismatch},
|
||||||
inhabitedness::is_ty_uninhabited_from,
|
inhabitedness::is_ty_uninhabited_from,
|
||||||
layout::LayoutError,
|
layout::LayoutError,
|
||||||
|
@ -2033,10 +2034,12 @@ pub fn mir_body_for_closure_query(
|
||||||
let closure_local = ctx.result.locals.alloc(Local {
|
let closure_local = ctx.result.locals.alloc(Local {
|
||||||
ty: match kind {
|
ty: match kind {
|
||||||
FnTrait::FnOnce => infer[expr].clone(),
|
FnTrait::FnOnce => infer[expr].clone(),
|
||||||
FnTrait::FnMut => TyKind::Ref(Mutability::Mut, static_lifetime(), infer[expr].clone())
|
FnTrait::FnMut => {
|
||||||
.intern(Interner),
|
TyKind::Ref(Mutability::Mut, error_lifetime(), infer[expr].clone()).intern(Interner)
|
||||||
FnTrait::Fn => TyKind::Ref(Mutability::Not, static_lifetime(), infer[expr].clone())
|
}
|
||||||
.intern(Interner),
|
FnTrait::Fn => {
|
||||||
|
TyKind::Ref(Mutability::Not, error_lifetime(), infer[expr].clone()).intern(Interner)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
ctx.result.param_locals.push(closure_local);
|
ctx.result.param_locals.push(closure_local);
|
||||||
|
|
|
@ -290,7 +290,7 @@ impl MirLowerCtx<'_> {
|
||||||
Some((_, _, mutability)) => mutability,
|
Some((_, _, mutability)) => mutability,
|
||||||
None => Mutability::Not,
|
None => Mutability::Not,
|
||||||
};
|
};
|
||||||
let result_ref = TyKind::Ref(mutability, static_lifetime(), result_ty).intern(Interner);
|
let result_ref = TyKind::Ref(mutability, error_lifetime(), result_ty).intern(Interner);
|
||||||
let mut result: Place = self.temp(result_ref, current, span)?.into();
|
let mut result: Place = self.temp(result_ref, current, span)?.into();
|
||||||
let index_fn_op = Operand::const_zst(
|
let index_fn_op = Operand::const_zst(
|
||||||
TyKind::FnDef(
|
TyKind::FnDef(
|
||||||
|
@ -333,8 +333,8 @@ impl MirLowerCtx<'_> {
|
||||||
BorrowKind::Mut { kind: MutBorrowKind::Default },
|
BorrowKind::Mut { kind: MutBorrowKind::Default },
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let ty_ref = TyKind::Ref(chalk_mut, static_lifetime(), source_ty.clone()).intern(Interner);
|
let ty_ref = TyKind::Ref(chalk_mut, error_lifetime(), source_ty.clone()).intern(Interner);
|
||||||
let target_ty_ref = TyKind::Ref(chalk_mut, static_lifetime(), target_ty).intern(Interner);
|
let target_ty_ref = TyKind::Ref(chalk_mut, error_lifetime(), target_ty).intern(Interner);
|
||||||
let ref_place: Place = self.temp(ty_ref, current, span)?.into();
|
let ref_place: Place = self.temp(ty_ref, current, span)?.into();
|
||||||
self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span);
|
self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span);
|
||||||
let deref_trait = self
|
let deref_trait = self
|
||||||
|
|
|
@ -1612,10 +1612,10 @@ fn test(
|
||||||
) {}
|
) {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
28..29 'a': impl Trait
|
28..29 'a': impl Trait + 'static
|
||||||
59..60 'b': impl Sized
|
59..60 'b': impl 'static
|
||||||
82..83 'c': impl Trait
|
82..83 'c': impl Trait
|
||||||
103..104 'd': impl Sized
|
103..104 'd': impl 'static
|
||||||
128..129 'e': impl ?Sized
|
128..129 'e': impl ?Sized
|
||||||
148..149 'f': impl Trait + ?Sized
|
148..149 'f': impl Trait + ?Sized
|
||||||
173..175 '{}': ()
|
173..175 '{}': ()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//! HirDisplay implementations for various hir types.
|
//! HirDisplay implementations for various hir types.
|
||||||
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
data::adt::{StructKind, VariantData},
|
data::adt::{StructKind, VariantData},
|
||||||
generics::{
|
generics::{
|
||||||
|
@ -13,7 +14,7 @@ use hir_ty::{
|
||||||
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
|
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
|
||||||
HirFormatter, SizedByDefault,
|
HirFormatter, SizedByDefault,
|
||||||
},
|
},
|
||||||
Interner, TraitRefExt, WhereClause,
|
AliasEq, AliasTy, Interner, ProjectionTyExt, TraitRefExt, TyKind, WhereClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -363,16 +364,52 @@ impl HirDisplay for TypeOrConstParam {
|
||||||
|
|
||||||
impl HirDisplay for TypeParam {
|
impl HirDisplay for TypeParam {
|
||||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||||
write!(f, "{}", self.name(f.db).display(f.db.upcast()))?;
|
let params = f.db.generic_params(self.id.parent());
|
||||||
|
let param_data = ¶ms.type_or_consts[self.id.local_id()];
|
||||||
|
let substs = TyBuilder::placeholder_subst(f.db, self.id.parent());
|
||||||
|
let krate = self.id.parent().krate(f.db).id;
|
||||||
|
let ty =
|
||||||
|
TyKind::Placeholder(hir_ty::to_placeholder_idx(f.db, self.id.into())).intern(Interner);
|
||||||
|
let predicates = f.db.generic_predicates(self.id.parent());
|
||||||
|
let predicates = predicates
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|pred| pred.substitute(Interner, &substs))
|
||||||
|
.filter(|wc| match wc.skip_binders() {
|
||||||
|
WhereClause::Implemented(tr) => tr.self_type_parameter(Interner) == ty,
|
||||||
|
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), ty: _ }) => {
|
||||||
|
proj.self_type_parameter(f.db) == ty
|
||||||
|
}
|
||||||
|
WhereClause::AliasEq(_) => false,
|
||||||
|
WhereClause::TypeOutlives(to) => to.ty == ty,
|
||||||
|
WhereClause::LifetimeOutlives(_) => false,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
match param_data {
|
||||||
|
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
||||||
|
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
|
||||||
|
write!(f, "{}", p.name.clone().unwrap().display(f.db.upcast()))?
|
||||||
|
}
|
||||||
|
TypeParamProvenance::ArgumentImplTrait => {
|
||||||
|
return write_bounds_like_dyn_trait_with_prefix(
|
||||||
|
f,
|
||||||
|
"impl",
|
||||||
|
Either::Left(&ty),
|
||||||
|
&predicates,
|
||||||
|
SizedByDefault::Sized { anchor: krate },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TypeOrConstParamData::ConstParamData(p) => {
|
||||||
|
write!(f, "{}", p.name.display(f.db.upcast()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if f.omit_verbose_types() {
|
if f.omit_verbose_types() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let bounds = f.db.generic_predicates_for_param(self.id.parent(), self.id.into(), None);
|
|
||||||
let substs = TyBuilder::placeholder_subst(f.db, self.id.parent());
|
|
||||||
let predicates: Vec<_> =
|
|
||||||
bounds.iter().cloned().map(|b| b.substitute(Interner, &substs)).collect();
|
|
||||||
let krate = self.id.parent().krate(f.db).id;
|
|
||||||
let sized_trait =
|
let sized_trait =
|
||||||
f.db.lang_item(krate, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
|
f.db.lang_item(krate, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
|
||||||
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
|
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
|
||||||
|
@ -382,7 +419,16 @@ impl HirDisplay for TypeParam {
|
||||||
let has_only_not_sized_bound = predicates.is_empty();
|
let has_only_not_sized_bound = predicates.is_empty();
|
||||||
if !has_only_sized_bound || has_only_not_sized_bound {
|
if !has_only_sized_bound || has_only_not_sized_bound {
|
||||||
let default_sized = SizedByDefault::Sized { anchor: krate };
|
let default_sized = SizedByDefault::Sized { anchor: krate };
|
||||||
write_bounds_like_dyn_trait_with_prefix(f, ":", &predicates, default_sized)?;
|
write_bounds_like_dyn_trait_with_prefix(
|
||||||
|
f,
|
||||||
|
":",
|
||||||
|
Either::Left(
|
||||||
|
&hir_ty::TyKind::Placeholder(hir_ty::to_placeholder_idx(f.db, self.id.into()))
|
||||||
|
.intern(Interner),
|
||||||
|
),
|
||||||
|
&predicates,
|
||||||
|
default_sized,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3910,7 +3910,7 @@ impl Type {
|
||||||
inner.derived(
|
inner.derived(
|
||||||
TyKind::Ref(
|
TyKind::Ref(
|
||||||
if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not },
|
if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not },
|
||||||
hir_ty::static_lifetime(),
|
hir_ty::error_lifetime(),
|
||||||
inner.ty.clone(),
|
inner.ty.clone(),
|
||||||
)
|
)
|
||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
|
|
|
@ -1585,6 +1585,38 @@ mod bar {
|
||||||
Foo;
|
Foo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_inline_import_has_alias() {
|
||||||
|
// FIXME
|
||||||
|
check_assist_not_applicable(
|
||||||
|
auto_import,
|
||||||
|
r#"
|
||||||
|
struct S<T>(T);
|
||||||
|
use S as IoResult;
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
pub fn bar() -> S$0<()> {}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alias_local() {
|
||||||
|
// FIXME
|
||||||
|
check_assist_not_applicable(
|
||||||
|
auto_import,
|
||||||
|
r#"
|
||||||
|
struct S<T>(T);
|
||||||
|
use S as IoResult;
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
pub fn bar() -> IoResult$0<()> {}
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4040,7 +4040,6 @@ impl<T> Foo<T$0> {}
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
// lifetimes bounds arent being tracked yet
|
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
//- minicore: sized
|
//- minicore: sized
|
||||||
|
@ -4051,7 +4050,7 @@ impl<T: 'static> Foo<T$0> {}
|
||||||
*T*
|
*T*
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
T
|
T: 'static
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue