Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs')
-rw-r--r--crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs112
1 files changed, 112 insertions, 0 deletions
diff --git a/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs b/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs
new file mode 100644
index 0000000000..438dd2fdcb
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs
@@ -0,0 +1,112 @@
+use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
+
+// Diagnostic: elided-lifetimes-in-path
+//
+// This diagnostic is triggered when lifetimes are elided in paths. It is a lint only for some cases,
+// and a hard error for others.
+pub(crate) fn elided_lifetimes_in_path(
+ ctx: &DiagnosticsContext<'_>,
+ d: &hir::ElidedLifetimesInPath,
+) -> Diagnostic {
+ if d.hard_error {
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcHardError("E0726"),
+ "implicit elided lifetime not allowed here",
+ d.generics_or_segment.map(Into::into),
+ )
+ .experimental()
+ } else {
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcLint("elided_lifetimes_in_paths"),
+ "hidden lifetime parameters in types are deprecated",
+ d.generics_or_segment.map(Into::into),
+ )
+ .experimental()
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::check_diagnostics;
+
+ #[test]
+ fn fn_() {
+ check_diagnostics(
+ r#"
+#![warn(elided_lifetimes_in_paths)]
+
+struct Foo<'a>(&'a ());
+
+fn foo(_: Foo) {}
+ // ^^^ warn: hidden lifetime parameters in types are deprecated
+ "#,
+ );
+ check_diagnostics(
+ r#"
+#![warn(elided_lifetimes_in_paths)]
+
+struct Foo<'a>(&'a ());
+
+fn foo(_: Foo<'_>) -> Foo { loop {} }
+ // ^^^ warn: hidden lifetime parameters in types are deprecated
+ "#,
+ );
+ }
+
+ #[test]
+ fn async_fn() {
+ check_diagnostics(
+ r#"
+struct Foo<'a>(&'a ());
+
+async fn foo(_: Foo) {}
+ // ^^^ error: implicit elided lifetime not allowed here
+ "#,
+ );
+ check_diagnostics(
+ r#"
+#![warn(elided_lifetimes_in_paths)]
+
+struct Foo<'a>(&'a ());
+
+fn foo(_: Foo<'_>) -> Foo { loop {} }
+ // ^^^ warn: hidden lifetime parameters in types are deprecated
+ "#,
+ );
+ }
+
+ #[test]
+ fn no_error_when_explicitly_elided() {
+ check_diagnostics(
+ r#"
+#![warn(elided_lifetimes_in_paths)]
+
+struct Foo<'a>(&'a ());
+trait Trait<'a> {}
+
+fn foo(_: Foo<'_>) -> Foo<'_> { loop {} }
+async fn bar(_: Foo<'_>) -> Foo<'_> { loop {} }
+impl Foo<'_> {}
+impl Trait<'_> for Foo<'_> {}
+ "#,
+ );
+ }
+
+ #[test]
+ fn impl_() {
+ check_diagnostics(
+ r#"
+struct Foo<'a>(&'a ());
+trait Trait<'a> {}
+
+impl Foo {}
+ // ^^^ error: implicit elided lifetime not allowed here
+
+impl Trait for Foo<'_> {}
+ // ^^^^^ error: implicit elided lifetime not allowed here
+ "#,
+ );
+ }
+}