Auto merge of #51042 - matthewjasper:reenable-trivial-bounds, r=nikomatsakis
Re-enable trivial bounds cc #50825 Remove implementations from global bounds in winnowing when there is ambiguity. This results in the reverse of #24066 happening sometimes. I'm not sure if anything can be done about that though. cc #48214 r? @nikomatsakis
This commit is contained in:
commit
1c5626f551
@ -648,13 +648,8 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
let predicates: Vec<_> =
|
let predicates: Vec<_> =
|
||||||
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
|
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
|
||||||
.filter(|p| !p.is_global() || p.has_late_bound_regions()) // (*)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// (*) FIXME(#50825) This shouldn't be needed.
|
|
||||||
// Removing the bounds here stopped them from being prefered in selection.
|
|
||||||
// See the issue-50825 ui tests for examples
|
|
||||||
|
|
||||||
debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
|
debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
|
||||||
predicates);
|
predicates);
|
||||||
|
|
||||||
|
@ -2011,9 +2011,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// attempt to evaluate recursive bounds to see if they are
|
// attempt to evaluate recursive bounds to see if they are
|
||||||
// satisfied.
|
// satisfied.
|
||||||
|
|
||||||
/// Returns true if `candidate_i` should be dropped in favor of
|
|
||||||
/// `candidate_j`. Generally speaking we will drop duplicate
|
|
||||||
/// candidates and prefer where-clause candidates.
|
|
||||||
/// Returns true if `victim` should be dropped in favor of
|
/// Returns true if `victim` should be dropped in favor of
|
||||||
/// `other`. Generally speaking we will drop duplicate
|
/// `other`. Generally speaking we will drop duplicate
|
||||||
/// candidates and prefer where-clause candidates.
|
/// candidates and prefer where-clause candidates.
|
||||||
@ -2025,13 +2022,46 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
other: &EvaluatedCandidate<'tcx>)
|
other: &EvaluatedCandidate<'tcx>)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
|
// Check if a bound would previously have been removed when normalizing
|
||||||
|
// the param_env so that it can be given the lowest priority. See
|
||||||
|
// #50825 for the motivation for this.
|
||||||
|
let is_global = |cand: &ty::PolyTraitRef<'_>| {
|
||||||
|
cand.is_global() && !cand.has_late_bound_regions()
|
||||||
|
};
|
||||||
|
|
||||||
if victim.candidate == other.candidate {
|
if victim.candidate == other.candidate {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
match other.candidate {
|
match other.candidate {
|
||||||
ObjectCandidate |
|
ParamCandidate(ref cand) => match victim.candidate {
|
||||||
ParamCandidate(_) | ProjectionCandidate => match victim.candidate {
|
AutoImplCandidate(..) => {
|
||||||
|
bug!(
|
||||||
|
"default implementations shouldn't be recorded \
|
||||||
|
when there are other valid candidates");
|
||||||
|
}
|
||||||
|
ImplCandidate(..) |
|
||||||
|
ClosureCandidate |
|
||||||
|
GeneratorCandidate |
|
||||||
|
FnPointerCandidate |
|
||||||
|
BuiltinObjectCandidate |
|
||||||
|
BuiltinUnsizeCandidate |
|
||||||
|
BuiltinCandidate { .. } => {
|
||||||
|
// Global bounds from the where clause should be ignored
|
||||||
|
// here (see issue #50825). Otherwise, we have a where
|
||||||
|
// clause so don't go around looking for impls.
|
||||||
|
!is_global(cand)
|
||||||
|
}
|
||||||
|
ObjectCandidate |
|
||||||
|
ProjectionCandidate => {
|
||||||
|
// Arbitrarily give param candidates priority
|
||||||
|
// over projection and object candidates.
|
||||||
|
!is_global(cand)
|
||||||
|
},
|
||||||
|
ParamCandidate(..) => false,
|
||||||
|
},
|
||||||
|
ObjectCandidate |
|
||||||
|
ProjectionCandidate => match victim.candidate {
|
||||||
AutoImplCandidate(..) => {
|
AutoImplCandidate(..) => {
|
||||||
bug!(
|
bug!(
|
||||||
"default implementations shouldn't be recorded \
|
"default implementations shouldn't be recorded \
|
||||||
@ -2044,8 +2074,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
BuiltinObjectCandidate |
|
BuiltinObjectCandidate |
|
||||||
BuiltinUnsizeCandidate |
|
BuiltinUnsizeCandidate |
|
||||||
BuiltinCandidate { .. } => {
|
BuiltinCandidate { .. } => {
|
||||||
// We have a where-clause so don't go around looking
|
|
||||||
// for impls.
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
ObjectCandidate |
|
ObjectCandidate |
|
||||||
@ -2054,22 +2082,44 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
// over projection and object candidates.
|
// over projection and object candidates.
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
ParamCandidate(..) => false,
|
ParamCandidate(ref cand) => is_global(cand),
|
||||||
},
|
},
|
||||||
ImplCandidate(other_def) => {
|
ImplCandidate(other_def) => {
|
||||||
// See if we can toss out `victim` based on specialization.
|
// See if we can toss out `victim` based on specialization.
|
||||||
// This requires us to know *for sure* that the `other` impl applies
|
// This requires us to know *for sure* that the `other` impl applies
|
||||||
// i.e. EvaluatedToOk:
|
// i.e. EvaluatedToOk:
|
||||||
if other.evaluation == EvaluatedToOk {
|
if other.evaluation == EvaluatedToOk {
|
||||||
if let ImplCandidate(victim_def) = victim.candidate {
|
match victim.candidate {
|
||||||
|
ImplCandidate(victim_def) => {
|
||||||
let tcx = self.tcx().global_tcx();
|
let tcx = self.tcx().global_tcx();
|
||||||
return tcx.specializes((other_def, victim_def)) ||
|
return tcx.specializes((other_def, victim_def)) ||
|
||||||
tcx.impls_are_allowed_to_overlap(other_def, victim_def);
|
tcx.impls_are_allowed_to_overlap(other_def, victim_def);
|
||||||
}
|
}
|
||||||
|
ParamCandidate(ref cand) => {
|
||||||
|
// Prefer the impl to a global where clause candidate.
|
||||||
|
return is_global(cand);
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
|
ClosureCandidate |
|
||||||
|
GeneratorCandidate |
|
||||||
|
FnPointerCandidate |
|
||||||
|
BuiltinObjectCandidate |
|
||||||
|
BuiltinUnsizeCandidate |
|
||||||
|
BuiltinCandidate { .. } => {
|
||||||
|
match victim.candidate {
|
||||||
|
ParamCandidate(ref cand) => {
|
||||||
|
// Prefer these to a global where-clause bound
|
||||||
|
// (see issue #50825)
|
||||||
|
is_global(cand) && other.evaluation == EvaluatedToOk
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,6 +711,7 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
|
|||||||
for pred in implied_obligations {
|
for pred in implied_obligations {
|
||||||
// Match the existing behavior.
|
// Match the existing behavior.
|
||||||
if pred.is_global() && !pred.has_late_bound_regions() {
|
if pred.is_global() && !pred.has_late_bound_regions() {
|
||||||
|
let pred = fcx.normalize_associated_types_in(span, &pred);
|
||||||
let obligation = traits::Obligation::new(
|
let obligation = traits::Obligation::new(
|
||||||
traits::ObligationCause::new(
|
traits::ObligationCause::new(
|
||||||
span,
|
span,
|
||||||
|
@ -28,7 +28,7 @@ union U where i32: Foo { f: i32 } //~ ERROR
|
|||||||
type Y where i32: Foo = (); // OK - bound is ignored
|
type Y where i32: Foo = (); // OK - bound is ignored
|
||||||
|
|
||||||
impl Foo for () where i32: Foo { //~ ERROR
|
impl Foo for () where i32: Foo { //~ ERROR
|
||||||
fn test(&self) { //~ ERROR
|
fn test(&self) {
|
||||||
3i32.test();
|
3i32.test();
|
||||||
Foo::test(&4i32);
|
Foo::test(&4i32);
|
||||||
generic_function(5i32);
|
generic_function(5i32);
|
||||||
@ -60,7 +60,7 @@ struct Dst<X: ?Sized> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct TwoStrs(str, str) where str: Sized; //~ ERROR
|
struct TwoStrs(str, str) where str: Sized; //~ ERROR
|
||||||
//~^ ERROR
|
|
||||||
|
|
||||||
fn unsized_local() where Dst<A>: Sized { //~ ERROR
|
fn unsized_local() where Dst<A>: Sized { //~ ERROR
|
||||||
let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
|
let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
|
||||||
|
@ -38,7 +38,7 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied
|
|||||||
--> $DIR/feature-gate-trivial_bounds.rs:30:1
|
--> $DIR/feature-gate-trivial_bounds.rs:30:1
|
||||||
|
|
|
|
||||||
LL | / impl Foo for () where i32: Foo { //~ ERROR
|
LL | / impl Foo for () where i32: Foo { //~ ERROR
|
||||||
LL | | fn test(&self) { //~ ERROR
|
LL | | fn test(&self) {
|
||||||
LL | | 3i32.test();
|
LL | | 3i32.test();
|
||||||
LL | | Foo::test(&4i32);
|
LL | | Foo::test(&4i32);
|
||||||
LL | | generic_function(5i32);
|
LL | | generic_function(5i32);
|
||||||
@ -97,15 +97,6 @@ LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
|
|||||||
= help: see issue #48214
|
= help: see issue #48214
|
||||||
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
|
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
|
|
||||||
--> $DIR/feature-gate-trivial_bounds.rs:62:16
|
|
||||||
|
|
|
||||||
LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
|
|
||||||
| ^^^ `str` does not have a constant size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `std::marker::Sized` is not implemented for `str`
|
|
||||||
= note: only the last field of a struct may have a dynamically sized type
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `A + 'static: std::marker::Sized` is not satisfied in `Dst<A + 'static>`
|
error[E0277]: the trait bound `A + 'static: std::marker::Sized` is not satisfied in `Dst<A + 'static>`
|
||||||
--> $DIR/feature-gate-trivial_bounds.rs:65:1
|
--> $DIR/feature-gate-trivial_bounds.rs:65:1
|
||||||
|
|
|
|
||||||
@ -131,22 +122,6 @@ LL | | }
|
|||||||
= help: see issue #48214
|
= help: see issue #48214
|
||||||
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
|
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0277]: the trait bound `i32: Foo` is not satisfied
|
error: aborting due to 11 previous errors
|
||||||
--> $DIR/feature-gate-trivial_bounds.rs:31:5
|
|
||||||
|
|
|
||||||
LL | / fn test(&self) { //~ ERROR
|
|
||||||
LL | | 3i32.test();
|
|
||||||
LL | | Foo::test(&4i32);
|
|
||||||
LL | | generic_function(5i32);
|
|
||||||
LL | | }
|
|
||||||
| |_____^ the trait `Foo` is not implemented for `i32`
|
|
||||||
|
|
|
||||||
note: required by `Foo`
|
|
||||||
--> $DIR/feature-gate-trivial_bounds.rs:14:1
|
|
||||||
|
|
|
||||||
LL | pub trait Foo {
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// run-pass
|
// run-pass
|
||||||
// regression test for issue #50825
|
// regression test for issue #50825
|
||||||
// Make sure that the `impl` bound (): X<T = ()> is prefered over
|
// Make sure that the `impl` bound (): X<T = ()> is preferred over
|
||||||
// the (): X bound in the where clause.
|
// the (): X bound in the where clause.
|
||||||
|
|
||||||
trait X {
|
trait X {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// run-pass
|
// run-pass
|
||||||
// regression test for issue #50825
|
// regression test for issue #50825
|
||||||
// Make sure that the built-in bound {integer}: Sized is prefered over
|
// Make sure that the built-in bound {integer}: Sized is preferred over
|
||||||
// the u64: Sized bound in the where clause.
|
// the u64: Sized bound in the where clause.
|
||||||
|
|
||||||
fn foo(y: &[()])
|
fn foo(y: &[()])
|
||||||
|
40
src/test/ui/issue-51044.rs
Normal file
40
src/test/ui/issue-51044.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// run-pass
|
||||||
|
// regression test for issue #50825
|
||||||
|
// Check that the feature gate normalizes associated types.
|
||||||
|
|
||||||
|
#![allow(dead_code)]
|
||||||
|
struct Foo<T>(T);
|
||||||
|
struct Duck;
|
||||||
|
struct Quack;
|
||||||
|
|
||||||
|
trait Hello<A> where A: Animal {
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Animal {
|
||||||
|
type Noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Loud<R> {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Loud<Quack> for f32 {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animal for Duck {
|
||||||
|
type Noise = Quack;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hello<Duck> for Foo<f32> where f32: Loud<<Duck as Animal>::Noise> {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// run-pass
|
// run-pass
|
||||||
// Inconsistent bounds with trait implementations
|
// Inconsistent bounds with trait implementations
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// Check that reborrows are still illegal with Copy mutable references
|
// Check that reborrows are still illegal with Copy mutable references
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// run-pass
|
// run-pass
|
||||||
// Check tautalogically false `Copy` bounds
|
// Check tautalogically false `Copy` bounds
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
|
33
src/test/ui/trivial-bounds-inconsistent-projection-error.rs
Normal file
33
src/test/ui/trivial-bounds-inconsistent-projection-error.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(trivial_bounds)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
struct B;
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
type X;
|
||||||
|
fn get_x() -> Self::X;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl A for B {
|
||||||
|
type X = u8;
|
||||||
|
fn get_x() -> u8 { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn global_bound_is_hidden() -> u8
|
||||||
|
where
|
||||||
|
B: A<X = i32>
|
||||||
|
{
|
||||||
|
B::get_x() //~ ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main () {}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/trivial-bounds-inconsistent-projection-error.rs:30:5
|
||||||
|
|
|
||||||
|
LL | fn global_bound_is_hidden() -> u8
|
||||||
|
| -- expected `u8` because of return type
|
||||||
|
...
|
||||||
|
LL | B::get_x() //~ ERROR
|
||||||
|
| ^^^^^^^^^^ expected u8, found i32
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
64
src/test/ui/trivial-bounds-inconsistent-projection.rs
Normal file
64
src/test/ui/trivial-bounds-inconsistent-projection.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// run-pass
|
||||||
|
// Check that global bounds result in the expected choice of associated type
|
||||||
|
|
||||||
|
#![feature(trivial_bounds)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
struct B;
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
type X;
|
||||||
|
fn get_x() -> Self::X;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl A for B {
|
||||||
|
type X = u8;
|
||||||
|
fn get_x() -> u8 { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn underspecified_bound() -> u8
|
||||||
|
where
|
||||||
|
B: A
|
||||||
|
{
|
||||||
|
B::get_x()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inconsistent_bound() -> i32
|
||||||
|
where
|
||||||
|
B: A<X = i32>
|
||||||
|
{
|
||||||
|
B::get_x()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn redundant_bound() -> u8
|
||||||
|
where
|
||||||
|
B: A<X = u8>
|
||||||
|
{
|
||||||
|
B::get_x()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inconsistent_dup_bound() -> i32
|
||||||
|
where
|
||||||
|
B: A<X = i32> + A
|
||||||
|
{
|
||||||
|
B::get_x()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn redundant_dup_bound() -> u8
|
||||||
|
where
|
||||||
|
B: A<X = u8> + A
|
||||||
|
{
|
||||||
|
B::get_x()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main () {}
|
57
src/test/ui/trivial-bounds-inconsistent-projection.stderr
Normal file
57
src/test/ui/trivial-bounds-inconsistent-projection.stderr
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
||||||
|
--> $DIR/trivial-bounds-inconsistent-projection.rs:29:1
|
||||||
|
|
|
||||||
|
LL | / fn underspecified_bound() -> u8
|
||||||
|
LL | | where
|
||||||
|
LL | | B: A
|
||||||
|
LL | | {
|
||||||
|
LL | | B::get_x()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
= note: #[warn(trivial_bounds)] on by default
|
||||||
|
|
||||||
|
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
||||||
|
--> $DIR/trivial-bounds-inconsistent-projection.rs:36:1
|
||||||
|
|
|
||||||
|
LL | / fn inconsistent_bound() -> i32
|
||||||
|
LL | | where
|
||||||
|
LL | | B: A<X = i32>
|
||||||
|
LL | | {
|
||||||
|
LL | | B::get_x()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
||||||
|
--> $DIR/trivial-bounds-inconsistent-projection.rs:43:1
|
||||||
|
|
|
||||||
|
LL | / fn redundant_bound() -> u8
|
||||||
|
LL | | where
|
||||||
|
LL | | B: A<X = u8>
|
||||||
|
LL | | {
|
||||||
|
LL | | B::get_x()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
||||||
|
--> $DIR/trivial-bounds-inconsistent-projection.rs:50:1
|
||||||
|
|
|
||||||
|
LL | / fn inconsistent_dup_bound() -> i32
|
||||||
|
LL | | where
|
||||||
|
LL | | B: A<X = i32> + A
|
||||||
|
LL | | {
|
||||||
|
LL | | B::get_x()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
||||||
|
--> $DIR/trivial-bounds-inconsistent-projection.rs:57:1
|
||||||
|
|
|
||||||
|
LL | / fn redundant_dup_bound() -> u8
|
||||||
|
LL | | where
|
||||||
|
LL | | B: A<X = u8> + A
|
||||||
|
LL | | {
|
||||||
|
LL | | B::get_x()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// run-pass
|
// run-pass
|
||||||
// Check tautalogically false `Sized` bounds
|
// Check tautalogically false `Sized` bounds
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// run-pass
|
// run-pass
|
||||||
// Test that inconsistent bounds are used in well-formedness checks
|
// Test that inconsistent bounds are used in well-formedness checks
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
// Check that tautalogically false bounds are accepted, and are used
|
// Check that tautalogically false bounds are accepted, and are used
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// Check that false Copy bounds don't leak
|
// Check that false Copy bounds don't leak
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
// Check that false bounds don't leak
|
// Check that false bounds don't leak
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-test FIXME(#50825)
|
|
||||||
#![feature(trivial_bounds)]
|
#![feature(trivial_bounds)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![deny(trivial_bounds)]
|
#![deny(trivial_bounds)]
|
||||||
|
28
src/test/ui/trivial-bounds-object.rs
Normal file
28
src/test/ui/trivial-bounds-object.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// run-pass
|
||||||
|
// Check that the object bound dyn A + 'a: A is preferred over the
|
||||||
|
// where clause bound dyn A + 'static: A.
|
||||||
|
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
fn test(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(x: &dyn A)
|
||||||
|
where
|
||||||
|
dyn A + 'static: A, // Using this bound would lead to a lifetime error.
|
||||||
|
{
|
||||||
|
x.test();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main () {}
|
Loading…
x
Reference in New Issue
Block a user