File tree 4 files changed +89
-1
lines changed
ide-diagnostics/src/handlers
4 files changed +89
-1
lines changed Original file line number Diff line number Diff line change @@ -575,6 +575,9 @@ impl<'a> InferenceContext<'a> {
575
575
let field_ty = field_def. map_or ( self . err_ty ( ) , |it| {
576
576
field_types[ it. local_id ] . clone ( ) . substitute ( Interner , & substs)
577
577
} ) ;
578
+ // Field type might have some unknown types
579
+ // FIXME: we may want to emit a single type variable for all instance of type fields?
580
+ let field_ty = self . insert_type_vars ( field_ty) ;
578
581
self . infer_expr_coerce ( field. expr , & Expectation :: has_type ( field_ty) ) ;
579
582
}
580
583
if let Some ( expr) = spread {
Original file line number Diff line number Diff line change @@ -781,8 +781,16 @@ impl<'a> InferenceTable<'a> {
781
781
pub ( super ) fn insert_const_vars_shallow ( & mut self , c : Const ) -> Const {
782
782
let data = c. data ( Interner ) ;
783
783
match & data. value {
784
- ConstValue :: Concrete ( cc) => match cc. interned {
784
+ ConstValue :: Concrete ( cc) => match & cc. interned {
785
785
crate :: ConstScalar :: Unknown => self . new_const_var ( data. ty . clone ( ) ) ,
786
+ // try to evaluate unevaluated const. Replace with new var if const eval failed.
787
+ crate :: ConstScalar :: UnevaluatedConst ( id, subst) => {
788
+ if let Ok ( eval) = self . db . const_eval ( * id, subst. clone ( ) ) {
789
+ eval
790
+ } else {
791
+ self . new_const_var ( data. ty . clone ( ) )
792
+ }
793
+ }
786
794
_ => c,
787
795
} ,
788
796
_ => c,
Original file line number Diff line number Diff line change @@ -1837,3 +1837,58 @@ fn foo() {
1837
1837
}" ,
1838
1838
) ;
1839
1839
}
1840
+
1841
+ #[ test]
1842
+ fn regression_14844 ( ) {
1843
+ check_no_mismatches (
1844
+ r#"
1845
+ pub type Ty = Unknown;
1846
+
1847
+ pub struct Inner<T>();
1848
+
1849
+ pub struct Outer {
1850
+ pub inner: Inner<Ty>,
1851
+ }
1852
+
1853
+ fn main() {
1854
+ _ = Outer {
1855
+ inner: Inner::<i32>(),
1856
+ };
1857
+ }
1858
+ "# ,
1859
+ ) ;
1860
+ check_no_mismatches (
1861
+ r#"
1862
+ pub const ONE: usize = 1;
1863
+
1864
+ pub struct Inner<const P: usize>();
1865
+
1866
+ pub struct Outer {
1867
+ pub inner: Inner<ONE>,
1868
+ }
1869
+
1870
+ fn main() {
1871
+ _ = Outer {
1872
+ inner: Inner::<1>(),
1873
+ };
1874
+ }
1875
+ "# ,
1876
+ ) ;
1877
+ check_no_mismatches (
1878
+ r#"
1879
+ pub const ONE: usize = unknown();
1880
+
1881
+ pub struct Inner<const P: usize>();
1882
+
1883
+ pub struct Outer {
1884
+ pub inner: Inner<ONE>,
1885
+ }
1886
+
1887
+ fn main() {
1888
+ _ = Outer {
1889
+ inner: Inner::<1>(),
1890
+ };
1891
+ }
1892
+ "# ,
1893
+ ) ;
1894
+ }
Original file line number Diff line number Diff line change @@ -644,6 +644,28 @@ fn h() {
644
644
) ;
645
645
}
646
646
647
+ #[ test]
648
+ fn evaluate_const_generics_in_types ( ) {
649
+ check_diagnostics (
650
+ r#"
651
+ pub const ONE: usize = 1;
652
+
653
+ pub struct Inner<const P: usize>();
654
+
655
+ pub struct Outer {
656
+ pub inner: Inner<ONE>,
657
+ }
658
+
659
+ fn main() {
660
+ _ = Outer {
661
+ inner: Inner::<2>(),
662
+ //^^^^^^^^^^^^ error: expected Inner<1>, found Inner<2>
663
+ };
664
+ }
665
+ "# ,
666
+ ) ;
667
+ }
668
+
647
669
#[ test]
648
670
fn type_mismatch_pat_smoke_test ( ) {
649
671
check_diagnostics (
You can’t perform that action at this time.
0 commit comments