Skip to content

Commit

Permalink
Do not apply #[do_not_recommend] if the feature flag is not set
Browse files Browse the repository at this point in the history
This commit adds additional checks for the feature flag as apparently it
is possible to use this on a beta compiler without feature flags. This
PR might be a candidate for backporting.

Reported in the bevy issue tracker: bevyengine/bevy#14591 (comment)
  • Loading branch information
weiznich committed Aug 5, 2024
1 parent 176e545 commit b36d15e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&self,
obligation: &mut PredicateObligation<'tcx>,
) -> bool {
if !self.tcx.features().do_not_recommend {
return false;
}

let mut base_cause = obligation.cause.code().clone();
let mut applied_do_not_recommend = false;
loop {
Expand Down Expand Up @@ -1782,10 +1786,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.into_iter()
.cloned()
.filter(|cand| {
!self.tcx.has_attrs_with_path(
cand.impl_def_id,
&[sym::diagnostic, sym::do_not_recommend],
)
!self.tcx.features().do_not_recommend
|| !self.tcx.has_attrs_with_path(
cand.impl_def_id,
&[sym::diagnostic, sym::do_not_recommend],
)
})
.collect::<Vec<_>>();

Expand All @@ -1803,9 +1808,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.all_impls(def_id)
// ignore `do_not_recommend` items
.filter(|def_id| {
!self
.tcx
.has_attrs_with_path(*def_id, &[sym::diagnostic, sym::do_not_recommend])
!self.tcx.features().do_not_recommend
|| !self
.tcx
.has_attrs_with_path(*def_id, &[sym::diagnostic, sym::do_not_recommend])
})
// Ignore automatically derived impls and `!Trait` impls.
.filter_map(|def_id| self.tcx.impl_trait_header(def_id))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![allow(unknown_or_malformed_diagnostic_attributes)]

trait Foo {}

#[diagnostic::do_not_recommend]
impl<A> Foo for (A,) {}

#[diagnostic::do_not_recommend]
impl<A, B> Foo for (A, B) {}

#[diagnostic::do_not_recommend]
impl<A, B, C> Foo for (A, B, C) {}

impl Foo for i32 {}

fn check(a: impl Foo) {}

fn main() {
check(());
//~^ ERROR the trait bound `(): Foo` is not satisfied
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0277]: the trait bound `(): Foo` is not satisfied
--> $DIR/do_not_apply_attribute_without_feature_flag.rs:19:11
|
LL | check(());
| ----- ^^ the trait `Foo` is not implemented for `()`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Foo`:
(A, B)
(A, B, C)
(A,)
note: required by a bound in `check`
--> $DIR/do_not_apply_attribute_without_feature_flag.rs:16:18
|
LL | fn check(a: impl Foo) {}
| ^^^ required by this bound in `check`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit b36d15e

Please sign in to comment.