@@ -26,7 +26,7 @@ use rustc_infer::infer::InferOk;
26
26
use rustc_infer:: infer:: TypeTrace ;
27
27
use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
28
28
use rustc_middle:: ty:: visit:: TypeVisitable ;
29
- use rustc_middle:: ty:: { self , DefIdTree , IsSuggestable , Ty , TypeSuperVisitable , TypeVisitor } ;
29
+ use rustc_middle:: ty:: { self , DefIdTree , IsSuggestable , Ty } ;
30
30
use rustc_session:: Session ;
31
31
use rustc_span:: symbol:: { kw, Ident } ;
32
32
use rustc_span:: { self , sym, Span } ;
@@ -36,8 +36,6 @@ use std::iter;
36
36
use std:: mem;
37
37
use std:: slice;
38
38
39
- use std:: ops:: ControlFlow ;
40
-
41
39
impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
42
40
pub ( in super :: super ) fn check_casts ( & mut self ) {
43
41
// don't hold the borrow to deferred_cast_checks while checking to avoid borrow checker errors
@@ -1758,372 +1756,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1758
1756
}
1759
1757
}
1760
1758
1761
- fn adjust_fulfillment_error_for_expr_obligation (
1762
- & self ,
1763
- error : & mut traits:: FulfillmentError < ' tcx > ,
1764
- ) -> bool {
1765
- let ( traits:: ExprItemObligation ( def_id, hir_id, idx) | traits:: ExprBindingObligation ( def_id, _, hir_id, idx) )
1766
- = * error. obligation . cause . code ( ) . peel_derives ( ) else { return false ; } ;
1767
- let hir = self . tcx . hir ( ) ;
1768
- let hir:: Node :: Expr ( expr) = hir. get ( hir_id) else { return false ; } ;
1769
-
1770
- let Some ( unsubstituted_pred) =
1771
- self . tcx . predicates_of ( def_id) . instantiate_identity ( self . tcx ) . predicates . into_iter ( ) . nth ( idx)
1772
- else { return false ; } ;
1773
-
1774
- let generics = self . tcx . generics_of ( def_id) ;
1775
- let predicate_substs = match unsubstituted_pred. kind ( ) . skip_binder ( ) {
1776
- ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( pred) ) => pred. trait_ref . substs ,
1777
- ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( pred) ) => pred. projection_ty . substs ,
1778
- _ => ty:: List :: empty ( ) ,
1779
- } ;
1780
-
1781
- let find_param_matching = |matches : & dyn Fn ( & ty:: ParamTy ) -> bool | {
1782
- predicate_substs. types ( ) . find_map ( |ty| {
1783
- ty. walk ( ) . find_map ( |arg| {
1784
- if let ty:: GenericArgKind :: Type ( ty) = arg. unpack ( )
1785
- && let ty:: Param ( param_ty) = ty. kind ( )
1786
- && matches ( param_ty)
1787
- {
1788
- Some ( arg)
1789
- } else {
1790
- None
1791
- }
1792
- } )
1793
- } )
1794
- } ;
1795
-
1796
- // Prefer generics that are local to the fn item, since these are likely
1797
- // to be the cause of the unsatisfied predicate.
1798
- let mut param_to_point_at = find_param_matching ( & |param_ty| {
1799
- self . tcx . parent ( generics. type_param ( param_ty, self . tcx ) . def_id ) == def_id
1800
- } ) ;
1801
- // Fall back to generic that isn't local to the fn item. This will come
1802
- // from a trait or impl, for example.
1803
- let mut fallback_param_to_point_at = find_param_matching ( & |param_ty| {
1804
- self . tcx . parent ( generics. type_param ( param_ty, self . tcx ) . def_id ) != def_id
1805
- && param_ty. name != rustc_span:: symbol:: kw:: SelfUpper
1806
- } ) ;
1807
- // Finally, the `Self` parameter is possibly the reason that the predicate
1808
- // is unsatisfied. This is less likely to be true for methods, because
1809
- // method probe means that we already kinda check that the predicates due
1810
- // to the `Self` type are true.
1811
- let mut self_param_to_point_at =
1812
- find_param_matching ( & |param_ty| param_ty. name == rustc_span:: symbol:: kw:: SelfUpper ) ;
1813
-
1814
- // Finally, for ambiguity-related errors, we actually want to look
1815
- // for a parameter that is the source of the inference type left
1816
- // over in this predicate.
1817
- if let traits:: FulfillmentErrorCode :: CodeAmbiguity = error. code {
1818
- fallback_param_to_point_at = None ;
1819
- self_param_to_point_at = None ;
1820
- param_to_point_at =
1821
- self . find_ambiguous_parameter_in ( def_id, error. root_obligation . predicate ) ;
1822
- }
1823
-
1824
- if self . closure_span_overlaps_error ( error, expr. span ) {
1825
- return false ;
1826
- }
1827
-
1828
- match & expr. kind {
1829
- hir:: ExprKind :: Path ( qpath) => {
1830
- if let hir:: Node :: Expr ( hir:: Expr {
1831
- kind : hir:: ExprKind :: Call ( callee, args) ,
1832
- hir_id : call_hir_id,
1833
- span : call_span,
1834
- ..
1835
- } ) = hir. get_parent ( expr. hir_id )
1836
- && callee. hir_id == expr. hir_id
1837
- {
1838
- if self . closure_span_overlaps_error ( error, * call_span) {
1839
- return false ;
1840
- }
1841
-
1842
- for param in
1843
- [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
1844
- . into_iter ( )
1845
- . flatten ( )
1846
- {
1847
- if self . blame_specific_arg_if_possible (
1848
- error,
1849
- def_id,
1850
- param,
1851
- * call_hir_id,
1852
- callee. span ,
1853
- None ,
1854
- args,
1855
- )
1856
- {
1857
- return true ;
1858
- }
1859
- }
1860
- }
1861
- // Notably, we only point to params that are local to the
1862
- // item we're checking, since those are the ones we are able
1863
- // to look in the final `hir::PathSegment` for. Everything else
1864
- // would require a deeper search into the `qpath` than I think
1865
- // is worthwhile.
1866
- if let Some ( param_to_point_at) = param_to_point_at
1867
- && self . point_at_path_if_possible ( error, def_id, param_to_point_at, qpath)
1868
- {
1869
- return true ;
1870
- }
1871
- }
1872
- hir:: ExprKind :: MethodCall ( segment, receiver, args, ..) => {
1873
- for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
1874
- . into_iter ( )
1875
- . flatten ( )
1876
- {
1877
- if self . blame_specific_arg_if_possible (
1878
- error,
1879
- def_id,
1880
- param,
1881
- hir_id,
1882
- segment. ident . span ,
1883
- Some ( receiver) ,
1884
- args,
1885
- ) {
1886
- return true ;
1887
- }
1888
- }
1889
- if let Some ( param_to_point_at) = param_to_point_at
1890
- && self . point_at_generic_if_possible ( error, def_id, param_to_point_at, segment)
1891
- {
1892
- return true ;
1893
- }
1894
- }
1895
- hir:: ExprKind :: Struct ( qpath, fields, ..) => {
1896
- if let Res :: Def ( DefKind :: Struct | DefKind :: Variant , variant_def_id) =
1897
- self . typeck_results . borrow ( ) . qpath_res ( qpath, hir_id)
1898
- {
1899
- for param in
1900
- [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
1901
- {
1902
- if let Some ( param) = param {
1903
- let refined_expr = self . point_at_field_if_possible (
1904
- def_id,
1905
- param,
1906
- variant_def_id,
1907
- fields,
1908
- ) ;
1909
-
1910
- match refined_expr {
1911
- None => { }
1912
- Some ( ( refined_expr, _) ) => {
1913
- error. obligation . cause . span = refined_expr
1914
- . span
1915
- . find_ancestor_in_same_ctxt ( error. obligation . cause . span )
1916
- . unwrap_or ( refined_expr. span ) ;
1917
- return true ;
1918
- }
1919
- }
1920
- }
1921
- }
1922
- }
1923
- if let Some ( param_to_point_at) = param_to_point_at
1924
- && self . point_at_path_if_possible ( error, def_id, param_to_point_at, qpath)
1925
- {
1926
- return true ;
1927
- }
1928
- }
1929
- _ => { }
1930
- }
1931
-
1932
- false
1933
- }
1934
-
1935
- fn closure_span_overlaps_error (
1936
- & self ,
1937
- error : & traits:: FulfillmentError < ' tcx > ,
1938
- span : Span ,
1939
- ) -> bool {
1940
- if let traits:: FulfillmentErrorCode :: CodeSelectionError (
1941
- traits:: SelectionError :: OutputTypeParameterMismatch ( _, expected, _) ,
1942
- ) = error. code
1943
- && let ty:: Closure ( def_id, _) | ty:: Generator ( def_id, ..) = expected. skip_binder ( ) . self_ty ( ) . kind ( )
1944
- && span. overlaps ( self . tcx . def_span ( * def_id) )
1945
- {
1946
- true
1947
- } else {
1948
- false
1949
- }
1950
- }
1951
-
1952
- /// - `blame_specific_*` means that the function will recursively traverse the expression,
1953
- /// looking for the most-specific-possible span to blame.
1954
- ///
1955
- /// - `point_at_*` means that the function will only go "one level", pointing at the specific
1956
- /// expression mentioned.
1957
- ///
1958
- /// `blame_specific_arg_if_possible` will find the most-specific expression anywhere inside
1959
- /// the provided function call expression, and mark it as responsible for the fullfillment
1960
- /// error.
1961
- fn blame_specific_arg_if_possible (
1962
- & self ,
1963
- error : & mut traits:: FulfillmentError < ' tcx > ,
1964
- def_id : DefId ,
1965
- param_to_point_at : ty:: GenericArg < ' tcx > ,
1966
- call_hir_id : hir:: HirId ,
1967
- callee_span : Span ,
1968
- receiver : Option < & ' tcx hir:: Expr < ' tcx > > ,
1969
- args : & ' tcx [ hir:: Expr < ' tcx > ] ,
1970
- ) -> bool {
1971
- let ty = self . tcx . type_of ( def_id) ;
1972
- if !ty. is_fn ( ) {
1973
- return false ;
1974
- }
1975
- let sig = ty. fn_sig ( self . tcx ) . skip_binder ( ) ;
1976
- let args_referencing_param: Vec < _ > = sig
1977
- . inputs ( )
1978
- . iter ( )
1979
- . enumerate ( )
1980
- . filter ( |( _, ty) | Self :: find_param_in_ty ( ( * * ty) . into ( ) , param_to_point_at) )
1981
- . collect ( ) ;
1982
- // If there's one field that references the given generic, great!
1983
- if let [ ( idx, _) ] = args_referencing_param. as_slice ( )
1984
- && let Some ( arg) = receiver
1985
- . map_or ( args. get ( * idx) , |rcvr| if * idx == 0 { Some ( rcvr) } else { args. get ( * idx - 1 ) } ) {
1986
-
1987
- error. obligation . cause . span = arg. span . find_ancestor_in_same_ctxt ( error. obligation . cause . span ) . unwrap_or ( arg. span ) ;
1988
-
1989
- if let hir:: Node :: Expr ( arg_expr) = self . tcx . hir ( ) . get ( arg. hir_id ) {
1990
- // This is more specific than pointing at the entire argument.
1991
- self . blame_specific_expr_if_possible ( error, arg_expr)
1992
- }
1993
-
1994
- error. obligation . cause . map_code ( |parent_code| {
1995
- ObligationCauseCode :: FunctionArgumentObligation {
1996
- arg_hir_id : arg. hir_id ,
1997
- call_hir_id,
1998
- parent_code,
1999
- }
2000
- } ) ;
2001
- return true ;
2002
- } else if args_referencing_param. len ( ) > 0 {
2003
- // If more than one argument applies, then point to the callee span at least...
2004
- // We have chance to fix this up further in `point_at_generics_if_possible`
2005
- error. obligation . cause . span = callee_span;
2006
- }
2007
-
2008
- false
2009
- }
2010
-
2011
- // FIXME: Make this private and move to mod adjust_fulfillment_errors
2012
- pub fn point_at_field_if_possible (
2013
- & self ,
2014
- def_id : DefId ,
2015
- param_to_point_at : ty:: GenericArg < ' tcx > ,
2016
- variant_def_id : DefId ,
2017
- expr_fields : & [ hir:: ExprField < ' tcx > ] ,
2018
- ) -> Option < ( & ' tcx hir:: Expr < ' tcx > , Ty < ' tcx > ) > {
2019
- let def = self . tcx . adt_def ( def_id) ;
2020
-
2021
- let identity_substs = ty:: InternalSubsts :: identity_for_item ( self . tcx , def_id) ;
2022
- let fields_referencing_param: Vec < _ > = def
2023
- . variant_with_id ( variant_def_id)
2024
- . fields
2025
- . iter ( )
2026
- . filter ( |field| {
2027
- let field_ty = field. ty ( self . tcx , identity_substs) ;
2028
- Self :: find_param_in_ty ( field_ty. into ( ) , param_to_point_at)
2029
- } )
2030
- . collect ( ) ;
2031
-
2032
- if let [ field] = fields_referencing_param. as_slice ( ) {
2033
- for expr_field in expr_fields {
2034
- // Look for the ExprField that matches the field, using the
2035
- // same rules that check_expr_struct uses for macro hygiene.
2036
- if self . tcx . adjust_ident ( expr_field. ident , variant_def_id) == field. ident ( self . tcx )
2037
- {
2038
- return Some ( ( expr_field. expr , self . tcx . type_of ( field. did ) ) ) ;
2039
- }
2040
- }
2041
- }
2042
-
2043
- None
2044
- }
2045
-
2046
- fn point_at_path_if_possible (
2047
- & self ,
2048
- error : & mut traits:: FulfillmentError < ' tcx > ,
2049
- def_id : DefId ,
2050
- param : ty:: GenericArg < ' tcx > ,
2051
- qpath : & QPath < ' tcx > ,
2052
- ) -> bool {
2053
- match qpath {
2054
- hir:: QPath :: Resolved ( _, path) => {
2055
- if let Some ( segment) = path. segments . last ( )
2056
- && self . point_at_generic_if_possible ( error, def_id, param, segment)
2057
- {
2058
- return true ;
2059
- }
2060
- }
2061
- hir:: QPath :: TypeRelative ( _, segment) => {
2062
- if self . point_at_generic_if_possible ( error, def_id, param, segment) {
2063
- return true ;
2064
- }
2065
- }
2066
- _ => { }
2067
- }
2068
-
2069
- false
2070
- }
2071
-
2072
- fn point_at_generic_if_possible (
2073
- & self ,
2074
- error : & mut traits:: FulfillmentError < ' tcx > ,
2075
- def_id : DefId ,
2076
- param_to_point_at : ty:: GenericArg < ' tcx > ,
2077
- segment : & hir:: PathSegment < ' tcx > ,
2078
- ) -> bool {
2079
- let own_substs = self
2080
- . tcx
2081
- . generics_of ( def_id)
2082
- . own_substs ( ty:: InternalSubsts :: identity_for_item ( self . tcx , def_id) ) ;
2083
- let Some ( ( index, _) ) = own_substs
2084
- . iter ( )
2085
- . filter ( |arg| matches ! ( arg. unpack( ) , ty:: GenericArgKind :: Type ( _) ) )
2086
- . enumerate ( )
2087
- . find ( |( _, arg) | * * arg == param_to_point_at) else { return false } ;
2088
- let Some ( arg) = segment
2089
- . args ( )
2090
- . args
2091
- . iter ( )
2092
- . filter ( |arg| matches ! ( arg, hir:: GenericArg :: Type ( _) ) )
2093
- . nth ( index) else { return false ; } ;
2094
- error. obligation . cause . span = arg
2095
- . span ( )
2096
- . find_ancestor_in_same_ctxt ( error. obligation . cause . span )
2097
- . unwrap_or ( arg. span ( ) ) ;
2098
- true
2099
- }
2100
-
2101
- fn find_ambiguous_parameter_in < T : TypeVisitable < ' tcx > > (
2102
- & self ,
2103
- item_def_id : DefId ,
2104
- t : T ,
2105
- ) -> Option < ty:: GenericArg < ' tcx > > {
2106
- struct FindAmbiguousParameter < ' a , ' tcx > ( & ' a FnCtxt < ' a , ' tcx > , DefId ) ;
2107
- impl < ' tcx > TypeVisitor < ' tcx > for FindAmbiguousParameter < ' _ , ' tcx > {
2108
- type BreakTy = ty:: GenericArg < ' tcx > ;
2109
- fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> std:: ops:: ControlFlow < Self :: BreakTy > {
2110
- if let Some ( origin) = self . 0 . type_var_origin ( ty)
2111
- && let TypeVariableOriginKind :: TypeParameterDefinition ( _, Some ( def_id) ) =
2112
- origin. kind
2113
- && let generics = self . 0 . tcx . generics_of ( self . 1 )
2114
- && let Some ( index) = generics. param_def_id_to_index ( self . 0 . tcx , def_id)
2115
- && let Some ( subst) = ty:: InternalSubsts :: identity_for_item ( self . 0 . tcx , self . 1 )
2116
- . get ( index as usize )
2117
- {
2118
- ControlFlow :: Break ( * subst)
2119
- } else {
2120
- ty. super_visit_with ( self )
2121
- }
2122
- }
2123
- }
2124
- t. visit_with ( & mut FindAmbiguousParameter ( self , item_def_id) ) . break_value ( )
2125
- }
2126
-
2127
1759
fn label_fn_like (
2128
1760
& self ,
2129
1761
err : & mut Diagnostic ,
0 commit comments