Merge pull request #19973 from Veykril/push-ppltxvqvqmkk

fix: Hide dyn inlay hints for incomplete `impl`s
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index b41ff02..1e8859a 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -1245,7 +1245,7 @@
 // Crate authors can opt their type out of completions in some cases.
 // This is done with the `#[rust_analyzer::completions(...)]` attribute.
 //
-// All completeable things support `#[rust_analyzer::completions(ignore_flyimport)]`,
+// All completable things support `#[rust_analyzer::completions(ignore_flyimport)]`,
 // which causes the thing to get excluded from flyimport completion. It will still
 // be completed when in scope. This is analogous to the setting `rust-analyzer.completion.autoimport.exclude`
 // with `"type": "always"`.
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs
index ed8d8dc..4809494 100644
--- a/crates/hir-ty/src/dyn_compatibility.rs
+++ b/crates/hir-ty/src/dyn_compatibility.rs
@@ -122,7 +122,7 @@
     res
 }
 
-fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
+pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
     let krate = def.module(db).krate();
     let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else {
         return false;
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs
index bb4aaf7..a3ed399 100644
--- a/crates/hir-ty/src/generics.rs
+++ b/crates/hir-ty/src/generics.rs
@@ -229,7 +229,7 @@
     }
 
     /// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
-    pub(crate) fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
+    pub fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
         Substitution::from_iter(
             Interner,
             self.iter_id().map(|id| match id {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index e8218cf..969fd3e 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -846,7 +846,7 @@
                     )
                 }
 
-                let missing: Vec<_> = required_items
+                let mut missing: Vec<_> = required_items
                     .filter(|(name, id)| {
                         !impl_assoc_items_scratch.iter().any(|(impl_name, impl_item)| {
                             discriminant(impl_item) == discriminant(id) && impl_name == name
@@ -854,6 +854,38 @@
                     })
                     .map(|(name, item)| (name.clone(), AssocItem::from(*item)))
                     .collect();
+
+                if !missing.is_empty() {
+                    let self_ty = db.impl_self_ty(impl_def.id).substitute(
+                        Interner,
+                        &hir_ty::generics::generics(db, impl_def.id.into()).placeholder_subst(db),
+                    );
+                    let self_ty = if let TyKind::Alias(AliasTy::Projection(projection)) =
+                        self_ty.kind(Interner)
+                    {
+                        db.normalize_projection(
+                            projection.clone(),
+                            db.trait_environment(impl_def.id.into()),
+                        )
+                    } else {
+                        self_ty
+                    };
+                    let self_ty_is_guaranteed_unsized = matches!(
+                        self_ty.kind(Interner),
+                        TyKind::Dyn(..) | TyKind::Slice(..) | TyKind::Str
+                    );
+                    if self_ty_is_guaranteed_unsized {
+                        missing.retain(|(_, assoc_item)| {
+                            let assoc_item = match *assoc_item {
+                                AssocItem::Function(it) => it.id.into(),
+                                AssocItem::Const(it) => it.id.into(),
+                                AssocItem::TypeAlias(it) => it.id.into(),
+                            };
+                            !hir_ty::dyn_compatibility::generics_require_sized_self(db, assoc_item)
+                        });
+                    }
+                }
+
                 if !missing.is_empty() {
                     acc.push(
                         TraitImplMissingAssocItems {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 4a2e8e3..953e2e7 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -159,13 +159,13 @@
     macro_call_cache: RefCell<FxHashMap<InFile<ast::MacroCall>, MacroCallId>>,
 }
 
-impl<DB> fmt::Debug for Semantics<'_, DB> {
+impl<DB: ?Sized> fmt::Debug for Semantics<'_, DB> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "Semantics {{ ... }}")
     }
 }
 
-impl<'db, DB> ops::Deref for Semantics<'db, DB> {
+impl<'db, DB: ?Sized> ops::Deref for Semantics<'db, DB> {
     type Target = SemanticsImpl<'db>;
 
     fn deref(&self) -> &Self::Target {
@@ -173,12 +173,28 @@
     }
 }
 
+// Note: while this variant of `Semantics<'_, _>` might seem unused, as it does not
+// find actual use within the rust-analyzer project itself, it exists to enable the use
+// within e.g. tracked salsa functions in third-party crates that build upon `ra_ap_hir`.
+impl Semantics<'_, dyn HirDatabase> {
+    /// Creates an instance that's weakly coupled to its underlying database type.
+    pub fn new_dyn(db: &'_ dyn HirDatabase) -> Semantics<'_, dyn HirDatabase> {
+        let impl_ = SemanticsImpl::new(db);
+        Semantics { db, imp: impl_ }
+    }
+}
+
 impl<DB: HirDatabase> Semantics<'_, DB> {
+    /// Creates an instance that's strongly coupled to its underlying database type.
     pub fn new(db: &DB) -> Semantics<'_, DB> {
         let impl_ = SemanticsImpl::new(db);
         Semantics { db, imp: impl_ }
     }
+}
 
+// Note: We take `DB` as `?Sized` here in order to support type-erased
+// use of `Semantics` via `Semantics<'_, dyn HirDatabase>`:
+impl<DB: HirDatabase + ?Sized> Semantics<'_, DB> {
     pub fn hir_file_for(&self, syntax_node: &SyntaxNode) -> HirFileId {
         self.imp.find_file(syntax_node).file_id
     }
diff --git a/crates/ide-db/src/generated/lints.rs b/crates/ide-db/src/generated/lints.rs
index f9ff392..de8a429 100644
--- a/crates/ide-db/src/generated/lints.rs
+++ b/crates/ide-db/src/generated/lints.rs
@@ -4458,20 +4458,6 @@
         deny_since: None,
     },
     Lint {
-        label: "const_eq_ignore_ascii_case",
-        description: r##"# `const_eq_ignore_ascii_case`
-
-The tracking issue for this feature is: [#131719]
-
-[#131719]: https://github.com/rust-lang/rust/issues/131719
-
-------------------------
-"##,
-        default_severity: Severity::Allow,
-        warn_since: None,
-        deny_since: None,
-    },
-    Lint {
         label: "const_eval_select",
         description: r##"# `const_eval_select`
 
diff --git a/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
index 87c9397..bf7ddda 100644
--- a/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
+++ b/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -135,6 +135,7 @@
                         "JSON syntax is not valid as a Rust item",
                         FileRange { file_id: vfs_file_id, range },
                     )
+                    .stable()
                     .with_fixes(Some(vec![{
                         let mut scb = SourceChangeBuilder::new(vfs_file_id);
                         let scope = scb.make_import_scope_mut(import_scope);
diff --git a/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs b/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs
index fa7ba90..0e18ce9 100644
--- a/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs
+++ b/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs
@@ -127,4 +127,33 @@
 "#,
         )
     }
+
+    #[test]
+    fn impl_sized_for_unsized() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+trait Trait {
+    type Item
+    where
+        Self: Sized;
+
+    fn item()
+    where
+        Self: Sized;
+}
+
+trait OtherTrait {}
+
+impl Trait for () {
+    type Item = ();
+    fn item() {}
+}
+
+// Items with Self: Sized bound not required to be implemented for unsized types.
+impl Trait for str {}
+impl Trait for dyn OtherTrait {}
+ "#,
+        )
+    }
 }
diff --git a/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs b/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs
index 6820e4b..2a72e50 100644
--- a/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs
+++ b/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs
@@ -31,6 +31,7 @@
         TokenTree::from(Literal::byte_string(b"byte_string")),
         TokenTree::from(Literal::character('c')),
         TokenTree::from(Literal::string("string")),
+        TokenTree::from(Literal::string("-string")),
         TokenTree::from(Literal::c_string(c"cstring")),
         // as of 2022-07-21, there's no method on `Literal` to build a raw
         // string or a raw byte string
diff --git a/crates/proc-macro-srv/src/server_impl.rs b/crates/proc-macro-srv/src/server_impl.rs
index ad28599..dd576f2 100644
--- a/crates/proc-macro-srv/src/server_impl.rs
+++ b/crates/proc-macro-srv/src/server_impl.rs
@@ -199,37 +199,29 @@
         }
 
         bridge::TokenTree::Literal(literal) => {
-            let token_trees =
-                if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
-                    let punct = tt::Punct {
-                        spacing: tt::Spacing::Alone,
-                        span: literal.span,
-                        char: '-' as char,
-                    };
-                    let leaf: tt::Leaf<Span> = tt::Leaf::from(punct);
-                    let minus_tree = tt::TokenTree::from(leaf);
-
-                    let literal = tt::Literal {
-                        symbol: Symbol::intern(symbol),
-                        suffix: literal.suffix,
-                        span: literal.span,
-                        kind: literal_kind_to_internal(literal.kind),
-                    };
-                    let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
-                    let tree = tt::TokenTree::from(leaf);
-                    vec![minus_tree, tree]
-                } else {
-                    let literal = tt::Literal {
-                        symbol: literal.symbol,
-                        suffix: literal.suffix,
-                        span: literal.span,
-                        kind: literal_kind_to_internal(literal.kind),
-                    };
-
-                    let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
-                    let tree = tt::TokenTree::from(leaf);
-                    vec![tree]
-                };
+            let mut token_trees = Vec::new();
+            let mut symbol = literal.symbol;
+            if matches!(
+                literal.kind,
+                proc_macro::bridge::LitKind::Integer | proc_macro::bridge::LitKind::Float
+            ) && symbol.as_str().starts_with('-')
+            {
+                token_trees.push(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
+                    spacing: tt::Spacing::Alone,
+                    span: literal.span,
+                    char: '-' as char,
+                })));
+                symbol = Symbol::intern(&symbol.as_str()[1..]);
+            }
+            let literal = tt::Literal {
+                symbol,
+                suffix: literal.suffix,
+                span: literal.span,
+                kind: literal_kind_to_internal(literal.kind),
+            };
+            let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
+            let tree = tt::TokenTree::from(leaf);
+            token_trees.push(tree);
             TokenStream { token_trees }
         }
 
diff --git a/crates/proc-macro-srv/src/tests/mod.rs b/crates/proc-macro-srv/src/tests/mod.rs
index 3a6ce63..d1ea89d 100644
--- a/crates/proc-macro-srv/src/tests/mod.rs
+++ b/crates/proc-macro-srv/src/tests/mod.rs
@@ -244,6 +244,7 @@
               LITERAL ByteStr byte_string 1
               LITERAL Char c 1
               LITERAL Str string 1
+              LITERAL Str -string 1
               LITERAL CStr cstring 1
               LITERAL Float 3.14f64 1
               PUNCH   - [alone] 1
@@ -266,6 +267,7 @@
               LITERAL ByteStr byte_string 42:2@0..100#ROOT2024
               LITERAL Char c 42:2@0..100#ROOT2024
               LITERAL Str string 42:2@0..100#ROOT2024
+              LITERAL Str -string 42:2@0..100#ROOT2024
               LITERAL CStr cstring 42:2@0..100#ROOT2024
               LITERAL Float 3.14f64 42:2@0..100#ROOT2024
               PUNCH   - [alone] 42:2@0..100#ROOT2024
diff --git a/docs/book/README.md b/docs/book/README.md
index 464ea02..0a3161f 100644
--- a/docs/book/README.md
+++ b/docs/book/README.md
@@ -19,7 +19,7 @@
 
 ## Making updates
 
-While not required, installing the mdbook binary can be helfpul in order to see the changes.
+While not required, installing the mdbook binary can be helpful in order to see the changes.
 Start with the mdbook [User Guide](https://rust-lang.github.io/mdBook/guide/installation.html) to familiarize yourself with the tool.
 
 ## Generated documentation
diff --git a/rust-version b/rust-version
index 5b47d1b..af0dd5c 100644
--- a/rust-version
+++ b/rust-version
@@ -1 +1 @@
-a8e4c68dcb4dc1e48a0db294c5323cab0227fcb9
+7c10378e1fee5ddc6573b916aeb884ab10e0de17