use hir::HirDisplay; use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; // Diagnostic: unimplemented-trait // // This diagnostic is triggered when rust-analyzer cannot infer some type. pub(crate) fn unimplemented_trait<'db>( ctx: &DiagnosticsContext<'_, 'db>, d: &hir::UnimplementedTrait<'db>, ) -> Diagnostic { let message = match &d.root_trait_predicate { Some(root_predicate) if *root_predicate != d.trait_predicate => format!( "the trait bound `{}` is not satisfied\n\ required by the bound `{}`\n", d.trait_predicate.display(ctx.db(), ctx.display_target), root_predicate.display(ctx.db(), ctx.display_target), ), _ => format!( "the trait bound `{}` is not satisfied", d.trait_predicate.display(ctx.db(), ctx.display_target), ), }; Diagnostic::new_with_syntax_node_ptr( ctx, DiagnosticCode::RustcHardError("E0277"), message, d.span.map(Into::into), ) } #[cfg(test)] mod tests { use crate::tests::check_diagnostics; #[test] fn smoke_test() { check_diagnostics( r#" trait Trait {} impl Trait for [T; N] {} fn foo(_v: impl Trait) {} fn bar() { foo(1); // ^^^ error: the trait bound `i32: Trait` is not satisfied foo([1]); // ^^^ error: the trait bound `i32: Trait` is not satisfied // | required by the bound `[i32; 1]: Trait` } "#, ); } #[test] fn async_closure_does_not_trigger() { check_diagnostics( r#" //- minicore: async_fn fn spawn_in(_f: AsyncFn) where AsyncFn: AsyncFnOnce(), { } fn foo() { spawn_in(async move || {}); } "#, ); } }