@@ -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) . 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+ -> DiagnosticBuilder < ' a > {
368380 let ( mut level, source) = lvlsrc;
369- if level == Allow { return }
381+ if level == Allow {
382+ return sess. diagnostic ( ) . struct_dummy ( ) ;
383+ }
370384
371385 let name = lint. name_lower ( ) ;
372386 let mut def = None ;
@@ -391,17 +405,19 @@ 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+
420+ err
405421}
406422
407423pub trait LintContext : Sized {
@@ -418,44 +434,74 @@ pub trait LintContext: Sized {
418434 self . lints ( ) . levels . get ( & LintId :: of ( lint) ) . map_or ( Allow , |& ( lvl, _) | lvl)
419435 }
420436
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) ) => {
437+ fn level_src ( & self , lint : & ' static Lint ) -> Option < LevelSource > {
438+ self . lints ( ) . levels . get ( & LintId :: of ( lint) ) . map ( |ls| match ls {
439+ & ( Warn , src) => {
425440 let lint_id = LintId :: of ( builtin:: WARNINGS ) ;
426441 ( self . lints ( ) . get_level_source ( lint_id) . 0 , src)
427442 }
428- Some ( & pair) => pair,
443+ _ => * ls
444+ } )
445+ }
446+
447+ fn lookup_and_emit ( & self , lint : & ' static Lint , span : Option < Span > , msg : & str ) {
448+ let ( level, src) = match self . level_src ( lint) {
449+ None => return ,
450+ Some ( pair) => pair,
429451 } ;
430452
431453 raw_emit_lint ( & self . sess ( ) , lint, ( level, src) , span, msg) ;
432454 }
433455
456+ fn lookup ( & self ,
457+ lint : & ' static Lint ,
458+ span : Option < Span > ,
459+ msg : & str )
460+ -> DiagnosticBuilder {
461+ let ( level, src) = match self . level_src ( lint) {
462+ None => return self . sess ( ) . diagnostic ( ) . struct_dummy ( ) ,
463+ Some ( pair) => pair,
464+ } ;
465+
466+ raw_struct_lint ( & self . sess ( ) , lint, ( level, src) , span, msg)
467+ }
468+
434469 /// Emit a lint at the appropriate level, for a particular span.
435470 fn span_lint ( & self , lint : & ' static Lint , span : Span , msg : & str ) {
436471 self . lookup_and_emit ( lint, Some ( span) , msg) ;
437472 }
438473
474+ fn struct_span_lint ( & self ,
475+ lint : & ' static Lint ,
476+ span : Span ,
477+ msg : & str )
478+ -> DiagnosticBuilder {
479+ self . lookup ( lint, Some ( span) , msg)
480+ }
481+
439482 /// Emit a lint and note at the appropriate level, for a particular span.
440483 fn span_lint_note ( & self , lint : & ' static Lint , span : Span , msg : & str ,
441484 note_span : Span , note : & str ) {
442- self . span_lint ( lint, span, msg) ;
485+ let mut err = self . lookup ( lint, Some ( span) , msg) ;
443486 if self . current_level ( lint) != Level :: Allow {
444487 if note_span == span {
445- self . sess ( ) . fileline_note ( note_span, note)
488+ err . fileline_note ( note_span, note) ;
446489 } else {
447- self . sess ( ) . span_note ( note_span, note)
490+ err . span_note ( note_span, note) ;
448491 }
449492 }
493+ err. emit ( ) ;
450494 }
451495
452496 /// Emit a lint and help at the appropriate level, for a particular span.
453497 fn span_lint_help ( & self , lint : & ' static Lint , span : Span ,
454498 msg : & str , help : & str ) {
499+ let mut err = self . lookup ( lint, Some ( span) , msg) ;
455500 self . span_lint ( lint, span, msg) ;
456501 if self . current_level ( lint) != Level :: Allow {
457- self . sess ( ) . span_help ( span, help)
502+ err . span_help ( span, help) ;
458503 }
504+ err. emit ( ) ;
459505 }
460506
461507 /// Emit a lint at the appropriate level, with no associated span.
0 commit comments