@@ -40,14 +40,14 @@ use std::mem;
4040use syntax:: ast_util:: { self , IdVisitingOperation } ;
4141use syntax:: attr:: { self , AttrMetaMethods } ;
4242use syntax:: codemap:: Span ;
43+ use syntax:: errors:: { self , DiagnosticBuilder } ;
4344use syntax:: parse:: token:: InternedString ;
4445use syntax:: ast;
4546use syntax:: attr:: ThinAttributesExt ;
4647use rustc_front:: hir;
4748use rustc_front:: util;
4849use rustc_front:: intravisit as hir_visit;
4950use syntax:: visit as ast_visit;
50- use syntax:: errors;
5151
5252/// Information about the registered lints.
5353///
@@ -363,10 +363,24 @@ pub fn gather_attrs(attrs: &[ast::Attribute])
363363/// in trans that run after the main lint pass is finished. Most
364364/// lints elsewhere in the compiler should call
365365/// `Session::add_lint()` instead.
366- pub fn raw_emit_lint ( sess : & Session , lint : & ' static Lint ,
367- lvlsrc : LevelSource , span : Option < Span > , msg : & str ) {
366+ pub fn raw_emit_lint ( sess : & Session ,
367+ lint : & ' static Lint ,
368+ lvlsrc : LevelSource ,
369+ span : Option < Span > ,
370+ msg : & str ) {
371+ raw_struct_lint ( sess, lint, lvlsrc, span, msg) . map ( |mut e| e. emit ( ) ) ;
372+ }
373+
374+ pub fn raw_struct_lint < ' a > ( sess : & ' a Session ,
375+ lint : & ' static Lint ,
376+ lvlsrc : LevelSource ,
377+ span : Option < Span > ,
378+ msg : & str )
379+ -> Option < DiagnosticBuilder < ' a > > {
368380 let ( mut level, source) = lvlsrc;
369- if level == Allow { return }
381+ if level == Allow {
382+ return None ;
383+ }
370384
371385 let name = lint. name_lower ( ) ;
372386 let mut def = None ;
@@ -391,17 +405,18 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
391405 // For purposes of printing, we can treat forbid as deny.
392406 if level == Forbid { level = Deny ; }
393407
394- match ( level, span) {
395- ( Warn , Some ( sp) ) => sess. span_warn ( sp, & msg[ ..] ) ,
396- ( Warn , None ) => sess. warn ( & msg[ ..] ) ,
397- ( Deny , Some ( sp) ) => sess. span_err ( sp, & msg[ ..] ) ,
398- ( Deny , None ) => sess. err ( & msg[ ..] ) ,
408+ let mut err = match ( level, span) {
409+ ( Warn , Some ( sp) ) => sess. struct_span_warn ( sp, & msg[ ..] ) ,
410+ ( Warn , None ) => sess. struct_warn ( & msg[ ..] ) ,
411+ ( Deny , Some ( sp) ) => sess. struct_span_err ( sp, & msg[ ..] ) ,
412+ ( Deny , None ) => sess. struct_err ( & msg[ ..] ) ,
399413 _ => sess. bug ( "impossible level in raw_emit_lint" ) ,
400- }
414+ } ;
401415
402416 if let Some ( span) = def {
403- sess . span_note ( span, "lint level defined here" ) ;
417+ err . span_note ( span, "lint level defined here" ) ;
404418 }
419+ Some ( err)
405420}
406421
407422pub trait LintContext : Sized {
@@ -418,44 +433,80 @@ pub trait LintContext: Sized {
418433 self . lints ( ) . levels . get ( & LintId :: of ( lint) ) . map_or ( Allow , |& ( lvl, _) | lvl)
419434 }
420435
421- fn lookup_and_emit ( & self , lint : & ' static Lint , span : Option < Span > , msg : & str ) {
422- let ( level, src) = match self . lints ( ) . levels . get ( & LintId :: of ( lint) ) {
423- None => return ,
424- Some ( & ( Warn , src) ) => {
436+ fn level_src ( & self , lint : & ' static Lint ) -> Option < LevelSource > {
437+ self . lints ( ) . levels . get ( & LintId :: of ( lint) ) . map ( |ls| match ls {
438+ & ( Warn , src) => {
425439 let lint_id = LintId :: of ( builtin:: WARNINGS ) ;
426440 ( self . lints ( ) . get_level_source ( lint_id) . 0 , src)
427441 }
428- Some ( & pair) => pair,
442+ _ => * ls
443+ } )
444+ }
445+
446+ fn lookup_and_emit ( & self , lint : & ' static Lint , span : Option < Span > , msg : & str ) {
447+ let ( level, src) = match self . level_src ( lint) {
448+ None => return ,
449+ Some ( pair) => pair,
429450 } ;
430451
431452 raw_emit_lint ( & self . sess ( ) , lint, ( level, src) , span, msg) ;
432453 }
433454
455+ fn lookup ( & self ,
456+ lint : & ' static Lint ,
457+ span : Option < Span > ,
458+ msg : & str )
459+ -> Option < DiagnosticBuilder > {
460+ let ( level, src) = match self . level_src ( lint) {
461+ None => return None ,
462+ Some ( pair) => pair,
463+ } ;
464+
465+ raw_struct_lint ( & self . sess ( ) , lint, ( level, src) , span, msg)
466+ }
467+
434468 /// Emit a lint at the appropriate level, for a particular span.
435469 fn span_lint ( & self , lint : & ' static Lint , span : Span , msg : & str ) {
436470 self . lookup_and_emit ( lint, Some ( span) , msg) ;
437471 }
438472
473+ fn struct_span_lint ( & self ,
474+ lint : & ' static Lint ,
475+ span : Span ,
476+ msg : & str )
477+ -> Option < DiagnosticBuilder > {
478+ self . lookup ( lint, Some ( span) , msg)
479+ }
480+
439481 /// Emit a lint and note at the appropriate level, for a particular span.
440482 fn span_lint_note ( & self , lint : & ' static Lint , span : Span , msg : & str ,
441483 note_span : Span , note : & str ) {
442- self . span_lint ( lint, span, msg) ;
484+ let mut err = match self . lookup ( lint, Some ( span) , msg) {
485+ Some ( e) => e,
486+ None => return
487+ } ;
443488 if self . current_level ( lint) != Level :: Allow {
444489 if note_span == span {
445- self . sess ( ) . fileline_note ( note_span, note)
490+ err . fileline_note ( note_span, note) ;
446491 } else {
447- self . sess ( ) . span_note ( note_span, note)
492+ err . span_note ( note_span, note) ;
448493 }
449494 }
495+ err. emit ( ) ;
450496 }
451497
452498 /// Emit a lint and help at the appropriate level, for a particular span.
453499 fn span_lint_help ( & self , lint : & ' static Lint , span : Span ,
454500 msg : & str , help : & str ) {
501+ let mut err = match self . lookup ( lint, Some ( span) , msg) {
502+ Some ( e) => e,
503+ None => return
504+ } ;
455505 self . span_lint ( lint, span, msg) ;
456506 if self . current_level ( lint) != Level :: Allow {
457- self . sess ( ) . span_help ( span, help)
507+ err . span_help ( span, help) ;
458508 }
509+ err. emit ( ) ;
459510 }
460511
461512 /// Emit a lint at the appropriate level, with no associated span.
0 commit comments