curr_size: 0,
max_size: None,
omit_verbose_types: false,
- #[cfg(not(test))]
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 },
}) {
Ok(()) => {}
/// The generated code should compile, so paths need to be qualified.
SourceCode { module_id: ModuleId },
/// Only for test purpose to keep real types
- #[cfg(test)]
Test { module_id: ModuleId },
}
matches!(self, Self::SourceCode {..})
}
fn is_test(&self) -> bool {
- #[cfg(test)]
- {
- matches!(self, Self::Test {..})
- }
- #[cfg(not(test))]
- {
- false
- }
+ matches!(self, Self::Test {..})
}
}
};
write!(f, "{}", name)?;
}
- DisplayTarget::SourceCode { 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 } => {
+ DisplayTarget::SourceCode { module_id } | DisplayTarget::Test { module_id } => {
if let Some(path) = find_path::find_path(
f.db.upcast(),
ItemInNs::Types(def_id.into()),
}
if self.parameters.len() > 0 {
- let parameters_to_write = if f.display_target.is_source_code()
- || f.display_target.is_test()
- || f.omit_verbose_types()
- {
- match self
- .ctor
- .as_generic_def()
- .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) => {
- let mut default_from = 0;
- for (i, parameter) in self.parameters.iter().enumerate() {
- 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 {
+ let parameters_to_write =
+ if f.display_target.is_source_code() || f.omit_verbose_types() {
+ match self
+ .ctor
+ .as_generic_def()
+ .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) => {
+ let mut default_from = 0;
+ for (i, parameter) in self.parameters.iter().enumerate() {
+ 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;
+ }
+ }
}
}
+ &self.parameters.0[0..default_from]
}
- &self.parameters.0[0..default_from]
}
- }
- } else {
- self.parameters.0.as_ref()
- };
+ } else {
+ self.parameters.0.as_ref()
+ };
if !parameters_to_write.is_empty() {
write!(f, "<")?;
f.write_joined(parameters_to_write, ", ")?;
(node.value.text_range(), node.value.text().to_string().replace("\n", " "))
};
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!(
buf,
"{}{:?} '{}': {}\n",
macro_prefix,
range,
ellipsize(text, 15),
- ty.display(&db)
+ ty.display_test(&db, module).unwrap()
);
}
if include_mismatches {
for (src_ptr, mismatch) in &mismatches {
let range = src_ptr.value.text_range();
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!(
buf,
"{}{:?}: expected {}, got {}\n",
macro_prefix,
range,
- mismatch.expected.display(&db),
- mismatch.actual.display(&db),
+ mismatch.expected.display_test(&db, module).unwrap(),
+ mismatch.actual.display_test(&db, module).unwrap(),
);
}
}
check_infer(
r#"
mod a {
- struct A;
+ pub struct A;
impl A { pub fn thing() -> A { A {} }}
}
mod b {
- struct B;
+ pub struct B;
impl B { pub fn thing() -> u32 { 99 }}
- mod c {
- struct C;
+ pub mod c {
+ pub struct C;
impl C { pub fn thing() -> C { C {} }}
}
}
}
"#,
expect![[r#"
- 55..63 '{ A {} }': A
- 57..61 'A {}': A
- 125..131 '{ 99 }': u32
- 127..129 '99': u32
- 201..209 '{ C {} }': C
- 203..207 'C {}': C
- 240..324 '{ ...g(); }': ()
- 250..251 'x': A
- 254..265 'a::A::thing': fn thing() -> A
- 254..267 'a::A::thing()': A
- 277..278 'y': u32
- 281..292 'b::B::thing': fn thing() -> u32
- 281..294 'b::B::thing()': u32
- 304..305 'z': C
- 308..319 'c::C::thing': fn thing() -> C
- 308..321 'c::C::thing()': C
+ 59..67 '{ A {} }': a::A
+ 61..65 'A {}': a::A
+ 133..139 '{ 99 }': u32
+ 135..137 '99': u32
+ 217..225 '{ C {} }': c::C
+ 219..223 'C {}': c::C
+ 256..340 '{ ...g(); }': ()
+ 266..267 'x': a::A
+ 270..281 'a::A::thing': fn thing() -> A
+ 270..283 'a::A::thing()': a::A
+ 293..294 'y': u32
+ 297..308 'b::B::thing': fn thing() -> u32
+ 297..310 'b::B::thing()': u32
+ 320..321 'z': c::C
+ 324..335 'c::C::thing': fn thing() -> C
+ 324..337 'c::C::thing()': c::C
"#]],
);
}
356..362 'repeat': Repeat<Map<|&f64| -> f64>>
365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
383..388 'inner': Map<|&f64| -> f64>
- 401..404 'vec': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item>
- 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..424 'from_i...epeat)': 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<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<IntoIterator::Item<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}
"#]],
);
use expect_test::expect;
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]
fn infer_await() {
108..261 '{ ...ter; }': ()
118..119 'x': u32
145..146 '1': u32
- 156..157 'y': <T as Iterable>::Item
- 183..192 'no_matter': <T as Iterable>::Item
- 202..203 'z': <T as Iterable>::Item
- 215..224 'no_matter': <T as Iterable>::Item
- 234..235 'a': <T as Iterable>::Item
- 249..258 'no_matter': <T as Iterable>::Item
+ 156..157 'y': Iterable::Item<T>
+ 183..192 'no_matter': Iterable::Item<T>
+ 202..203 'z': Iterable::Item<T>
+ 215..224 'no_matter': Iterable::Item<T>
+ 234..235 'a': Iterable::Item<T>
+ 249..258 'no_matter': Iterable::Item<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]
fn argument_impl_trait() {
check_infer_with_mismatches(
"#,
expect![[r#"
40..44 'self': &Self
- 46..47 'x': <Self as Trait>::Item
+ 46..47 'x': Trait::Item<Self>
126..130 'self': &S
132..133 'x': u32
147..161 '{ let y = x; }': ()
"#,
);
}
-
-#[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
- "#]],
- );
-}
"#,
);
}
+
+ #[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
+ }
+ "#,
+ );
+ }
}