mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 10:45:18 +00:00
Auto merge of #53707 - eddyb:phantom-waffles, r=oli-obk
rustc_typeck: turn `where Type:,` into a WF(Type) predicate, instead of ignoring it. Fixes #53696, assuming crater doesn't catch anyone using this syntax already. Allowing an empty list of bounds in the grammar was done for the benefit of macro authors, most of which would *probably* be using it for bounds on type parameters, which are always WF. r? @nikomatsakis cc @petrochenkov
This commit is contained in:
commit
35a5541fd9
@ -1799,6 +1799,21 @@ fn explicit_predicates_of<'a, 'tcx>(
|
|||||||
&hir::WherePredicate::BoundPredicate(ref bound_pred) => {
|
&hir::WherePredicate::BoundPredicate(ref bound_pred) => {
|
||||||
let ty = icx.to_ty(&bound_pred.bounded_ty);
|
let ty = icx.to_ty(&bound_pred.bounded_ty);
|
||||||
|
|
||||||
|
// Keep the type around in a WF predicate, in case of no bounds.
|
||||||
|
// That way, `where Ty:` is not a complete noop (see #53696).
|
||||||
|
if bound_pred.bounds.is_empty() {
|
||||||
|
if let ty::Param(_) = ty.sty {
|
||||||
|
// This is a `where T:`, which can be in the HIR from the
|
||||||
|
// transformation that moves `?Sized` to `T`'s declaration.
|
||||||
|
// We can skip the predicate because type parameters are
|
||||||
|
// trivially WF, but also we *should*, to avoid exposing
|
||||||
|
// users who never wrote `where Type:,` themselves, to
|
||||||
|
// compiler/tooling bugs from not handling WF predicates.
|
||||||
|
} else {
|
||||||
|
predicates.push(ty::Predicate::WellFormed(ty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for bound in bound_pred.bounds.iter() {
|
for bound in bound_pred.bounds.iter() {
|
||||||
match bound {
|
match bound {
|
||||||
&hir::GenericBound::Trait(ref poly_trait_ref, _) => {
|
&hir::GenericBound::Trait(ref poly_trait_ref, _) => {
|
||||||
|
@ -1312,7 +1312,13 @@ impl<'a> Clean<WherePredicate> for ty::Predicate<'a> {
|
|||||||
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
|
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
|
||||||
Predicate::TypeOutlives(ref pred) => pred.clean(cx),
|
Predicate::TypeOutlives(ref pred) => pred.clean(cx),
|
||||||
Predicate::Projection(ref pred) => pred.clean(cx),
|
Predicate::Projection(ref pred) => pred.clean(cx),
|
||||||
Predicate::WellFormed(_) => panic!("not user writable"),
|
Predicate::WellFormed(ty) => {
|
||||||
|
// This comes from `where Ty:` (i.e. no bounds) (see #53696).
|
||||||
|
WherePredicate::BoundPredicate {
|
||||||
|
ty: ty.clean(cx),
|
||||||
|
bounds: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
Predicate::ObjectSafe(_) => panic!("not user writable"),
|
Predicate::ObjectSafe(_) => panic!("not user writable"),
|
||||||
Predicate::ClosureKind(..) => panic!("not user writable"),
|
Predicate::ClosureKind(..) => panic!("not user writable"),
|
||||||
Predicate::ConstEvaluatable(..) => panic!("not user writable"),
|
Predicate::ConstEvaluatable(..) => panic!("not user writable"),
|
||||||
|
@ -14,7 +14,15 @@ use std::fmt::{Debug, Display};
|
|||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
#[rustc_dump_program_clauses] //~ ERROR program clause dump
|
#[rustc_dump_program_clauses] //~ ERROR program clause dump
|
||||||
trait Foo<'a, 'b, S, T, U> where S: Debug, T: Borrow<U>, U: ?Sized, 'a: 'b, U: 'b {
|
trait Foo<'a, 'b, S, T, U>
|
||||||
|
where
|
||||||
|
S: Debug,
|
||||||
|
T: Borrow<U>,
|
||||||
|
U: ?Sized,
|
||||||
|
'a: 'b,
|
||||||
|
U: 'b,
|
||||||
|
Vec<T>:, // NOTE(#53696) this checks an empty list of bounds.
|
||||||
|
{
|
||||||
fn s(_: S) -> S;
|
fn s(_: S) -> S;
|
||||||
fn t(_: T) -> T;
|
fn t(_: T) -> T;
|
||||||
fn u(_: U) -> U;
|
fn u(_: U) -> U;
|
||||||
|
@ -11,7 +11,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
|
|||||||
= note: Implemented(Self: Foo<'a, 'b, S, T, U>) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
= note: Implemented(Self: Foo<'a, 'b, S, T, U>) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
||||||
= note: RegionOutlives('a : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
= note: RegionOutlives('a : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
||||||
= note: TypeOutlives(U : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
= note: TypeOutlives(U : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
||||||
= note: WellFormed(Self: Foo<'a, 'b, S, T, U>) :- Implemented(Self: Foo<'a, 'b, S, T, U>), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(S: std::fmt::Debug), WellFormed(T: std::borrow::Borrow<U>), RegionOutlives('a : 'b), TypeOutlives(U : 'b).
|
= note: WellFormed(Self: Foo<'a, 'b, S, T, U>) :- Implemented(Self: Foo<'a, 'b, S, T, U>), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(S: std::fmt::Debug), WellFormed(T: std::borrow::Borrow<U>), RegionOutlives('a : 'b), TypeOutlives(U : 'b), WellFormed(std::vec::Vec<T>).
|
||||||
|
= note: WellFormed(std::vec::Vec<T>) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
// Test that we check where-clauses on fn items.
|
// Test that we check where-clauses on fn items.
|
||||||
|
|
||||||
#![feature(associated_type_defaults)]
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
@ -20,5 +19,9 @@ fn foo<T,U>() where T: ExtraCopy<U> //~ ERROR E0277
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bar() where Vec<dyn Copy>:, {}
|
||||||
|
//~^ ERROR E0277
|
||||||
|
//~| ERROR E0038
|
||||||
|
|
||||||
#[rustc_error]
|
#[rustc_error]
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
|
error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
|
||||||
--> $DIR/wf-fn-where-clause.rs:19:1
|
--> $DIR/wf-fn-where-clause.rs:18:1
|
||||||
|
|
|
|
||||||
LL | / fn foo<T,U>() where T: ExtraCopy<U> //~ ERROR E0277
|
LL | / fn foo<T,U>() where T: ExtraCopy<U> //~ ERROR E0277
|
||||||
LL | | {
|
LL | | {
|
||||||
@ -8,11 +8,30 @@ LL | | }
|
|||||||
|
|
|
|
||||||
= help: consider adding a `where U: std::marker::Copy` bound
|
= help: consider adding a `where U: std::marker::Copy` bound
|
||||||
note: required by `ExtraCopy`
|
note: required by `ExtraCopy`
|
||||||
--> $DIR/wf-fn-where-clause.rs:17:1
|
--> $DIR/wf-fn-where-clause.rs:16:1
|
||||||
|
|
|
|
||||||
LL | trait ExtraCopy<T:Copy> { }
|
LL | trait ExtraCopy<T:Copy> { }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time
|
||||||
|
--> $DIR/wf-fn-where-clause.rs:22:1
|
||||||
|
|
|
||||||
|
LL | fn bar() where Vec<dyn Copy>:, {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::marker::Copy + 'static)`
|
||||||
|
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||||
|
= note: required by `std::vec::Vec`
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
error[E0038]: the trait `std::marker::Copy` cannot be made into an object
|
||||||
|
--> $DIR/wf-fn-where-clause.rs:22:1
|
||||||
|
|
|
||||||
|
LL | fn bar() where Vec<dyn Copy>:, {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` cannot be made into an object
|
||||||
|
|
|
||||||
|
= note: the trait cannot require that `Self : Sized`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors occurred: E0038, E0277.
|
||||||
|
For more information about an error, try `rustc --explain E0038`.
|
||||||
|
Loading…
Reference in New Issue
Block a user