diff options
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/simple.rs | 55 |
2 files changed, 61 insertions, 0 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 13240f790..98bc23173 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -488,6 +488,12 @@ impl<'a> InferenceContext<'a> { | |||
488 | if let Some(box_) = self.resolve_boxed_box() { | 488 | if let Some(box_) = self.resolve_boxed_box() { |
489 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); | 489 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
490 | sb = sb.push(inner_ty); | 490 | sb = sb.push(inner_ty); |
491 | match self.db.generic_defaults(box_.into()).as_ref() { | ||
492 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | ||
493 | sb = sb.push(alloc_ty.value.clone()); | ||
494 | } | ||
495 | _ => (), | ||
496 | } | ||
491 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 497 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
492 | Ty::Adt(box_, sb.build()) | 498 | Ty::Adt(box_, sb.build()) |
493 | } else { | 499 | } else { |
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 12ec4657b..2947857a5 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -2491,3 +2491,58 @@ fn inner_use_enum_rename() { | |||
2491 | "#]], | 2491 | "#]], |
2492 | ) | 2492 | ) |
2493 | } | 2493 | } |
2494 | |||
2495 | #[test] | ||
2496 | fn box_into_vec() { | ||
2497 | check_infer( | ||
2498 | r#" | ||
2499 | #[lang = "sized"] | ||
2500 | pub trait Sized {} | ||
2501 | |||
2502 | #[lang = "unsize"] | ||
2503 | pub trait Unsize<T: ?Sized> {} | ||
2504 | |||
2505 | #[lang = "coerce_unsized"] | ||
2506 | pub trait CoerceUnsized<T> {} | ||
2507 | |||
2508 | pub unsafe trait Allocator {} | ||
2509 | |||
2510 | pub struct Global; | ||
2511 | unsafe impl Allocator for Global {} | ||
2512 | |||
2513 | #[lang = "owned_box"] | ||
2514 | #[fundamental] | ||
2515 | pub struct Box<T: ?Sized, A: Allocator = Global>; | ||
2516 | |||
2517 | impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {} | ||
2518 | |||
2519 | pub struct Vec<T, A: Allocator = Global> {} | ||
2520 | |||
2521 | #[lang = "slice"] | ||
2522 | impl<T> [T] {} | ||
2523 | |||
2524 | #[lang = "slice_alloc"] | ||
2525 | impl<T> [T] { | ||
2526 | pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> { | ||
2527 | unimplemented!() | ||
2528 | } | ||
2529 | } | ||
2530 | |||
2531 | fn test() { | ||
2532 | let vec = <[_]>::into_vec(box [1i32]); | ||
2533 | } | ||
2534 | "#, | ||
2535 | expect![[r#" | ||
2536 | 569..573 'self': Box<[T], A> | ||
2537 | 602..634 '{ ... }': Vec<T, A> | ||
2538 | 612..628 'unimpl...ted!()': Vec<T, A> | ||
2539 | 648..694 '{ ...2]); }': () | ||
2540 | 658..661 'vec': Vec<i32, Global> | ||
2541 | 664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global> | ||
2542 | 664..691 '<[_]>:...1i32])': Vec<i32, Global> | ||
2543 | 680..690 'box [1i32]': Box<[i32; _], Global> | ||
2544 | 684..690 '[1i32]': [i32; _] | ||
2545 | 685..689 '1i32': i32 | ||
2546 | "#]], | ||
2547 | ) | ||
2548 | } | ||