@@ -27,7 +27,7 @@ enum AttrError {
2727 UnsupportedLiteral
2828}
2929
30- fn handle_errors ( diag : & Handler , span : Span , error : AttrError ) {
30+ fn handle_errors ( diag : & Handler , span : Span , error : AttrError , is_bytestr : bool ) {
3131 match error {
3232 AttrError :: MultipleItem ( item) => span_err ! ( diag, span, E0538 ,
3333 "multiple '{}' items" , item) ,
@@ -44,7 +44,25 @@ fn handle_errors(diag: &Handler, span: Span, error: AttrError) {
4444 AttrError :: MissingFeature => span_err ! ( diag, span, E0546 , "missing 'feature'" ) ,
4545 AttrError :: MultipleStabilityLevels => span_err ! ( diag, span, E0544 ,
4646 "multiple stability levels" ) ,
47- AttrError :: UnsupportedLiteral => span_err ! ( diag, span, E0565 , "unsupported literal" ) ,
47+ AttrError :: UnsupportedLiteral => {
48+ let mut err = struct_span_err ! (
49+ diag,
50+ span,
51+ E0565 ,
52+ "unsupported literal" ,
53+ ) ;
54+ if is_bytestr {
55+ if let Ok ( lint_str) = sess. source_map . span_to_snippet ( span) {
56+ err. span_suggestion_with_applicability (
57+ span,
58+ "consider removing the prefix" ,
59+ format ! ( "{}" , lint_str[ 1 ..] ) ,
60+ Applicability :: MaybeIncorrect ,
61+ ) ;
62+ }
63+ }
64+ err. emit ( ) ;
65+ }
4866 }
4967}
5068
@@ -202,7 +220,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
202220 let meta = meta. as_ref ( ) . unwrap ( ) ;
203221 let get = |meta : & MetaItem , item : & mut Option < Symbol > | {
204222 if item. is_some ( ) {
205- handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. name ( ) ) ) ;
223+ handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. name ( ) ) , false ) ;
206224 return false
207225 }
208226 if let Some ( v) = meta. value_str ( ) {
@@ -231,12 +249,14 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
231249 handle_errors(
232250 diagnostic,
233251 mi. span,
234- AttrError :: UnknownMetaItem ( mi. name( ) , expected) ) ;
252+ AttrError :: UnknownMetaItem ( mi. name( ) , expected) ,
253+ false
254+ ) ;
235255 continue ' outer
236256 }
237257 }
238258 } else {
239- handle_errors( diagnostic, meta. span, AttrError :: UnsupportedLiteral ) ;
259+ handle_errors( diagnostic, meta. span, AttrError :: UnsupportedLiteral , false ) ;
240260 continue ' outer
241261 }
242262 }
@@ -261,7 +281,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
261281 } )
262282 }
263283 ( None , _) => {
264- handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingSince ) ;
284+ handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingSince , false ) ;
265285 continue
266286 }
267287 _ => {
@@ -287,7 +307,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
287307 }
288308 "unstable" => {
289309 if stab. is_some ( ) {
290- handle_errors ( diagnostic, attr. span ( ) , AttrError :: MultipleStabilityLevels ) ;
310+ handle_errors ( diagnostic, attr. span ( ) , AttrError :: MultipleStabilityLevels , false ) ;
291311 break
292312 }
293313
@@ -308,12 +328,13 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
308328 mi. name ( ) ,
309329 & [ "feature" , "reason" , "issue" ]
310330 ) ,
331+ false ,
311332 ) ;
312333 continue ' outer
313334 }
314335 }
315336 } else {
316- handle_errors ( diagnostic, meta. span , AttrError :: UnsupportedLiteral ) ;
337+ handle_errors ( diagnostic, meta. span , AttrError :: UnsupportedLiteral , false ) ;
317338 continue ' outer
318339 }
319340 }
@@ -340,7 +361,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
340361 } )
341362 }
342363 ( None , _, _) => {
343- handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingFeature ) ;
364+ handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingFeature , false ) ;
344365 continue
345366 }
346367 _ => {
@@ -351,29 +372,37 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
351372 }
352373 "stable" => {
353374 if stab. is_some ( ) {
354- handle_errors ( diagnostic, attr. span ( ) , AttrError :: MultipleStabilityLevels ) ;
375+ handle_errors ( diagnostic, attr. span ( ) , AttrError :: MultipleStabilityLevels , false ) ;
355376 break
356377 }
357378
358379 let mut feature = None ;
359380 let mut since = None ;
360381 for meta in metas {
361- if let NestedMetaItemKind :: MetaItem ( ref mi) = meta. node {
362- match & * mi. name ( ) . as_str ( ) {
363- "feature" => if !get ( mi, & mut feature) { continue ' outer } ,
364- "since" => if !get ( mi, & mut since) { continue ' outer } ,
365- _ => {
366- handle_errors (
367- diagnostic,
368- meta. span ,
369- AttrError :: UnknownMetaItem ( mi. name ( ) , & [ "since" , "note" ] ) ,
370- ) ;
371- continue ' outer
382+ match & meta. node {
383+ NestedMetaItemKind :: MetaItem ( mi) => {
384+ match & * mi. name ( ) . as_str ( ) {
385+ "feature" => if !get ( mi, & mut feature) { continue ' outer } ,
386+ "since" => if !get ( mi, & mut since) { continue ' outer } ,
387+ _ => {
388+ handle_errors (
389+ diagnostic,
390+ meta. span ,
391+ AttrError :: UnknownMetaItem ( mi. name ( ) , & [ "since" , "note" ] ) ,
392+ false ,
393+ ) ;
394+ continue ' outer
395+ }
372396 }
397+ NestedMetaItemKind :: Literal ( lit) => {
398+ handle_errors (
399+ diagnostic,
400+ meta. span ,
401+ AttrError :: UnsupportedLiteral ,
402+ lit. node . is_bytestr ( )
403+ ) ;
404+ continue ' outer
373405 }
374- } else {
375- handle_errors ( diagnostic, meta. span , AttrError :: UnsupportedLiteral ) ;
376- continue ' outer
377406 }
378407 }
379408
@@ -390,11 +419,11 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
390419 } )
391420 }
392421 ( None , _) => {
393- handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingFeature ) ;
422+ handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingFeature , false ) ;
394423 continue
395424 }
396425 _ => {
397- handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingSince ) ;
426+ handle_errors ( diagnostic, attr. span ( ) , AttrError :: MissingSince , false ) ;
398427 continue
399428 }
400429 }
@@ -461,8 +490,13 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
461490 MetaItemKind :: List ( ..) => {
462491 error ( cfg. span , "unexpected parentheses after `cfg` predicate key" )
463492 }
464- MetaItemKind :: NameValue ( lit) if !lit. node . is_str ( ) => {
465- error ( lit. span , "literal in `cfg` predicate value must be a string" )
493+ MetaItemKind :: NameValue ( lit) => if !lit. node . is_str ( ) {
494+ handle_errors (
495+ & sess. span_diagnostic ,
496+ lit. span , AttrError :: UnsupportedLiteral ,
497+ lit. node . is_bytestr ( ) ,
498+ ) ;
499+ true
466500 }
467501 MetaItemKind :: NameValue ( ..) | MetaItemKind :: Word => {
468502 sess. config . contains ( & ( cfg. name ( ) , cfg. value_str ( ) ) )
@@ -481,7 +515,7 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
481515 ast:: MetaItemKind :: List ( ref mis) => {
482516 for mi in mis. iter ( ) {
483517 if !mi. is_meta_item ( ) {
484- handle_errors ( & sess. span_diagnostic , mi. span , AttrError :: UnsupportedLiteral ) ;
518+ handle_errors ( & sess. span_diagnostic , mi. span , AttrError :: UnsupportedLiteral , false ) ;
485519 return false ;
486520 }
487521 }
@@ -551,7 +585,7 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
551585 depr = if let Some ( metas) = attr. meta_item_list ( ) {
552586 let get = |meta : & MetaItem , item : & mut Option < Symbol > | {
553587 if item. is_some ( ) {
554- handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. name ( ) ) ) ;
588+ handle_errors ( diagnostic, meta. span , AttrError :: MultipleItem ( meta. name ( ) ) , false ) ;
555589 return false
556590 }
557591 if let Some ( v) = meta. value_str ( ) {
@@ -566,22 +600,27 @@ fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
566600 let mut since = None ;
567601 let mut note = None ;
568602 for meta in metas {
569- if let NestedMetaItemKind :: MetaItem ( ref mi) = meta. node {
570- match & * mi. name ( ) . as_str ( ) {
571- "since" => if !get ( mi, & mut since) { continue ' outer } ,
572- "note" => if !get ( mi, & mut note) { continue ' outer } ,
573- _ => {
574- handle_errors (
575- diagnostic,
576- meta. span ,
577- AttrError :: UnknownMetaItem ( mi. name ( ) , & [ "since" , "note" ] ) ,
578- ) ;
579- continue ' outer
603+ match & meta. node {
604+ NestedMetaItemKind :: MetaItem ( mi) => {
605+ match & * mi. name ( ) . as_str ( ) {
606+ "since" => if !get ( mi, & mut since) { continue ' outer } ,
607+ "note" => if !get ( mi, & mut note) { continue ' outer } ,
608+ _ => {
609+ handle_errors (
610+ diagnostic,
611+ meta. span ,
612+ AttrError :: UnknownMetaItem ( mi. name ( ) , & [ "since" , "note" ] ) ,
613+ false ,
614+ ) ;
615+ continue ' outer
616+ }
580617 }
581618 }
582- } else {
583- handle_errors ( diagnostic, meta. span , AttrError :: UnsupportedLiteral ) ;
584- continue ' outer
619+ NestedMetaItemKind :: Literal ( lit) => {
620+ let is_bytestr = lit. node . is_bytestr ( ) ;
621+ handle_errors ( diagnostic, meta. span , AttrError :: UnsupportedLiteral , is_bytestr) ;
622+ continue ' outer
623+ }
585624 }
586625 }
587626
@@ -638,7 +677,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
638677 mark_used ( attr) ;
639678 for item in items {
640679 if !item. is_meta_item ( ) {
641- handle_errors ( diagnostic, item. span , AttrError :: UnsupportedLiteral ) ;
680+ handle_errors ( diagnostic, item. span , AttrError :: UnsupportedLiteral , false ) ;
642681 continue
643682 }
644683
0 commit comments