From 91c53c97a990e9d1ab87b2d932362a53236fba49 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Jul 2025 00:32:54 +0000 Subject: [PATCH] Consider polarity in sizedness fast path --- compiler/rustc_trait_selection/src/traits/util.rs | 7 ++++--- tests/ui/traits/negative-bounds/negative-sized.rs | 8 ++++++++ .../traits/negative-bounds/negative-sized.stderr | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/negative-bounds/negative-sized.rs create mode 100644 tests/ui/traits/negative-bounds/negative-sized.stderr diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a05bae535663..141454bfe375 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -368,16 +368,17 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc // Proving `Sized`/`MetaSized`, very often on "obviously sized" types like // `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to // canonicalize and all that for such cases. - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) = + if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = predicate.kind().skip_binder() + && trait_pred.polarity == ty::PredicatePolarity::Positive { - let sizedness = match tcx.as_lang_item(trait_ref.def_id()) { + let sizedness = match tcx.as_lang_item(trait_pred.def_id()) { Some(LangItem::Sized) => SizedTraitKind::Sized, Some(LangItem::MetaSized) => SizedTraitKind::MetaSized, _ => return false, }; - if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) { + if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) { debug!("fast path -- trivial sizedness"); return true; } diff --git a/tests/ui/traits/negative-bounds/negative-sized.rs b/tests/ui/traits/negative-bounds/negative-sized.rs new file mode 100644 index 000000000000..18369c784275 --- /dev/null +++ b/tests/ui/traits/negative-bounds/negative-sized.rs @@ -0,0 +1,8 @@ +#![feature(negative_bounds)] + +fn foo() {} + +fn main() { + foo::<()>(); + //~^ ERROR the trait bound `(): !Sized` is not satisfied +} diff --git a/tests/ui/traits/negative-bounds/negative-sized.stderr b/tests/ui/traits/negative-bounds/negative-sized.stderr new file mode 100644 index 000000000000..143933803b81 --- /dev/null +++ b/tests/ui/traits/negative-bounds/negative-sized.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): !Sized` is not satisfied + --> $DIR/negative-sized.rs:6:11 + | +LL | foo::<()>(); + | ^^ the trait bound `(): !Sized` is not satisfied + | +note: required by a bound in `foo` + --> $DIR/negative-sized.rs:3:11 + | +LL | fn foo() {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.