Support Option and similar enums as type of static variable with linkage attribute.
Compiler MCP: https://github.com/rust-lang/compiler-team/issues/565
This commit is contained in:
parent
5873ebeef3
commit
f44a0153bc
7 changed files with 67 additions and 5 deletions
|
@ -494,6 +494,7 @@ E0786: include_str!("./error_codes/E0786.md"),
|
||||||
E0787: include_str!("./error_codes/E0787.md"),
|
E0787: include_str!("./error_codes/E0787.md"),
|
||||||
E0788: include_str!("./error_codes/E0788.md"),
|
E0788: include_str!("./error_codes/E0788.md"),
|
||||||
E0790: include_str!("./error_codes/E0790.md"),
|
E0790: include_str!("./error_codes/E0790.md"),
|
||||||
|
E0791: include_str!("./error_codes/E0791.md"),
|
||||||
;
|
;
|
||||||
// E0006, // merged with E0005
|
// E0006, // merged with E0005
|
||||||
// E0008, // cannot bind by-move into a pattern guard
|
// E0008, // cannot bind by-move into a pattern guard
|
||||||
|
|
41
compiler/rustc_error_codes/src/error_codes/E0791.md
Normal file
41
compiler/rustc_error_codes/src/error_codes/E0791.md
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
Static variables with the `#[linkage]` attribute within external blocks
|
||||||
|
must have one of the following types, which are equivalent to a nullable
|
||||||
|
pointer in C:
|
||||||
|
|
||||||
|
* `*mut T` or `*const T`, where `T` may be any type.
|
||||||
|
|
||||||
|
* An enumerator type with no `#[repr]` attribute and with two variants, where
|
||||||
|
one of the variants has no fields, and the other has a single field of one of
|
||||||
|
the following non-nullable types:
|
||||||
|
* Reference type
|
||||||
|
* Function pointer type
|
||||||
|
|
||||||
|
The variants can appear in either order.
|
||||||
|
|
||||||
|
For example, the following declaration is invalid:
|
||||||
|
|
||||||
|
```compile_fail,E0791
|
||||||
|
#![feature(linkage)]
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[linkage = "extern_weak"]
|
||||||
|
static foo: i8;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The following declarations are valid:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(linkage)]
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[linkage = "extern_weak"]
|
||||||
|
static foo: Option<unsafe extern "C" fn()>;
|
||||||
|
|
||||||
|
#[linkage = "extern_weak"]
|
||||||
|
static bar: Option<&'static i8>;
|
||||||
|
|
||||||
|
#[linkage = "extern_weak"]
|
||||||
|
static baz: *mut i8;
|
||||||
|
}
|
||||||
|
```
|
|
@ -115,4 +115,4 @@ hir_analysis_self_in_impl_self =
|
||||||
.note = replace `Self` with a different type
|
.note = replace `Self` with a different type
|
||||||
|
|
||||||
hir_analysis_linkage_type =
|
hir_analysis_linkage_type =
|
||||||
must have type `*const T` or `*mut T` due to `#[linkage]` attribute
|
invalid type for variable with `#[linkage]` attribute
|
||||||
|
|
|
@ -21,7 +21,7 @@ use rustc_middle::middle::stability::EvalResult;
|
||||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
use rustc_middle::ty::subst::GenericArgKind;
|
||||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||||
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
|
use rustc_middle::ty::{self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
|
||||||
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
|
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{self, Span};
|
use rustc_span::{self, Span};
|
||||||
|
@ -479,10 +479,29 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_enum_of_nonnullable_ptr<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
adt_def: AdtDef<'tcx>,
|
||||||
|
substs: SubstsRef<'tcx>,
|
||||||
|
) -> bool {
|
||||||
|
if adt_def.repr().inhibit_enum_layout_opt() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [var_one, var_two] = &adt_def.variants().raw[..] else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let (([], [field]) | ([field], [])) = (&var_one.fields[..], &var_two.fields[..]) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..))
|
||||||
|
}
|
||||||
|
|
||||||
fn check_static_linkage<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
fn check_static_linkage<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
||||||
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
|
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
|
||||||
if match tcx.type_of(def_id).kind() {
|
if match tcx.type_of(def_id).kind() {
|
||||||
ty::RawPtr(_) => false,
|
ty::RawPtr(_) => false,
|
||||||
|
ty::Adt(adt_def, substs) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *substs),
|
||||||
_ => true,
|
_ => true,
|
||||||
} {
|
} {
|
||||||
tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) });
|
tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) });
|
||||||
|
|
|
@ -287,7 +287,7 @@ pub struct SelfInImplSelf {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_linkage_type)]
|
#[diag(hir_analysis_linkage_type, code = "E0791")]
|
||||||
pub(crate) struct LinkageType {
|
pub(crate) struct LinkageType {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[linkage = "extern_weak"]
|
#[linkage = "extern_weak"]
|
||||||
static foo: i32;
|
static foo: i32;
|
||||||
//~^ ERROR: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
|
//~^ ERROR: invalid type for variable with `#[linkage]` attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
|
error[E0791]: invalid type for variable with `#[linkage]` attribute
|
||||||
--> $DIR/linkage2.rs:7:5
|
--> $DIR/linkage2.rs:7:5
|
||||||
|
|
|
|
||||||
LL | static foo: i32;
|
LL | static foo: i32;
|
||||||
|
@ -6,3 +6,4 @@ LL | static foo: i32;
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0791`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue