}
ty::ReVar(vid) => {
- let r = self
+ let resolved_vid = self
.infcx
.unwrap()
.inner
.borrow_mut()
.unwrap_region_constraints()
- .opportunistic_resolve_var(self.tcx, vid);
+ .opportunistic_resolve_var(vid);
debug!(
"canonical: region var found with vid {:?}, \
opportunistically resolved to {:?}",
vid, r
);
+ // micro-optimize -- avoid an interner look-up if the vid
+ // hasn't changed.
+ let r = if vid == resolved_vid {
+ r
+ } else {
+ self.tcx.mk_region(ty::ReVar(resolved_vid))
+ };
self.canonicalize_region_mode.canonicalize_free_region(self, r)
}
/// R1 <= R2 and R2 <= R1 and (b) we unify the two regions in this
/// table. You can then call `opportunistic_resolve_var` early
/// which will map R1 and R2 to some common region (i.e., either
- /// R1 or R2). This is important when dropck and other such code
- /// is iterating to a fixed point, because otherwise we sometimes
- /// would wind up with a fresh stream of region variables that
- /// have been equated but appear distinct.
+ /// R1 or R2). This is important when fulfillment, dropck and other such
+ /// code is iterating to a fixed point, because otherwise we sometimes
+ /// would wind up with a fresh stream of region variables that have been
+ /// equated but appear distinct.
pub(super) unification_table: ut::UnificationTableStorage<ty::RegionVid>,
/// a flag set to true when we perform any unifications; this is used
}
}
- pub fn opportunistic_resolve_var(
- &mut self,
- tcx: TyCtxt<'tcx>,
- rid: RegionVid,
- ) -> ty::Region<'tcx> {
- let vid = self.unification_table().probe_value(rid).min_vid;
- tcx.mk_region(ty::ReVar(vid))
+ pub fn opportunistic_resolve_var(&mut self, rid: RegionVid) -> ty::RegionVid {
+ self.unification_table().probe_value(rid).min_vid
}
fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
}
}
-/// The opportunistic type and region resolver is similar to the
-/// opportunistic type resolver, but also opportunistically resolves
-/// regions. It is useful for canonicalization.
-pub struct OpportunisticTypeAndRegionResolver<'a, 'tcx> {
+/// The opportunistic region resolver opportunistically resolves regions
+/// variables to the variable with the least variable id. It is used when
+/// normlizing projections to avoid hitting the recursion limit by creating
+/// many versions of a predicate for types that in the end have to unify.
+///
+/// If you want to resolve type and const variables as well, call
+/// [InferCtxt::resolve_vars_if_possible] first.
+pub struct OpportunisticRegionResolver<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
}
-impl<'a, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'tcx> {
+impl<'a, 'tcx> OpportunisticRegionResolver<'a, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
- OpportunisticTypeAndRegionResolver { infcx }
+ OpportunisticRegionResolver { infcx }
}
}
-impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver<'a, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !t.needs_infer() {
+ if !t.has_infer_regions() {
t // micro-optimize -- if there is nothing in this type that this fold affects...
} else {
- let t0 = self.infcx.shallow_resolve(t);
- t0.super_fold_with(self)
+ t.super_fold_with(self)
}
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReVar(rid) => self
- .infcx
- .inner
- .borrow_mut()
- .unwrap_region_constraints()
- .opportunistic_resolve_var(self.tcx(), rid),
+ ty::ReVar(rid) => {
+ let resolved = self
+ .infcx
+ .inner
+ .borrow_mut()
+ .unwrap_region_constraints()
+ .opportunistic_resolve_var(rid);
+ if resolved == rid { r } else { self.tcx().mk_region(ty::ReVar(resolved)) }
+ }
_ => r,
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
- if !ct.needs_infer() {
+ if !ct.has_infer_regions() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
- let c0 = self.infcx.shallow_resolve(ct);
- c0.super_fold_with(self)
+ ct.super_fold_with(self)
}
}
}
fn has_param_types_or_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
}
+ fn has_infer_regions(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_RE_INFER)
+ }
fn has_infer_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
use rustc_errors::ErrorReported;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::{FnOnceTraitLangItem, GeneratorTraitLangItem};
+use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::util::IntTypeExt;
) -> Progress<'tcx> {
debug!("confirm_candidate(candidate={:?}, obligation={:?})", candidate, obligation);
- match candidate {
+ let mut progress = match candidate {
ProjectionTyCandidate::ParamEnv(poly_projection)
| ProjectionTyCandidate::TraitDef(poly_projection) => {
confirm_param_env_candidate(selcx, obligation, poly_projection)
ProjectionTyCandidate::Select(impl_source) => {
confirm_select_candidate(selcx, obligation, obligation_trait_ref, impl_source)
}
+ };
+ // When checking for cycle during evaluation, we compare predicates with
+ // "syntactic" equality. Since normalization generally introduces a type
+ // with new region variables, we need to resolve them to existing variables
+ // when possible for this to work. See `auto-trait-projection-recursion.rs`
+ // for a case where this matters.
+ if progress.ty.has_infer_regions() {
+ progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty);
}
+ progress
}
fn confirm_select_candidate<'cx, 'tcx>(
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
- --> $DIR/project-fn-ret-invariant.rs:48:8
+ --> $DIR/project-fn-ret-invariant.rs:48:4
|
LL | bar(foo, x)
- | ^^^
+ | ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8...
--> $DIR/project-fn-ret-invariant.rs:44:8
+++ /dev/null
-// run-pass
-
-#![allow(path_statements)]
-#![allow(dead_code)]
-macro_rules! auto {
- () => (struct S;)
-}
-
-auto!();
-
-fn auto() {}
-
-fn main() {
- auto();
- let auto = 10;
- auto;
- auto as u8;
-}
+++ /dev/null
-#![feature(optin_builtin_traits)]
-
-auto trait Generic<T> {}
-//~^ auto traits cannot have generic parameters [E0567]
-auto trait Bound : Copy {}
-//~^ auto traits cannot have super traits [E0568]
-auto trait MyTrait { fn foo() {} }
-//~^ auto traits cannot have methods or associated items [E0380]
-fn main() {}
+++ /dev/null
-error[E0567]: auto traits cannot have generic parameters
- --> $DIR/auto-trait-validation.rs:3:19
- |
-LL | auto trait Generic<T> {}
- | -------^^^ help: remove the parameters
- | |
- | auto trait cannot have generic parameters
-
-error[E0568]: auto traits cannot have super traits
- --> $DIR/auto-trait-validation.rs:5:20
- |
-LL | auto trait Bound : Copy {}
- | ----- ^^^^ help: remove the super traits
- | |
- | auto trait cannot have super traits
-
-error[E0380]: auto traits cannot have methods or associated items
- --> $DIR/auto-trait-validation.rs:7:25
- |
-LL | auto trait MyTrait { fn foo() {} }
- | ------- ^^^
- | |
- | auto trait cannot have items
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0380, E0567, E0568.
-For more information about an error, try `rustc --explain E0380`.
--- /dev/null
+// run-pass
+
+#![allow(path_statements)]
+#![allow(dead_code)]
+macro_rules! auto {
+ () => (struct S;)
+}
+
+auto!();
+
+fn auto() {}
+
+fn main() {
+ auto();
+ let auto = 10;
+ auto;
+ auto as u8;
+}
--- /dev/null
+// Checking the `Send` bound in `main` requires:
+//
+// checking <C<'static> as Y>::P: Send
+// which normalizes to Box<X<C<'?1>>>: Send
+// which needs X<C<'?1>>: Send
+// which needs <C<'?1> as Y>::P: Send
+//
+// At this point we used to normalize the predicate to `Box<X<C<'?2>>>: Send`
+// and continue in a loop where we created new region variables to the
+// recursion limit. To avoid this we now "canonicalize" region variables to
+// lowest unified region vid. This means we instead have to prove
+// `Box<X<C<'?1>>>: Send`, which we can because auto traits are coinductive.
+
+// check-pass
+
+// Avoid a really long error message if this regresses.
+#![recursion_limit="20"]
+
+trait Y {
+ type P;
+}
+
+impl<'a> Y for C<'a> {
+ type P = Box<X<C<'a>>>;
+}
+
+struct C<'a>(&'a ());
+struct X<T: Y>(T::P);
+
+fn is_send<S: Send>() {}
+
+fn main() {
+ is_send::<X<C<'static>>>();
+}
--- /dev/null
+#![feature(optin_builtin_traits)]
+
+auto trait Generic<T> {}
+//~^ auto traits cannot have generic parameters [E0567]
+auto trait Bound : Copy {}
+//~^ auto traits cannot have super traits [E0568]
+auto trait MyTrait { fn foo() {} }
+//~^ auto traits cannot have methods or associated items [E0380]
+fn main() {}
--- /dev/null
+error[E0567]: auto traits cannot have generic parameters
+ --> $DIR/auto-trait-validation.rs:3:19
+ |
+LL | auto trait Generic<T> {}
+ | -------^^^ help: remove the parameters
+ | |
+ | auto trait cannot have generic parameters
+
+error[E0568]: auto traits cannot have super traits
+ --> $DIR/auto-trait-validation.rs:5:20
+ |
+LL | auto trait Bound : Copy {}
+ | ----- ^^^^ help: remove the super traits
+ | |
+ | auto trait cannot have super traits
+
+error[E0380]: auto traits cannot have methods or associated items
+ --> $DIR/auto-trait-validation.rs:7:25
+ |
+LL | auto trait MyTrait { fn foo() {} }
+ | ------- ^^^
+ | |
+ | auto trait cannot have items
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0380, E0567, E0568.
+For more information about an error, try `rustc --explain E0380`.
--- /dev/null
+// run-pass
+#![allow(unused_doc_comments)]
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait Auto {}
+unsafe auto trait AutoUnsafe {}
+
+impl !Auto for bool {}
+impl !AutoUnsafe for bool {}
+
+struct AutoBool(bool);
+
+impl Auto for AutoBool {}
+unsafe impl AutoUnsafe for AutoBool {}
+
+fn take_auto<T: Auto>(_: T) {}
+fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
+
+fn main() {
+ // Parse inside functions.
+ auto trait AutoInner {}
+ unsafe auto trait AutoUnsafeInner {}
+
+ take_auto(0);
+ take_auto(AutoBool(true));
+ take_auto_unsafe(0);
+ take_auto_unsafe(AutoBool(true));
+
+ /// Auto traits are allowed in trait object bounds.
+ let _: &(dyn Send + Auto) = &0;
+}
--- /dev/null
+//~ ERROR
+
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+unsafe auto trait Trait {
+ type Output; //~ ERROR E0380
+}
+
+fn call_method<T: Trait>(x: T) {}
+
+fn main() {
+ // ICE
+ call_method(());
+}
--- /dev/null
+error[E0380]: auto traits cannot have methods or associated items
+ --> $DIR/issue-23080-2.rs:7:10
+ |
+LL | unsafe auto trait Trait {
+ | ----- auto trait cannot have items
+LL | type Output;
+ | ^^^^^^
+
+error[E0275]: overflow evaluating the requirement `<() as Trait>::Output`
+ |
+ = note: required because of the requirements on the impl of `Trait` for `()`
+ = note: required because of the requirements on the impl of `Trait` for `()`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0275, E0380.
+For more information about an error, try `rustc --explain E0275`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+unsafe auto trait Trait {
+ fn method(&self) { //~ ERROR E0380
+ println!("Hello");
+ }
+}
+
+fn call_method<T: Trait>(x: T) {
+ x.method();
+}
+
+fn main() {
+ // ICE
+ call_method(());
+}
--- /dev/null
+error[E0380]: auto traits cannot have methods or associated items
+ --> $DIR/issue-23080.rs:5:8
+ |
+LL | unsafe auto trait Trait {
+ | ----- auto trait cannot have items
+LL | fn method(&self) {
+ | ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0380`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
+impl<T:Magic> Magic for T {}
+
+fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
+
+#[derive(Debug)]
+struct NoClone;
+
+fn main() {
+ let (a, b) = copy(NoClone);
+ println!("{:?} {:?}", a, b);
+}
--- /dev/null
+error[E0568]: auto traits cannot have super traits
+ --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:20
+ |
+LL | auto trait Magic : Sized where Option<Self> : Magic {}
+ | ----- ^^^^^ help: remove the super traits
+ | |
+ | auto trait cannot have super traits
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0568`.
--- /dev/null
+// This test is for #29859, we need to ensure auto traits,
+// (also known previously as default traits), do not have
+// supertraits. Since the compiler synthesizes these
+// instances on demand, we are essentially enabling
+// users to write axioms if we view trait selection,
+// as a proof system.
+//
+// For example the below test allows us to add the rule:
+// forall (T : Type), T : Copy
+//
+// Providing a copy instance for *any* type, which
+// is most definitely unsound. Imagine copying a
+// type that contains a mutable reference, enabling
+// mutable aliasing.
+//
+// You can imagine an even more dangerous test,
+// which currently compiles on nightly.
+//
+// fn main() {
+// let mut i = 10;
+// let (a, b) = copy(&mut i);
+// println!("{:?} {:?}", a, b);
+// }
+
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait Magic: Copy {} //~ ERROR E0568
+impl<T:Magic> Magic for T {}
+
+fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
+
+#[derive(Debug)]
+struct NoClone;
+
+fn main() {
+ let (a, b) = copy(NoClone);
+ println!("{:?} {:?}", a, b);
+}
--- /dev/null
+error[E0568]: auto traits cannot have super traits
+ --> $DIR/typeck-auto-trait-no-supertraits.rs:28:19
+ |
+LL | auto trait Magic: Copy {}
+ | ----- ^^^^ help: remove the super traits
+ | |
+ | auto trait cannot have super traits
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0568`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait MyTrait {}
+
+struct MyS;
+
+struct MyS2;
+
+impl !MyTrait for MyS2 {}
+
+fn is_mytrait<T: MyTrait>() {}
+
+fn main() {
+ is_mytrait::<MyS>();
+
+ is_mytrait::<(MyS2, MyS)>();
+ //~^ ERROR `MyS2: MyTrait` is not satisfied
+}
--- /dev/null
+error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)`
+ --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5
+ |
+LL | fn is_mytrait<T: MyTrait>() {}
+ | ------- required by this bound in `is_mytrait`
+...
+LL | is_mytrait::<(MyS2, MyS)>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
+ |
+ = help: the following implementations were found:
+ <MyS2 as MyTrait>
+ = note: required because it appears within the type `(MyS2, MyS)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait MyTrait {}
+
+impl<T> !MyTrait for *mut T {}
+
+struct MyS;
+
+struct MyS2;
+
+impl !MyTrait for MyS2 {}
+
+struct MyS3;
+
+fn is_mytrait<T: MyTrait>() {}
+
+fn main() {
+ is_mytrait::<MyS>();
+
+ is_mytrait::<MyS2>();
+ //~^ ERROR `MyS2: MyTrait` is not satisfied
+}
--- /dev/null
+error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied
+ --> $DIR/typeck-default-trait-impl-constituent-types.rs:21:18
+ |
+LL | fn is_mytrait<T: MyTrait>() {}
+ | ------- required by this bound in `is_mytrait`
+...
+LL | is_mytrait::<MyS2>();
+ | ^^^^ the trait `MyTrait` is not implemented for `MyS2`
+ |
+ = help: the following implementations were found:
+ <MyS2 as MyTrait>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait MyTrait {}
+
+unsafe auto trait MyUnsafeTrait {}
+
+struct ThisImplsTrait;
+
+impl !MyUnsafeTrait for ThisImplsTrait {}
+
+
+struct ThisImplsUnsafeTrait;
+
+impl !MyTrait for ThisImplsUnsafeTrait {}
+
+fn is_my_trait<T: MyTrait>() {}
+fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
+
+fn main() {
+ is_my_trait::<ThisImplsTrait>();
+ is_my_trait::<ThisImplsUnsafeTrait>();
+ //~^ ERROR `ThisImplsUnsafeTrait: MyTrait` is not satisfied
+
+ is_my_unsafe_trait::<ThisImplsTrait>();
+ //~^ ERROR `ThisImplsTrait: MyUnsafeTrait` is not satisfied
+
+ is_my_unsafe_trait::<ThisImplsUnsafeTrait>();
+}
--- /dev/null
+error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied
+ --> $DIR/typeck-default-trait-impl-negation.rs:22:19
+ |
+LL | fn is_my_trait<T: MyTrait>() {}
+ | ------- required by this bound in `is_my_trait`
+...
+LL | is_my_trait::<ThisImplsUnsafeTrait>();
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
+ |
+ = help: the following implementations were found:
+ <ThisImplsUnsafeTrait as MyTrait>
+
+error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied
+ --> $DIR/typeck-default-trait-impl-negation.rs:25:26
+ |
+LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
+ | ------------- required by this bound in `is_my_unsafe_trait`
+...
+LL | is_my_unsafe_trait::<ThisImplsTrait>();
+ | ^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
+ |
+ = help: the following implementations were found:
+ <ThisImplsTrait as MyUnsafeTrait>
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies
+// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
+// other words, the auto impl only applies if there are no existing
+// impls whose types unify.
+
+#![feature(optin_builtin_traits)]
+#![feature(negative_impls)]
+
+auto trait Defaulted { }
+impl<'a,T:Signed> Defaulted for &'a T { }
+impl<'a,T:Signed> Defaulted for &'a mut T { }
+fn is_defaulted<T:Defaulted>() { }
+
+trait Signed { }
+impl Signed for i32 { }
+
+fn main() {
+ is_defaulted::<&'static i32>();
+ is_defaulted::<&'static u32>();
+ //~^ ERROR `u32: Signed` is not satisfied
+}
--- /dev/null
+error[E0277]: the trait bound `u32: Signed` is not satisfied
+ --> $DIR/typeck-default-trait-impl-precedence.rs:19:5
+ |
+LL | fn is_defaulted<T:Defaulted>() { }
+ | --------- required by this bound in `is_defaulted`
+...
+LL | is_defaulted::<&'static u32>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
+ |
+ = note: required because of the requirements on the impl of `Defaulted` for `&'static u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-//~ ERROR
-
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-unsafe auto trait Trait {
- type Output; //~ ERROR E0380
-}
-
-fn call_method<T: Trait>(x: T) {}
-
-fn main() {
- // ICE
- call_method(());
-}
+++ /dev/null
-error[E0380]: auto traits cannot have methods or associated items
- --> $DIR/issue-23080-2.rs:7:10
- |
-LL | unsafe auto trait Trait {
- | ----- auto trait cannot have items
-LL | type Output;
- | ^^^^^^
-
-error[E0275]: overflow evaluating the requirement `<() as Trait>::Output`
- |
- = note: required because of the requirements on the impl of `Trait` for `()`
- = note: required because of the requirements on the impl of `Trait` for `()`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0275, E0380.
-For more information about an error, try `rustc --explain E0275`.
+++ /dev/null
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-unsafe auto trait Trait {
- fn method(&self) { //~ ERROR E0380
- println!("Hello");
- }
-}
-
-fn call_method<T: Trait>(x: T) {
- x.method();
-}
-
-fn main() {
- // ICE
- call_method(());
-}
+++ /dev/null
-error[E0380]: auto traits cannot have methods or associated items
- --> $DIR/issue-23080.rs:5:8
- |
-LL | unsafe auto trait Trait {
- | ----- auto trait cannot have items
-LL | fn method(&self) {
- | ^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0380`.
+++ /dev/null
-// run-pass
-#![allow(unused_doc_comments)]
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait Auto {}
-unsafe auto trait AutoUnsafe {}
-
-impl !Auto for bool {}
-impl !AutoUnsafe for bool {}
-
-struct AutoBool(bool);
-
-impl Auto for AutoBool {}
-unsafe impl AutoUnsafe for AutoBool {}
-
-fn take_auto<T: Auto>(_: T) {}
-fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
-
-fn main() {
- // Parse inside functions.
- auto trait AutoInner {}
- unsafe auto trait AutoUnsafeInner {}
-
- take_auto(0);
- take_auto(AutoBool(true));
- take_auto_unsafe(0);
- take_auto_unsafe(AutoBool(true));
-
- /// Auto traits are allowed in trait object bounds.
- let _: &(dyn Send + Auto) = &0;
-}
--- /dev/null
+// Test that we don't hit the recursion limit for short cycles involving lifetimes.
+
+// Shouldn't hit this, we should realize that we're in a cycle sooner.
+#![recursion_limit="20"]
+
+trait NotAuto {}
+trait Y {
+ type P;
+}
+
+impl<'a> Y for C<'a> {
+ type P = Box<X<C<'a>>>;
+}
+
+struct C<'a>(&'a ());
+struct X<T: Y>(T::P);
+
+impl<T: NotAuto> NotAuto for Box<T> {}
+impl<T: Y> NotAuto for X<T> where T::P: NotAuto {}
+impl<'a> NotAuto for C<'a> {}
+
+fn is_send<S: NotAuto>() {}
+//~^ NOTE: required
+
+fn main() {
+ // Should only be a few notes.
+ is_send::<X<C<'static>>>();
+ //~^ ERROR overflow evaluating
+ //~| NOTE: required
+}
--- /dev/null
+error[E0275]: overflow evaluating the requirement `std::boxed::Box<X<C<'_>>>: NotAuto`
+ --> $DIR/traits-inductive-overflow-lifetime.rs:27:5
+ |
+LL | fn is_send<S: NotAuto>() {}
+ | ------- required by this bound in `is_send`
+...
+LL | is_send::<X<C<'static>>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: required because of the requirements on the impl of `NotAuto` for `X<C<'static>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
+++ /dev/null
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
-impl<T:Magic> Magic for T {}
-
-fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-
-#[derive(Debug)]
-struct NoClone;
-
-fn main() {
- let (a, b) = copy(NoClone);
- println!("{:?} {:?}", a, b);
-}
+++ /dev/null
-error[E0568]: auto traits cannot have super traits
- --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:20
- |
-LL | auto trait Magic : Sized where Option<Self> : Magic {}
- | ----- ^^^^^ help: remove the super traits
- | |
- | auto trait cannot have super traits
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0568`.
+++ /dev/null
-// This test is for #29859, we need to ensure auto traits,
-// (also known previously as default traits), do not have
-// supertraits. Since the compiler synthesizes these
-// instances on demand, we are essentially enabling
-// users to write axioms if we view trait selection,
-// as a proof system.
-//
-// For example the below test allows us to add the rule:
-// forall (T : Type), T : Copy
-//
-// Providing a copy instance for *any* type, which
-// is most definitely unsound. Imagine copying a
-// type that contains a mutable reference, enabling
-// mutable aliasing.
-//
-// You can imagine an even more dangerous test,
-// which currently compiles on nightly.
-//
-// fn main() {
-// let mut i = 10;
-// let (a, b) = copy(&mut i);
-// println!("{:?} {:?}", a, b);
-// }
-
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait Magic: Copy {} //~ ERROR E0568
-impl<T:Magic> Magic for T {}
-
-fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-
-#[derive(Debug)]
-struct NoClone;
-
-fn main() {
- let (a, b) = copy(NoClone);
- println!("{:?} {:?}", a, b);
-}
+++ /dev/null
-error[E0568]: auto traits cannot have super traits
- --> $DIR/typeck-auto-trait-no-supertraits.rs:28:19
- |
-LL | auto trait Magic: Copy {}
- | ----- ^^^^ help: remove the super traits
- | |
- | auto trait cannot have super traits
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0568`.
+++ /dev/null
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait MyTrait {}
-
-struct MyS;
-
-struct MyS2;
-
-impl !MyTrait for MyS2 {}
-
-fn is_mytrait<T: MyTrait>() {}
-
-fn main() {
- is_mytrait::<MyS>();
-
- is_mytrait::<(MyS2, MyS)>();
- //~^ ERROR `MyS2: MyTrait` is not satisfied
-}
+++ /dev/null
-error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)`
- --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5
- |
-LL | fn is_mytrait<T: MyTrait>() {}
- | ------- required by this bound in `is_mytrait`
-...
-LL | is_mytrait::<(MyS2, MyS)>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
- |
- = help: the following implementations were found:
- <MyS2 as MyTrait>
- = note: required because it appears within the type `(MyS2, MyS)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait MyTrait {}
-
-impl<T> !MyTrait for *mut T {}
-
-struct MyS;
-
-struct MyS2;
-
-impl !MyTrait for MyS2 {}
-
-struct MyS3;
-
-fn is_mytrait<T: MyTrait>() {}
-
-fn main() {
- is_mytrait::<MyS>();
-
- is_mytrait::<MyS2>();
- //~^ ERROR `MyS2: MyTrait` is not satisfied
-}
+++ /dev/null
-error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied
- --> $DIR/typeck-default-trait-impl-constituent-types.rs:21:18
- |
-LL | fn is_mytrait<T: MyTrait>() {}
- | ------- required by this bound in `is_mytrait`
-...
-LL | is_mytrait::<MyS2>();
- | ^^^^ the trait `MyTrait` is not implemented for `MyS2`
- |
- = help: the following implementations were found:
- <MyS2 as MyTrait>
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait MyTrait {}
-
-unsafe auto trait MyUnsafeTrait {}
-
-struct ThisImplsTrait;
-
-impl !MyUnsafeTrait for ThisImplsTrait {}
-
-
-struct ThisImplsUnsafeTrait;
-
-impl !MyTrait for ThisImplsUnsafeTrait {}
-
-fn is_my_trait<T: MyTrait>() {}
-fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
-
-fn main() {
- is_my_trait::<ThisImplsTrait>();
- is_my_trait::<ThisImplsUnsafeTrait>();
- //~^ ERROR `ThisImplsUnsafeTrait: MyTrait` is not satisfied
-
- is_my_unsafe_trait::<ThisImplsTrait>();
- //~^ ERROR `ThisImplsTrait: MyUnsafeTrait` is not satisfied
-
- is_my_unsafe_trait::<ThisImplsUnsafeTrait>();
-}
+++ /dev/null
-error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied
- --> $DIR/typeck-default-trait-impl-negation.rs:22:19
- |
-LL | fn is_my_trait<T: MyTrait>() {}
- | ------- required by this bound in `is_my_trait`
-...
-LL | is_my_trait::<ThisImplsUnsafeTrait>();
- | ^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
- |
- = help: the following implementations were found:
- <ThisImplsUnsafeTrait as MyTrait>
-
-error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied
- --> $DIR/typeck-default-trait-impl-negation.rs:25:26
- |
-LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
- | ------------- required by this bound in `is_my_unsafe_trait`
-...
-LL | is_my_unsafe_trait::<ThisImplsTrait>();
- | ^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
- |
- = help: the following implementations were found:
- <ThisImplsTrait as MyUnsafeTrait>
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies
-// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
-// other words, the auto impl only applies if there are no existing
-// impls whose types unify.
-
-#![feature(optin_builtin_traits)]
-#![feature(negative_impls)]
-
-auto trait Defaulted { }
-impl<'a,T:Signed> Defaulted for &'a T { }
-impl<'a,T:Signed> Defaulted for &'a mut T { }
-fn is_defaulted<T:Defaulted>() { }
-
-trait Signed { }
-impl Signed for i32 { }
-
-fn main() {
- is_defaulted::<&'static i32>();
- is_defaulted::<&'static u32>();
- //~^ ERROR `u32: Signed` is not satisfied
-}
+++ /dev/null
-error[E0277]: the trait bound `u32: Signed` is not satisfied
- --> $DIR/typeck-default-trait-impl-precedence.rs:19:5
- |
-LL | fn is_defaulted<T:Defaulted>() { }
- | --------- required by this bound in `is_defaulted`
-...
-LL | is_defaulted::<&'static u32>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
- |
- = note: required because of the requirements on the impl of `Defaulted` for `&'static u32`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.