Rollup merge of #142671 - davidtwco:no-default-bounds-attr, r=lcnr
add #![rustc_no_implicit_bounds] Follow-up from rust-lang/rust#137944. Adds a new `rustc_attrs` attribute that stops rustc from adding any default bounds. Useful for tests where default bounds just add noise and make debugging harder. After reviewing all tests with `?Sized`, these tests seem like they could probably benefit from `#![rustc_no_implicit_bounds]`. - Skipping most of `tests/ui/unsized` as these seem to want to test `?Sized` - Skipping tests that used `Box<T>` because it's still bound by `T: MetaSized` - Skipping parsing or other tests that cared about `?Sized` syntactically - Skipping tests for `derive(CoercePointee)` because this appears to check that the pointee type is relaxed with `?Sized` explicitly r? `@lcnr`
This commit is contained in:
@@ -1139,6 +1139,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
TEST, rustc_insignificant_dtor, Normal, template!(Word),
|
TEST, rustc_insignificant_dtor, Normal, template!(Word),
|
||||||
WarnFollowing, EncodeCrossCrate::Yes
|
WarnFollowing, EncodeCrossCrate::Yes
|
||||||
),
|
),
|
||||||
|
rustc_attr!(
|
||||||
|
TEST, rustc_no_implicit_bounds, CrateLevel, template!(Word),
|
||||||
|
WarnFollowing, EncodeCrossCrate::No
|
||||||
|
),
|
||||||
rustc_attr!(
|
rustc_attr!(
|
||||||
TEST, rustc_strict_coherence, Normal, template!(Word),
|
TEST, rustc_strict_coherence, Normal, template!(Word),
|
||||||
WarnFollowing, EncodeCrossCrate::Yes
|
WarnFollowing, EncodeCrossCrate::Yes
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ use rustc_errors::codes::*;
|
|||||||
use rustc_errors::struct_span_code_err;
|
use rustc_errors::struct_span_code_err;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
||||||
use rustc_hir::{AmbigArg, LangItem, PolyTraitRef};
|
use rustc_hir::{AmbigArg, LangItem, PolyTraitRef};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||||
TypeVisitor, Upcast,
|
TypeVisitor, Upcast,
|
||||||
};
|
};
|
||||||
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw};
|
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
@@ -188,6 +188,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
|
// Skip adding any default bounds if `#![rustc_no_implicit_bounds]`
|
||||||
|
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
|
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
|
||||||
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
|
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
|
||||||
|
|
||||||
@@ -408,24 +413,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let trait_id = tcx.lang_items().get(trait_);
|
let trait_id = tcx.lang_items().get(trait_);
|
||||||
if let Some(trait_id) = trait_id
|
if let Some(trait_id) = trait_id
|
||||||
&& self.do_not_provide_default_trait_bound(
|
&& self.should_add_default_traits(trait_id, hir_bounds, self_ty_where_predicates)
|
||||||
trait_id,
|
|
||||||
hir_bounds,
|
|
||||||
self_ty_where_predicates,
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
add_trait_bound(tcx, bounds, self_ty, trait_id, span);
|
add_trait_bound(tcx, bounds, self_ty, trait_id, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_not_provide_default_trait_bound<'a>(
|
/// Returns `true` if default trait bound should be added.
|
||||||
|
fn should_add_default_traits<'a>(
|
||||||
&self,
|
&self,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
hir_bounds: &'a [hir::GenericBound<'tcx>],
|
hir_bounds: &'a [hir::GenericBound<'tcx>],
|
||||||
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id);
|
let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id);
|
||||||
!collected.any()
|
!self.tcx().has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) && !collected.any()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
|
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
|
||||||
|
|||||||
@@ -1876,6 +1876,7 @@ symbols! {
|
|||||||
rustc_never_returns_null_ptr,
|
rustc_never_returns_null_ptr,
|
||||||
rustc_never_type_options,
|
rustc_never_type_options,
|
||||||
rustc_no_implicit_autorefs,
|
rustc_no_implicit_autorefs,
|
||||||
|
rustc_no_implicit_bounds,
|
||||||
rustc_no_mir_inline,
|
rustc_no_mir_inline,
|
||||||
rustc_nonnull_optimization_guaranteed,
|
rustc_nonnull_optimization_guaranteed,
|
||||||
rustc_nounwind,
|
rustc_nounwind,
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
//@ compile-flags: -Znext-solver=coherence
|
//@ compile-flags: -Znext-solver=coherence
|
||||||
|
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
#![recursion_limit = "10"]
|
#![recursion_limit = "10"]
|
||||||
|
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
|
|
||||||
struct W<T: ?Sized>(*const T);
|
struct W<T>(*const T);
|
||||||
trait TwoW {}
|
trait TwoW {}
|
||||||
impl<T: ?Sized + TwoW> TwoW for W<W<T>> {}
|
impl<T: TwoW> TwoW for W<W<T>> {}
|
||||||
|
|
||||||
impl<T: ?Sized + TwoW> Trait for W<T> {}
|
impl<T: TwoW> Trait for W<T> {}
|
||||||
impl<T: ?Sized + TwoW> Trait for T {}
|
impl<T: TwoW> Trait for T {}
|
||||||
//~^ ERROR conflicting implementations of trait `Trait` for type `W
|
//~^ ERROR conflicting implementations of trait `Trait` for type `W
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
|
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
|
||||||
--> $DIR/coherence-fulfill-overflow.rs:12:1
|
--> $DIR/coherence-fulfill-overflow.rs:14:1
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
|
LL | impl<T: TwoW> Trait for W<T> {}
|
||||||
| ------------------------------------- first implementation here
|
| ---------------------------- first implementation here
|
||||||
LL | impl<T: ?Sized + TwoW> Trait for T {}
|
LL | impl<T: TwoW> Trait for T {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//@ revisions: with without
|
//@ revisions: with without
|
||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
// This test is incredibly subtle. At its core the goal is to get a coinductive cycle,
|
// This test is incredibly subtle. At its core the goal is to get a coinductive cycle,
|
||||||
// which, depending on its root goal, either holds or errors. We achieve this by getting
|
// which, depending on its root goal, either holds or errors. We achieve this by getting
|
||||||
@@ -17,20 +18,20 @@
|
|||||||
// test for that.
|
// test for that.
|
||||||
|
|
||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
||||||
trait Trait<T: ?Sized, V: ?Sized, D: ?Sized> {}
|
trait Trait<T, V, D> {}
|
||||||
struct A<T: ?Sized>(*const T);
|
struct A<T>(*const T);
|
||||||
struct B<T: ?Sized>(*const T);
|
struct B<T>(*const T);
|
||||||
|
|
||||||
trait IncompleteGuidance<T: ?Sized, V: ?Sized> {}
|
trait IncompleteGuidance<T, V> {}
|
||||||
impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, u8> for T {}
|
impl<T, U: 'static> IncompleteGuidance<U, u8> for T {}
|
||||||
impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, i8> for T {}
|
impl<T, U: 'static> IncompleteGuidance<U, i8> for T {}
|
||||||
impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, i16> for T {}
|
impl<T, U: 'static> IncompleteGuidance<U, i16> for T {}
|
||||||
|
|
||||||
trait ImplGuidance<T: ?Sized, V: ?Sized> {}
|
trait ImplGuidance<T, V> {}
|
||||||
impl<T: ?Sized> ImplGuidance<u32, u8> for T {}
|
impl<T> ImplGuidance<u32, u8> for T {}
|
||||||
impl<T: ?Sized> ImplGuidance<i32, i8> for T {}
|
impl<T> ImplGuidance<i32, i8> for T {}
|
||||||
|
|
||||||
impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T>
|
impl<T, U, V, D> Trait<U, V, D> for A<T>
|
||||||
where
|
where
|
||||||
T: IncompleteGuidance<U, V>,
|
T: IncompleteGuidance<U, V>,
|
||||||
A<T>: Trait<U, D, V>,
|
A<T>: Trait<U, D, V>,
|
||||||
@@ -39,17 +40,17 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ToU8<T: ?Sized> {}
|
trait ToU8<T> {}
|
||||||
impl ToU8<u8> for () {}
|
impl ToU8<u8> for () {}
|
||||||
|
|
||||||
impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for B<T>
|
impl<T, U, V, D> Trait<U, V, D> for B<T>
|
||||||
where
|
where
|
||||||
T: ImplGuidance<U, V>,
|
T: ImplGuidance<U, V>,
|
||||||
A<T>: Trait<U, V, D>,
|
A<T>: Trait<U, V, D>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {}
|
fn impls_trait<T: Trait<U, V, D>, U, V, D>() {}
|
||||||
|
|
||||||
fn with_bound<X>()
|
fn with_bound<X>()
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
|
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
|
||||||
--> $DIR/incompleteness-unstable-result.rs:65:19
|
--> $DIR/incompleteness-unstable-result.rs:66:19
|
||||||
|
|
|
|
||||||
LL | impls_trait::<A<X>, _, _, _>();
|
LL | impls_trait::<A<X>, _, _, _>();
|
||||||
| ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
|
| ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
|
||||||
|
|
|
|
||||||
= help: the trait `Trait<U, V, D>` is implemented for `A<T>`
|
= help: the trait `Trait<U, V, D>` is implemented for `A<T>`
|
||||||
note: required for `A<X>` to implement `Trait<_, _, _>`
|
note: required for `A<X>` to implement `Trait<_, _, _>`
|
||||||
--> $DIR/incompleteness-unstable-result.rs:33:50
|
--> $DIR/incompleteness-unstable-result.rs:34:18
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T>
|
LL | impl<T, U, V, D> Trait<U, V, D> for A<T>
|
||||||
| ^^^^^^^^^^^^^^ ^^^^
|
| ^^^^^^^^^^^^^^ ^^^^
|
||||||
...
|
...
|
||||||
LL | A<T>: Trait<U, D, V>,
|
LL | A<T>: Trait<U, D, V>,
|
||||||
| -------------- unsatisfied trait bound introduced here
|
| -------------- unsatisfied trait bound introduced here
|
||||||
= note: 8 redundant requirements hidden
|
= note: 8 redundant requirements hidden
|
||||||
= note: required for `A<X>` to implement `Trait<_, _, _>`
|
= note: required for `A<X>` to implement `Trait<_, _, _>`
|
||||||
note: required by a bound in `impls_trait`
|
note: required by a bound in `impls_trait`
|
||||||
--> $DIR/incompleteness-unstable-result.rs:52:28
|
--> $DIR/incompleteness-unstable-result.rs:53:19
|
||||||
|
|
|
|
||||||
LL | fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {}
|
LL | fn impls_trait<T: Trait<U, V, D>, U, V, D>() {}
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `impls_trait`
|
| ^^^^^^^^^^^^^^ required by this bound in `impls_trait`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
|
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
|
||||||
--> $DIR/incompleteness-unstable-result.rs:65:19
|
--> $DIR/incompleteness-unstable-result.rs:66:19
|
||||||
|
|
|
|
||||||
LL | impls_trait::<A<X>, _, _, _>();
|
LL | impls_trait::<A<X>, _, _, _>();
|
||||||
| ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
|
| ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
|
||||||
|
|
|
|
||||||
= help: the trait `Trait<U, V, D>` is implemented for `A<T>`
|
= help: the trait `Trait<U, V, D>` is implemented for `A<T>`
|
||||||
note: required for `A<X>` to implement `Trait<_, _, _>`
|
note: required for `A<X>` to implement `Trait<_, _, _>`
|
||||||
--> $DIR/incompleteness-unstable-result.rs:33:50
|
--> $DIR/incompleteness-unstable-result.rs:34:18
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T>
|
LL | impl<T, U, V, D> Trait<U, V, D> for A<T>
|
||||||
| ^^^^^^^^^^^^^^ ^^^^
|
| ^^^^^^^^^^^^^^ ^^^^
|
||||||
...
|
...
|
||||||
LL | A<T>: Trait<U, D, V>,
|
LL | A<T>: Trait<U, D, V>,
|
||||||
| -------------- unsatisfied trait bound introduced here
|
| -------------- unsatisfied trait bound introduced here
|
||||||
= note: 8 redundant requirements hidden
|
= note: 8 redundant requirements hidden
|
||||||
= note: required for `A<X>` to implement `Trait<_, _, _>`
|
= note: required for `A<X>` to implement `Trait<_, _, _>`
|
||||||
note: required by a bound in `impls_trait`
|
note: required by a bound in `impls_trait`
|
||||||
--> $DIR/incompleteness-unstable-result.rs:52:28
|
--> $DIR/incompleteness-unstable-result.rs:53:19
|
||||||
|
|
|
|
||||||
LL | fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {}
|
LL | fn impls_trait<T: Trait<U, V, D>, U, V, D>() {}
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `impls_trait`
|
| ^^^^^^^^^^^^^^ required by this bound in `impls_trait`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
// Check that we correctly rerun the trait solver for heads of cycles,
|
// Check that we correctly rerun the trait solver for heads of cycles,
|
||||||
// even if they are not the root.
|
// even if they are not the root.
|
||||||
|
|
||||||
struct A<T: ?Sized>(*const T);
|
struct A<T>(*const T);
|
||||||
struct B<T: ?Sized>(*const T);
|
struct B<T>(*const T);
|
||||||
struct C<T: ?Sized>(*const T);
|
struct C<T>(*const T);
|
||||||
|
|
||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
||||||
trait Trait<'a, 'b> {}
|
trait Trait<'a, 'b> {}
|
||||||
trait NotImplemented {}
|
trait NotImplemented {}
|
||||||
|
|
||||||
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for A<T> where B<T>: Trait<'a, 'b> {}
|
impl<'a, 'b, T> Trait<'a, 'b> for A<T> where B<T>: Trait<'a, 'b> {}
|
||||||
|
|
||||||
// With this the root of `B<T>` is `A<T>`, even if the other impl does
|
// With this the root of `B<T>` is `A<T>`, even if the other impl does
|
||||||
// not have a cycle with `A<T>`. This candidate never applies because of
|
// not have a cycle with `A<T>`. This candidate never applies because of
|
||||||
// the `A<T>: NotImplemented` bound.
|
// the `A<T>: NotImplemented` bound.
|
||||||
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B<T>
|
impl<'a, 'b, T> Trait<'a, 'b> for B<T>
|
||||||
where
|
where
|
||||||
A<T>: Trait<'a, 'b>,
|
A<T>: Trait<'a, 'b>,
|
||||||
A<T>: NotImplemented,
|
A<T>: NotImplemented,
|
||||||
@@ -31,7 +32,7 @@ where
|
|||||||
// use the impl itself to prove that adds region constraints as we uniquified the
|
// use the impl itself to prove that adds region constraints as we uniquified the
|
||||||
// regions in the `A<T>: Trait<'a, 'b>` where-bound. As both the impl above
|
// regions in the `A<T>: Trait<'a, 'b>` where-bound. As both the impl above
|
||||||
// and the impl below now apply with some constraints, we failed with ambiguity.
|
// and the impl below now apply with some constraints, we failed with ambiguity.
|
||||||
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B<T>
|
impl<'a, 'b, T> Trait<'a, 'b> for B<T>
|
||||||
where
|
where
|
||||||
A<T>: NotImplemented,
|
A<T>: NotImplemented,
|
||||||
{}
|
{}
|
||||||
@@ -40,7 +41,7 @@ where
|
|||||||
//
|
//
|
||||||
// Because of the coinductive cycle through `C<T>` it also requires
|
// Because of the coinductive cycle through `C<T>` it also requires
|
||||||
// 'a to be 'static.
|
// 'a to be 'static.
|
||||||
impl<'a, T: ?Sized> Trait<'a, 'static> for B<T>
|
impl<'a, T> Trait<'a, 'static> for B<T>
|
||||||
where
|
where
|
||||||
C<T>: Trait<'a, 'a>,
|
C<T>: Trait<'a, 'a>,
|
||||||
{}
|
{}
|
||||||
@@ -48,14 +49,14 @@ where
|
|||||||
// In the first iteration of `B<T>: Trait<'a, 'b>` we don't add any
|
// In the first iteration of `B<T>: Trait<'a, 'b>` we don't add any
|
||||||
// constraints here, only after setting the provisional result to require
|
// constraints here, only after setting the provisional result to require
|
||||||
// `'b == 'static` do we also add that constraint for `'a`.
|
// `'b == 'static` do we also add that constraint for `'a`.
|
||||||
impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for C<T>
|
impl<'a, 'b, T> Trait<'a, 'b> for C<T>
|
||||||
where
|
where
|
||||||
B<T>: Trait<'a, 'b>,
|
B<T>: Trait<'a, 'b>,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
fn impls_trait<'a, 'b, T: Trait<'a, 'b> + ?Sized>() {}
|
fn impls_trait<'a, 'b, T: Trait<'a, 'b>>() {}
|
||||||
|
|
||||||
fn check<'a, T: ?Sized>() {
|
fn check<'a, T>() {
|
||||||
impls_trait::<'a, 'static, A<T>>();
|
impls_trait::<'a, 'static, A<T>>();
|
||||||
//~^ ERROR lifetime may not live long enough
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/fixpoint-rerun-all-cycle-heads.rs:59:5
|
--> $DIR/fixpoint-rerun-all-cycle-heads.rs:60:5
|
||||||
|
|
|
|
||||||
LL | fn check<'a, T: ?Sized>() {
|
LL | fn check<'a, T>() {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | impls_trait::<'a, 'static, A<T>>();
|
LL | impls_trait::<'a, 'static, A<T>>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
// This currently hangs if we do not erase constraints from
|
// This currently hangs if we do not erase constraints from
|
||||||
// overflow.
|
// overflow.
|
||||||
@@ -17,9 +19,9 @@
|
|||||||
// the solver to hang without hitting the recursion limit.
|
// the solver to hang without hitting the recursion limit.
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
|
|
||||||
struct W<T: ?Sized>(*const T);
|
struct W<T>(*const T);
|
||||||
|
|
||||||
impl<T: ?Sized> Trait for W<W<T>>
|
impl<T> Trait for W<W<T>>
|
||||||
where
|
where
|
||||||
W<T>: Trait,
|
W<T>: Trait,
|
||||||
W<T>: Trait,
|
W<T>: Trait,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
||||||
--> $DIR/inductive-fixpoint-hang.rs:31:19
|
--> $DIR/inductive-fixpoint-hang.rs:33:19
|
||||||
|
|
|
|
||||||
LL | impls_trait::<W<_>>();
|
LL | impls_trait::<W<_>>();
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `impls_trait`
|
note: required by a bound in `impls_trait`
|
||||||
--> $DIR/inductive-fixpoint-hang.rs:28:19
|
--> $DIR/inductive-fixpoint-hang.rs:30:19
|
||||||
|
|
|
|
||||||
LL | fn impls_trait<T: Trait>() {}
|
LL | fn impls_trait<T: Trait>() {}
|
||||||
| ^^^^^ required by this bound in `impls_trait`
|
| ^^^^^ required by this bound in `impls_trait`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
// A test showcasing that using a provisional cache can differ
|
// A test showcasing that using a provisional cache can differ
|
||||||
// from only tracking stack entries.
|
// from only tracking stack entries.
|
||||||
@@ -59,9 +60,9 @@ trait B {}
|
|||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
||||||
trait C {}
|
trait C {}
|
||||||
|
|
||||||
impl<T: ?Sized + B + C> A for T {}
|
impl<T: B + C> A for T {}
|
||||||
impl<T: ?Sized + A + C> B for T {}
|
impl<T: A + C> B for T {}
|
||||||
impl<T: ?Sized + B> C for T {}
|
impl<T: B> C for T {}
|
||||||
|
|
||||||
fn impls_a<T: A>() {}
|
fn impls_a<T: A>() {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
trait Tr<'a> {}
|
trait Tr<'a> {}
|
||||||
|
|
||||||
@@ -16,9 +18,9 @@ trait Tr<'a> {}
|
|||||||
// Then, when we recompute the goal `W<?0>: Constrain<'error>`, when
|
// Then, when we recompute the goal `W<?0>: Constrain<'error>`, when
|
||||||
// collecting ambiguities and overflows, we end up assembling a default
|
// collecting ambiguities and overflows, we end up assembling a default
|
||||||
// error candidate w/o ambiguity, which causes the goal to pass, and ICE.
|
// error candidate w/o ambiguity, which causes the goal to pass, and ICE.
|
||||||
impl<'a, A: ?Sized> Tr<'a> for W<A> {}
|
impl<'a, A> Tr<'a> for W<A> {}
|
||||||
struct W<A: ?Sized>(A);
|
struct W<A>(A);
|
||||||
impl<'a, A: ?Sized> Tr<'a> for A where A: Constrain<'a> {}
|
impl<'a, A> Tr<'a> for A where A: Constrain<'a> {}
|
||||||
//~^ ERROR conflicting implementations of trait `Tr<'_>` for type `W<_>`
|
//~^ ERROR conflicting implementations of trait `Tr<'_>` for type `W<_>`
|
||||||
|
|
||||||
trait Constrain<'a> {}
|
trait Constrain<'a> {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error[E0261]: use of undeclared lifetime name `'missing`
|
error[E0261]: use of undeclared lifetime name `'missing`
|
||||||
--> $DIR/dont-canonicalize-re-error.rs:25:26
|
--> $DIR/dont-canonicalize-re-error.rs:27:26
|
||||||
|
|
|
|
||||||
LL | impl<A: Sized> Constrain<'missing> for W<A> {}
|
LL | impl<A: Sized> Constrain<'missing> for W<A> {}
|
||||||
| ^^^^^^^^ undeclared lifetime
|
| ^^^^^^^^ undeclared lifetime
|
||||||
@@ -10,13 +10,13 @@ LL | impl<'missing, A: Sized> Constrain<'missing> for W<A> {}
|
|||||||
| +++++++++
|
| +++++++++
|
||||||
|
|
||||||
error[E0119]: conflicting implementations of trait `Tr<'_>` for type `W<_>`
|
error[E0119]: conflicting implementations of trait `Tr<'_>` for type `W<_>`
|
||||||
--> $DIR/dont-canonicalize-re-error.rs:21:1
|
--> $DIR/dont-canonicalize-re-error.rs:23:1
|
||||||
|
|
|
|
||||||
LL | impl<'a, A: ?Sized> Tr<'a> for W<A> {}
|
LL | impl<'a, A> Tr<'a> for W<A> {}
|
||||||
| ----------------------------------- first implementation here
|
| --------------------------- first implementation here
|
||||||
LL | struct W<A: ?Sized>(A);
|
LL | struct W<A>(A);
|
||||||
LL | impl<'a, A: ?Sized> Tr<'a> for A where A: Constrain<'a> {}
|
LL | impl<'a, A> Tr<'a> for A where A: Constrain<'a> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
//@ revisions: normalize_param_env normalize_obligation hrtb
|
//@ revisions: normalize_param_env normalize_obligation hrtb
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
#[cfg(normalize_param_env)]
|
#[cfg(normalize_param_env)]
|
||||||
@@ -11,11 +13,11 @@ trait Foo {
|
|||||||
type Gat<'b> where for<'a> <Self as MirrorRegion<'a>>::Assoc: 'b;
|
type Gat<'b> where for<'a> <Self as MirrorRegion<'a>>::Assoc: 'b;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Mirror { type Assoc: ?Sized; }
|
trait Mirror { type Assoc; }
|
||||||
impl<T: ?Sized> Mirror for T { type Assoc = T; }
|
impl<T> Mirror for T { type Assoc = T; }
|
||||||
|
|
||||||
trait MirrorRegion<'a> { type Assoc: ?Sized; }
|
trait MirrorRegion<'a> { type Assoc; }
|
||||||
impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; }
|
impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; }
|
||||||
|
|
||||||
impl<T> Foo for T {
|
impl<T> Foo for T {
|
||||||
#[cfg(normalize_param_env)]
|
#[cfg(normalize_param_env)]
|
||||||
|
|||||||
@@ -4,16 +4,18 @@
|
|||||||
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
|
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
|
||||||
|
|
||||||
#![feature(lazy_type_alias)]
|
#![feature(lazy_type_alias)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
type Id<T: ?Sized> = T;
|
type Id<T> = T;
|
||||||
trait NotImplemented {}
|
trait NotImplemented {}
|
||||||
|
|
||||||
struct W<T: ?Sized, U: ?Sized>(*const T, *const U);
|
struct W<T, U>(*const T, *const U);
|
||||||
trait Trait {
|
trait Trait {
|
||||||
type Assoc: ?Sized;
|
type Assoc;
|
||||||
}
|
}
|
||||||
impl<T: ?Sized + Trait> Trait for W<T, T> {
|
impl<T: Trait> Trait for W<T, T> {
|
||||||
#[cfg(ai)]
|
#[cfg(ai)]
|
||||||
type Assoc = W<T::Assoc, Id<T::Assoc>>;
|
type Assoc = W<T::Assoc, Id<T::Assoc>>;
|
||||||
#[cfg(ia)]
|
#[cfg(ia)]
|
||||||
@@ -22,8 +24,8 @@ impl<T: ?Sized + Trait> Trait for W<T, T> {
|
|||||||
type Assoc = W<Id<T::Assoc>, Id<T::Assoc>>;
|
type Assoc = W<Id<T::Assoc>, Id<T::Assoc>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Overlap<T: ?Sized> {}
|
trait Overlap<T> {}
|
||||||
impl<T: ?Sized> Overlap<T> for W<T, T> {}
|
impl<T> Overlap<T> for W<T, T> {}
|
||||||
impl<T: ?Sized + Trait + NotImplemented> Overlap<T::Assoc> for T {}
|
impl<T: Trait + NotImplemented> Overlap<T::Assoc> for T {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
//@ compile-flags: -Znext-solver=coherence
|
//@ compile-flags: -Znext-solver=coherence
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
// A regression test for trait-system-refactor-initiative#70.
|
// A regression test for trait-system-refactor-initiative#70.
|
||||||
|
|
||||||
@@ -7,8 +9,8 @@ trait Trait {
|
|||||||
type Assoc;
|
type Assoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct W<T: ?Sized>(*mut T);
|
struct W<T>(*mut T);
|
||||||
impl<T: ?Sized> Trait for W<W<T>>
|
impl<T> Trait for W<W<T>>
|
||||||
where
|
where
|
||||||
W<T>: Trait,
|
W<T>: Trait,
|
||||||
{
|
{
|
||||||
@@ -20,6 +22,6 @@ impl<T: Trait<Assoc = u32>> NoOverlap for T {}
|
|||||||
// `Projection(<W<_> as Trait>::Assoc, u32)` should result in error even
|
// `Projection(<W<_> as Trait>::Assoc, u32)` should result in error even
|
||||||
// though applying the impl results in overflow. This is necessary to match
|
// though applying the impl results in overflow. This is necessary to match
|
||||||
// the behavior of the old solver.
|
// the behavior of the old solver.
|
||||||
impl<T: ?Sized> NoOverlap for W<T> {}
|
impl<T> NoOverlap for W<T> {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/171>.
|
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/171>.
|
||||||
// Tests that we don't try to replace `<V as Super>::Output` when replacing projections in the
|
// Tests that we don't try to replace `<V as Super>::Output` when replacing projections in the
|
||||||
@@ -13,9 +15,9 @@ pub trait Super {
|
|||||||
type Output;
|
type Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bound<T: Trait + ?Sized>() {}
|
fn bound<T: Trait>() {}
|
||||||
|
|
||||||
fn visit_simd_operator<V: Super + ?Sized>() {
|
fn visit_simd_operator<V: Super>() {
|
||||||
bound::<dyn Trait<Output = <V as Super>::Output>>();
|
bound::<dyn Trait<Output = <V as Super>::Output>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![rustc_no_implicit_bounds]
|
||||||
|
|
||||||
trait Hello {}
|
trait Hello {}
|
||||||
|
|
||||||
struct Foo<'a, T: ?Sized>(&'a T);
|
struct Foo<'a, T>(&'a T);
|
||||||
|
|
||||||
impl<'a, T: ?Sized> Hello for Foo<'a, &'a T> where Foo<'a, T>: Hello {}
|
impl<'a, T> Hello for Foo<'a, &'a T> where Foo<'a, T>: Hello {}
|
||||||
|
|
||||||
impl Hello for Foo<'static, i32> {}
|
impl Hello for Foo<'static, i32> {}
|
||||||
|
|
||||||
fn hello<T: ?Sized + Hello>() {}
|
fn hello<T: Hello>() {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
hello();
|
hello();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error[E0283]: type annotations needed
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/overflow-computing-ambiguity.rs:12:5
|
--> $DIR/overflow-computing-ambiguity.rs:15:5
|
||||||
|
|
|
|
||||||
LL | hello();
|
LL | hello();
|
||||||
| ^^^^^ cannot infer type of the type parameter `T` declared on the function `hello`
|
| ^^^^^ cannot infer type of the type parameter `T` declared on the function `hello`
|
||||||
@@ -9,10 +9,10 @@ LL | hello();
|
|||||||
Foo<'a, &'a T>
|
Foo<'a, &'a T>
|
||||||
Foo<'static, i32>
|
Foo<'static, i32>
|
||||||
note: required by a bound in `hello`
|
note: required by a bound in `hello`
|
||||||
--> $DIR/overflow-computing-ambiguity.rs:9:22
|
--> $DIR/overflow-computing-ambiguity.rs:12:13
|
||||||
|
|
|
|
||||||
LL | fn hello<T: ?Sized + Hello>() {}
|
LL | fn hello<T: Hello>() {}
|
||||||
| ^^^^^ required by this bound in `hello`
|
| ^^^^^ required by this bound in `hello`
|
||||||
help: consider specifying the generic argument
|
help: consider specifying the generic argument
|
||||||
|
|
|
|
||||||
LL | hello::<T>();
|
LL | hello::<T>();
|
||||||
|
|||||||
Reference in New Issue
Block a user