@@ -43,12 +43,6 @@ pub trait InferCtxtExt<'tcx> {
43
43
body_id : hir:: HirId ,
44
44
) ;
45
45
46
- fn suggest_borrow_on_unsized_slice (
47
- & self ,
48
- code : & ObligationCauseCode < ' tcx > ,
49
- err : & mut DiagnosticBuilder < ' _ > ,
50
- ) ;
51
-
52
46
fn suggest_dereferences (
53
47
& self ,
54
48
obligation : & PredicateObligation < ' tcx > ,
@@ -515,32 +509,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
515
509
}
516
510
}
517
511
518
- /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
519
- /// suggestion to borrow the initializer in order to use have a slice instead.
520
- fn suggest_borrow_on_unsized_slice (
521
- & self ,
522
- code : & ObligationCauseCode < ' tcx > ,
523
- err : & mut DiagnosticBuilder < ' _ > ,
524
- ) {
525
- if let & ObligationCauseCode :: VariableType ( hir_id) = code {
526
- let parent_node = self . tcx . hir ( ) . get_parent_node ( hir_id) ;
527
- if let Some ( Node :: Local ( ref local) ) = self . tcx . hir ( ) . find ( parent_node) {
528
- if let Some ( ref expr) = local. init {
529
- if let hir:: ExprKind :: Index ( _, _) = expr. kind {
530
- if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( expr. span ) {
531
- err. span_suggestion (
532
- expr. span ,
533
- "consider borrowing here" ,
534
- format ! ( "&{}" , snippet) ,
535
- Applicability :: MachineApplicable ,
536
- ) ;
537
- }
538
- }
539
- }
540
- }
541
- }
542
- }
543
-
544
512
/// Given a closure's `DefId`, return the given name of the closure.
545
513
///
546
514
/// This doesn't account for reassignments, but it's only used for suggestions.
@@ -1817,15 +1785,56 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1817
1785
}
1818
1786
}
1819
1787
}
1820
- ObligationCauseCode :: VariableType ( _) => {
1821
- err. note ( "all local variables must have a statically known size" ) ;
1788
+ ObligationCauseCode :: VariableType ( hir_id) => {
1789
+ let parent_node = self . tcx . hir ( ) . get_parent_node ( hir_id) ;
1790
+ match self . tcx . hir ( ) . find ( parent_node) {
1791
+ Some ( Node :: Local ( hir:: Local {
1792
+ init : Some ( hir:: Expr { kind : hir:: ExprKind :: Index ( _, _) , span, .. } ) ,
1793
+ ..
1794
+ } ) ) => {
1795
+ // When encountering an assignment of an unsized trait, like
1796
+ // `let x = ""[..];`, provide a suggestion to borrow the initializer in
1797
+ // order to use have a slice instead.
1798
+ err. span_suggestion_verbose (
1799
+ span. shrink_to_lo ( ) ,
1800
+ "consider borrowing here" ,
1801
+ "&" . to_owned ( ) ,
1802
+ Applicability :: MachineApplicable ,
1803
+ ) ;
1804
+ err. note ( "all local variables must have a statically known size" ) ;
1805
+ }
1806
+ Some ( Node :: Param ( param) ) => {
1807
+ err. span_suggestion_verbose (
1808
+ param. ty_span . shrink_to_lo ( ) ,
1809
+ "function arguments must have a statically known size, borrowed types \
1810
+ always have a known size",
1811
+ "&" . to_owned ( ) ,
1812
+ Applicability :: MachineApplicable ,
1813
+ ) ;
1814
+ }
1815
+ _ => {
1816
+ err. note ( "all local variables must have a statically known size" ) ;
1817
+ }
1818
+ }
1822
1819
if !self . tcx . features ( ) . unsized_locals {
1823
1820
err. help ( "unsized locals are gated as an unstable feature" ) ;
1824
1821
}
1825
1822
}
1826
- ObligationCauseCode :: SizedArgumentType => {
1827
- err. note ( "all function arguments must have a statically known size" ) ;
1828
- if !self . tcx . features ( ) . unsized_locals {
1823
+ ObligationCauseCode :: SizedArgumentType ( sp) => {
1824
+ if let Some ( span) = sp {
1825
+ err. span_suggestion_verbose (
1826
+ span. shrink_to_lo ( ) ,
1827
+ "function arguments must have a statically known size, borrowed types \
1828
+ always have a known size",
1829
+ "&" . to_string ( ) ,
1830
+ Applicability :: MachineApplicable ,
1831
+ ) ;
1832
+ } else {
1833
+ err. note ( "all function arguments must have a statically known size" ) ;
1834
+ }
1835
+ if tcx. sess . opts . unstable_features . is_nightly_build ( )
1836
+ && !self . tcx . features ( ) . unsized_locals
1837
+ {
1829
1838
err. help ( "unsized locals are gated as an unstable feature" ) ;
1830
1839
}
1831
1840
}
@@ -1844,26 +1853,44 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1844
1853
ObligationCauseCode :: StructInitializerSized => {
1845
1854
err. note ( "structs must have a statically known size to be initialized" ) ;
1846
1855
}
1847
- ObligationCauseCode :: FieldSized { adt_kind : ref item, last } => match * item {
1848
- AdtKind :: Struct => {
1849
- if last {
1850
- err. note (
1851
- "the last field of a packed struct may only have a \
1852
- dynamically sized type if it does not need drop to be run",
1853
- ) ;
1854
- } else {
1855
- err. note (
1856
- "only the last field of a struct may have a dynamically sized type" ,
1857
- ) ;
1856
+ ObligationCauseCode :: FieldSized { adt_kind : ref item, last, span } => {
1857
+ match * item {
1858
+ AdtKind :: Struct => {
1859
+ if last {
1860
+ err. note (
1861
+ "the last field of a packed struct may only have a \
1862
+ dynamically sized type if it does not need drop to be run",
1863
+ ) ;
1864
+ } else {
1865
+ err. note (
1866
+ "only the last field of a struct may have a dynamically sized type" ,
1867
+ ) ;
1868
+ }
1869
+ }
1870
+ AdtKind :: Union => {
1871
+ err. note ( "no field of a union may have a dynamically sized type" ) ;
1872
+ }
1873
+ AdtKind :: Enum => {
1874
+ err. note ( "no field of an enum variant may have a dynamically sized type" ) ;
1858
1875
}
1859
1876
}
1860
- AdtKind :: Union => {
1861
- err. note ( "no field of a union may have a dynamically sized type" ) ;
1862
- }
1863
- AdtKind :: Enum => {
1864
- err. note ( "no field of an enum variant may have a dynamically sized type" ) ;
1865
- }
1866
- } ,
1877
+ err. help ( "change the field's type to have a statically known size" ) ;
1878
+ err. span_suggestion (
1879
+ span. shrink_to_lo ( ) ,
1880
+ "borrowed types always have a statically known size" ,
1881
+ "&" . to_string ( ) ,
1882
+ Applicability :: MachineApplicable ,
1883
+ ) ;
1884
+ err. multipart_suggestion (
1885
+ "the `Box` type always has a statically known size and allocates its contents \
1886
+ in the heap",
1887
+ vec ! [
1888
+ ( span. shrink_to_lo( ) , "Box<" . to_string( ) ) ,
1889
+ ( span. shrink_to_hi( ) , ">" . to_string( ) ) ,
1890
+ ] ,
1891
+ Applicability :: MachineApplicable ,
1892
+ ) ;
1893
+ }
1867
1894
ObligationCauseCode :: ConstSized => {
1868
1895
err. note ( "constant expressions must have a statically known size" ) ;
1869
1896
}
0 commit comments