diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 28aef9055ef44..fffba7c4789f6 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -209,12 +209,6 @@ lint_crate_name_in_cfg_attr_deprecated = lint_crate_type_in_cfg_attr_deprecated = `crate_type` within an `#![cfg_attr]` attribute is deprecated -lint_cstring_ptr = getting the inner pointer of a temporary `CString` - .as_ptr_label = this pointer will be invalid - .unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime - .note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - .help = for more information, see https://doc.rust-lang.org/reference/destructors.html - lint_custom_inner_attribute_unstable = custom inner attributes are unstable lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance @@ -411,6 +405,12 @@ lint_incomplete_include = lint_inner_macro_attribute_unstable = inner macro attributes are unstable +lint_instantly_dangling = getting a pointer from a temporary `{$ty}` will result in a dangling pointer + .label_ptr = this pointer will immediately be invalid + .label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + .note = pointers do not have a lifetime; when calling `{$callee}` the `{$ty}` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + .help = for more information, see https://doc.rust-lang.org/reference/destructors.html + lint_invalid_asm_label_binary = avoid using labels containing only the digits `0` and `1` in inline assembly .label = use a different label that doesn't start with `0` or `1` .help = start numbering with `2` instead diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs new file mode 100644 index 0000000000000..3bc66e10ed6fe --- /dev/null +++ b/compiler/rustc_lint/src/dangling.rs @@ -0,0 +1,137 @@ +use rustc_hir::{Expr, ExprKind, LangItem}; +use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::symbol::sym; + +use crate::lints::InstantlyDangling; +use crate::{LateContext, LateLintPass, LintContext}; + +// FIXME: does not catch UnsafeCell::get +// FIXME: does not catch getting a ref to a temporary and then converting it to a ptr +declare_lint! { + /// The `dangling_pointers_from_temporaries` lint detects getting a pointer to data + /// of a temporary that will immediately get dropped. + /// + /// ### Example + /// + /// ```rust + /// # #![allow(unused)] + /// # unsafe fn use_data(ptr: *const u8) { + /// # dbg!(unsafe { ptr.read() }); + /// # } + /// fn gather_and_use(bytes: impl Iterator<Item = u8>) { + /// let x: *const u8 = bytes.collect::<Vec<u8>>().as_ptr(); + /// unsafe { use_data(x) } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Getting a pointer from a temporary value will not prolong its lifetime, + /// which means that the value can be dropped and the allocation freed + /// while the pointer still exists, making the pointer dangling. + /// This is not an error (as far as the type system is concerned) + /// but probably is not what the user intended either. + /// + /// If you need stronger guarantees, consider using references instead, + /// as they are statically verified by the borrow-checker to never dangle. + pub DANGLING_POINTERS_FROM_TEMPORARIES, + Warn, + "detects getting a pointer from a temporary" +} + +declare_lint_pass!(DanglingPointers => [DANGLING_POINTERS_FROM_TEMPORARIES]); + +impl<'tcx> LateLintPass<'tcx> for DanglingPointers { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::MethodCall(method, receiver, _args, _span) = expr.kind + && matches!(method.ident.name, sym::as_ptr | sym::as_mut_ptr) + && is_temporary_rvalue(receiver) + && let ty = cx.typeck_results().expr_ty(receiver) + && is_interesting(cx.tcx, ty) + { + cx.emit_span_lint( + DANGLING_POINTERS_FROM_TEMPORARIES, + method.ident.span, + InstantlyDangling { + callee: method.ident.name, + ty, + ptr_span: method.ident.span, + temporary_span: receiver.span, + }, + ) + } + } +} + +fn is_temporary_rvalue(expr: &Expr<'_>) -> bool { + match expr.kind { + // Const is not temporary. + ExprKind::ConstBlock(..) | ExprKind::Repeat(..) | ExprKind::Lit(..) => false, + + // This is literally lvalue. + ExprKind::Path(..) => false, + + // Calls return rvalues. + ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Binary(..) => true, + + // Inner blocks are rvalues. + ExprKind::If(..) | ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::Block(..) => true, + + // FIXME: these should probably recurse and typecheck along the way. + // Some false negatives are possible for now. + ExprKind::Index(..) | ExprKind::Field(..) | ExprKind::Unary(..) => false, + + ExprKind::Struct(..) => true, + + // FIXME: this has false negatives, but I do not want to deal with 'static/const promotion just yet. + ExprKind::Array(..) => false, + + // These typecheck to `!` + ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Become(..) => { + false + } + + // These typecheck to `()` + ExprKind::Assign(..) | ExprKind::AssignOp(..) | ExprKind::Yield(..) => false, + + // Compiler-magic macros + ExprKind::AddrOf(..) | ExprKind::OffsetOf(..) | ExprKind::InlineAsm(..) => false, + + // We are not interested in these + ExprKind::Cast(..) + | ExprKind::Closure(..) + | ExprKind::Tup(..) + | ExprKind::DropTemps(..) + | ExprKind::Let(..) => false, + + // Not applicable + ExprKind::Type(..) | ExprKind::Err(..) => false, + } +} + +// Array, Vec, String, CString, MaybeUninit, Cell, Box<[_]>, Box<str>, Box<CStr>, +// or any of the above in arbitrary many nested Box'es. +fn is_interesting(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool { + if ty.is_array() { + true + } else if ty.is_box() { + let inner = ty.boxed_ty(); + inner.is_slice() + || inner.is_str() + || inner.ty_adt_def().is_some_and(|def| tcx.is_lang_item(def.did(), LangItem::CStr)) + || is_interesting(tcx, inner) + } else if let Some(def) = ty.ty_adt_def() { + for lang_item in [LangItem::String, LangItem::MaybeUninit] { + if tcx.is_lang_item(def.did(), lang_item) { + return true; + } + } + tcx.get_diagnostic_name(def.did()) + .is_some_and(|name| matches!(name, sym::cstring_type | sym::Vec | sym::Cell)) + } else { + false + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 1828b6ea93c06..67a2e29b82e0f 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -45,6 +45,7 @@ mod async_closures; mod async_fn_in_trait; pub mod builtin; mod context; +mod dangling; mod deref_into_dyn_supertrait; mod drop_forget_useless; mod early; @@ -63,7 +64,6 @@ mod levels; mod lints; mod macro_expr_fragment_specifier_2024_migration; mod map_unit_fn; -mod methods; mod multiple_supertrait_upcastable; mod non_ascii_idents; mod non_fmt_panic; @@ -87,6 +87,7 @@ mod unused; use async_closures::AsyncClosureUsage; use async_fn_in_trait::AsyncFnInTrait; use builtin::*; +use dangling::*; use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; @@ -98,7 +99,6 @@ use invalid_from_utf8::*; use let_underscore::*; use macro_expr_fragment_specifier_2024_migration::*; use map_unit_fn::*; -use methods::*; use multiple_supertrait_upcastable::*; use non_ascii_idents::*; use non_fmt_panic::NonPanicFmt; @@ -225,7 +225,7 @@ late_lint_methods!( UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller, ShadowedIntoIter: ShadowedIntoIter, DropTraitConstraints: DropTraitConstraints, - TemporaryCStringAsPtr: TemporaryCStringAsPtr, + DanglingPointers: DanglingPointers, NonPanicFmt: NonPanicFmt, NoopMethodCall: NoopMethodCall, EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums, @@ -346,6 +346,7 @@ fn register_builtins(store: &mut LintStore) { store.register_renamed("non_fmt_panic", "non_fmt_panics"); store.register_renamed("unused_tuple_struct_fields", "dead_code"); store.register_renamed("static_mut_ref", "static_mut_refs"); + store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries"); // These were moved to tool lints, but rustc still sees them when compiling normally, before // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c12c5427997f9..fbc7c1c28eace 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1124,16 +1124,19 @@ pub struct IgnoredUnlessCrateSpecified<'a> { pub name: Symbol, } -// methods.rs +// dangling.rs #[derive(LintDiagnostic)] -#[diag(lint_cstring_ptr)] +#[diag(lint_instantly_dangling)] #[note] #[help] -pub struct CStringPtr { - #[label(lint_as_ptr_label)] - pub as_ptr: Span, - #[label(lint_unwrap_label)] - pub unwrap: Span, +// FIXME: use #[primary_span] +pub struct InstantlyDangling<'tcx> { + pub callee: Symbol, + pub ty: Ty<'tcx>, + #[label(lint_label_ptr)] + pub ptr_span: Span, + #[label(lint_label_temporary)] + pub temporary_span: Span, } // multiple_supertrait_upcastable.rs diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs deleted file mode 100644 index dff72bb622f23..0000000000000 --- a/compiler/rustc_lint/src/methods.rs +++ /dev/null @@ -1,70 +0,0 @@ -use rustc_hir::{Expr, ExprKind}; -use rustc_middle::ty; -use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::symbol::sym; -use rustc_span::Span; - -use crate::lints::CStringPtr; -use crate::{LateContext, LateLintPass, LintContext}; - -declare_lint! { - /// The `temporary_cstring_as_ptr` lint detects getting the inner pointer of - /// a temporary `CString`. - /// - /// ### Example - /// - /// ```rust - /// # #![allow(unused)] - /// # use std::ffi::CString; - /// let c_str = CString::new("foo").unwrap().as_ptr(); - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The inner pointer of a `CString` lives only as long as the `CString` it - /// points to. Getting the inner pointer of a *temporary* `CString` allows the `CString` - /// to be dropped at the end of the statement, as it is not being referenced as far as the - /// typesystem is concerned. This means outside of the statement the pointer will point to - /// freed memory, which causes undefined behavior if the pointer is later dereferenced. - pub TEMPORARY_CSTRING_AS_PTR, - Warn, - "detects getting the inner pointer of a temporary `CString`" -} - -declare_lint_pass!(TemporaryCStringAsPtr => [TEMPORARY_CSTRING_AS_PTR]); - -impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let ExprKind::MethodCall(as_ptr_path, as_ptr_receiver, ..) = expr.kind - && as_ptr_path.ident.name == sym::as_ptr - && let ExprKind::MethodCall(unwrap_path, unwrap_receiver, ..) = as_ptr_receiver.kind - && (unwrap_path.ident.name == sym::unwrap || unwrap_path.ident.name == sym::expect) - { - lint_cstring_as_ptr(cx, as_ptr_path.ident.span, unwrap_receiver, as_ptr_receiver); - } - } -} - -fn lint_cstring_as_ptr( - cx: &LateContext<'_>, - as_ptr_span: Span, - source: &rustc_hir::Expr<'_>, - unwrap: &rustc_hir::Expr<'_>, -) { - let source_type = cx.typeck_results().expr_ty(source); - if let ty::Adt(def, args) = source_type.kind() { - if cx.tcx.is_diagnostic_item(sym::Result, def.did()) { - if let ty::Adt(adt, _) = args.type_at(0).kind() { - if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) { - cx.emit_span_lint( - TEMPORARY_CSTRING_AS_PTR, - as_ptr_span, - CStringPtr { as_ptr: as_ptr_span, unwrap: unwrap.span }, - ); - } - } - } - } -} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a2e94492f8c23..14328b2447bd8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -170,6 +170,7 @@ symbols! { CallOnceFuture, CallRefFuture, Capture, + Cell, Center, Cleanup, Clone, @@ -411,6 +412,7 @@ symbols! { arm, arm_target_feature, array, + as_mut_ptr, as_ptr, as_ref, as_str, diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index faee64b2f6738..6d19eb485bc90 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -4,6 +4,7 @@ use core::mem::MaybeUninit; use core::ptr::NonNull; #[test] +#[cfg_attr(not(bootstrap), expect(dangling_pointers_from_temporaries))] fn uninitialized_zero_size_box() { assert_eq!( &*Box::<()>::new_uninit() as *const _, diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index d860f3415d982..347e00ad1321c 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -304,6 +304,7 @@ pub use once::OnceCell; /// ``` /// /// See the [module-level documentation](self) for more. +#[cfg_attr(not(test), rustc_diagnostic_item = "Cell")] #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] pub struct Cell<T: ?Sized> { diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 22084dcff8f88..6585bf8f294fd 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -463,7 +463,9 @@ impl CStr { /// behavior when `ptr` is used inside the `unsafe` block: /// /// ```no_run - /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)] + /// # #![allow(unused_must_use)] + /// # #![cfg_attr(bootstrap, expect(temporary_cstring_as_ptr))] + /// # #![cfg_attr(not(bootstrap), expect(dangling_pointers_from_temporaries))] /// use std::ffi::CString; /// /// // Do not do this: diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index 0066ed643251a..77dbe9b78a182 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -166,7 +166,7 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[ #[clippy::version = ""] ("clippy::positional_named_format_parameters", "named_arguments_used_positionally"), #[clippy::version = ""] - ("clippy::temporary_cstring_as_ptr", "temporary_cstring_as_ptr"), + ("clippy::temporary_cstring_as_ptr", "dangling_pointers_from_temporaries"), #[clippy::version = ""] ("clippy::undropped_manually_drops", "undropped_manually_drops"), #[clippy::version = ""] diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index b810fd8224f63..0d6e07aa546cf 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -54,7 +54,7 @@ #![allow(enum_intrinsics_non_enums)] #![allow(non_fmt_panics)] #![allow(named_arguments_used_positionally)] -#![allow(temporary_cstring_as_ptr)] +#![allow(dangling_pointers_from_temporaries)] #![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] @@ -120,7 +120,7 @@ #![warn(unexpected_cfgs)] //~ ERROR: lint `clippy::mismatched_target_os` #![warn(non_fmt_panics)] //~ ERROR: lint `clippy::panic_params` #![warn(named_arguments_used_positionally)] //~ ERROR: lint `clippy::positional_named_format_parameters` -#![warn(temporary_cstring_as_ptr)] //~ ERROR: lint `clippy::temporary_cstring_as_ptr` +#![warn(dangling_pointers_from_temporaries)] //~ ERROR: lint `clippy::temporary_cstring_as_ptr` #![warn(undropped_manually_drops)] //~ ERROR: lint `clippy::undropped_manually_drops` #![warn(unknown_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints` #![warn(unused_labels)] //~ ERROR: lint `clippy::unused_label` diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 46d9f0fac59f9..b906079d7df3e 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,11 +1,17 @@ +error: lint `temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` + --> tests/ui/rename.rs:57:10 + | +LL | #![allow(temporary_cstring_as_ptr)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` + | + = note: `-D renamed-and-removed-lints` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]` + error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` --> tests/ui/rename.rs:63:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` - | - = note: `-D renamed-and-removed-lints` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` --> tests/ui/rename.rs:64:9 @@ -361,11 +367,11 @@ error: lint `clippy::positional_named_format_parameters` has been renamed to `na LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` -error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` +error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` --> tests/ui/rename.rs:123:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` --> tests/ui/rename.rs:124:9 @@ -397,5 +403,5 @@ error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_e LL | #![warn(clippy::reverse_range_loop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges` -error: aborting due to 66 previous errors +error: aborting due to 67 previous errors diff --git a/tests/ui/consts/zst_no_llvm_alloc.rs b/tests/ui/consts/zst_no_llvm_alloc.rs index 48ef11e2b58cf..d29f64b4729db 100644 --- a/tests/ui/consts/zst_no_llvm_alloc.rs +++ b/tests/ui/consts/zst_no_llvm_alloc.rs @@ -17,8 +17,11 @@ fn main() { // The exact addresses returned by these library functions are not necessarily stable guarantees // but for now we assert that we're still matching. - assert_eq!(<Vec<i32>>::new().as_ptr(), <&[i32]>::default().as_ptr()); - assert_eq!(<Box<[i32]>>::default().as_ptr(), (&[]).as_ptr()); + #[expect(dangling_pointers_from_temporaries)] + { + assert_eq!(<Vec<i32>>::new().as_ptr(), <&[i32]>::default().as_ptr()); + assert_eq!(<Box<[i32]>>::default().as_ptr(), (&[]).as_ptr()); + }; // statics must have a unique address (see https://github.com/rust-lang/rust/issues/18297, not // clear whether this is a stable guarantee) diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs b/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs new file mode 100644 index 0000000000000..8566191987ff5 --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs @@ -0,0 +1,9 @@ +//@ check-pass + +// This should not ICE. + +#![allow(dangling_pointers_from_temporaries)] + +fn main() { + dbg!(String::new().as_ptr()); +} diff --git a/tests/ui/lint/lint-temporary-cstring-as-param.rs b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-param.rs similarity index 50% rename from tests/ui/lint/lint-temporary-cstring-as-param.rs rename to tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-param.rs index 9f5805367e43d..843c898ce823a 100644 --- a/tests/ui/lint/lint-temporary-cstring-as-param.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-param.rs @@ -1,4 +1,5 @@ #![deny(temporary_cstring_as_ptr)] +//~^ WARNING lint `temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` use std::ffi::CString; use std::os::raw::c_char; @@ -7,5 +8,5 @@ fn some_function(data: *const c_char) {} fn main() { some_function(CString::new("").unwrap().as_ptr()); - //~^ ERROR getting the inner pointer of a temporary `CString` + //~^ ERROR getting a pointer from a temporary `CString` will result in a dangling pointer } diff --git a/tests/ui/lint/lint-temporary-cstring-as-param.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-param.stderr similarity index 54% rename from tests/ui/lint/lint-temporary-cstring-as-param.stderr rename to tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-param.stderr index 7aa21f2560c2d..c28cd82ed289c 100644 --- a/tests/ui/lint/lint-temporary-cstring-as-param.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-param.stderr @@ -1,18 +1,26 @@ -error: getting the inner pointer of a temporary `CString` - --> $DIR/lint-temporary-cstring-as-param.rs:9:45 +warning: lint `temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` + --> $DIR/cstring-as-param.rs:1:9 + | +LL | #![deny(temporary_cstring_as_ptr)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +error: getting a pointer from a temporary `CString` will result in a dangling pointer + --> $DIR/cstring-as-param.rs:10:45 | LL | some_function(CString::new("").unwrap().as_ptr()); - | ------------------------- ^^^^^^ this pointer will be invalid + | ------------------------- ^^^^^^ this pointer will immediately be invalid | | | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime | = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned = help: for more information, see https://doc.rust-lang.org/reference/destructors.html note: the lint level is defined here - --> $DIR/lint-temporary-cstring-as-param.rs:1:9 + --> $DIR/cstring-as-param.rs:1:9 | LL | #![deny(temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/lint/lint-temporary-cstring-as-ptr.rs b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs similarity index 54% rename from tests/ui/lint/lint-temporary-cstring-as-ptr.rs rename to tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs index fab792f128411..659d4e11b85f2 100644 --- a/tests/ui/lint/lint-temporary-cstring-as-ptr.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs @@ -1,17 +1,18 @@ // this program is not technically incorrect, but is an obscure enough style to be worth linting #![deny(temporary_cstring_as_ptr)] +//~^ WARNING lint `temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` use std::ffi::CString; macro_rules! mymacro { () => { let s = CString::new("some text").unwrap().as_ptr(); - //~^ ERROR getting the inner pointer of a temporary `CString` + //~^ ERROR getting a pointer from a temporary `CString` will result in a dangling pointer } } fn main() { let s = CString::new("some text").unwrap().as_ptr(); - //~^ ERROR getting the inner pointer of a temporary `CString` + //~^ ERROR getting a pointer from a temporary `CString` will result in a dangling pointer mymacro!(); } diff --git a/tests/ui/lint/lint-temporary-cstring-as-ptr.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr similarity index 65% rename from tests/ui/lint/lint-temporary-cstring-as-ptr.stderr rename to tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr index 4e5c8aa069364..9d31a50839eab 100644 --- a/tests/ui/lint/lint-temporary-cstring-as-ptr.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr @@ -1,24 +1,32 @@ -error: getting the inner pointer of a temporary `CString` - --> $DIR/lint-temporary-cstring-as-ptr.rs:14:48 +warning: lint `temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` + --> $DIR/cstring-as-ptr.rs:2:9 + | +LL | #![deny(temporary_cstring_as_ptr)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +error: getting a pointer from a temporary `CString` will result in a dangling pointer + --> $DIR/cstring-as-ptr.rs:15:48 | LL | let s = CString::new("some text").unwrap().as_ptr(); - | ---------------------------------- ^^^^^^ this pointer will be invalid + | ---------------------------------- ^^^^^^ this pointer will immediately be invalid | | | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime | = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned = help: for more information, see https://doc.rust-lang.org/reference/destructors.html note: the lint level is defined here - --> $DIR/lint-temporary-cstring-as-ptr.rs:2:9 + --> $DIR/cstring-as-ptr.rs:2:9 | LL | #![deny(temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: getting the inner pointer of a temporary `CString` - --> $DIR/lint-temporary-cstring-as-ptr.rs:8:52 +error: getting a pointer from a temporary `CString` will result in a dangling pointer + --> $DIR/cstring-as-ptr.rs:9:52 | LL | let s = CString::new("some text").unwrap().as_ptr(); - | ---------------------------------- ^^^^^^ this pointer will be invalid + | ---------------------------------- ^^^^^^ this pointer will immediately be invalid | | | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime ... @@ -29,5 +37,5 @@ LL | mymacro!(); = help: for more information, see https://doc.rust-lang.org/reference/destructors.html = note: this error originates in the macro `mymacro` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs new file mode 100644 index 0000000000000..457b5fb4ee743 --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs @@ -0,0 +1,13 @@ +#![deny(dangling_pointers_from_temporaries)] + +const MAX_PATH: usize = 260; +fn main() { + let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + let str2 = String::from("TotototototototototototototototototoT").as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + unsafe { + std::ptr::copy_nonoverlapping(str2, str1, 30); + println!("{:?}", String::from_raw_parts(str1, 30, 30)); + } +} diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr new file mode 100644 index 0000000000000..de66565674c0a --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr @@ -0,0 +1,29 @@ +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/example-from-issue123613.rs:5:48 + | +LL | let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); + | ------------------------------- ^^^^^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_mut_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html +note: the lint level is defined here + --> $DIR/example-from-issue123613.rs:1:9 + | +LL | #![deny(dangling_pointers_from_temporaries)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/example-from-issue123613.rs:7:70 + | +LL | let str2 = String::from("TotototototototototototototototototoT").as_ptr(); + | ----------------------------------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs b/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs new file mode 100644 index 0000000000000..6287b4317d525 --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs @@ -0,0 +1,8 @@ +#![deny(dangling_pointers_from_temporaries)] + +fn main() { + vec![0u8].as_ptr(); + //~^ ERROR getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer + vec![0u8].as_mut_ptr(); + //~^ ERROR getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer +} diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr new file mode 100644 index 0000000000000..245204325b837 --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr @@ -0,0 +1,29 @@ +error: getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer + --> $DIR/methods.rs:4:15 + | +LL | vec![0u8].as_ptr(); + | --------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Vec<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html +note: the lint level is defined here + --> $DIR/methods.rs:1:9 + | +LL | #![deny(dangling_pointers_from_temporaries)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer + --> $DIR/methods.rs:6:15 + | +LL | vec![0u8].as_mut_ptr(); + | --------- ^^^^^^^^^^ this pointer will immediately be invalid + | | + | this `Vec<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_mut_ptr` the `Vec<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs new file mode 100644 index 0000000000000..3bfb9c69a319d --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs @@ -0,0 +1,136 @@ +#![allow(unused)] +#![deny(dangling_pointers_from_temporaries)] + +fn string() -> String { + "hello".into() +} + +struct Wrapper(String); + +fn main() { + // ConstBlock + const { String::new() }.as_ptr(); + + // Array + { + [string()].as_ptr(); // False negative + [true].as_ptr(); + } + + // Call + string().as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + + // MethodCall + "hello".to_string().as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + + // Tup + // impossible + + // Binary + (string() + "hello").as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + + // Path + { + let x = string(); + x.as_ptr(); + } + + // Unary + { + let x = string(); + let x: &String = &x; + (*x).as_ptr(); + (&[0u8]).as_ptr(); + (&string()).as_ptr(); // False negative + (*&string()).as_ptr(); // False negative + } + + // Lit + "hello".as_ptr(); + + // Cast + // impossible + + // Type + // impossible + + // DropTemps + // impossible + + // Let + // impossible + + // If + { + (if true { String::new() } else { "hello".into() }).as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + } + + // Loop + { + (loop { + break String::new(); + }) + .as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + } + + // Match + { + match string() { + s => s, + } + .as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + } + + // Closure + // impossible + + // Block + { string() }.as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + + // Assign, AssignOp + // impossible + + // Field + { + Wrapper(string()).0.as_ptr(); // False negative + let x = Wrapper(string()); + x.0.as_ptr(); + } + + // Index + { + vec![string()][0].as_ptr(); // False negative + let x = vec![string()]; + x[0].as_ptr(); + } + + // AddrOf, InlineAsm, OffsetOf + // impossible + + // Break, Continue, Ret + // are ! + + // Become, Yield + // unstable, are ! + + // Repeat + [0u8; 100].as_ptr(); + [const { String::new() }; 100].as_ptr(); + + // Struct + // Cannot test this without access to private fields of the linted types. + + // Err + // impossible + + // Macro + vec![0u8].as_ptr(); + //~^ ERROR getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer +} diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr new file mode 100644 index 0000000000000..d46b2375fdf73 --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr @@ -0,0 +1,99 @@ +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:21:14 + | +LL | string().as_ptr(); + | -------- ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html +note: the lint level is defined here + --> $DIR/temporaries.rs:2:9 + | +LL | #![deny(dangling_pointers_from_temporaries)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:25:25 + | +LL | "hello".to_string().as_ptr(); + | ------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:32:26 + | +LL | (string() + "hello").as_ptr(); + | -------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:68:61 + | +LL | (if true { String::new() } else { "hello".into() }).as_ptr(); + | --------------------------------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:77:10 + | +LL | / (loop { +LL | | break String::new(); +LL | | }) + | |__________- this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime +LL | .as_ptr(); + | ^^^^^^ this pointer will immediately be invalid + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:86:10 + | +LL | / match string() { +LL | | s => s, +LL | | } + | |_________- this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime +LL | .as_ptr(); + | ^^^^^^ this pointer will immediately be invalid + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/temporaries.rs:94:18 + | +LL | { string() }.as_ptr(); + | ------------ ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer + --> $DIR/temporaries.rs:134:15 + | +LL | vec![0u8].as_ptr(); + | --------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Vec<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: aborting due to 8 previous errors + diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/types.rs b/tests/ui/lint/dangling-pointers-from-temporaries/types.rs new file mode 100644 index 0000000000000..80cb7d056489c --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/types.rs @@ -0,0 +1,52 @@ +#![deny(dangling_pointers_from_temporaries)] + +use std::cell::Cell; +use std::ffi::{CStr, CString}; +use std::mem::MaybeUninit; + +struct AsPtrFake; + +impl AsPtrFake { + fn as_ptr(&self) -> *const () { + std::ptr::null() + } +} + +fn declval<T>() -> T { + loop {} +} + +fn main() { + declval::<CString>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `CString` will result in a dangling pointer + declval::<String>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `String` will result in a dangling pointer + declval::<Vec<u8>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer + declval::<Box<CString>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<CString>` will result in a dangling pointer + declval::<Box<[u8]>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<[u8]>` will result in a dangling pointer + declval::<Box<str>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<str>` will result in a dangling pointer + declval::<Box<CStr>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<CStr>` will result in a dangling pointer + declval::<[u8; 10]>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `[u8; 10]` will result in a dangling pointer + declval::<Box<[u8; 10]>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<[u8; 10]>` will result in a dangling pointer + declval::<Box<Vec<u8>>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<Vec<u8>>` will result in a dangling pointer + declval::<Box<String>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<String>` will result in a dangling pointer + declval::<Box<Box<Box<Box<[u8]>>>>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Box<Box<Box<Box<[u8]>>>>` will result in a dangling pointer + declval::<Cell<u8>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Cell<u8>` will result in a dangling pointer + declval::<MaybeUninit<u8>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `MaybeUninit<u8>` will result in a dangling pointer + declval::<Vec<AsPtrFake>>().as_ptr(); + //~^ ERROR getting a pointer from a temporary `Vec<AsPtrFake>` will result in a dangling pointer + declval::<Box<AsPtrFake>>().as_ptr(); + declval::<AsPtrFake>().as_ptr(); +} diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr new file mode 100644 index 0000000000000..cb9c9702420b8 --- /dev/null +++ b/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr @@ -0,0 +1,172 @@ +error: getting a pointer from a temporary `CString` will result in a dangling pointer + --> $DIR/types.rs:20:26 + | +LL | declval::<CString>().as_ptr(); + | -------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html +note: the lint level is defined here + --> $DIR/types.rs:1:9 + | +LL | #![deny(dangling_pointers_from_temporaries)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: getting a pointer from a temporary `String` will result in a dangling pointer + --> $DIR/types.rs:22:25 + | +LL | declval::<String>().as_ptr(); + | ------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Vec<u8>` will result in a dangling pointer + --> $DIR/types.rs:24:26 + | +LL | declval::<Vec<u8>>().as_ptr(); + | -------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Vec<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<CString>` will result in a dangling pointer + --> $DIR/types.rs:26:31 + | +LL | declval::<Box<CString>>().as_ptr(); + | ------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<CString>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<CString>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<[u8]>` will result in a dangling pointer + --> $DIR/types.rs:28:28 + | +LL | declval::<Box<[u8]>>().as_ptr(); + | ---------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<[u8]>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<[u8]>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<str>` will result in a dangling pointer + --> $DIR/types.rs:30:27 + | +LL | declval::<Box<str>>().as_ptr(); + | --------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<str>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<str>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<CStr>` will result in a dangling pointer + --> $DIR/types.rs:32:28 + | +LL | declval::<Box<CStr>>().as_ptr(); + | ---------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<CStr>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<CStr>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `[u8; 10]` will result in a dangling pointer + --> $DIR/types.rs:34:27 + | +LL | declval::<[u8; 10]>().as_ptr(); + | --------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `[u8; 10]` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `[u8; 10]` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<[u8; 10]>` will result in a dangling pointer + --> $DIR/types.rs:36:32 + | +LL | declval::<Box<[u8; 10]>>().as_ptr(); + | -------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<[u8; 10]>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<[u8; 10]>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<Vec<u8>>` will result in a dangling pointer + --> $DIR/types.rs:38:31 + | +LL | declval::<Box<Vec<u8>>>().as_ptr(); + | ------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<Vec<u8>>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<Vec<u8>>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<String>` will result in a dangling pointer + --> $DIR/types.rs:40:30 + | +LL | declval::<Box<String>>().as_ptr(); + | ------------------------ ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<String>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<String>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Box<Box<Box<Box<[u8]>>>>` will result in a dangling pointer + --> $DIR/types.rs:42:43 + | +LL | declval::<Box<Box<Box<Box<[u8]>>>>>().as_ptr(); + | ------------------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Box<Box<Box<Box<[u8]>>>>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<Box<Box<Box<[u8]>>>>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Cell<u8>` will result in a dangling pointer + --> $DIR/types.rs:44:27 + | +LL | declval::<Cell<u8>>().as_ptr(); + | --------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Cell<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Cell<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `MaybeUninit<u8>` will result in a dangling pointer + --> $DIR/types.rs:46:34 + | +LL | declval::<MaybeUninit<u8>>().as_ptr(); + | ---------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `MaybeUninit<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `MaybeUninit<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: getting a pointer from a temporary `Vec<AsPtrFake>` will result in a dangling pointer + --> $DIR/types.rs:48:33 + | +LL | declval::<Vec<AsPtrFake>>().as_ptr(); + | --------------------------- ^^^^^^ this pointer will immediately be invalid + | | + | this `Vec<AsPtrFake>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | + = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<AsPtrFake>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html + +error: aborting due to 15 previous errors +