Skip to content
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
17 changes: 13 additions & 4 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind};
use rustc_type_ir::{
self as ty, Interner, Movability, TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode,
Upcast as _, elaborate,
self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
};
use tracing::{debug, instrument, trace};

Expand Down Expand Up @@ -133,19 +133,26 @@ where
cx: I,
clause_def_id: I::DefId,
goal_def_id: I::DefId,
polarity: PredicatePolarity,
) -> bool {
clause_def_id == goal_def_id
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
// check for a `MetaSized` supertrait being matched against a `Sized` assumption.
//
// `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
|| (cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
|| (polarity == PredicatePolarity::Positive
&& cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
&& cx.is_lang_item(goal_def_id, TraitSolverLangItem::MetaSized))
}

if let Some(trait_clause) = assumption.as_trait_clause()
&& trait_clause.polarity() == goal.predicate.polarity
&& trait_def_id_matches(ecx.cx(), trait_clause.def_id(), goal.predicate.def_id())
&& trait_def_id_matches(
ecx.cx(),
trait_clause.def_id(),
goal.predicate.def_id(),
goal.predicate.polarity,
)
&& DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
trait_clause.skip_binder().trait_ref.args,
Expand All @@ -168,6 +175,8 @@ where
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
// are syntactic sugar for a lack of bounds so don't need this.
// We don't need to check polarity, `fast_reject_assumption` already rejected non-`Positive`
// polarity `Sized` assumptions as matching non-`Positive` `MetaSized` goals.
if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
&& ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
{
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ pub use rustc_infer::traits::util::*;
use rustc_middle::bug;
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::{
self, PolyTraitPredicate, SizedTraitKind, TraitPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
TypeFolder, TypeSuperFoldable, TypeVisitableExt,
self, PolyTraitPredicate, PredicatePolarity, SizedTraitKind, TraitPredicate, TraitRef, Ty,
TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
};
pub use rustc_next_trait_solver::placeholder::BoundVarReplacer;
use rustc_span::Span;
Expand Down Expand Up @@ -427,7 +427,9 @@ pub(crate) fn lazily_elaborate_sizedness_candidate<'tcx>(
return candidate;
}

if obligation.predicate.polarity() != candidate.polarity() {
if obligation.predicate.polarity() != PredicatePolarity::Positive
|| candidate.polarity() != PredicatePolarity::Positive
{
return candidate;
}

Expand Down
39 changes: 39 additions & 0 deletions tests/ui/traits/negative-bounds/negative-metasized.current.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error[E0277]: the trait bound `T: !MetaSized` is not satisfied
--> $DIR/negative-metasized.rs:12:11
|
LL | foo::<T>();
| ^ the trait bound `T: !MetaSized` is not satisfied
|
note: required by a bound in `foo`
--> $DIR/negative-metasized.rs:9:11
|
LL | fn foo<T: !MetaSized>() {}
| ^^^^^^^^^^ required by this bound in `foo`

error[E0277]: the trait bound `(): !MetaSized` is not satisfied
--> $DIR/negative-metasized.rs:17:11
|
LL | foo::<()>();
| ^^ the trait bound `(): !MetaSized` is not satisfied
|
note: required by a bound in `foo`
--> $DIR/negative-metasized.rs:9:11
|
LL | fn foo<T: !MetaSized>() {}
| ^^^^^^^^^^ required by this bound in `foo`

error[E0277]: the trait bound `str: !MetaSized` is not satisfied
--> $DIR/negative-metasized.rs:19:11
|
LL | foo::<str>();
| ^^^ the trait bound `str: !MetaSized` is not satisfied
|
note: required by a bound in `foo`
--> $DIR/negative-metasized.rs:9:11
|
LL | fn foo<T: !MetaSized>() {}
| ^^^^^^^^^^ required by this bound in `foo`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
39 changes: 39 additions & 0 deletions tests/ui/traits/negative-bounds/negative-metasized.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error[E0277]: the trait bound `T: !MetaSized` is not satisfied
--> $DIR/negative-metasized.rs:12:11
|
LL | foo::<T>();
| ^ the trait bound `T: !MetaSized` is not satisfied
|
note: required by a bound in `foo`
--> $DIR/negative-metasized.rs:9:11
|
LL | fn foo<T: !MetaSized>() {}
| ^^^^^^^^^^ required by this bound in `foo`

error[E0277]: the trait bound `(): !MetaSized` is not satisfied
--> $DIR/negative-metasized.rs:17:11
|
LL | foo::<()>();
| ^^ the trait bound `(): !MetaSized` is not satisfied
|
note: required by a bound in `foo`
--> $DIR/negative-metasized.rs:9:11
|
LL | fn foo<T: !MetaSized>() {}
| ^^^^^^^^^^ required by this bound in `foo`

error[E0277]: the trait bound `str: !MetaSized` is not satisfied
--> $DIR/negative-metasized.rs:19:11
|
LL | foo::<str>();
| ^^^ the trait bound `str: !MetaSized` is not satisfied
|
note: required by a bound in `foo`
--> $DIR/negative-metasized.rs:9:11
|
LL | fn foo<T: !MetaSized>() {}
| ^^^^^^^^^^ required by this bound in `foo`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
21 changes: 21 additions & 0 deletions tests/ui/traits/negative-bounds/negative-metasized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
#![feature(negative_bounds)]
#![feature(sized_hierarchy)]

use std::marker::MetaSized;

fn foo<T: !MetaSized>() {}

fn bar<T: !Sized + MetaSized>() {
foo::<T>();
//~^ ERROR the trait bound `T: !MetaSized` is not satisfied
}

fn main() {
foo::<()>();
//~^ ERROR the trait bound `(): !MetaSized` is not satisfied
foo::<str>();
//~^ ERROR the trait bound `str: !MetaSized` is not satisfied
}
Loading