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
+