//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.
-use crate::{declare_lint, declare_lint_pass, FutureBreakage};
+use crate::{declare_lint, declare_lint_pass, FutureBreakage, FutureIncompatibilityReason};
use rustc_span::edition::Edition;
declare_lint! {
"applying forbid to lint-groups",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>",
- edition: None,
};
}
"ill-formed attribute inputs that were previously accepted and used in practice",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
- edition: None,
};
crate_level_only
}
"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #68585 <https://github.com/rust-lang/rust/issues/68585>",
- edition: None,
};
}
"constant evaluation encountered erroneous expression",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #71800 <https://github.com/rust-lang/rust/issues/71800>",
- edition: None,
};
report_in_external_macro
}
"detect private items in public interfaces not caught by the old implementation",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
- edition: None,
};
}
"detect public re-exports of private extern crates",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
- edition: None,
};
}
"type parameter default erroneously allowed in invalid location",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
- edition: None,
};
}
"detects unaligned references to fields of packed structs",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>",
- edition: None,
};
report_in_external_macro
}
"patterns in functions without body were erroneously allowed",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
- edition: None,
};
}
"detects missing fragment specifiers in unused `macro_rules!` patterns",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
- edition: None,
};
}
"detects generic lifetime arguments in path segments with late bound lifetime parameters",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
- edition: None,
};
}
"trait-object types were treated as different depending on marker-trait order",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
- edition: None,
};
}
"distinct impls distinguished only by the leak-check code",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #56105 <https://github.com/rust-lang/rust/issues/56105>",
- edition: None,
};
}
"raw pointer to an inference variable",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
- edition: Some(Edition::Edition2018),
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
};
}
"suggest using `dyn Trait` for trait objects",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #80165 <https://github.com/rust-lang/rust/issues/80165>",
- edition: Some(Edition::Edition2021),
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
};
}
instead of `crate`, `self`, or an extern crate name",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>",
- edition: Some(Edition::Edition2018),
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
};
}
"floating-point literals cannot be used in patterns",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
- edition: None,
};
}
"detects name collision with an existing but unstable method",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
- edition: None,
// Note: this item represents future incompatibility of all unstable functions in the
// standard library, and thus should never be removed or changed to an error.
};
"checks the object safety of where clauses",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
- edition: None,
};
}
"detects proc macro derives using inaccessible names from parent modules",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #83583 <https://github.com/rust-lang/rust/issues/83583>",
- edition: None,
};
}
cannot be referred to by absolute paths",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
- edition: None,
};
crate_level_only
}
"constant used in pattern contains value of non-structural-match type in a field or a variant",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
- edition: None,
};
}
"pointers are not structural-match",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/70861>",
- edition: None,
};
}
expression contains values of non-structural-match types",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #73448 <https://github.com/rust-lang/rust/issues/73448>",
- edition: None,
};
}
"ambiguous associated items",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
- edition: None,
};
}
"reservation of a two-phased borrow conflicts with other shared borrows",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>",
- edition: None,
};
}
"a feature gate that doesn't break dependent crates",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
- edition: None,
};
}
"a C-like enum implementing Drop is cast",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #73333 <https://github.com/rust-lang/rust/issues/73333>",
- edition: None,
};
}
"detects a generic constant is used in a type without a emitting a warning",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #76200 <https://github.com/rust-lang/rust/issues/76200>",
- edition: None,
};
}
"uninhabited static",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #74840 <https://github.com/rust-lang/rust/issues/74840>",
- edition: None,
};
}
"unsupported naked function definitions",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #32408 <https://github.com/rust-lang/rust/issues/32408>",
- edition: None,
};
}
"trailing semicolon in macro body used as expression",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
- edition: None,
};
}
PROC_MACRO_BACK_COMPAT,
OR_PATTERNS_BACK_COMPAT,
LARGE_ASSIGNMENTS,
+ FUTURE_PRELUDE_COLLISION,
+ RESERVED_PREFIX,
]
}
"detects invalid `#[doc(...)]` attributes",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>",
- edition: None,
};
}
"detects usage of old versions of certain proc-macro crates",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>",
- edition: None,
future_breakage: Some(FutureBreakage {
date: None
})
"detects usage of old versions of or-patterns",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #84869 <https://github.com/rust-lang/rust/issues/84869>",
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
+ };
+}
+
+declare_lint! {
+ /// The `future_prelude_collision` lint detects the usage of trait methods which are ambiguous
+ /// with traits added to the prelude in future editions.
+ ///
+ /// ### Example
+ ///
+ /// ```rust,compile_fail
+ /// #![deny(future_prelude_collision)]
+ ///
+ /// trait Foo {
+ /// fn try_into(self) -> Result<String, !>;
+ /// }
+ ///
+ /// impl Foo for &str {
+ /// fn try_into(self) -> Result<String, !> {
+ /// Ok(String::from(self))
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let x: String = "3".try_into().unwrap();
+ /// // ^^^^^^^^
+ /// // This call to try_into matches both Foo:try_into and TryInto::try_into as
+ /// // `TryInto` has been added to the Rust prelude in 2021 edition.
+ /// println!("{}", x);
+ /// }
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// In Rust 2021, one of the important introductions is the [prelude changes], which add
+ /// `TryFrom`, `TryInto`, and `FromIterator` into the standard library's prelude. Since this
+ /// results in an ambiguity as to which method/function to call when an existing `try_into`
+ /// method is called via dot-call syntax or a `try_from`/`from_iter` associated function
+ /// is called directly on a type.
+ ///
+ /// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes
+ pub FUTURE_PRELUDE_COLLISION,
+ Allow,
+ "detects the usage of trait methods which are ambiguous with traits added to the \
+ prelude in future editions",
+ @future_incompatible = FutureIncompatibleInfo {
+ reference: "issue #85684 <https://github.com/rust-lang/rust/issues/85684>",
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
+ };
+}
+
+declare_lint! {
+ /// The `reserved_prefix` lint detects identifiers that will be parsed as a
+ /// prefix instead in Rust 2021.
+ ///
+ /// ### Example
+ ///
+ /// ```rust,compile_fail
+ /// #![deny(reserved_prefix)]
+ ///
+ /// macro_rules! m {
+ /// (z $x:expr) => ();
+ /// }
+ ///
+ /// m!(z"hey");
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// In Rust 2015 and 2018, `z"hey"` is two tokens: the identifier `z`
+ /// followed by the string literal `"hey"`. In Rust 2021, the `z` is
+ /// considered a prefix for `"hey"`.
+ ///
+ /// This lint suggests to add whitespace between the `z` and `"hey"` tokens
+ /// to keep them separated in Rust 2021.
+ pub RESERVED_PREFIX,
+ Allow,
+ "identifiers that will be parsed as a prefix in Rust 2021",
+ @future_incompatible = FutureIncompatibleInfo {
+ reference: "issue #84978 <https://github.com/rust-lang/rust/issues/84978>",
edition: Some(Edition::Edition2021),
};
+ crate_level_only
}