@@ -93,10 +93,21 @@ impl<'s> LintLevelsBuilder<'s> {
9393 self . store 
9494 } 
9595
96+  fn  current_specs ( & self )  -> & FxHashMap < LintId ,  LevelAndSource >  { 
97+  & self . sets . list [ self . cur ] . specs 
98+  } 
99+ 
100+  fn  current_specs_mut ( & mut  self )  -> & mut  FxHashMap < LintId ,  LevelAndSource >  { 
101+  & mut  self . sets . list [ self . cur ] . specs 
102+  } 
103+ 
96104 fn  process_command_line ( & mut  self ,  sess :  & Session ,  store :  & LintStore )  { 
97-  let  mut  specs = FxHashMap :: default ( ) ; 
98105 self . sets . lint_cap  = sess. opts . lint_cap . unwrap_or ( Level :: Forbid ) ; 
99106
107+  self . cur  = self . sets . list . push ( LintSet  { 
108+  specs :  FxHashMap :: default ( ) , 
109+  parent :  COMMAND_LINE , 
110+  } ) ; 
100111 for  & ( ref  lint_name,  level)  in  & sess. opts . lint_opts  { 
101112 store. check_lint_name_cmdline ( sess,  & lint_name,  level,  self . registered_tools ) ; 
102113 let  orig_level = level; 
@@ -108,30 +119,28 @@ impl<'s> LintLevelsBuilder<'s> {
108119 } ; 
109120 for  id in  ids { 
110121 // ForceWarn and Forbid cannot be overriden 
111-  if  let  Some ( ( Level :: ForceWarn  | Level :: Forbid ,  _) )  = specs . get ( & id)  { 
122+  if  let  Some ( ( Level :: ForceWarn  | Level :: Forbid ,  _) )  = self . current_specs ( ) . get ( & id)  { 
112123 continue ; 
113124 } 
114125
115-  self . check_gated_lint ( id,  DUMMY_SP ) ; 
116-  let  src = LintLevelSource :: CommandLine ( lint_flag_val,  orig_level) ; 
117-  specs. insert ( id,  ( level,  src) ) ; 
126+  if  self . check_gated_lint ( id,  DUMMY_SP )  { 
127+  let  src = LintLevelSource :: CommandLine ( lint_flag_val,  orig_level) ; 
128+  self . current_specs_mut ( ) . insert ( id,  ( level,  src) ) ; 
129+  } 
118130 } 
119131 } 
120- 
121-  self . cur  = self . sets . list . push ( LintSet  {  specs,  parent :  COMMAND_LINE  } ) ; 
122132 } 
123133
124134 /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful 
125135/// (e.g. if a forbid was already inserted on the same scope), then emits a 
126136/// diagnostic with no change to `specs`. 
127137fn  insert_spec ( 
128138 & mut  self , 
129-  specs :  & mut  FxHashMap < LintId ,  LevelAndSource > , 
130139 id :  LintId , 
131140 ( level,  src) :  LevelAndSource , 
132141 )  { 
133142 let  ( old_level,  old_src)  =
134-  self . sets . get_lint_level ( id. lint ,  self . cur ,  Some ( & specs ) ,  & self . sess ) ; 
143+  self . sets . get_lint_level ( id. lint ,  self . cur ,  Some ( self . current_specs ( ) ) ,  & self . sess ) ; 
135144 // Setting to a non-forbid level is an error if the lint previously had 
136145 // a forbid level. Note that this is not necessarily true even with a 
137146 // `#[forbid(..)]` attribute present, as that is overriden by `--cap-lints`. 
@@ -154,7 +163,7 @@ impl<'s> LintLevelsBuilder<'s> {
154163 } ; 
155164 debug ! ( 
156165 "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}" , 
157-  fcw_warning,  specs ,  old_src,  id_name
166+  fcw_warning,  self . current_specs ( ) ,  old_src,  id_name
158167 ) ; 
159168
160169 let  decorate_diag = |diag :  & mut  Diagnostic | { 
@@ -213,9 +222,9 @@ impl<'s> LintLevelsBuilder<'s> {
213222 } 
214223 } 
215224 if  let  Level :: ForceWarn  = old_level { 
216-  specs . insert ( id,  ( old_level,  old_src) ) ; 
225+  self . current_specs_mut ( ) . insert ( id,  ( old_level,  old_src) ) ; 
217226 }  else  { 
218-  specs . insert ( id,  ( level,  src) ) ; 
227+  self . current_specs_mut ( ) . insert ( id,  ( level,  src) ) ; 
219228 } 
220229 } 
221230
@@ -239,7 +248,11 @@ impl<'s> LintLevelsBuilder<'s> {
239248 is_crate_node :  bool , 
240249 source_hir_id :  Option < HirId > , 
241250 )  -> BuilderPush  { 
242-  let  mut  specs = FxHashMap :: default ( ) ; 
251+  let  prev = self . cur ; 
252+  self . cur  = self . sets . list . push ( LintSet  { 
253+  specs :  FxHashMap :: default ( ) , 
254+  parent :  prev, 
255+  } ) ; 
243256 let  sess = self . sess ; 
244257 let  bad_attr = |span| struct_span_err ! ( sess,  span,  E0452 ,  "malformed lint attribute input" ) ; 
245258 for  ( attr_index,  attr)  in  attrs. iter ( ) . enumerate ( )  { 
@@ -348,8 +361,9 @@ impl<'s> LintLevelsBuilder<'s> {
348361 reason, 
349362 ) ; 
350363 for  & id in  * ids { 
351-  self . check_gated_lint ( id,  attr. span ) ; 
352-  self . insert_spec ( & mut  specs,  id,  ( level,  src) ) ; 
364+  if  self . check_gated_lint ( id,  attr. span )  { 
365+  self . insert_spec ( id,  ( level,  src) ) ; 
366+  } 
353367 } 
354368 if  let  Level :: Expect ( expect_id)  = level { 
355369 self . lint_expectations 
@@ -368,7 +382,7 @@ impl<'s> LintLevelsBuilder<'s> {
368382 reason, 
369383 ) ; 
370384 for  id in  ids { 
371-  self . insert_spec ( & mut  specs ,   * id,  ( level,  src) ) ; 
385+  self . insert_spec ( * id,  ( level,  src) ) ; 
372386 } 
373387 if  let  Level :: Expect ( expect_id)  = level { 
374388 self . lint_expectations 
@@ -378,7 +392,7 @@ impl<'s> LintLevelsBuilder<'s> {
378392 Err ( ( Some ( ids) ,  ref  new_lint_name) )  => { 
379393 let  lint = builtin:: RENAMED_AND_REMOVED_LINTS ; 
380394 let  ( lvl,  src)  =
381-  self . sets . get_lint_level ( lint,  self . cur ,  Some ( & specs ) ,  & sess) ; 
395+  self . sets . get_lint_level ( lint,  self . cur ,  Some ( self . current_specs ( ) ) ,  & sess) ; 
382396 struct_lint_level ( 
383397 self . sess , 
384398 lint, 
@@ -408,7 +422,7 @@ impl<'s> LintLevelsBuilder<'s> {
408422 reason, 
409423 ) ; 
410424 for  id in  ids { 
411-  self . insert_spec ( & mut  specs ,   * id,  ( level,  src) ) ; 
425+  self . insert_spec ( * id,  ( level,  src) ) ; 
412426 } 
413427 if  let  Level :: Expect ( expect_id)  = level { 
414428 self . lint_expectations 
@@ -449,7 +463,7 @@ impl<'s> LintLevelsBuilder<'s> {
449463 CheckLintNameResult :: Warning ( msg,  renamed)  => { 
450464 let  lint = builtin:: RENAMED_AND_REMOVED_LINTS ; 
451465 let  ( renamed_lint_level,  src)  =
452-  self . sets . get_lint_level ( lint,  self . cur ,  Some ( & specs ) ,  & sess) ; 
466+  self . sets . get_lint_level ( lint,  self . cur ,  Some ( self . current_specs ( ) ) ,  & sess) ; 
453467 struct_lint_level ( 
454468 self . sess , 
455469 lint, 
@@ -473,7 +487,7 @@ impl<'s> LintLevelsBuilder<'s> {
473487 CheckLintNameResult :: NoLint ( suggestion)  => { 
474488 let  lint = builtin:: UNKNOWN_LINTS ; 
475489 let  ( level,  src)  =
476-  self . sets . get_lint_level ( lint,  self . cur ,  Some ( & specs ) ,  self . sess ) ; 
490+  self . sets . get_lint_level ( lint,  self . cur ,  Some ( self . current_specs ( ) ) ,  self . sess ) ; 
477491 struct_lint_level ( self . sess ,  lint,  level,  src,  Some ( sp. into ( ) ) ,  |lint| { 
478492 let  name = if  let  Some ( tool_ident)  = tool_ident { 
479493 format ! ( "{}::{}" ,  tool_ident. name,  name) 
@@ -504,8 +518,9 @@ impl<'s> LintLevelsBuilder<'s> {
504518 { 
505519 let  src = LintLevelSource :: Node ( Symbol :: intern ( & new_name) ,  sp,  reason) ; 
506520 for  & id in  ids { 
507-  self . check_gated_lint ( id,  attr. span ) ; 
508-  self . insert_spec ( & mut  specs,  id,  ( level,  src) ) ; 
521+  if  self . check_gated_lint ( id,  attr. span )  { 
522+  self . insert_spec ( id,  ( level,  src) ) ; 
523+  } 
509524 } 
510525 if  let  Level :: Expect ( expect_id)  = level { 
511526 self . lint_expectations 
@@ -519,7 +534,7 @@ impl<'s> LintLevelsBuilder<'s> {
519534 } 
520535
521536 if  !is_crate_node { 
522-  for  ( id,  & ( level,  ref  src) )  in  specs . iter ( )  { 
537+  for  ( id,  & ( level,  ref  src) )  in  self . current_specs ( ) . iter ( )  { 
523538 if  !id. lint . crate_level_only  { 
524539 continue ; 
525540 } 
@@ -530,7 +545,7 @@ impl<'s> LintLevelsBuilder<'s> {
530545
531546 let  lint = builtin:: UNUSED_ATTRIBUTES ; 
532547 let  ( lint_level,  lint_src)  =
533-  self . sets . get_lint_level ( lint,  self . cur ,  Some ( & specs ) ,  self . sess ) ; 
548+  self . sets . get_lint_level ( lint,  self . cur ,  Some ( self . current_specs ( ) ) ,  self . sess ) ; 
534549 struct_lint_level ( 
535550 self . sess , 
536551 lint, 
@@ -551,9 +566,9 @@ impl<'s> LintLevelsBuilder<'s> {
551566 } 
552567 } 
553568
554-  let  prev =  self . cur ; 
555-  if  !specs . is_empty ( )   { 
556-  self . cur  = self . sets . list . push ( LintSet   {  specs ,   parent :   prev  } ) ; 
569+  if   self . current_specs ( ) . is_empty ( )   { 
570+    self . sets . list . pop ( ) ; 
571+  self . cur  = prev; 
557572 } 
558573
559574 BuilderPush  {  prev,  changed :  prev != self . cur  } 
@@ -574,18 +589,25 @@ impl<'s> LintLevelsBuilder<'s> {
574589 } 
575590
576591 /// Checks if the lint is gated on a feature that is not enabled. 
577- fn  check_gated_lint ( & self ,  lint_id :  LintId ,  span :  Span )  { 
592+ /// 
593+ /// Returns `true` if the lint's feature is enabled. 
594+ fn  check_gated_lint ( & self ,  lint_id :  LintId ,  span :  Span )  -> bool  { 
578595 if  let  Some ( feature)  = lint_id. lint . feature_gate  { 
579596 if  !self . sess . features_untracked ( ) . enabled ( feature)  { 
580-  feature_err ( 
581-  & self . sess . parse_sess , 
582-  feature, 
583-  span, 
584-  & format ! ( "the `{}` lint is unstable" ,  lint_id. lint. name_lower( ) ) , 
585-  ) 
586-  . emit ( ) ; 
597+  let  ( unknown_lints_level,  _)  = self . lint_level ( builtin:: UNKNOWN_LINTS ) ; 
598+  if  unknown_lints_level != Level :: Allow  { 
599+  feature_err ( 
600+  & self . sess . parse_sess , 
601+  feature, 
602+  span, 
603+  & format ! ( "the `{}` lint is unstable" ,  lint_id. lint. name_lower( ) ) , 
604+  ) 
605+  . emit ( ) ; 
606+  } 
607+  return  false ; 
587608 } 
588609 } 
610+  true 
589611 } 
590612
591613 /// Called after `push` when the scope of a set of attributes are exited. 
0 commit comments