@@ -1922,39 +1922,31 @@ fn report_bivariance<'tcx>(
1922
1922
) ;
1923
1923
1924
1924
if !usage_spans. is_empty ( ) {
1925
- // First, check if the ADT is (probably) cyclical. We say probably here, since
1926
- // we're not actually looking into substitutions, just walking through fields.
1927
- // And we only recurse into the fields of ADTs, and not the hidden types of
1928
- // opaques or anything else fancy.
1925
+ // First, check if the ADT/LTA is (probably) cyclical. We say probably here, since we're
1926
+ // not actually looking into substitutions, just walking through fields / the "RHS".
1927
+ // We don't recurse into the hidden types of opaques or anything else fancy.
1929
1928
let item_def_id = item. owner_id . to_def_id ( ) ;
1930
- let is_probably_cyclical = if matches ! (
1931
- tcx. def_kind( item_def_id) ,
1932
- DefKind :: Struct | DefKind :: Union | DefKind :: Enum
1933
- ) {
1934
- IsProbablyCyclical { tcx, adt_def_id : item_def_id, seen : Default :: default ( ) }
1935
- . visit_all_fields ( tcx. adt_def ( item_def_id) )
1936
- . is_break ( )
1937
- } else {
1938
- false
1939
- } ;
1940
- // If the ADT is cyclical, then if at least one usage of the type parameter or
1941
- // the `Self` alias is present in the, then it's probably a cyclical struct, and
1942
- // we should call those parameter usages recursive rather than just saying they're
1943
- // unused...
1929
+ let is_probably_cyclical =
1930
+ IsProbablyCyclical { tcx, item_def_id, seen : Default :: default ( ) }
1931
+ . visit_def ( item_def_id)
1932
+ . is_break ( ) ;
1933
+ // If the ADT/LTA is cyclical, then if at least one usage of the type parameter or
1934
+ // the `Self` alias is present in the, then it's probably a cyclical struct/ type
1935
+ // alias, and we should call those parameter usages recursive rather than just saying
1936
+ // they're unused...
1944
1937
//
1945
1938
// We currently report *all* of the parameter usages, since computing the exact
1946
1939
// subset is very involved, and the fact we're mentioning recursion at all is
1947
1940
// likely to guide the user in the right direction.
1948
1941
if is_probably_cyclical {
1949
- let diag = tcx. dcx ( ) . create_err ( errors:: RecursiveGenericParameter {
1942
+ return tcx. dcx ( ) . emit_err ( errors:: RecursiveGenericParameter {
1950
1943
spans : usage_spans,
1951
1944
param_span : param. span ,
1952
1945
param_name,
1953
1946
param_def_kind : tcx. def_descr ( param. def_id . to_def_id ( ) ) ,
1954
1947
help,
1955
1948
note : ( ) ,
1956
1949
} ) ;
1957
- return diag. emit ( ) ;
1958
1950
}
1959
1951
}
1960
1952
@@ -1974,42 +1966,51 @@ fn report_bivariance<'tcx>(
1974
1966
diag. emit ( )
1975
1967
}
1976
1968
1977
- /// Detects cases where an ADT is trivially cyclical -- we want to detect this so
1978
- /// / we only mention that its parameters are used cyclically if the ADT is truly
1969
+ /// Detects cases where an ADT/LTA is trivially cyclical -- we want to detect this so
1970
+ /// we only mention that its parameters are used cyclically if the ADT/LTA is truly
1979
1971
/// cyclical.
1980
1972
///
1981
1973
/// Notably, we don't consider substitutions here, so this may have false positives.
1982
1974
struct IsProbablyCyclical < ' tcx > {
1983
1975
tcx : TyCtxt < ' tcx > ,
1984
- adt_def_id : DefId ,
1976
+ item_def_id : DefId ,
1985
1977
seen : FxHashSet < DefId > ,
1986
1978
}
1987
1979
1988
1980
impl < ' tcx > IsProbablyCyclical < ' tcx > {
1989
- fn visit_all_fields ( & mut self , adt_def : ty:: AdtDef < ' tcx > ) -> ControlFlow < ( ) , ( ) > {
1990
- for field in adt_def. all_fields ( ) {
1991
- self . tcx . type_of ( field. did ) . instantiate_identity ( ) . visit_with ( self ) ?;
1981
+ fn visit_def ( & mut self , def_id : DefId ) -> ControlFlow < ( ) , ( ) > {
1982
+ match self . tcx . def_kind ( def_id) {
1983
+ DefKind :: Struct | DefKind :: Enum | DefKind :: Union => {
1984
+ self . tcx . adt_def ( def_id) . all_fields ( ) . try_for_each ( |field| {
1985
+ self . tcx . type_of ( field. did ) . instantiate_identity ( ) . visit_with ( self )
1986
+ } )
1987
+ }
1988
+ DefKind :: TyAlias if self . tcx . type_alias_is_lazy ( def_id) => {
1989
+ self . tcx . type_of ( def_id) . instantiate_identity ( ) . visit_with ( self )
1990
+ }
1991
+ _ => ControlFlow :: Continue ( ( ) ) ,
1992
1992
}
1993
-
1994
- ControlFlow :: Continue ( ( ) )
1995
1993
}
1996
1994
}
1997
1995
1998
1996
impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for IsProbablyCyclical < ' tcx > {
1999
1997
type Result = ControlFlow < ( ) , ( ) > ;
2000
1998
2001
- fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < ( ) , ( ) > {
2002
- if let Some ( adt_def) = t. ty_adt_def ( ) {
2003
- if adt_def. did ( ) == self . adt_def_id {
1999
+ fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < ( ) , ( ) > {
2000
+ let def_id = match ty. kind ( ) {
2001
+ ty:: Adt ( adt_def, _) => Some ( adt_def. did ( ) ) ,
2002
+ ty:: Alias ( ty:: Weak , alias_ty) => Some ( alias_ty. def_id ) ,
2003
+ _ => None ,
2004
+ } ;
2005
+ if let Some ( def_id) = def_id {
2006
+ if def_id == self . item_def_id {
2004
2007
return ControlFlow :: Break ( ( ) ) ;
2005
2008
}
2006
-
2007
- if self . seen . insert ( adt_def. did ( ) ) {
2008
- self . visit_all_fields ( adt_def) ?;
2009
+ if self . seen . insert ( def_id) {
2010
+ self . visit_def ( def_id) ?;
2009
2011
}
2010
2012
}
2011
-
2012
- t. super_visit_with ( self )
2013
+ ty. super_visit_with ( self )
2013
2014
}
2014
2015
}
2015
2016
0 commit comments