@@ -1930,7 +1930,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19301930 let mut features = Features :: new ( ) ;
19311931 let mut edition_enabled_features = FxHashMap ( ) ;
19321932
1933- for & ( name, .., f_edition, set) in ACTIVE_FEATURES . iter ( ) {
1933+ for & edition in ALL_EDITIONS {
1934+ if edition <= crate_edition {
1935+ // The `crate_edition` implies its respective umbrella feature-gate
1936+ // (i.e. `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
1937+ edition_enabled_features. insert ( Symbol :: intern ( edition. feature_name ( ) ) , edition) ;
1938+ }
1939+ }
1940+
1941+ for & ( name, .., f_edition, set) in ACTIVE_FEATURES {
19341942 if let Some ( f_edition) = f_edition {
19351943 if f_edition <= crate_edition {
19361944 set ( & mut features, DUMMY_SP ) ;
@@ -1939,26 +1947,22 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19391947 }
19401948 }
19411949
1950+ // Process the edition umbrella feature-gates first, to ensure
1951+ // `edition_enabled_features` is completed before it's queried.
19421952 for attr in krate_attrs {
19431953 if !attr. check_name ( "feature" ) {
19441954 continue
19451955 }
19461956
19471957 let list = match attr. meta_item_list ( ) {
19481958 Some ( list) => list,
1949- None => {
1950- span_err ! ( span_handler, attr. span, E0555 ,
1951- "malformed feature attribute, expected #![feature(...)]" ) ;
1952- continue
1953- }
1959+ None => continue ,
19541960 } ;
19551961
19561962 for mi in list {
19571963 let name = if let Some ( word) = mi. word ( ) {
19581964 word. name ( )
19591965 } else {
1960- span_err ! ( span_handler, mi. span, E0556 ,
1961- "malformed feature, expected just one word" ) ;
19621966 continue
19631967 } ;
19641968
@@ -1974,10 +1978,10 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19741978
19751979 if let Some ( edition) = ALL_EDITIONS . iter ( ) . find ( |e| name == e. feature_name ( ) ) {
19761980 if * edition <= crate_edition {
1977- continue
1981+ continue ;
19781982 }
19791983
1980- for & ( name, .., f_edition, set) in ACTIVE_FEATURES . iter ( ) {
1984+ for & ( name, .., f_edition, set) in ACTIVE_FEATURES {
19811985 if let Some ( f_edition) = f_edition {
19821986 if f_edition <= * edition {
19831987 // FIXME(Manishearth) there is currently no way to set
@@ -1987,24 +1991,53 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19871991 }
19881992 }
19891993 }
1994+ }
1995+ }
1996+ }
1997+
1998+ for attr in krate_attrs {
1999+ if !attr. check_name ( "feature" ) {
2000+ continue
2001+ }
2002+
2003+ let list = match attr. meta_item_list ( ) {
2004+ Some ( list) => list,
2005+ None => {
2006+ span_err ! ( span_handler, attr. span, E0555 ,
2007+ "malformed feature attribute, expected #![feature(...)]" ) ;
2008+ continue
2009+ }
2010+ } ;
19902011
2012+ for mi in list {
2013+ let name = if let Some ( word) = mi. word ( ) {
2014+ word. name ( )
2015+ } else {
2016+ span_err ! ( span_handler, mi. span, E0556 ,
2017+ "malformed feature, expected just one word" ) ;
19912018 continue
2019+ } ;
2020+
2021+ if let Some ( edition) = edition_enabled_features. get ( & name) {
2022+ struct_span_warn ! (
2023+ span_handler,
2024+ mi. span,
2025+ E0705 ,
2026+ "the feature `{}` is included in the Rust {} edition" ,
2027+ name,
2028+ edition,
2029+ ) . emit ( ) ;
2030+ continue ;
2031+ }
2032+
2033+ if ALL_EDITIONS . iter ( ) . any ( |e| name == e. feature_name ( ) ) {
2034+ // Handled in the separate loop above.
2035+ continue ;
19922036 }
19932037
19942038 if let Some ( ( .., set) ) = ACTIVE_FEATURES . iter ( ) . find ( |f| name == f. 0 ) {
1995- if let Some ( edition) = edition_enabled_features. get ( & name) {
1996- struct_span_warn ! (
1997- span_handler,
1998- mi. span,
1999- E0705 ,
2000- "the feature `{}` is included in the Rust {} edition" ,
2001- name,
2002- edition,
2003- ) . emit ( ) ;
2004- } else {
2005- set ( & mut features, mi. span ) ;
2006- features. declared_lang_features . push ( ( name, mi. span , None ) ) ;
2007- }
2039+ set ( & mut features, mi. span ) ;
2040+ features. declared_lang_features . push ( ( name, mi. span , None ) ) ;
20082041 continue
20092042 }
20102043
0 commit comments