@@ -20,13 +20,13 @@ use rustc_hir::{
2020 TraitItem , CRATE_HIR_ID , CRATE_OWNER_ID ,
2121} ;
2222use rustc_macros:: LintDiagnostic ;
23- use rustc_middle:: bug;
2423use rustc_middle:: hir:: nested_filter;
2524use rustc_middle:: middle:: resolve_bound_vars:: ObjectLifetimeDefault ;
2625use rustc_middle:: query:: Providers ;
2726use rustc_middle:: traits:: ObligationCause ;
2827use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
2928use rustc_middle:: ty:: { self , TyCtxt } ;
29+ use rustc_middle:: { bug, span_bug} ;
3030use rustc_session:: lint:: builtin:: {
3131 CONFLICTING_REPR_HINTS , INVALID_DOC_ATTRIBUTES , INVALID_MACRO_EXPORT_ARGUMENTS ,
3232 UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES , UNUSED_ATTRIBUTES ,
@@ -239,7 +239,59 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
239239 self . check_generic_attr ( hir_id, attr, target, Target :: Fn ) ;
240240 self . check_proc_macro ( hir_id, target, ProcMacroKind :: Derive )
241241 }
242- _ => { }
242+ [ sym:: coroutine] => {
243+ self . check_coroutine ( attr, target) ;
244+ }
245+ [
246+ // ok
247+ sym:: allow
248+ | sym:: expect
249+ | sym:: warn
250+ | sym:: deny
251+ | sym:: forbid
252+ | sym:: cfg
253+ // need to be fixed
254+ | sym:: cfi_encoding // FIXME(cfi_encoding)
255+ | sym:: may_dangle // FIXME(dropck_eyepatch)
256+ | sym:: pointee // FIXME(derive_smart_pointer)
257+ | sym:: linkage // FIXME(linkage)
258+ | sym:: no_sanitize // FIXME(no_sanitize)
259+ | sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
260+ | sym:: used // handled elsewhere to restrict to static items
261+ | sym:: repr // handled elsewhere to restrict to type decls items
262+ | sym:: instruction_set // broken on stable!!!
263+ | sym:: windows_subsystem // broken on stable!!!
264+ | sym:: patchable_function_entry // FIXME(patchable_function_entry)
265+ | sym:: deprecated_safe // FIXME(deprecated_safe)
266+ // internal
267+ | sym:: prelude_import
268+ | sym:: panic_handler
269+ | sym:: allow_internal_unsafe
270+ | sym:: fundamental
271+ | sym:: lang
272+ | sym:: needs_allocator
273+ | sym:: default_lib_allocator
274+ | sym:: start
275+ | sym:: custom_mir,
276+ ] => { }
277+ [ name, ..] => {
278+ match BUILTIN_ATTRIBUTE_MAP . get ( name) {
279+ // checked below
280+ Some ( BuiltinAttribute { type_ : AttributeType :: CrateLevel , .. } ) => { }
281+ Some ( _) => {
282+ // FIXME: differentiate between unstable and internal attributes just like we do with features instead
283+ // of just accepting `rustc_` attributes by name. That should allow trimming the above list, too.
284+ if !name. as_str ( ) . starts_with ( "rustc_" ) {
285+ span_bug ! (
286+ attr. span,
287+ "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
288+ )
289+ }
290+ }
291+ None => ( ) ,
292+ }
293+ }
294+ [ ] => unreachable ! ( ) ,
243295 }
244296
245297 let builtin = attr. ident ( ) . and_then ( |ident| BUILTIN_ATTRIBUTE_MAP . get ( & ident. name ) ) ;
@@ -376,6 +428,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
376428
377429 /// Checks that `#[optimize(..)]` is applied to a function/closure/method,
378430 /// or to an impl block or module.
431+ // FIXME(#128488): this should probably be elevated to an error?
379432 fn check_optimize ( & self , hir_id : HirId , attr : & Attribute , target : Target ) {
380433 match target {
381434 Target :: Fn
@@ -2279,6 +2332,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22792332 self . abort . set ( true ) ;
22802333 }
22812334 }
2335+
2336+ fn check_coroutine ( & self , attr : & Attribute , target : Target ) {
2337+ match target {
2338+ Target :: Closure => return ,
2339+ _ => {
2340+ self . dcx ( ) . emit_err ( errors:: CoroutineOnNonClosure { span : attr. span } ) ;
2341+ }
2342+ }
2343+ }
22822344}
22832345
22842346impl < ' tcx > Visitor < ' tcx > for CheckAttrVisitor < ' tcx > {
0 commit comments