Diagnostic for invalid lifetime param 'static

This commit is contained in:
David Tolnay 2021-04-08 18:20:29 -07:00
parent d7705ddaad
commit ef1b70d0db
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
2 changed files with 39 additions and 2 deletions

View File

@ -2,12 +2,13 @@ use crate::syntax::atom::Atom::{self, *};
use crate::syntax::report::Errors;
use crate::syntax::visit::{self, Visit};
use crate::syntax::{
error, ident, trivial, Api, Array, Enum, ExternFn, ExternType, Impl, Lang, NamedType, Ptr,
Receiver, Ref, Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,
error, ident, trivial, Api, Array, Enum, ExternFn, ExternType, Impl, Lang, Lifetimes,
NamedType, Ptr, Receiver, Ref, Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,
};
use proc_macro2::{Delimiter, Group, Ident, TokenStream};
use quote::{quote, ToTokens};
use std::fmt::Display;
use syn::{GenericParam, Generics, Lifetime};
pub(crate) struct Check<'a> {
apis: &'a [Api],
@ -294,6 +295,7 @@ fn check_type_fn(cx: &mut Check, ty: &Signature) {
fn check_api_struct(cx: &mut Check, strct: &Struct) {
let name = &strct.name;
check_reserved_name(cx, &name.rust);
check_lifetimes(cx, &strct.generics);
if strct.fields.is_empty() {
let span = span_for_struct_error(strct);
@ -330,6 +332,7 @@ fn check_api_struct(cx: &mut Check, strct: &Struct) {
fn check_api_enum(cx: &mut Check, enm: &Enum) {
check_reserved_name(cx, &enm.name.rust);
check_lifetimes(cx, &enm.generics);
if enm.variants.is_empty() && !enm.explicit_repr {
let span = span_for_enum_error(enm);
@ -349,6 +352,7 @@ fn check_api_enum(cx: &mut Check, enm: &Enum) {
fn check_api_type(cx: &mut Check, ety: &ExternType) {
check_reserved_name(cx, &ety.name.rust);
check_lifetimes(cx, &ety.generics);
for derive in &ety.derives {
if derive.what == Trait::ExternType && ety.lang == Lang::Rust {
@ -400,6 +404,8 @@ fn check_api_fn(cx: &mut Check, efn: &ExternFn) {
}
}
check_generics(cx, &efn.sig.generics);
if let Some(receiver) = &efn.receiver {
let ref span = span_for_receiver_error(receiver);
@ -472,6 +478,8 @@ fn check_api_fn(cx: &mut Check, efn: &ExternFn) {
}
fn check_api_type_alias(cx: &mut Check, alias: &TypeAlias) {
check_lifetimes(cx, &alias.generics);
for derive in &alias.derives {
let msg = format!("derive({}) on extern type alias is not supported", derive);
cx.error(derive, msg);
@ -481,6 +489,8 @@ fn check_api_type_alias(cx: &mut Check, alias: &TypeAlias) {
fn check_api_impl(cx: &mut Check, imp: &Impl) {
let ty = &imp.ty;
check_lifetimes(cx, &imp.impl_generics);
if let Some(negative) = imp.negative_token {
let span = quote!(#negative #ty);
cx.error(span, "negative impl is not supported yet");
@ -583,6 +593,26 @@ fn check_reserved_name(cx: &mut Check, ident: &Ident) {
}
}
fn check_reserved_lifetime(cx: &mut Check, lifetime: &Lifetime) {
if lifetime.ident == "static" {
cx.error(lifetime, error::RESERVED_LIFETIME);
}
}
fn check_lifetimes(cx: &mut Check, generics: &Lifetimes) {
for lifetime in &generics.lifetimes {
check_reserved_lifetime(cx, lifetime);
}
}
fn check_generics(cx: &mut Check, generics: &Generics) {
for generic_param in &generics.params {
if let GenericParam::Lifetime(def) = generic_param {
check_reserved_lifetime(cx, &def.lifetime);
}
}
}
fn is_unsized(cx: &mut Check, ty: &Type) -> bool {
match ty {
Type::Ident(ident) => {

View File

@ -21,6 +21,7 @@ pub static ERRORS: &[Error] = &[
DISCRIMINANT_OVERFLOW,
DOT_INCLUDE,
DOUBLE_UNDERSCORE,
RESERVED_LIFETIME,
RUST_TYPE_BY_VALUE,
UNSUPPORTED_TYPE,
USE_NOT_ALLOWED,
@ -68,6 +69,12 @@ pub static DOUBLE_UNDERSCORE: Error = Error {
note: Some("identifiers containing double underscore are reserved in C++"),
};
pub static RESERVED_LIFETIME: Error = Error {
msg: "invalid lifetime parameter name: `'static`",
label: Some("'static is a reserved lifetime name"),
note: None,
};
pub static RUST_TYPE_BY_VALUE: Error = Error {
msg: "opaque Rust type by value is not supported",
label: None,