Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,10 @@ impl Type {
Some(adt.into())
}

pub fn as_builtin(&self) -> Option<BuiltinType> {
self.ty.as_builtin().map(|inner| BuiltinType { inner })
}

pub fn as_dyn_trait(&self) -> Option<Trait> {
self.ty.dyn_trait().map(Into::into)
}
Expand Down
36 changes: 34 additions & 2 deletions crates/hir_ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Various extensions traits for Chalk types.

use chalk_ir::Mutability;
use chalk_ir::{FloatTy, IntTy, Mutability, Scalar, UintTy};
use hir_def::{
type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup, TraitId,
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
type_ref::Rawness,
AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup, TraitId,
};

use crate::{
Expand All @@ -18,6 +20,7 @@ pub trait TyExt {
fn is_unknown(&self) -> bool;

fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
fn as_builtin(&self) -> Option<BuiltinType>;
fn as_tuple(&self) -> Option<&Substitution>;
fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId>;
fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)>;
Expand Down Expand Up @@ -59,6 +62,35 @@ impl TyExt for Ty {
}
}

fn as_builtin(&self) -> Option<BuiltinType> {
match self.kind(&Interner) {
TyKind::Str => Some(BuiltinType::Str),
TyKind::Scalar(Scalar::Bool) => Some(BuiltinType::Bool),
TyKind::Scalar(Scalar::Char) => Some(BuiltinType::Char),
TyKind::Scalar(Scalar::Float(fty)) => Some(BuiltinType::Float(match fty {
FloatTy::F64 => BuiltinFloat::F64,
FloatTy::F32 => BuiltinFloat::F32,
})),
TyKind::Scalar(Scalar::Int(ity)) => Some(BuiltinType::Int(match ity {
IntTy::Isize => BuiltinInt::Isize,
IntTy::I8 => BuiltinInt::I8,
IntTy::I16 => BuiltinInt::I16,
IntTy::I32 => BuiltinInt::I32,
IntTy::I64 => BuiltinInt::I64,
IntTy::I128 => BuiltinInt::I128,
})),
TyKind::Scalar(Scalar::Uint(ity)) => Some(BuiltinType::Uint(match ity {
UintTy::Usize => BuiltinUint::Usize,
UintTy::U8 => BuiltinUint::U8,
UintTy::U16 => BuiltinUint::U16,
UintTy::U32 => BuiltinUint::U32,
UintTy::U64 => BuiltinUint::U64,
UintTy::U128 => BuiltinUint::U128,
})),
_ => None,
}
}

fn as_tuple(&self) -> Option<&Substitution> {
match self.kind(&Interner) {
TyKind::Tuple(_, substs) => Some(substs),
Expand Down
64 changes: 59 additions & 5 deletions crates/ide/src/references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub(crate) fn find_all_refs(
(find_def(&sema, &syntax, position)?, false)
};

let mut usages = def.usages(sema).set_scope(search_scope).all();
let mut usages = def.usages(sema).set_scope(search_scope).include_self_refs().all();
if is_literal_search {
// filter for constructor-literals
let refs = usages.references.values_mut();
Expand Down Expand Up @@ -1163,21 +1163,75 @@ fn foo<const FOO$0: usize>() -> usize {
}

#[test]
fn test_find_self_ty_in_trait_def() {
fn test_trait() {
check(
r#"
trait Foo {
fn f() -> Self$0;
trait Foo$0 where Self: {}

impl Foo for () {}
"#,
expect![[r#"
Foo Trait FileId(0) 0..24 6..9

FileId(0) 31..34
"#]],
);
}

#[test]
fn test_trait_self() {
check(
r#"
trait Foo where Self$0 {
fn f() -> Self;
}

impl Foo for () {}
"#,
expect![[r#"
Self TypeParam FileId(0) 6..9 6..9

FileId(0) 26..30
FileId(0) 16..20
FileId(0) 37..41
"#]],
);
}

#[test]
fn test_self_ty() {
check(
r#"
struct $0Foo;

impl Foo where Self: {
fn f() -> Self;
}
"#,
expect![[r#"
Foo Struct FileId(0) 0..11 7..10

FileId(0) 18..21
FileId(0) 28..32
FileId(0) 50..54
"#]],
);
check(
r#"
struct Foo;

impl Foo where Self: {
fn f() -> Self$0;
}
"#,
expect![[r#"
impl Impl FileId(0) 13..57 18..21

FileId(0) 18..21
FileId(0) 28..32
FileId(0) 50..54
"#]],
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s somewhat inconsistent indentation :)

Copy link
Member Author

@Veykril Veykril May 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one downside of expect-testing is rustfmt not touching it while also continuing to pass with a different indentation 😄

}
#[test]
fn test_self_variant_with_payload() {
check(
Expand Down
17 changes: 17 additions & 0 deletions crates/ide/src/references/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1888,4 +1888,21 @@ impl Foo {
"error: Cannot rename `Self`",
);
}

#[test]
fn test_rename_ignores_self_ty() {
check(
"Fo0",
r#"
struct $0Foo;

impl Foo where Self: {}
"#,
r#"
struct Fo0;

impl Fo0 where Self: {}
"#,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ fn edit_struct_references(
names: &[ast::Name],
) {
let strukt_def = Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(strukt)));
let usages = strukt_def.usages(&ctx.sema).include_self_kw_refs(true).all();
let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();

let edit_node = |edit: &mut AssistBuilder, node: SyntaxNode| -> Option<()> {
match_ast! {
Expand Down
Loading