lint: don't suggest assume_init for uninhabited types
This commit is contained in:
parent
3eb5c4581a
commit
0610df9314
6 changed files with 32 additions and 59 deletions
|
@ -2635,7 +2635,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
||||||
cx.emit_spanned_lint(
|
cx.emit_spanned_lint(
|
||||||
INVALID_VALUE,
|
INVALID_VALUE,
|
||||||
expr.span,
|
expr.span,
|
||||||
BuiltinUnpermittedTypeInit { msg, ty: conjured_ty, label: expr.span, sub },
|
BuiltinUnpermittedTypeInit {
|
||||||
|
msg,
|
||||||
|
ty: conjured_ty,
|
||||||
|
label: expr.span,
|
||||||
|
sub,
|
||||||
|
tcx: cx.tcx,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,9 @@ use rustc_errors::{
|
||||||
};
|
};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::{PolyExistentialTraitRef, Predicate, Ty, TyCtxt};
|
use rustc_middle::ty::{
|
||||||
|
inhabitedness::InhabitedPredicate, PolyExistentialTraitRef, Predicate, Ty, TyCtxt,
|
||||||
|
};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
|
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
|
||||||
|
|
||||||
|
@ -419,6 +421,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> {
|
||||||
pub ty: Ty<'a>,
|
pub ty: Ty<'a>,
|
||||||
pub label: Span,
|
pub label: Span,
|
||||||
pub sub: BuiltinUnpermittedTypeInitSub,
|
pub sub: BuiltinUnpermittedTypeInitSub,
|
||||||
|
pub tcx: TyCtxt<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
||||||
|
@ -428,7 +431,13 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
||||||
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
|
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
|
||||||
diag.set_arg("ty", self.ty);
|
diag.set_arg("ty", self.ty);
|
||||||
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
|
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
|
||||||
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label_suggestion);
|
if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
|
||||||
|
// Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited.
|
||||||
|
diag.span_label(
|
||||||
|
self.label,
|
||||||
|
fluent::lint_builtin_unpermitted_type_init_label_suggestion,
|
||||||
|
);
|
||||||
|
}
|
||||||
self.sub.add_to_diagnostic(diag);
|
self.sub.add_to_diagnostic(diag);
|
||||||
diag
|
diag
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,7 @@ warning: the type `!` does not permit zero-initialization
|
||||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||||
|
|
|
|
||||||
LL | unsafe { std::mem::transmute(()) }
|
LL | unsafe { std::mem::transmute(()) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: the `!` type has no valid value
|
= note: the `!` type has no valid value
|
||||||
= note: `#[warn(invalid_value)]` on by default
|
= note: `#[warn(invalid_value)]` on by default
|
||||||
|
@ -40,10 +37,7 @@ warning: the type `empty::Empty` does not permit zero-initialization
|
||||||
--> $DIR/validate_uninhabited_zsts.rs:21:42
|
--> $DIR/validate_uninhabited_zsts.rs:21:42
|
||||||
|
|
|
|
||||||
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
|
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: in this struct field
|
note: in this struct field
|
||||||
--> $DIR/validate_uninhabited_zsts.rs:16:22
|
--> $DIR/validate_uninhabited_zsts.rs:16:22
|
||||||
|
|
|
@ -2,10 +2,7 @@ warning: the type `!` does not permit zero-initialization
|
||||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||||
|
|
|
|
||||||
LL | unsafe { std::mem::transmute(()) }
|
LL | unsafe { std::mem::transmute(()) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: the `!` type has no valid value
|
= note: the `!` type has no valid value
|
||||||
= note: `#[warn(invalid_value)]` on by default
|
= note: `#[warn(invalid_value)]` on by default
|
||||||
|
@ -40,10 +37,7 @@ warning: the type `empty::Empty` does not permit zero-initialization
|
||||||
--> $DIR/validate_uninhabited_zsts.rs:21:42
|
--> $DIR/validate_uninhabited_zsts.rs:21:42
|
||||||
|
|
|
|
||||||
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
|
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: in this struct field
|
note: in this struct field
|
||||||
--> $DIR/validate_uninhabited_zsts.rs:16:22
|
--> $DIR/validate_uninhabited_zsts.rs:16:22
|
||||||
|
|
|
@ -61,10 +61,7 @@ error: the type `!` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:65:23
|
--> $DIR/invalid_value.rs:65:23
|
||||||
|
|
|
|
||||||
LL | let _val: ! = mem::zeroed();
|
LL | let _val: ! = mem::zeroed();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: the `!` type has no valid value
|
= note: the `!` type has no valid value
|
||||||
|
|
||||||
|
@ -72,10 +69,7 @@ error: the type `!` does not permit being left uninitialized
|
||||||
--> $DIR/invalid_value.rs:66:23
|
--> $DIR/invalid_value.rs:66:23
|
||||||
|
|
|
|
||||||
LL | let _val: ! = mem::uninitialized();
|
LL | let _val: ! = mem::uninitialized();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: the `!` type has no valid value
|
= note: the `!` type has no valid value
|
||||||
|
|
||||||
|
@ -83,10 +77,7 @@ error: the type `(i32, !)` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:68:30
|
--> $DIR/invalid_value.rs:68:30
|
||||||
|
|
|
|
||||||
LL | let _val: (i32, !) = mem::zeroed();
|
LL | let _val: (i32, !) = mem::zeroed();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: the `!` type has no valid value
|
= note: the `!` type has no valid value
|
||||||
|
|
||||||
|
@ -94,10 +85,7 @@ error: the type `(i32, !)` does not permit being left uninitialized
|
||||||
--> $DIR/invalid_value.rs:69:30
|
--> $DIR/invalid_value.rs:69:30
|
||||||
|
|
|
|
||||||
LL | let _val: (i32, !) = mem::uninitialized();
|
LL | let _val: (i32, !) = mem::uninitialized();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
= note: integers must be initialized
|
= note: integers must be initialized
|
||||||
|
|
||||||
|
@ -105,10 +93,7 @@ error: the type `Void` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:71:26
|
--> $DIR/invalid_value.rs:71:26
|
||||||
|
|
|
|
||||||
LL | let _val: Void = mem::zeroed();
|
LL | let _val: Void = mem::zeroed();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: enums with no inhabited variants have no valid value
|
note: enums with no inhabited variants have no valid value
|
||||||
--> $DIR/invalid_value.rs:12:1
|
--> $DIR/invalid_value.rs:12:1
|
||||||
|
@ -120,10 +105,7 @@ error: the type `Void` does not permit being left uninitialized
|
||||||
--> $DIR/invalid_value.rs:72:26
|
--> $DIR/invalid_value.rs:72:26
|
||||||
|
|
|
|
||||||
LL | let _val: Void = mem::uninitialized();
|
LL | let _val: Void = mem::uninitialized();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: enums with no inhabited variants have no valid value
|
note: enums with no inhabited variants have no valid value
|
||||||
--> $DIR/invalid_value.rs:12:1
|
--> $DIR/invalid_value.rs:12:1
|
||||||
|
@ -405,10 +387,7 @@ error: the type `TwoUninhabited` does not permit zero-initialization
|
||||||
--> $DIR/invalid_value.rs:104:36
|
--> $DIR/invalid_value.rs:104:36
|
||||||
|
|
|
|
||||||
LL | let _val: TwoUninhabited = mem::zeroed();
|
LL | let _val: TwoUninhabited = mem::zeroed();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: enums with no inhabited variants have no valid value
|
note: enums with no inhabited variants have no valid value
|
||||||
--> $DIR/invalid_value.rs:42:1
|
--> $DIR/invalid_value.rs:42:1
|
||||||
|
@ -420,10 +399,7 @@ error: the type `TwoUninhabited` does not permit being left uninitialized
|
||||||
--> $DIR/invalid_value.rs:105:36
|
--> $DIR/invalid_value.rs:105:36
|
||||||
|
|
|
|
||||||
LL | let _val: TwoUninhabited = mem::uninitialized();
|
LL | let _val: TwoUninhabited = mem::uninitialized();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: enums with no inhabited variants have no valid value
|
note: enums with no inhabited variants have no valid value
|
||||||
--> $DIR/invalid_value.rs:42:1
|
--> $DIR/invalid_value.rs:42:1
|
||||||
|
|
|
@ -53,10 +53,7 @@ warning: the type `Void` does not permit zero-initialization
|
||||||
--> $DIR/uninhabited-static.rs:12:31
|
--> $DIR/uninhabited-static.rs:12:31
|
||||||
|
|
|
|
||||||
LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
|
LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: enums with no inhabited variants have no valid value
|
note: enums with no inhabited variants have no valid value
|
||||||
--> $DIR/uninhabited-static.rs:4:1
|
--> $DIR/uninhabited-static.rs:4:1
|
||||||
|
@ -75,10 +72,7 @@ warning: the type `Void` does not permit zero-initialization
|
||||||
--> $DIR/uninhabited-static.rs:16:32
|
--> $DIR/uninhabited-static.rs:16:32
|
||||||
|
|
|
|
||||||
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
|
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
||||||
| |
|
|
||||||
| this code causes undefined behavior when executed
|
|
||||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
|
||||||
|
|
|
|
||||||
note: enums with no inhabited variants have no valid value
|
note: enums with no inhabited variants have no valid value
|
||||||
--> $DIR/uninhabited-static.rs:4:1
|
--> $DIR/uninhabited-static.rs:4:1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue