mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
do not use associated types placeholder for inlay hint
Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
This commit is contained in:
parent
8762b797fd
commit
ef2f7bb243
6 changed files with 108 additions and 155 deletions
|
@ -74,9 +74,29 @@ pub trait HirDisplay {
|
||||||
curr_size: 0,
|
curr_size: 0,
|
||||||
max_size: None,
|
max_size: None,
|
||||||
omit_verbose_types: false,
|
omit_verbose_types: false,
|
||||||
#[cfg(not(test))]
|
|
||||||
display_target: DisplayTarget::SourceCode { module_id },
|
display_target: DisplayTarget::SourceCode { module_id },
|
||||||
#[cfg(test)]
|
}) {
|
||||||
|
Ok(()) => {}
|
||||||
|
Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"),
|
||||||
|
Err(HirDisplayError::DisplaySourceCodeError(e)) => return Err(e),
|
||||||
|
};
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a String representation of `self` for test purposes
|
||||||
|
fn display_test<'a>(
|
||||||
|
&'a self,
|
||||||
|
db: &'a dyn HirDatabase,
|
||||||
|
module_id: ModuleId,
|
||||||
|
) -> Result<String, DisplaySourceCodeError> {
|
||||||
|
let mut result = String::new();
|
||||||
|
match self.hir_fmt(&mut HirFormatter {
|
||||||
|
db,
|
||||||
|
fmt: &mut result,
|
||||||
|
buf: String::with_capacity(20),
|
||||||
|
curr_size: 0,
|
||||||
|
max_size: None,
|
||||||
|
omit_verbose_types: false,
|
||||||
display_target: DisplayTarget::Test { module_id },
|
display_target: DisplayTarget::Test { module_id },
|
||||||
}) {
|
}) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
|
@ -138,7 +158,6 @@ enum DisplayTarget {
|
||||||
/// The generated code should compile, so paths need to be qualified.
|
/// The generated code should compile, so paths need to be qualified.
|
||||||
SourceCode { module_id: ModuleId },
|
SourceCode { module_id: ModuleId },
|
||||||
/// Only for test purpose to keep real types
|
/// Only for test purpose to keep real types
|
||||||
#[cfg(test)]
|
|
||||||
Test { module_id: ModuleId },
|
Test { module_id: ModuleId },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,14 +166,7 @@ impl DisplayTarget {
|
||||||
matches!(self, Self::SourceCode {..})
|
matches!(self, Self::SourceCode {..})
|
||||||
}
|
}
|
||||||
fn is_test(&self) -> bool {
|
fn is_test(&self) -> bool {
|
||||||
#[cfg(test)]
|
matches!(self, Self::Test {..})
|
||||||
{
|
|
||||||
matches!(self, Self::Test {..})
|
|
||||||
}
|
|
||||||
#[cfg(not(test))]
|
|
||||||
{
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,21 +356,7 @@ impl HirDisplay for ApplicationTy {
|
||||||
};
|
};
|
||||||
write!(f, "{}", name)?;
|
write!(f, "{}", name)?;
|
||||||
}
|
}
|
||||||
DisplayTarget::SourceCode { module_id } => {
|
DisplayTarget::SourceCode { module_id } | DisplayTarget::Test { module_id } => {
|
||||||
if let Some(path) = find_path::find_path(
|
|
||||||
f.db.upcast(),
|
|
||||||
ItemInNs::Types(def_id.into()),
|
|
||||||
module_id,
|
|
||||||
) {
|
|
||||||
write!(f, "{}", path)?;
|
|
||||||
} else {
|
|
||||||
return Err(HirDisplayError::DisplaySourceCodeError(
|
|
||||||
DisplaySourceCodeError::PathNotFound,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(test)]
|
|
||||||
DisplayTarget::Test { module_id } => {
|
|
||||||
if let Some(path) = find_path::find_path(
|
if let Some(path) = find_path::find_path(
|
||||||
f.db.upcast(),
|
f.db.upcast(),
|
||||||
ItemInNs::Types(def_id.into()),
|
ItemInNs::Types(def_id.into()),
|
||||||
|
@ -374,40 +372,38 @@ impl HirDisplay for ApplicationTy {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.parameters.len() > 0 {
|
if self.parameters.len() > 0 {
|
||||||
let parameters_to_write = if f.display_target.is_source_code()
|
let parameters_to_write =
|
||||||
|| f.display_target.is_test()
|
if f.display_target.is_source_code() || f.omit_verbose_types() {
|
||||||
|| f.omit_verbose_types()
|
match self
|
||||||
{
|
.ctor
|
||||||
match self
|
.as_generic_def()
|
||||||
.ctor
|
.map(|generic_def_id| f.db.generic_defaults(generic_def_id))
|
||||||
.as_generic_def()
|
.filter(|defaults| !defaults.is_empty())
|
||||||
.map(|generic_def_id| f.db.generic_defaults(generic_def_id))
|
{
|
||||||
.filter(|defaults| !defaults.is_empty())
|
None => self.parameters.0.as_ref(),
|
||||||
{
|
Some(default_parameters) => {
|
||||||
None => self.parameters.0.as_ref(),
|
let mut default_from = 0;
|
||||||
Some(default_parameters) => {
|
for (i, parameter) in self.parameters.iter().enumerate() {
|
||||||
let mut default_from = 0;
|
match (parameter, default_parameters.get(i)) {
|
||||||
for (i, parameter) in self.parameters.iter().enumerate() {
|
(&Ty::Unknown, _) | (_, None) => {
|
||||||
match (parameter, default_parameters.get(i)) {
|
|
||||||
(&Ty::Unknown, _) | (_, None) => {
|
|
||||||
default_from = i + 1;
|
|
||||||
}
|
|
||||||
(_, Some(default_parameter)) => {
|
|
||||||
let actual_default = default_parameter
|
|
||||||
.clone()
|
|
||||||
.subst(&self.parameters.prefix(i));
|
|
||||||
if parameter != &actual_default {
|
|
||||||
default_from = i + 1;
|
default_from = i + 1;
|
||||||
}
|
}
|
||||||
|
(_, Some(default_parameter)) => {
|
||||||
|
let actual_default = default_parameter
|
||||||
|
.clone()
|
||||||
|
.subst(&self.parameters.prefix(i));
|
||||||
|
if parameter != &actual_default {
|
||||||
|
default_from = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&self.parameters.0[0..default_from]
|
||||||
}
|
}
|
||||||
&self.parameters.0[0..default_from]
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
self.parameters.0.as_ref()
|
||||||
self.parameters.0.as_ref()
|
};
|
||||||
};
|
|
||||||
if !parameters_to_write.is_empty() {
|
if !parameters_to_write.is_empty() {
|
||||||
write!(f, "<")?;
|
write!(f, "<")?;
|
||||||
f.write_joined(parameters_to_write, ", ")?;
|
f.write_joined(parameters_to_write, ", ")?;
|
||||||
|
|
|
@ -157,13 +157,14 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||||
(node.value.text_range(), node.value.text().to_string().replace("\n", " "))
|
(node.value.text_range(), node.value.text().to_string().replace("\n", " "))
|
||||||
};
|
};
|
||||||
let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" };
|
let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" };
|
||||||
|
let module = db.module_for_file(node.file_id.original_file(&db));
|
||||||
format_to!(
|
format_to!(
|
||||||
buf,
|
buf,
|
||||||
"{}{:?} '{}': {}\n",
|
"{}{:?} '{}': {}\n",
|
||||||
macro_prefix,
|
macro_prefix,
|
||||||
range,
|
range,
|
||||||
ellipsize(text, 15),
|
ellipsize(text, 15),
|
||||||
ty.display(&db)
|
ty.display_test(&db, module).unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if include_mismatches {
|
if include_mismatches {
|
||||||
|
@ -174,13 +175,14 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||||
for (src_ptr, mismatch) in &mismatches {
|
for (src_ptr, mismatch) in &mismatches {
|
||||||
let range = src_ptr.value.text_range();
|
let range = src_ptr.value.text_range();
|
||||||
let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
|
let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
|
||||||
|
let module = db.module_for_file(src_ptr.file_id.original_file(&db));
|
||||||
format_to!(
|
format_to!(
|
||||||
buf,
|
buf,
|
||||||
"{}{:?}: expected {}, got {}\n",
|
"{}{:?}: expected {}, got {}\n",
|
||||||
macro_prefix,
|
macro_prefix,
|
||||||
range,
|
range,
|
||||||
mismatch.expected.display(&db),
|
mismatch.expected.display_test(&db, module).unwrap(),
|
||||||
mismatch.actual.display(&db),
|
mismatch.actual.display_test(&db, module).unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,16 +108,16 @@ fn infer_associated_method_with_modules() {
|
||||||
check_infer(
|
check_infer(
|
||||||
r#"
|
r#"
|
||||||
mod a {
|
mod a {
|
||||||
struct A;
|
pub struct A;
|
||||||
impl A { pub fn thing() -> A { A {} }}
|
impl A { pub fn thing() -> A { A {} }}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod b {
|
mod b {
|
||||||
struct B;
|
pub struct B;
|
||||||
impl B { pub fn thing() -> u32 { 99 }}
|
impl B { pub fn thing() -> u32 { 99 }}
|
||||||
|
|
||||||
mod c {
|
pub mod c {
|
||||||
struct C;
|
pub struct C;
|
||||||
impl C { pub fn thing() -> C { C {} }}
|
impl C { pub fn thing() -> C { C {} }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,22 +130,22 @@ fn infer_associated_method_with_modules() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
55..63 '{ A {} }': A
|
59..67 '{ A {} }': a::A
|
||||||
57..61 'A {}': A
|
61..65 'A {}': a::A
|
||||||
125..131 '{ 99 }': u32
|
133..139 '{ 99 }': u32
|
||||||
127..129 '99': u32
|
135..137 '99': u32
|
||||||
201..209 '{ C {} }': C
|
217..225 '{ C {} }': c::C
|
||||||
203..207 'C {}': C
|
219..223 'C {}': c::C
|
||||||
240..324 '{ ...g(); }': ()
|
256..340 '{ ...g(); }': ()
|
||||||
250..251 'x': A
|
266..267 'x': a::A
|
||||||
254..265 'a::A::thing': fn thing() -> A
|
270..281 'a::A::thing': fn thing() -> A
|
||||||
254..267 'a::A::thing()': A
|
270..283 'a::A::thing()': a::A
|
||||||
277..278 'y': u32
|
293..294 'y': u32
|
||||||
281..292 'b::B::thing': fn thing() -> u32
|
297..308 'b::B::thing': fn thing() -> u32
|
||||||
281..294 'b::B::thing()': u32
|
297..310 'b::B::thing()': u32
|
||||||
304..305 'z': C
|
320..321 'z': c::C
|
||||||
308..319 'c::C::thing': fn thing() -> C
|
324..335 'c::C::thing': fn thing() -> C
|
||||||
308..321 'c::C::thing()': C
|
324..337 'c::C::thing()': c::C
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -831,11 +831,11 @@ fn issue_4966() {
|
||||||
356..362 'repeat': Repeat<Map<|&f64| -> f64>>
|
356..362 'repeat': Repeat<Map<|&f64| -> f64>>
|
||||||
365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
|
365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
|
||||||
383..388 'inner': Map<|&f64| -> f64>
|
383..388 'inner': Map<|&f64| -> f64>
|
||||||
401..404 'vec': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item>
|
401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
|
||||||
407..416 'from_iter': fn from_iter<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item>
|
407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item>
|
||||||
407..424 'from_i...epeat)': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item>
|
407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
|
||||||
417..423 'repeat': Repeat<Map<|&f64| -> f64>>
|
417..423 'repeat': Repeat<Map<|&f64| -> f64>>
|
||||||
431..434 'vec': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item>
|
431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
|
||||||
431..444 'vec.foo_bar()': {unknown}
|
431..444 'vec.foo_bar()': {unknown}
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use expect_test::expect;
|
use expect_test::expect;
|
||||||
use test_utils::mark;
|
use test_utils::mark;
|
||||||
|
|
||||||
use super::{check_infer, check_infer_with_mismatches, check_types, check_types_source_code};
|
use super::{check_infer, check_infer_with_mismatches, check_types};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_await() {
|
fn infer_await() {
|
||||||
|
@ -384,12 +384,12 @@ fn infer_project_associated_type() {
|
||||||
108..261 '{ ...ter; }': ()
|
108..261 '{ ...ter; }': ()
|
||||||
118..119 'x': u32
|
118..119 'x': u32
|
||||||
145..146 '1': u32
|
145..146 '1': u32
|
||||||
156..157 'y': <T as Iterable>::Item
|
156..157 'y': Iterable::Item<T>
|
||||||
183..192 'no_matter': <T as Iterable>::Item
|
183..192 'no_matter': Iterable::Item<T>
|
||||||
202..203 'z': <T as Iterable>::Item
|
202..203 'z': Iterable::Item<T>
|
||||||
215..224 'no_matter': <T as Iterable>::Item
|
215..224 'no_matter': Iterable::Item<T>
|
||||||
234..235 'a': <T as Iterable>::Item
|
234..235 'a': Iterable::Item<T>
|
||||||
249..258 'no_matter': <T as Iterable>::Item
|
249..258 'no_matter': Iterable::Item<T>
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -945,45 +945,6 @@ fn test<T: ApplyL>(t: T) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn associated_type_placeholder() {
|
|
||||||
check_types_source_code(
|
|
||||||
r#"
|
|
||||||
pub trait ApplyL {
|
|
||||||
type Out;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RefMutL<T>;
|
|
||||||
|
|
||||||
impl<T> ApplyL for RefMutL<T> {
|
|
||||||
type Out = <T as ApplyL>::Out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test<T: ApplyL>() {
|
|
||||||
let y: <RefMutL<T> as ApplyL>::Out = no_matter;
|
|
||||||
y;
|
|
||||||
} //^ ApplyL::Out<T>
|
|
||||||
"#,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn associated_type_placeholder_2() {
|
|
||||||
check_types_source_code(
|
|
||||||
r#"
|
|
||||||
pub trait ApplyL {
|
|
||||||
type Out;
|
|
||||||
}
|
|
||||||
fn foo<T: ApplyL>(t: T) -> <T as ApplyL>::Out;
|
|
||||||
|
|
||||||
fn test<T: ApplyL>(t: T) {
|
|
||||||
let y = foo(t);
|
|
||||||
y;
|
|
||||||
} //^ ApplyL::Out<T>
|
|
||||||
"#,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn argument_impl_trait() {
|
fn argument_impl_trait() {
|
||||||
check_infer_with_mismatches(
|
check_infer_with_mismatches(
|
||||||
|
@ -2158,7 +2119,7 @@ fn unselected_projection_on_impl_self() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
40..44 'self': &Self
|
40..44 'self': &Self
|
||||||
46..47 'x': <Self as Trait>::Item
|
46..47 'x': Trait::Item<Self>
|
||||||
126..130 'self': &S
|
126..130 'self': &S
|
||||||
132..133 'x': u32
|
132..133 'x': u32
|
||||||
147..161 '{ let y = x; }': ()
|
147..161 '{ let y = x; }': ()
|
||||||
|
@ -3189,30 +3150,3 @@ fn test() {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn infer_call_method_return_associated_types_with_generic() {
|
|
||||||
check_infer(
|
|
||||||
r#"
|
|
||||||
pub trait Default {
|
|
||||||
fn default() -> Self;
|
|
||||||
}
|
|
||||||
pub trait Foo {
|
|
||||||
type Bar: Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn quux<T: Foo>() -> T::Bar {
|
|
||||||
let y = Default::default();
|
|
||||||
|
|
||||||
y
|
|
||||||
}
|
|
||||||
"#,
|
|
||||||
expect![[r#"
|
|
||||||
122..164 '{ ... y }': <T as Foo>::Bar
|
|
||||||
132..133 'y': <T as Foo>::Bar
|
|
||||||
136..152 'Defaul...efault': fn default<<T as Foo>::Bar>() -> <T as Foo>::Bar
|
|
||||||
136..154 'Defaul...ault()': <T as Foo>::Bar
|
|
||||||
161..162 'y': <T as Foo>::Bar
|
|
||||||
"#]],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1235,4 +1235,25 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn infer_call_method_return_associated_types_with_generic() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
pub trait Default {
|
||||||
|
fn default() -> Self;
|
||||||
|
}
|
||||||
|
pub trait Foo {
|
||||||
|
type Bar: Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn quux<T: Foo>() -> T::Bar {
|
||||||
|
let y = Default::default();
|
||||||
|
//^ <T as Foo>::Bar
|
||||||
|
|
||||||
|
y
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue