Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't report on_unimplemented message for negative traits #131701

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
continue;
}
unimplemented_traits.entry(p.trait_ref.def_id).or_insert((
predicate.kind().rebind(p.trait_ref),
predicate.kind().rebind(p),
Obligation {
cause: cause.clone(),
param_env: self.param_env,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
notes,
parent_label,
append_const_msg,
} = self.on_unimplemented_note(main_trait_ref, o, &mut long_ty_file);
} = self.on_unimplemented_note(main_trait_predicate, o, &mut long_ty_file);

let have_alt_message = message.is_some() || label.is_some();
let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::LintDiagnostic;
use rustc_middle::bug;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{self, GenericArgsRef, GenericParamDefKind, TyCtxt};
use rustc_middle::ty::{self, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, TyCtxt};
use rustc_parse_format::{ParseMode, Parser, Piece, Position};
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_span::Span;
Expand Down Expand Up @@ -108,14 +108,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

pub fn on_unimplemented_note(
&self,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
obligation: &PredicateObligation<'tcx>,
long_ty_file: &mut Option<PathBuf>,
) -> OnUnimplementedNote {
if trait_pred.polarity() != ty::PredicatePolarity::Positive {
return OnUnimplementedNote::default();
}

let (def_id, args) = self
.impl_similar_to(trait_ref, obligation)
.unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().args));
let trait_ref = trait_ref.skip_binder();
.impl_similar_to(trait_pred.to_poly_trait_ref(), obligation)
.unwrap_or_else(|| (trait_pred.def_id(), trait_pred.skip_binder().trait_ref.args));
let trait_pred = trait_pred.skip_binder();

let mut flags = vec![];
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): HIR is not present for RPITITs,
Expand Down Expand Up @@ -144,13 +148,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
flags.push((sym::cause, Some("MainFunctionType".to_string())));
}

flags.push((sym::Trait, Some(trait_ref.print_trait_sugared().to_string())));
flags.push((sym::Trait, Some(trait_pred.trait_ref.print_trait_sugared().to_string())));

// Add all types without trimmed paths or visible paths, ensuring they end up with
// their "canonical" def path.
ty::print::with_no_trimmed_paths!(ty::print::with_no_visible_paths!({
let generics = self.tcx.generics_of(def_id);
let self_ty = trait_ref.self_ty();
let self_ty = trait_pred.self_ty();
// This is also included through the generics list as `Self`,
// but the parser won't allow you to use it
flags.push((sym::_Self, Some(self_ty.to_string())));
Expand Down Expand Up @@ -266,7 +270,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}));

if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {
command.evaluate(self.tcx, trait_ref, &flags, long_ty_file)
command.evaluate(self.tcx, trait_pred.trait_ref, &flags, long_ty_file)
} else {
OnUnimplementedNote::default()
}
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/traits/negative-bounds/on-unimplemented.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(negative_bounds)]

#[diagnostic::on_unimplemented(message = "this ain't fooing")]
trait Foo {}
struct NotFoo;

fn hello() -> impl !Foo {
//~^ ERROR the trait bound `NotFoo: !Foo` is not satisfied
NotFoo
}

fn main() {}
18 changes: 18 additions & 0 deletions tests/ui/traits/negative-bounds/on-unimplemented.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0277]: the trait bound `NotFoo: !Foo` is not satisfied
--> $DIR/on-unimplemented.rs:7:15
|
LL | fn hello() -> impl !Foo {
| ^^^^^^^^^ the trait bound `NotFoo: !Foo` is not satisfied
LL |
LL | NotFoo
| ------ return type was inferred to be `NotFoo` here
|
help: this trait has no implementations, consider adding one
--> $DIR/on-unimplemented.rs:4:1
|
LL | trait Foo {}
| ^^^^^^^^^

error: aborting due to 1 previous error

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