diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-06 11:56:59 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-06 11:56:59 +0100 |
commit | a609336d7287b3ddddbde30b1f0fb606bf149baf (patch) | |
tree | 343d39c2a01bd3643bcab13eb01dfbd4f6a511cc | |
parent | 02f7b5d7abbab829c2a0f66cdcbb6678afb412a4 (diff) | |
parent | a4a4a1854ebb53e1cdd7a5e3b308112bbbf3c676 (diff) |
Merge #4765
4765: Fix type parameter defaults r=matklad a=flodiebold
They should not be applied in expression or pattern contexts, unless there are other explicitly given type args.
(The existing tests about this were actually wrong.)
Co-authored-by: Florian Diebold <[email protected]>
-rw-r--r-- | crates/ra_assists/src/handlers/add_explicit_type.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 70 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/display_source_code.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 108 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 54 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 4 |
10 files changed, 192 insertions, 115 deletions
diff --git a/crates/ra_assists/src/handlers/add_explicit_type.rs b/crates/ra_assists/src/handlers/add_explicit_type.rs index ab20c6649..90b06a625 100644 --- a/crates/ra_assists/src/handlers/add_explicit_type.rs +++ b/crates/ra_assists/src/handlers/add_explicit_type.rs | |||
@@ -195,7 +195,7 @@ struct Test<K, T = u8> { | |||
195 | } | 195 | } |
196 | 196 | ||
197 | fn main() { | 197 | fn main() { |
198 | let test<|> = Test { t: 23, k: 33 }; | 198 | let test<|> = Test { t: 23u8, k: 33 }; |
199 | }"#, | 199 | }"#, |
200 | r#" | 200 | r#" |
201 | struct Test<K, T = u8> { | 201 | struct Test<K, T = u8> { |
@@ -204,7 +204,7 @@ struct Test<K, T = u8> { | |||
204 | } | 204 | } |
205 | 205 | ||
206 | fn main() { | 206 | fn main() { |
207 | let test: Test<i32> = Test { t: 23, k: 33 }; | 207 | let test: Test<i32> = Test { t: 23u8, k: 33 }; |
208 | }"#, | 208 | }"#, |
209 | ); | 209 | ); |
210 | } | 210 | } |
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index d9bf3c2f0..2e16e5120 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -439,13 +439,13 @@ impl<'a> InferenceContext<'a> { | |||
439 | }; | 439 | }; |
440 | return match resolution { | 440 | return match resolution { |
441 | TypeNs::AdtId(AdtId::StructId(strukt)) => { | 441 | TypeNs::AdtId(AdtId::StructId(strukt)) => { |
442 | let substs = Ty::substs_from_path(&ctx, path, strukt.into()); | 442 | let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true); |
443 | let ty = self.db.ty(strukt.into()); | 443 | let ty = self.db.ty(strukt.into()); |
444 | let ty = self.insert_type_vars(ty.subst(&substs)); | 444 | let ty = self.insert_type_vars(ty.subst(&substs)); |
445 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) | 445 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) |
446 | } | 446 | } |
447 | TypeNs::EnumVariantId(var) => { | 447 | TypeNs::EnumVariantId(var) => { |
448 | let substs = Ty::substs_from_path(&ctx, path, var.into()); | 448 | let substs = Ty::substs_from_path(&ctx, path, var.into(), true); |
449 | let ty = self.db.ty(var.parent.into()); | 449 | let ty = self.db.ty(var.parent.into()); |
450 | let ty = self.insert_type_vars(ty.subst(&substs)); | 450 | let ty = self.insert_type_vars(ty.subst(&substs)); |
451 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) | 451 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) |
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs index 1c2e56fb0..1ad0d8397 100644 --- a/crates/ra_hir_ty/src/infer/path.rs +++ b/crates/ra_hir_ty/src/infer/path.rs | |||
@@ -95,7 +95,7 @@ impl<'a> InferenceContext<'a> { | |||
95 | // self_subst is just for the parent | 95 | // self_subst is just for the parent |
96 | let parent_substs = self_subst.unwrap_or_else(Substs::empty); | 96 | let parent_substs = self_subst.unwrap_or_else(Substs::empty); |
97 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 97 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
98 | let substs = Ty::substs_from_path(&ctx, path, typable); | 98 | let substs = Ty::substs_from_path(&ctx, path, typable, true); |
99 | let full_substs = Substs::builder(substs.len()) | 99 | let full_substs = Substs::builder(substs.len()) |
100 | .use_parent_substs(&parent_substs) | 100 | .use_parent_substs(&parent_substs) |
101 | .fill(substs.0[parent_substs.len()..].iter().cloned()) | 101 | .fill(substs.0[parent_substs.len()..].iter().cloned()) |
@@ -141,6 +141,7 @@ impl<'a> InferenceContext<'a> { | |||
141 | def, | 141 | def, |
142 | resolved_segment, | 142 | resolved_segment, |
143 | remaining_segments_for_ty, | 143 | remaining_segments_for_ty, |
144 | true, | ||
144 | ); | 145 | ); |
145 | if let Ty::Unknown = ty { | 146 | if let Ty::Unknown = ty { |
146 | return None; | 147 | return None; |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index a05cbd7fc..42713928f 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -323,6 +323,7 @@ impl Ty { | |||
323 | resolution: TypeNs, | 323 | resolution: TypeNs, |
324 | resolved_segment: PathSegment<'_>, | 324 | resolved_segment: PathSegment<'_>, |
325 | remaining_segments: PathSegments<'_>, | 325 | remaining_segments: PathSegments<'_>, |
326 | infer_args: bool, | ||
326 | ) -> (Ty, Option<TypeNs>) { | 327 | ) -> (Ty, Option<TypeNs>) { |
327 | let ty = match resolution { | 328 | let ty = match resolution { |
328 | TypeNs::TraitId(trait_) => { | 329 | TypeNs::TraitId(trait_) => { |
@@ -400,9 +401,15 @@ impl Ty { | |||
400 | ctx.db.ty(adt.into()).subst(&substs) | 401 | ctx.db.ty(adt.into()).subst(&substs) |
401 | } | 402 | } |
402 | 403 | ||
403 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), | 404 | TypeNs::AdtId(it) => { |
404 | TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), | 405 | Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) |
405 | TypeNs::TypeAliasId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), | 406 | } |
407 | TypeNs::BuiltinType(it) => { | ||
408 | Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) | ||
409 | } | ||
410 | TypeNs::TypeAliasId(it) => { | ||
411 | Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) | ||
412 | } | ||
406 | // FIXME: report error | 413 | // FIXME: report error |
407 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), | 414 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), |
408 | }; | 415 | }; |
@@ -428,7 +435,13 @@ impl Ty { | |||
428 | ), | 435 | ), |
429 | Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), | 436 | Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), |
430 | }; | 437 | }; |
431 | Ty::from_partly_resolved_hir_path(ctx, resolution, resolved_segment, remaining_segments) | 438 | Ty::from_partly_resolved_hir_path( |
439 | ctx, | ||
440 | resolution, | ||
441 | resolved_segment, | ||
442 | remaining_segments, | ||
443 | false, | ||
444 | ) | ||
432 | } | 445 | } |
433 | 446 | ||
434 | fn select_associated_type( | 447 | fn select_associated_type( |
@@ -474,13 +487,14 @@ impl Ty { | |||
474 | ctx: &TyLoweringContext<'_>, | 487 | ctx: &TyLoweringContext<'_>, |
475 | segment: PathSegment<'_>, | 488 | segment: PathSegment<'_>, |
476 | typable: TyDefId, | 489 | typable: TyDefId, |
490 | infer_args: bool, | ||
477 | ) -> Ty { | 491 | ) -> Ty { |
478 | let generic_def = match typable { | 492 | let generic_def = match typable { |
479 | TyDefId::BuiltinType(_) => None, | 493 | TyDefId::BuiltinType(_) => None, |
480 | TyDefId::AdtId(it) => Some(it.into()), | 494 | TyDefId::AdtId(it) => Some(it.into()), |
481 | TyDefId::TypeAliasId(it) => Some(it.into()), | 495 | TyDefId::TypeAliasId(it) => Some(it.into()), |
482 | }; | 496 | }; |
483 | let substs = substs_from_path_segment(ctx, segment, generic_def, false); | 497 | let substs = substs_from_path_segment(ctx, segment, generic_def, infer_args); |
484 | ctx.db.ty(typable).subst(&substs) | 498 | ctx.db.ty(typable).subst(&substs) |
485 | } | 499 | } |
486 | 500 | ||
@@ -493,6 +507,7 @@ impl Ty { | |||
493 | // `ValueTyDefId` is just a convenient way to pass generics and | 507 | // `ValueTyDefId` is just a convenient way to pass generics and |
494 | // special-case enum variants | 508 | // special-case enum variants |
495 | resolved: ValueTyDefId, | 509 | resolved: ValueTyDefId, |
510 | infer_args: bool, | ||
496 | ) -> Substs { | 511 | ) -> Substs { |
497 | let last = path.segments().last().expect("path should have at least one segment"); | 512 | let last = path.segments().last().expect("path should have at least one segment"); |
498 | let (segment, generic_def) = match resolved { | 513 | let (segment, generic_def) = match resolved { |
@@ -515,22 +530,27 @@ impl Ty { | |||
515 | (segment, Some(var.parent.into())) | 530 | (segment, Some(var.parent.into())) |
516 | } | 531 | } |
517 | }; | 532 | }; |
518 | substs_from_path_segment(ctx, segment, generic_def, false) | 533 | substs_from_path_segment(ctx, segment, generic_def, infer_args) |
519 | } | 534 | } |
520 | } | 535 | } |
521 | 536 | ||
522 | pub(super) fn substs_from_path_segment( | 537 | fn substs_from_path_segment( |
523 | ctx: &TyLoweringContext<'_>, | 538 | ctx: &TyLoweringContext<'_>, |
524 | segment: PathSegment<'_>, | 539 | segment: PathSegment<'_>, |
525 | def_generic: Option<GenericDefId>, | 540 | def_generic: Option<GenericDefId>, |
526 | _add_self_param: bool, | 541 | infer_args: bool, |
527 | ) -> Substs { | 542 | ) -> Substs { |
528 | let mut substs = Vec::new(); | 543 | let mut substs = Vec::new(); |
529 | let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); | 544 | let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); |
530 | 545 | ||
531 | let (parent_params, self_params, type_params, impl_trait_params) = | 546 | let (parent_params, self_params, type_params, impl_trait_params) = |
532 | def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); | 547 | def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); |
548 | let total_len = parent_params + self_params + type_params + impl_trait_params; | ||
549 | |||
533 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); | 550 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); |
551 | |||
552 | let mut had_explicit_args = false; | ||
553 | |||
534 | if let Some(generic_args) = &segment.args_and_bindings { | 554 | if let Some(generic_args) = &segment.args_and_bindings { |
535 | if !generic_args.has_self_type { | 555 | if !generic_args.has_self_type { |
536 | substs.extend(iter::repeat(Ty::Unknown).take(self_params)); | 556 | substs.extend(iter::repeat(Ty::Unknown).take(self_params)); |
@@ -542,31 +562,35 @@ pub(super) fn substs_from_path_segment( | |||
542 | for arg in generic_args.args.iter().skip(skip).take(expected_num) { | 562 | for arg in generic_args.args.iter().skip(skip).take(expected_num) { |
543 | match arg { | 563 | match arg { |
544 | GenericArg::Type(type_ref) => { | 564 | GenericArg::Type(type_ref) => { |
565 | had_explicit_args = true; | ||
545 | let ty = Ty::from_hir(ctx, type_ref); | 566 | let ty = Ty::from_hir(ctx, type_ref); |
546 | substs.push(ty); | 567 | substs.push(ty); |
547 | } | 568 | } |
548 | } | 569 | } |
549 | } | 570 | } |
550 | } | 571 | } |
551 | let total_len = parent_params + self_params + type_params + impl_trait_params; | ||
552 | // add placeholders for args that were not provided | ||
553 | for _ in substs.len()..total_len { | ||
554 | substs.push(Ty::Unknown); | ||
555 | } | ||
556 | assert_eq!(substs.len(), total_len); | ||
557 | 572 | ||
558 | // handle defaults | 573 | // handle defaults. In expression or pattern path segments without |
559 | if let Some(def_generic) = def_generic { | 574 | // explicitly specified type arguments, missing type arguments are inferred |
560 | let default_substs = ctx.db.generic_defaults(def_generic); | 575 | // (i.e. defaults aren't used). |
561 | assert_eq!(substs.len(), default_substs.len()); | 576 | if !infer_args || had_explicit_args { |
577 | if let Some(def_generic) = def_generic { | ||
578 | let default_substs = ctx.db.generic_defaults(def_generic); | ||
579 | assert_eq!(total_len, default_substs.len()); | ||
562 | 580 | ||
563 | for (i, default_ty) in default_substs.iter().enumerate() { | 581 | for default_ty in default_substs.iter().skip(substs.len()) { |
564 | if substs[i] == Ty::Unknown { | 582 | substs.push(default_ty.clone()); |
565 | substs[i] = default_ty.clone(); | ||
566 | } | 583 | } |
567 | } | 584 | } |
568 | } | 585 | } |
569 | 586 | ||
587 | // add placeholders for args that were not provided | ||
588 | // FIXME: emit diagnostics in contexts where this is not allowed | ||
589 | for _ in substs.len()..total_len { | ||
590 | substs.push(Ty::Unknown); | ||
591 | } | ||
592 | assert_eq!(substs.len(), total_len); | ||
593 | |||
570 | Substs(substs.into()) | 594 | Substs(substs.into()) |
571 | } | 595 | } |
572 | 596 | ||
@@ -615,9 +639,7 @@ impl TraitRef { | |||
615 | segment: PathSegment<'_>, | 639 | segment: PathSegment<'_>, |
616 | resolved: TraitId, | 640 | resolved: TraitId, |
617 | ) -> Substs { | 641 | ) -> Substs { |
618 | let has_self_param = | 642 | substs_from_path_segment(ctx, segment, Some(resolved.into()), false) |
619 | segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); | ||
620 | substs_from_path_segment(ctx, segment, Some(resolved.into()), !has_self_param) | ||
621 | } | 643 | } |
622 | 644 | ||
623 | pub(crate) fn from_type_bound( | 645 | pub(crate) fn from_type_bound( |
diff --git a/crates/ra_hir_ty/src/tests/display_source_code.rs b/crates/ra_hir_ty/src/tests/display_source_code.rs index 4088b1d22..5dfa0a014 100644 --- a/crates/ra_hir_ty/src/tests/display_source_code.rs +++ b/crates/ra_hir_ty/src/tests/display_source_code.rs | |||
@@ -29,7 +29,7 @@ fn omit_default_type_parameters() { | |||
29 | //- /main.rs | 29 | //- /main.rs |
30 | struct Foo<T = u8> { t: T } | 30 | struct Foo<T = u8> { t: T } |
31 | fn main() { | 31 | fn main() { |
32 | let foo = Foo { t: 5 }; | 32 | let foo = Foo { t: 5u8 }; |
33 | foo<|>; | 33 | foo<|>; |
34 | } | 34 | } |
35 | ", | 35 | ", |
@@ -41,7 +41,7 @@ fn omit_default_type_parameters() { | |||
41 | //- /main.rs | 41 | //- /main.rs |
42 | struct Foo<K, T = u8> { k: K, t: T } | 42 | struct Foo<K, T = u8> { k: K, t: T } |
43 | fn main() { | 43 | fn main() { |
44 | let foo = Foo { k: 400, t: 5 }; | 44 | let foo = Foo { k: 400, t: 5u8 }; |
45 | foo<|>; | 45 | foo<|>; |
46 | } | 46 | } |
47 | ", | 47 | ", |
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 558a70022..804297315 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -184,60 +184,6 @@ fn test() { | |||
184 | } | 184 | } |
185 | 185 | ||
186 | #[test] | 186 | #[test] |
187 | fn infer_associated_method_generics_with_default_param() { | ||
188 | assert_snapshot!( | ||
189 | infer(r#" | ||
190 | struct Gen<T=u32> { | ||
191 | val: T | ||
192 | } | ||
193 | |||
194 | impl<T> Gen<T> { | ||
195 | pub fn make() -> Gen<T> { | ||
196 | loop { } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | fn test() { | ||
201 | let a = Gen::make(); | ||
202 | } | ||
203 | "#), | ||
204 | @r###" | ||
205 | 80..104 '{ ... }': Gen<T> | ||
206 | 90..98 'loop { }': ! | ||
207 | 95..98 '{ }': () | ||
208 | 118..146 '{ ...e(); }': () | ||
209 | 128..129 'a': Gen<u32> | ||
210 | 132..141 'Gen::make': fn make<u32>() -> Gen<u32> | ||
211 | 132..143 'Gen::make()': Gen<u32> | ||
212 | "### | ||
213 | ); | ||
214 | } | ||
215 | |||
216 | #[test] | ||
217 | fn infer_associated_method_generics_with_default_tuple_param() { | ||
218 | let t = type_at( | ||
219 | r#" | ||
220 | //- /main.rs | ||
221 | struct Gen<T=()> { | ||
222 | val: T | ||
223 | } | ||
224 | |||
225 | impl<T> Gen<T> { | ||
226 | pub fn make() -> Gen<T> { | ||
227 | loop { } | ||
228 | } | ||
229 | } | ||
230 | |||
231 | fn test() { | ||
232 | let a = Gen::make(); | ||
233 | a.val<|>; | ||
234 | } | ||
235 | "#, | ||
236 | ); | ||
237 | assert_eq!(t, "()"); | ||
238 | } | ||
239 | |||
240 | #[test] | ||
241 | fn infer_associated_method_generics_without_args() { | 187 | fn infer_associated_method_generics_without_args() { |
242 | assert_snapshot!( | 188 | assert_snapshot!( |
243 | infer(r#" | 189 | infer(r#" |
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 88309157b..8a5031756 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs | |||
@@ -1997,3 +1997,111 @@ fn foo() { | |||
1997 | "### | 1997 | "### |
1998 | ); | 1998 | ); |
1999 | } | 1999 | } |
2000 | |||
2001 | #[test] | ||
2002 | fn generic_default() { | ||
2003 | assert_snapshot!( | ||
2004 | infer(r#" | ||
2005 | struct Thing<T = ()> { t: T } | ||
2006 | enum OtherThing<T = ()> { | ||
2007 | One { t: T }, | ||
2008 | Two(T), | ||
2009 | } | ||
2010 | |||
2011 | fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) { | ||
2012 | t1.t; | ||
2013 | t3.t; | ||
2014 | match t2 { | ||
2015 | OtherThing::One { t } => { t; }, | ||
2016 | OtherThing::Two(t) => { t; }, | ||
2017 | } | ||
2018 | match t4 { | ||
2019 | OtherThing::One { t } => { t; }, | ||
2020 | OtherThing::Two(t) => { t; }, | ||
2021 | } | ||
2022 | } | ||
2023 | "#), | ||
2024 | @r###" | ||
2025 | 98..100 't1': Thing<()> | ||
2026 | 109..111 't2': OtherThing<()> | ||
2027 | 125..127 't3': Thing<i32> | ||
2028 | 141..143 't4': OtherThing<i32> | ||
2029 | 162..385 '{ ... } }': () | ||
2030 | 168..170 't1': Thing<()> | ||
2031 | 168..172 't1.t': () | ||
2032 | 178..180 't3': Thing<i32> | ||
2033 | 178..182 't3.t': i32 | ||
2034 | 188..283 'match ... }': () | ||
2035 | 194..196 't2': OtherThing<()> | ||
2036 | 207..228 'OtherT... { t }': OtherThing<()> | ||
2037 | 225..226 't': () | ||
2038 | 232..238 '{ t; }': () | ||
2039 | 234..235 't': () | ||
2040 | 248..266 'OtherT...Two(t)': OtherThing<()> | ||
2041 | 264..265 't': () | ||
2042 | 270..276 '{ t; }': () | ||
2043 | 272..273 't': () | ||
2044 | 288..383 'match ... }': () | ||
2045 | 294..296 't4': OtherThing<i32> | ||
2046 | 307..328 'OtherT... { t }': OtherThing<i32> | ||
2047 | 325..326 't': i32 | ||
2048 | 332..338 '{ t; }': () | ||
2049 | 334..335 't': i32 | ||
2050 | 348..366 'OtherT...Two(t)': OtherThing<i32> | ||
2051 | 364..365 't': i32 | ||
2052 | 370..376 '{ t; }': () | ||
2053 | 372..373 't': i32 | ||
2054 | "### | ||
2055 | ); | ||
2056 | } | ||
2057 | |||
2058 | #[test] | ||
2059 | fn generic_default_in_struct_literal() { | ||
2060 | assert_snapshot!( | ||
2061 | infer(r#" | ||
2062 | struct Thing<T = ()> { t: T } | ||
2063 | enum OtherThing<T = ()> { | ||
2064 | One { t: T }, | ||
2065 | Two(T), | ||
2066 | } | ||
2067 | |||
2068 | fn test() { | ||
2069 | let x = Thing { t: loop {} }; | ||
2070 | let y = Thing { t: () }; | ||
2071 | let z = Thing { t: 1i32 }; | ||
2072 | if let Thing { t } = z { | ||
2073 | t; | ||
2074 | } | ||
2075 | |||
2076 | let a = OtherThing::One { t: 1i32 }; | ||
2077 | let b = OtherThing::Two(1i32); | ||
2078 | } | ||
2079 | "#), | ||
2080 | @r###" | ||
2081 | 100..320 '{ ...32); }': () | ||
2082 | 110..111 'x': Thing<!> | ||
2083 | 114..134 'Thing ...p {} }': Thing<!> | ||
2084 | 125..132 'loop {}': ! | ||
2085 | 130..132 '{}': () | ||
2086 | 144..145 'y': Thing<()> | ||
2087 | 148..163 'Thing { t: () }': Thing<()> | ||
2088 | 159..161 '()': () | ||
2089 | 173..174 'z': Thing<i32> | ||
2090 | 177..194 'Thing ...1i32 }': Thing<i32> | ||
2091 | 188..192 '1i32': i32 | ||
2092 | 200..241 'if let... }': () | ||
2093 | 207..218 'Thing { t }': Thing<i32> | ||
2094 | 215..216 't': i32 | ||
2095 | 221..222 'z': Thing<i32> | ||
2096 | 223..241 '{ ... }': () | ||
2097 | 233..234 't': i32 | ||
2098 | 251..252 'a': OtherThing<i32> | ||
2099 | 255..282 'OtherT...1i32 }': OtherThing<i32> | ||
2100 | 276..280 '1i32': i32 | ||
2101 | 292..293 'b': OtherThing<i32> | ||
2102 | 296..311 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32> | ||
2103 | 296..317 'OtherT...(1i32)': OtherThing<i32> | ||
2104 | 312..316 '1i32': i32 | ||
2105 | "### | ||
2106 | ); | ||
2107 | } | ||
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 0c538a62d..133fb5f39 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1806,33 +1806,33 @@ fn test() { | |||
1806 | } | 1806 | } |
1807 | "#), | 1807 | "#), |
1808 | @r###" | 1808 | @r###" |
1809 | 65..69 'self': &Self | 1809 | 65..69 'self': &Self |
1810 | 166..170 'self': Self | 1810 | 166..170 'self': Self |
1811 | 172..176 'args': Args | 1811 | 172..176 'args': Args |
1812 | 240..244 'self': &Foo | 1812 | 240..244 'self': &Foo |
1813 | 255..257 '{}': () | 1813 | 255..257 '{}': () |
1814 | 335..336 'f': F | 1814 | 335..336 'f': F |
1815 | 355..357 '{}': () | 1815 | 355..357 '{}': () |
1816 | 444..690 '{ ...o(); }': () | 1816 | 444..690 '{ ...o(); }': () |
1817 | 454..459 'lazy1': Lazy<Foo, fn() -> T> | 1817 | 454..459 'lazy1': Lazy<Foo, || -> Foo> |
1818 | 476..485 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> | 1818 | 476..485 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> |
1819 | 476..493 'Lazy::...| Foo)': Lazy<Foo, fn() -> T> | 1819 | 476..493 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> |
1820 | 486..492 '|| Foo': || -> T | 1820 | 486..492 '|| Foo': || -> Foo |
1821 | 489..492 'Foo': Foo | 1821 | 489..492 'Foo': Foo |
1822 | 503..505 'r1': {unknown} | 1822 | 503..505 'r1': usize |
1823 | 508..513 'lazy1': Lazy<Foo, fn() -> T> | 1823 | 508..513 'lazy1': Lazy<Foo, || -> Foo> |
1824 | 508..519 'lazy1.foo()': {unknown} | 1824 | 508..519 'lazy1.foo()': usize |
1825 | 561..576 'make_foo_fn_ptr': fn() -> Foo | 1825 | 561..576 'make_foo_fn_ptr': fn() -> Foo |
1826 | 592..603 'make_foo_fn': fn make_foo_fn() -> Foo | 1826 | 592..603 'make_foo_fn': fn make_foo_fn() -> Foo |
1827 | 613..618 'lazy2': Lazy<Foo, fn() -> T> | 1827 | 613..618 'lazy2': Lazy<Foo, fn() -> Foo> |
1828 | 635..644 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> | 1828 | 635..644 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> |
1829 | 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> T> | 1829 | 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> |
1830 | 645..660 'make_foo_fn_ptr': fn() -> Foo | 1830 | 645..660 'make_foo_fn_ptr': fn() -> Foo |
1831 | 671..673 'r2': {unknown} | 1831 | 671..673 'r2': {unknown} |
1832 | 676..681 'lazy2': Lazy<Foo, fn() -> T> | 1832 | 676..681 'lazy2': Lazy<Foo, fn() -> Foo> |
1833 | 676..687 'lazy2.foo()': {unknown} | 1833 | 676..687 'lazy2.foo()': {unknown} |
1834 | 550..552 '{}': () | 1834 | 550..552 '{}': () |
1835 | "### | 1835 | "### |
1836 | ); | 1836 | ); |
1837 | } | 1837 | } |
1838 | 1838 | ||
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 62df07459..846d8c69b 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -529,7 +529,7 @@ struct Test<K, T = u8> { | |||
529 | } | 529 | } |
530 | 530 | ||
531 | fn main() { | 531 | fn main() { |
532 | let zz<|> = Test { t: 23, k: 33 }; | 532 | let zz<|> = Test { t: 23u8, k: 33 }; |
533 | }"#, | 533 | }"#, |
534 | &["Test<i32, u8>"], | 534 | &["Test<i32, u8>"], |
535 | ); | 535 | ); |
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 49366de98..7eb2cef73 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -415,7 +415,7 @@ struct Test<K, T = u8> { | |||
415 | } | 415 | } |
416 | 416 | ||
417 | fn main() { | 417 | fn main() { |
418 | let zz = Test { t: 23, k: 33 }; | 418 | let zz = Test { t: 23u8, k: 33 }; |
419 | let zz_ref = &zz; | 419 | let zz_ref = &zz; |
420 | }"#, | 420 | }"#, |
421 | ); | 421 | ); |
@@ -428,7 +428,7 @@ fn main() { | |||
428 | label: "Test<i32>", | 428 | label: "Test<i32>", |
429 | }, | 429 | }, |
430 | InlayHint { | 430 | InlayHint { |
431 | range: 105..111, | 431 | range: 107..113, |
432 | kind: TypeHint, | 432 | kind: TypeHint, |
433 | label: "&Test<i32>", | 433 | label: "&Test<i32>", |
434 | }, | 434 | }, |