]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide/src/inlay_hints/adjustment.rs
Auto merge of #13806 - WaffleLapkin:typed_blÄhaj, r=Veykril
[rust.git] / crates / ide / src / inlay_hints / adjustment.rs
index 3fa2ed3307d5c92367876f25049feba044b9b600..b2bec10d05d7bd62b299850efce931a462215d3e 100644 (file)
@@ -1,3 +1,8 @@
+//! Implementation of "adjustment" inlay hints:
+//! ```no_run
+//! let _: u32  = /* <never-to-any> */ loop {};
+//! let _: &u32 = /* &* */ &mut 0;
+//! ```
 use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics};
 use ide_db::RootDatabase;
 
@@ -54,8 +59,12 @@ pub(super) fn hints(
         });
     }
     for adjustment in adjustments.into_iter().rev() {
+        if adjustment.source == adjustment.target {
+            continue;
+        }
+
         // FIXME: Add some nicer tooltips to each of these
-        let text = match adjustment {
+        let text = match adjustment.kind {
             Adjust::NeverToAny if config.adjustment_hints == AdjustmentHints::Always => {
                 "<never-to-any>"
             }
@@ -100,3 +109,128 @@ pub(super) fn hints(
     }
     Some(())
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        inlay_hints::tests::{check_with_config, DISABLED_CONFIG},
+        AdjustmentHints, InlayHintsConfig,
+    };
+
+    #[test]
+    fn adjustment_hints() {
+        check_with_config(
+            InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
+            r#"
+//- minicore: coerce_unsized
+fn main() {
+    let _: u32         = loop {};
+                       //^^^^^^^<never-to-any>
+    let _: &u32        = &mut 0;
+                       //^^^^^^&
+                       //^^^^^^*
+    let _: &mut u32    = &mut 0;
+                       //^^^^^^&mut $
+                       //^^^^^^*
+    let _: *const u32  = &mut 0;
+                       //^^^^^^&raw const $
+                       //^^^^^^*
+    let _: *mut u32    = &mut 0;
+                       //^^^^^^&raw mut $
+                       //^^^^^^*
+    let _: fn()        = main;
+                       //^^^^<fn-item-to-fn-pointer>
+    let _: unsafe fn() = main;
+                       //^^^^<safe-fn-pointer-to-unsafe-fn-pointer>
+                       //^^^^<fn-item-to-fn-pointer>
+    let _: unsafe fn() = main as fn();
+                       //^^^^^^^^^^^^<safe-fn-pointer-to-unsafe-fn-pointer>
+    let _: fn()        = || {};
+                       //^^^^^<closure-to-fn-pointer>
+    let _: unsafe fn() = || {};
+                       //^^^^^<closure-to-unsafe-fn-pointer>
+    let _: *const u32  = &mut 0u32 as *mut u32;
+                       //^^^^^^^^^^^^^^^^^^^^^<mut-ptr-to-const-ptr>
+    let _: &mut [_]    = &mut [0; 0];
+                       //^^^^^^^^^^^<unsize>
+                       //^^^^^^^^^^^&mut $
+                       //^^^^^^^^^^^*
+
+    Struct.consume();
+    Struct.by_ref();
+  //^^^^^^(
+  //^^^^^^&
+  //^^^^^^)
+    Struct.by_ref_mut();
+  //^^^^^^(
+  //^^^^^^&mut $
+  //^^^^^^)
+
+    (&Struct).consume();
+   //^^^^^^^*
+    (&Struct).by_ref();
+
+    (&mut Struct).consume();
+   //^^^^^^^^^^^*
+    (&mut Struct).by_ref();
+   //^^^^^^^^^^^&
+   //^^^^^^^^^^^*
+    (&mut Struct).by_ref_mut();
+
+    // Check that block-like expressions don't duplicate hints
+    let _: &mut [u32] = (&mut []);
+                       //^^^^^^^<unsize>
+                       //^^^^^^^&mut $
+                       //^^^^^^^*
+    let _: &mut [u32] = { &mut [] };
+                        //^^^^^^^<unsize>
+                        //^^^^^^^&mut $
+                        //^^^^^^^*
+    let _: &mut [u32] = unsafe { &mut [] };
+                               //^^^^^^^<unsize>
+                               //^^^^^^^&mut $
+                               //^^^^^^^*
+    let _: &mut [u32] = if true {
+        &mut []
+      //^^^^^^^<unsize>
+      //^^^^^^^&mut $
+      //^^^^^^^*
+    } else {
+        loop {}
+      //^^^^^^^<never-to-any>
+    };
+    let _: &mut [u32] = match () { () => &mut [] }
+                                       //^^^^^^^<unsize>
+                                       //^^^^^^^&mut $
+                                       //^^^^^^^*
+}
+
+#[derive(Copy, Clone)]
+struct Struct;
+impl Struct {
+    fn consume(self) {}
+    fn by_ref(&self) {}
+    fn by_ref_mut(&mut self) {}
+}
+trait Trait {}
+impl Trait for Struct {}
+"#,
+        )
+    }
+
+    #[test]
+    fn never_to_never_is_never_shown() {
+        check_with_config(
+            InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
+            r#"
+fn never() -> ! {
+    return loop {};
+}
+
+fn or_else() {
+    let () = () else { return };
+}
+            "#,
+        )
+    }
+}