Do not consider a T: !Sized candidate to satisfy a T: !MetaSized obligation.
This commit is contained in:
@@ -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};
|
||||
|
||||
@@ -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,
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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`.
|
||||
@@ -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
tests/ui/traits/negative-bounds/negative-metasized.rs
Normal file
21
tests/ui/traits/negative-bounds/negative-metasized.rs
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user