From 47b16b656376021041110df42e71c551fb2c4881 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sun, 4 Aug 2019 21:50:05 +1200 Subject: [PATCH 1/9] Remove recommendation about idiomatic syntax for Arc::Clone Signed-off-by: Nick Cameron --- src/liballoc/sync.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index e11873218e8a4..de8db01ce8bd7 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -106,10 +106,6 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// // a, b, and foo are all Arcs that point to the same memory location /// ``` /// -/// The [`Arc::clone(&from)`] syntax is the most idiomatic because it conveys more explicitly -/// the meaning of the code. In the example above, this syntax makes it easier to see that -/// this code is creating a new reference rather than copying the whole content of foo. -/// /// ## `Deref` behavior /// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), From f0b394bfb65ebe1c58c9cf131c6d31e63ed79ba6 Mon Sep 17 00:00:00 2001 From: Salim Nasser Date: Sat, 17 Aug 2019 18:56:38 -0700 Subject: [PATCH 2/9] Fixed: error: unnecessary trailing semicolon --- src/libstd/sys/vxworks/process/process_common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs index 397200c39c2d7..ba797354a7380 100644 --- a/src/libstd/sys/vxworks/process/process_common.rs +++ b/src/libstd/sys/vxworks/process/process_common.rs @@ -155,7 +155,7 @@ impl Command { _f: Box io::Result<()> + Send + Sync>, ) { // Fork() is not supported in vxWorks so no way to run the closure in the new procecss. - unimplemented!();; + unimplemented!(); } pub fn stdin(&mut self, stdin: Stdio) { From ef3e66d69f18574b3f32fca76d4324c486afa874 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Mon, 19 Aug 2019 13:25:06 +0100 Subject: [PATCH 3/9] Fix suggestion from move async to async move. --- .../borrow_check/conflict_errors.rs | 11 +++++++++- .../async-borrowck-escaping-closure-error.rs | 10 +++++++++ ...ync-borrowck-escaping-closure-error.stderr | 21 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/async-await/async-borrowck-escaping-closure-error.rs create mode 100644 src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index 4217a29bc663c..247783c420e25 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -1190,7 +1190,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) { - Ok(string) => format!("move {}", string), + Ok(mut string) => { + if string.starts_with("async ") { + string.insert_str(6, "move "); + } else if string.starts_with("async|") { + string.insert_str(5, " move"); + } else { + string.insert_str(0, "move "); + }; + string + }, Err(_) => "move || ".to_string() }; diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.rs b/src/test/ui/async-await/async-borrowck-escaping-closure-error.rs new file mode 100644 index 0000000000000..d2fa5d0a3d0f1 --- /dev/null +++ b/src/test/ui/async-await/async-borrowck-escaping-closure-error.rs @@ -0,0 +1,10 @@ +// edition:2018 +#![feature(async_closure,async_await)] +fn foo() -> Box> { + let x = 0u32; + Box::new((async || x)()) + //~^ ERROR E0373 +} + +fn main() { +} diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr new file mode 100644 index 0000000000000..8bcfcf989208e --- /dev/null +++ b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr @@ -0,0 +1,21 @@ +error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function + --> $DIR/async-borrowck-escaping-closure-error.rs:5:15 + | +LL | Box::new((async || x)()) + | ^^^^^^^^ - `x` is borrowed here + | | + | may outlive borrowed value `x` + | +note: closure is returned here + --> $DIR/async-borrowck-escaping-closure-error.rs:5:5 + | +LL | Box::new((async || x)()) + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword + | +LL | Box::new((async move || x)()) + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0373`. From b51df1def0e621fd5fd6cb777511d64d490c0363 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 8 Aug 2019 03:49:45 -0400 Subject: [PATCH 4/9] add debug logs --- src/librustc/hir/lowering.rs | 42 +++++++++++++++++++++++-- src/librustc/infer/opaque_types/mod.rs | 1 + src/librustc/middle/resolve_lifetime.rs | 5 +++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index cc2e6137df38a..cd127177e9f34 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -322,7 +322,7 @@ enum ParenthesizedGenericArgs { /// `resolve_lifetime` module. Often we "fallthrough" to that code by generating /// an "elided" or "underscore" lifetime name. In the future, we probably want to move /// everything into HIR lowering. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] enum AnonymousLifetimeMode { /// For **Modern** cases, create a new anonymous region parameter /// and reference that. @@ -715,10 +715,16 @@ impl<'a> LoweringContext<'a> { anonymous_lifetime_mode: AnonymousLifetimeMode, op: impl FnOnce(&mut Self) -> R, ) -> R { + debug!( + "with_anonymous_lifetime_mode(anonymous_lifetime_mode={:?})", + anonymous_lifetime_mode, + ); let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode; self.anonymous_lifetime_mode = anonymous_lifetime_mode; let result = op(self); self.anonymous_lifetime_mode = old_anonymous_lifetime_mode; + debug!("with_anonymous_lifetime_mode: restoring anonymous_lifetime_mode={:?}", + old_anonymous_lifetime_mode); result } @@ -1355,6 +1361,13 @@ impl<'a> LoweringContext<'a> { opaque_ty_node_id: NodeId, lower_bounds: impl FnOnce(&mut LoweringContext<'_>) -> hir::GenericBounds, ) -> hir::TyKind { + debug!( + "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})", + fn_def_id, + opaque_ty_node_id, + span, + ); + // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop // desugaring that explicitly states that we don't want to track that. @@ -1382,6 +1395,14 @@ impl<'a> LoweringContext<'a> { &hir_bounds, ); + debug!( + "lower_opaque_impl_trait: lifetimes={:#?}", lifetimes, + ); + + debug!( + "lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs, + ); + self.with_hir_id_owner(opaque_ty_node_id, |lctx| { let opaque_ty_item = hir::OpaqueTy { generics: hir::Generics { @@ -1397,7 +1418,7 @@ impl<'a> LoweringContext<'a> { origin: hir::OpaqueTyOrigin::FnReturn, }; - trace!("exist ty from impl trait def-index: {:#?}", opaque_ty_def_index); + trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_index); let opaque_ty_id = lctx.generate_opaque_type( opaque_ty_node_id, opaque_ty_item, @@ -1445,6 +1466,13 @@ impl<'a> LoweringContext<'a> { parent_index: DefIndex, bounds: &hir::GenericBounds, ) -> (HirVec, HirVec) { + debug!( + "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \ + parent_index={:?}, \ + bounds={:#?})", + opaque_ty_id, parent_index, bounds, + ); + // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that // appear in the bounds, excluding lifetimes that are created within the bounds. // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`. @@ -2182,6 +2210,14 @@ impl<'a> LoweringContext<'a> { fn_def_id: DefId, opaque_ty_node_id: NodeId, ) -> hir::FunctionRetTy { + debug!( + "lower_async_fn_ret_ty(\ + output={:?}, \ + fn_def_id={:?}, \ + opaque_ty_node_id={:?})", + output, fn_def_id, opaque_ty_node_id, + ); + let span = output.span(); let opaque_ty_span = self.mark_span_with_reason( @@ -2264,6 +2300,8 @@ impl<'a> LoweringContext<'a> { ), ); + debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound); + // Calculate all the lifetimes that should be captured // by the opaque type. This should include all in-scope // lifetime parameters, including those defined in-band. diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 5c62f76e3bb31..fd4f2c99659c8 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -1108,6 +1108,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { // Use the same type variable if the exact same opaque type appears more // than once in the return type (e.g., if it's passed to a type alias). if let Some(opaque_defn) = self.opaque_types.get(&def_id) { + debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty); return opaque_defn.concrete_ty; } let span = tcx.def_span(def_id); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f8f01f79e1db4..74031541f567b 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -585,6 +585,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.is_in_fn_syntax = was_in_fn_syntax; } hir::TyKind::TraitObject(ref bounds, ref lifetime) => { + debug!("visit_ty: TraitObject(bounds={:?}, lifetime={:?})", bounds, lifetime); for bound in bounds { self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); } @@ -897,6 +898,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { + debug!("visit_lifetime(lifetime_ref={:?})", lifetime_ref); if lifetime_ref.is_elided() { self.resolve_elided_lifetimes(vec![lifetime_ref]); return; @@ -2347,6 +2349,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn resolve_elided_lifetimes(&mut self, lifetime_refs: Vec<&'tcx hir::Lifetime>) { + debug!("resolve_elided_lifetimes(lifetime_refs={:?})", lifetime_refs); + if lifetime_refs.is_empty() { return; } @@ -2539,6 +2543,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) { + debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref); let mut late_depth = 0; let mut scope = self.scope; let lifetime = loop { From af86fb1959b520ae0256272899df5c43b11df2a7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 8 Aug 2019 03:36:24 -0400 Subject: [PATCH 5/9] distinguish object-lifetime-default elision from other elision Object-lifetime-default elision is distinct from other forms of elision; it always refers to some enclosing lifetime *present in the surrounding type* (e.g., `&dyn Bar` expands to `&'a (dyn Bar + 'a)`. If there is no enclosing lifetime, then it expands to `'static`. Therefore, in an `impl Trait` setting, we don't expand to create a lifetime parameter for the `dyn Bar + 'X` bound. It will just be resolved to `'static`. Annoyingly, the responsibility for this resolution is spread across multiple bits of code right now (`middle::resolve_lifetimes`, `lowering`). The lowering code knows that the default is for an object lifetime, but it doesn't know what the correct result would be. Probably this should be fixed, but what we do now is a surgical fix: we have it generate a different result for elided lifetimes in a object context, and then we can ignore those results when figuring out the lifetimes that are captured in the opaque type. --- src/librustc/hir/intravisit.rs | 1 + src/librustc/hir/lowering.rs | 19 ++++++++++++++- src/librustc/hir/mod.rs | 21 +++++++++++++++-- src/librustc/middle/resolve_lifetime.rs | 17 ++++++++++++++ .../error_reporting/region_name.rs | 3 ++- .../ui/async-await/issues/issue-62517-1.rs | 23 +++++++++++++++++++ .../ui/async-await/issues/issue-62517-2.rs | 16 +++++++++++++ .../async-await/issues/issue-62517-2.stderr | 11 +++++++++ .../dyn-trait-elided-two-inputs-assoc.rs | 16 +++++++++++++ .../dyn-trait-elided-two-inputs-param.rs | 11 +++++++++ .../dyn-trait-elided-two-inputs-ref-param.rs | 23 +++++++++++++++++++ .../lifetime-elision-return-type-trait.rs | 2 +- .../lifetime-elision-return-type-trait.stderr | 10 ++++---- 13 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/async-await/issues/issue-62517-1.rs create mode 100644 src/test/ui/async-await/issues/issue-62517-2.rs create mode 100644 src/test/ui/async-await/issues/issue-62517-2.stderr create mode 100644 src/test/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs create mode 100644 src/test/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs create mode 100644 src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 2c6373bdfa40d..fa274f831b795 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -433,6 +433,7 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime LifetimeName::Static | LifetimeName::Error | LifetimeName::Implicit | + LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Underscore => {} } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index cd127177e9f34..e04e45e5fbc92 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1560,6 +1560,11 @@ impl<'a> LoweringContext<'a> { } } hir::LifetimeName::Param(_) => lifetime.name, + + // Refers to some other lifetime that is "in + // scope" within the type. + hir::LifetimeName::ImplicitObjectLifetimeDefault => return, + hir::LifetimeName::Error | hir::LifetimeName::Static => return, }; @@ -2550,6 +2555,12 @@ impl<'a> LoweringContext<'a> { hir::LifetimeName::Implicit | hir::LifetimeName::Underscore | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()), + hir::LifetimeName::ImplicitObjectLifetimeDefault => { + span_bug!( + param.ident.span, + "object-lifetime-default should not occur here", + ); + } hir::LifetimeName::Error => ParamName::Error, }; @@ -3293,7 +3304,13 @@ impl<'a> LoweringContext<'a> { AnonymousLifetimeMode::PassThrough => {} } - self.new_implicit_lifetime(span) + let r = hir::Lifetime { + hir_id: self.next_id(), + span, + name: hir::LifetimeName::ImplicitObjectLifetimeDefault, + }; + debug!("elided_dyn_bound: r={:?}", r); + r } fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index b469b7016beb7..983048188527f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -221,6 +221,19 @@ pub enum LifetimeName { /// User wrote nothing (e.g., the lifetime in `&u32`). Implicit, + /// Implicit lifetime in a context like `dyn Foo`. This is + /// distinguished from implicit lifetimes elsewhere because the + /// lifetime that they default to must appear elsewhere within the + /// enclosing type. This means that, in an `impl Trait` context, we + /// don't have to create a parameter for them. That is, `impl + /// Trait` expands to an opaque type like `type + /// Foo<'a> = impl Trait`, but `impl Trait` expands to `type Foo = impl Trait`. The latter uses `ImplicitObjectLifetimeDefault` so + /// that surrounding code knows not to create a lifetime + /// parameter. + ImplicitObjectLifetimeDefault, + /// Indicates an error during lowering (usually `'_` in wrong place) /// that was already reported. Error, @@ -235,7 +248,9 @@ pub enum LifetimeName { impl LifetimeName { pub fn ident(&self) -> Ident { match *self { - LifetimeName::Implicit | LifetimeName::Error => Ident::invalid(), + LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Implicit + | LifetimeName::Error => Ident::invalid(), LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), LifetimeName::Param(param_name) => param_name.ident(), @@ -244,7 +259,9 @@ impl LifetimeName { pub fn is_elided(&self) -> bool { match self { - LifetimeName::Implicit | LifetimeName::Underscore => true, + LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Implicit + | LifetimeName::Underscore => true, // It might seem surprising that `Fresh(_)` counts as // *not* elided -- but this is because, as far as the code diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 74031541f567b..3b604bef78ee2 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -5,6 +5,8 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. +// ignore-tidy-filelength + use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use crate::hir::map::Map; @@ -591,6 +593,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } match lifetime.name { LifetimeName::Implicit => { + // For types like `dyn Foo`, we should + // generate a special form of elided. + span_bug!( + ty.span, + "object-lifetime-default expected, not implict", + ); + } + LifetimeName::ImplicitObjectLifetimeDefault => { // If the user does not write *anything*, we // use the object lifetime defaulting // rules. So e.g., `Box` becomes @@ -2643,6 +2653,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit => { self.resolve_lifetime_ref(lt); } + hir::LifetimeName::ImplicitObjectLifetimeDefault => { + self.tcx.sess.delay_span_bug( + lt.span, + "lowering generated `ImplicitObjectLifetimeDefault` \ + outside of an object type", + ) + } hir::LifetimeName::Error => { // No need to do anything, error already reported. } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 3f5b2f4bce78b..ca68b9e31b6b9 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -578,7 +578,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) } - hir::LifetimeName::Implicit => { + hir::LifetimeName::ImplicitObjectLifetimeDefault + | hir::LifetimeName::Implicit => { // In this case, the user left off the lifetime; so // they wrote something like: // diff --git a/src/test/ui/async-await/issues/issue-62517-1.rs b/src/test/ui/async-await/issues/issue-62517-1.rs new file mode 100644 index 0000000000000..5955d9751afbb --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62517-1.rs @@ -0,0 +1,23 @@ +// Regression test for #62517. We used to ICE when you had an `async +// fn` with an `impl Trait` return that mentioned a `dyn Bar` with no +// explicit lifetime bound. +// +// edition:2018 +// check-pass + +#![feature(async_await)] + +trait FirstTrait {} +trait SecondTrait { + type Item: ?Sized; +} + +async fn foo(x: &str) -> impl SecondTrait { +} + + +impl SecondTrait for T { + type Item = dyn FirstTrait; +} + +fn main() { } diff --git a/src/test/ui/async-await/issues/issue-62517-2.rs b/src/test/ui/async-await/issues/issue-62517-2.rs new file mode 100644 index 0000000000000..72dae58e51641 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62517-2.rs @@ -0,0 +1,16 @@ +// Regression test for #62517. We used to ICE when you had an `async +// fn` with an `impl Trait` return that mentioned a `dyn Bar` with no +// explicit lifetime bound. +// +// edition:2018 + +#![feature(async_await)] + +trait Object {} + +trait Alpha {} + +async fn foo<'a>(_: &'a ()) -> impl Alpha {} +//~^ ERROR not satisfied + +fn main() { } diff --git a/src/test/ui/async-await/issues/issue-62517-2.stderr b/src/test/ui/async-await/issues/issue-62517-2.stderr new file mode 100644 index 0000000000000..4f9b3047bfe18 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62517-2.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `(): Alpha<(dyn Object + 'static)>` is not satisfied + --> $DIR/issue-62517-2.rs:13:32 + | +LL | async fn foo<'a>(_: &'a ()) -> impl Alpha {} + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Alpha<(dyn Object + 'static)>` is not implemented for `()` + | + = note: the return type of a function must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs new file mode 100644 index 0000000000000..3b7141573847f --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs @@ -0,0 +1,16 @@ +// Test that we don't get an error with `dyn Bar` in an impl Trait +// when there are multiple inputs. The `dyn Bar` should default to `+ +// 'static`. This used to erroneously generate an error (cc #62517). +// +// check-pass + +trait Foo { type Item: ?Sized; } +trait Bar { } + +impl Foo for T { + type Item = dyn Bar; +} + +fn foo(x: &str, y: &str) -> impl Foo { () } + +fn main() { } diff --git a/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs new file mode 100644 index 0000000000000..e8da52aad0eac --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs @@ -0,0 +1,11 @@ +// Test that we don't get an error with `dyn Object` in an impl Trait +// when there are multiple inputs. The `dyn Object` should default to `+ +// 'static`. This used to erroneously generate an error (cc #62517). +// +// check-pass + +trait Alpha {} +trait Object {} +impl Alpha for T {} +fn alpha(x: &str, y: &str) -> impl Alpha { () } +fn main() { } diff --git a/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs new file mode 100644 index 0000000000000..8d34c1b6c2af7 --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs @@ -0,0 +1,23 @@ +// Test that `impl Alpha` resets the object-lifetime +// default to `'static`. +// +// check-pass + +trait Alpha { + fn item(&self) -> Box { + panic!() + } +} + +trait Object {} +impl Alpha for T {} +fn alpha(x: &str, y: &str) -> impl Alpha { () } +fn is_static(_: T) where T: 'static { } + +fn bar(x: &str) -> &impl Alpha { &() } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs index 2370084b072c7..ea0d0ccbc5532 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs @@ -6,7 +6,7 @@ trait Future { use std::error::Error; fn foo() -> impl Future> { -//~^ ERROR missing lifetime +//~^ ERROR not satisfied Ok(()) } diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 06b317ce95278..228582d0001da 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -1,11 +1,11 @@ -error[E0106]: missing lifetime specifier - --> $DIR/lifetime-elision-return-type-trait.rs:8:44 +error[E0277]: the trait bound `std::result::Result<(), _>: Future` is not satisfied + --> $DIR/lifetime-elision-return-type-trait.rs:8:13 | LL | fn foo() -> impl Future> { - | ^^^^^^^^^ help: consider giving it a 'static lifetime: `dyn Error + 'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `std::result::Result<(), _>` | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from + = note: the return type of a function must have a statically known size error: aborting due to previous error -For more information about this error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0277`. From 832199ee767004091d083affb5e641502f6d39bc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 12 Aug 2019 10:41:05 -0400 Subject: [PATCH 6/9] use static as object-lifetime default for type XX in `Foo` Currently the default is "inherited" from context, so e.g. `&impl Foo` would default to `&'x impl Foo`, but this triggers an ICE and is not very consistent. This patch doesn't implement what I expect would be the correct semantics, because those are likely too complex. Instead, it handles what I'd expect to be the common case -- where the trait has no lifetime parameters. --- src/librustc/middle/resolve_lifetime.rs | 71 ++++++++++++++++++- .../dyn-trait-elided-two-inputs-ref-assoc.rs | 27 +++++++ ...lifetime-default-dyn-binding-nonstatic1.rs | 27 +++++++ ...time-default-dyn-binding-nonstatic1.stderr | 8 +++ ...lifetime-default-dyn-binding-nonstatic2.rs | 30 ++++++++ ...time-default-dyn-binding-nonstatic2.stderr | 8 +++ ...lifetime-default-dyn-binding-nonstatic3.rs | 23 ++++++ ...time-default-dyn-binding-nonstatic3.stderr | 8 +++ ...ect-lifetime-default-dyn-binding-static.rs | 28 ++++++++ 9 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 3b604bef78ee2..f5b0af61693be 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -558,6 +558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty) { debug!("visit_ty: id={:?} ty={:?}", ty.hir_id, ty); + debug!("visit_ty: ty.node={:?}", ty.node); match ty.node { hir::TyKind::BareFn(ref c) => { let next_early_index = self.next_early_index(); @@ -1923,6 +1924,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn visit_segment_args(&mut self, res: Res, depth: usize, generic_args: &'tcx hir::GenericArgs) { + debug!( + "visit_segment_args(res={:?}, depth={:?}, generic_args={:?})", + res, + depth, + generic_args, + ); + if generic_args.parenthesized { let was_in_fn_syntax = self.is_in_fn_syntax; self.is_in_fn_syntax = true; @@ -1976,6 +1984,23 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { _ => None, }; + debug!("visit_segment_args: type_def_id={:?}", type_def_id); + + // Compute a vector of defaults, one for each type parameter, + // per the rules given in RFCs 599 and 1156. Example: + // + // ```rust + // struct Foo<'a, T: 'a, U> { } + // ``` + // + // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default + // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound) + // and `dyn Baz` to `dyn Baz + 'static` (because there is no + // such bound). + // + // Therefore, we would compute `object_lifetime_defaults` to a + // vector like `['x, 'static]`. Note that the vector only + // includes type parameters. let object_lifetime_defaults = type_def_id.map_or(vec![], |def_id| { let in_body = { let mut scope = self.scope; @@ -2015,6 +2040,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .collect() }) }; + debug!("visit_segment_args: unsubst={:?}", unsubst); unsubst .iter() .map(|set| match *set { @@ -2035,6 +2061,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .collect() }); + debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults); + let mut i = 0; for arg in &generic_args.args { match arg { @@ -2057,8 +2085,49 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + // Hack: when resolving the type `XX` in binding like `dyn + // Foo<'b, Item = XX>`, the current object-lifetime default + // would be to examine the trait `Foo` to check whether it has + // a lifetime bound declared on `Item`. e.g., if `Foo` is + // declared like so, then the default object lifetime bound in + // `XX` should be `'b`: + // + // ```rust + // trait Foo<'a> { + // type Item: 'a; + // } + // ``` + // + // but if we just have `type Item;`, then it would be + // `'static`. However, we don't get all of this logic correct. + // + // Instead, we do something hacky: if there are no lifetime parameters + // to the trait, then we simply use a default object lifetime + // bound of `'static`, because there is no other possibility. On the other hand, + // if there ARE lifetime parameters, then we require the user to give an + // explicit bound for now. + // + // This is intended to leave room for us to implement the + // correct behavior in the future. + let has_lifetime_parameter = generic_args + .args + .iter() + .any(|arg| match arg { + GenericArg::Lifetime(_) => true, + _ => false, + }); + + // Resolve lifetimes found in the type `XX` from `Item = XX` bindings. for b in &generic_args.bindings { - self.visit_assoc_type_binding(b); + let scope = Scope::ObjectLifetimeDefault { + lifetime: if has_lifetime_parameter { + None + } else { + Some(Region::Static) + }, + s: self.scope, + }; + self.with(scope, |_, this| this.visit_assoc_type_binding(b)); } } diff --git a/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs new file mode 100644 index 0000000000000..aad9d89fe2433 --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs @@ -0,0 +1,27 @@ +// Test that we don't get an error with `dyn Bar` in an impl Trait +// when there are multiple inputs. The `dyn Bar` should default to `+ +// 'static`. This used to erroneously generate an error (cc #62517). +// +// check-pass + +trait Foo { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +fn bar(x: &str) -> &impl Foo { &() } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs new file mode 100644 index 0000000000000..7337383e29784 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs @@ -0,0 +1,27 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. + +trait Foo<'a> { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo<'_> for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +// Here, we should default to `dyn Bar + 'static`, but the current +// code forces us into a conservative, hacky path. +fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } +//~^ ERROR please supply an explicit bound + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr new file mode 100644 index 0000000000000..9dbf7a78ed7a7 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr @@ -0,0 +1,8 @@ +error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound + --> $DIR/object-lifetime-default-dyn-binding-nonstatic1.rs:20:50 + | +LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs new file mode 100644 index 0000000000000..2a7415174f8a0 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs @@ -0,0 +1,30 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. + +trait Foo<'a> { + type Item: 'a + ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo<'_> for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +// Here, we default to `dyn Bar + 'a`. Or, we *should*, but the +// current code forces us into a conservative, hacky path. +fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } +//~^ ERROR please supply an explicit bound + +fn main() { + let s = format!("foo"); + let r = bar(&s); + + // If it weren't for the conservative path above, we'd expect an + // error here. + is_static(r.item()); +} diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr new file mode 100644 index 0000000000000..d069f52ce47db --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr @@ -0,0 +1,8 @@ +error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound + --> $DIR/object-lifetime-default-dyn-binding-nonstatic2.rs:20:50 + | +LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs new file mode 100644 index 0000000000000..51be999a6329d --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs @@ -0,0 +1,23 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. + +trait Foo<'a> { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +fn is_static(_: T) where T: 'static { } + +// Here, we should default to `dyn Bar + 'static`, but the current +// code forces us into a conservative, hacky path. +fn bar(x: &str) -> &dyn Foo { &() } +//~^ ERROR please supply an explicit bound + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr new file mode 100644 index 0000000000000..9c7b6b98f2e36 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr @@ -0,0 +1,8 @@ +error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound + --> $DIR/object-lifetime-default-dyn-binding-nonstatic3.rs:16:36 + | +LL | fn bar(x: &str) -> &dyn Foo { &() } + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs new file mode 100644 index 0000000000000..339f3356bd71e --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs @@ -0,0 +1,28 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. +// +// check-pass + +trait Foo { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +// Here, we default to `dyn Bar + 'static`, and not `&'x dyn Foo`. +fn bar(x: &str) -> &dyn Foo { &() } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} From 7ee1af51ccc521779300eba0819bcb08c07632cf Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 19 Aug 2019 13:53:06 -0400 Subject: [PATCH 7/9] adjust test to be check-pass --- src/test/ui/async-await/issues/issue-62517-2.rs | 6 ++++-- src/test/ui/async-await/issues/issue-62517-2.stderr | 11 ----------- 2 files changed, 4 insertions(+), 13 deletions(-) delete mode 100644 src/test/ui/async-await/issues/issue-62517-2.stderr diff --git a/src/test/ui/async-await/issues/issue-62517-2.rs b/src/test/ui/async-await/issues/issue-62517-2.rs index 72dae58e51641..17fac408151ea 100644 --- a/src/test/ui/async-await/issues/issue-62517-2.rs +++ b/src/test/ui/async-await/issues/issue-62517-2.rs @@ -3,14 +3,16 @@ // explicit lifetime bound. // // edition:2018 +// check-pass #![feature(async_await)] trait Object {} -trait Alpha {} +trait Alpha {} async fn foo<'a>(_: &'a ()) -> impl Alpha {} -//~^ ERROR not satisfied + +impl Alpha for T { } fn main() { } diff --git a/src/test/ui/async-await/issues/issue-62517-2.stderr b/src/test/ui/async-await/issues/issue-62517-2.stderr deleted file mode 100644 index 4f9b3047bfe18..0000000000000 --- a/src/test/ui/async-await/issues/issue-62517-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: the trait bound `(): Alpha<(dyn Object + 'static)>` is not satisfied - --> $DIR/issue-62517-2.rs:13:32 - | -LL | async fn foo<'a>(_: &'a ()) -> impl Alpha {} - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Alpha<(dyn Object + 'static)>` is not implemented for `()` - | - = note: the return type of a function must have a statically known size - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. From 94ee54c42504267cbbce6ec8ab8fc408161a0bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Aug 2019 16:40:12 -0700 Subject: [PATCH 8/9] Use constraint span when lowering associated types --- src/librustc/hir/lowering.rs | 6 +- src/librustc/infer/opaque_types/mod.rs | 5 +- src/librustc/traits/fulfill.rs | 17 +- .../associated-item-type-issue-63594.rs | 22 ++ .../associated-item-type-issue-63594.stderr | 11 + .../ui/associated-type-bounds/duplicate.rs | 165 +++++++------ .../associated-type-bounds/duplicate.stderr | 224 ++++++++++++------ .../ui/associated-type-bounds/inside-adt.rs | 39 ++- .../associated-type-bounds/inside-adt.stderr | 54 ++++- 9 files changed, 354 insertions(+), 189 deletions(-) create mode 100644 src/test/ui/associated-item/associated-item-type-issue-63594.rs create mode 100644 src/test/ui/associated-item/associated-item-type-issue-63594.stderr diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index cc2e6137df38a..0ead9671937bf 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -72,7 +72,7 @@ use syntax::symbol::{kw, sym, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::parse::token::{self, Token}; use syntax::visit::{self, Visitor}; -use syntax_pos::{DUMMY_SP, Span}; +use syntax_pos::Span; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; @@ -1094,7 +1094,7 @@ impl<'a> LoweringContext<'a> { impl_trait_node_id, DefPathData::ImplTrait, ExpnId::root(), - DUMMY_SP + c.span, ); self.with_dyn_type_scope(false, |this| { @@ -1102,7 +1102,7 @@ impl<'a> LoweringContext<'a> { &Ty { id: this.sess.next_node_id(), node: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), - span: DUMMY_SP, + span: c.span, }, itctx, ); diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 5c62f76e3bb31..df57224ab927c 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -127,8 +127,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)> { debug!( "instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \ - param_env={:?})", - value, parent_def_id, body_id, param_env, + param_env={:?}, value_span={:?})", + value, parent_def_id, body_id, param_env, value_span, ); let mut instantiator = Instantiator { infcx: self, @@ -1111,6 +1111,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { return opaque_defn.concrete_ty; } let span = tcx.def_span(def_id); + debug!("fold_opaque_ty {:?} {:?}", self.value_span, span); let ty_var = infcx .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 99b5ef3894b9c..f3c85277a8ada 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -248,10 +248,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { /// This is always inlined, despite its size, because it has a single /// callsite and it is called *very* frequently. #[inline(always)] - fn process_obligation(&mut self, - pending_obligation: &mut Self::Obligation) - -> ProcessResult - { + fn process_obligation( + &mut self, + pending_obligation: &mut Self::Obligation, + ) -> ProcessResult { // if we were stalled on some unresolved variables, first check // whether any of them have been resolved; if not, don't bother // doing more work yet @@ -277,7 +277,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { self.selcx.infcx().resolve_vars_if_possible(&obligation.predicate); } - debug!("process_obligation: obligation = {:?}", obligation); + debug!("process_obligation: obligation = {:?} cause = {:?}", obligation, obligation.cause); match obligation.predicate { ty::Predicate::Trait(ref data) => { @@ -425,10 +425,13 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } ty::Predicate::WellFormed(ty) => { - match ty::wf::obligations(self.selcx.infcx(), + match ty::wf::obligations( + self.selcx.infcx(), obligation.param_env, obligation.cause.body_id, - ty, obligation.cause.span) { + ty, + obligation.cause.span, + ) { None => { pending_obligation.stalled_on = vec![ty]; ProcessResult::Unchanged diff --git a/src/test/ui/associated-item/associated-item-type-issue-63594.rs b/src/test/ui/associated-item/associated-item-type-issue-63594.rs new file mode 100644 index 0000000000000..65b58b70e9259 --- /dev/null +++ b/src/test/ui/associated-item/associated-item-type-issue-63594.rs @@ -0,0 +1,22 @@ +#![feature(associated_type_bounds)] + +fn main() {} + +trait Bar { type Assoc; } + +trait Thing { + type Out; + fn func() -> Self::Out; +} + +struct AssocNoCopy; +impl Bar for AssocNoCopy { type Assoc = String; } + +impl Thing for AssocNoCopy { + type Out = Box>; + //~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied + + fn func() -> Self::Out { + Box::new(AssocNoCopy) + } +} diff --git a/src/test/ui/associated-item/associated-item-type-issue-63594.stderr b/src/test/ui/associated-item/associated-item-type-issue-63594.stderr new file mode 100644 index 0000000000000..432a761b19157 --- /dev/null +++ b/src/test/ui/associated-item/associated-item-type-issue-63594.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied + --> $DIR/associated-item-type-issue-63594.rs:16:28 + | +LL | type Out = Box>; + | ^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` + | + = note: the return type of a function must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index 1f2d755ed71ab..a89fd9807da8f 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -1,161 +1,184 @@ // compile-fail // ignore-tidy-linelength -// error-pattern:could not find defining uses #![feature(associated_type_bounds)] #![feature(type_alias_impl_trait)] -#![feature(impl_trait_in_bindings)] +#![feature(impl_trait_in_bindings)] //~ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash [incomplete_features] #![feature(untagged_unions)] use std::iter; struct SI1> { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] struct SI2> { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] struct SI3> { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] struct SW1 where T: Iterator { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] struct SW2 where T: Iterator { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] struct SW3 where T: Iterator { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] enum EI1> { V(T) } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] enum EI2> { V(T) } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] enum EI3> { V(T) } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] enum EW1 where T: Iterator { V(T) } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] enum EW2 where T: Iterator { V(T) } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] enum EW3 where T: Iterator { V(T) } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] union UI1> { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] union UI2> { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] union UI3> { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] union UW1 where T: Iterator { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] union UW2 where T: Iterator { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] union UW3 where T: Iterator { f: T } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FI1>() {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FI2>() {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FI3>() {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FW1() where T: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FW2() where T: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FW3() where T: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FRPIT1() -> impl Iterator { iter::empty() } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FRPIT2() -> impl Iterator { iter::empty() } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FRPIT3() -> impl Iterator { iter::empty() } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FAPIT1(_: impl Iterator) {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FAPIT2(_: impl Iterator) {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn FAPIT3(_: impl Iterator) {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] const CIT1: impl Iterator = iter::empty(); -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] const CIT2: impl Iterator = iter::empty(); -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] const CIT3: impl Iterator = iter::empty(); -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] static SIT1: impl Iterator = iter::empty(); -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] static SIT2: impl Iterator = iter::empty(); -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] static SIT3: impl Iterator = iter::empty(); -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn lit1() { let _: impl Iterator = iter::empty(); } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn lit2() { let _: impl Iterator = iter::empty(); } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] fn lit3() { let _: impl Iterator = iter::empty(); } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TAI1> = T; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TAI2> = T; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TAI3> = T; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TAW1 where T: Iterator = T; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TAW2 where T: Iterator = T; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TAW3 where T: Iterator = T; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type ETAI1> = impl Copy; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type ETAI2> = impl Copy; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type ETAI3> = impl Copy; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type ETAI4 = impl Iterator; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type ETAI5 = impl Iterator; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type ETAI6 = impl Iterator; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses trait TRI1> {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRI2> {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRI3> {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRS1: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRS2: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRS3: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRW1 where T: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRW2 where T: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRW3 where T: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRSW1 where Self: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRSW2 where Self: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRSW3 where Self: Iterator {} -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRA1 { type A: Iterator; } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRA2 { type A: Iterator; } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRA3 { type A: Iterator; } -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] type TADyn1 = dyn Iterator; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type TADyn2 = Box>; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses type TADyn3 = dyn Iterator; -//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~^ ERROR the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +//~| ERROR could not find defining uses +//~| ERROR could not find defining uses fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index 7f3a65ab696d6..e5e85d6856fd3 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/duplicate.rs:7:12 + --> $DIR/duplicate.rs:6:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:12:36 + --> $DIR/duplicate.rs:11:36 | LL | struct SI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -15,7 +15,7 @@ LL | struct SI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:14:36 + --> $DIR/duplicate.rs:13:36 | LL | struct SI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -23,7 +23,7 @@ LL | struct SI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:16:39 + --> $DIR/duplicate.rs:15:39 | LL | struct SI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -31,7 +31,7 @@ LL | struct SI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:18:45 + --> $DIR/duplicate.rs:17:45 | LL | struct SW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -39,7 +39,7 @@ LL | struct SW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:20:45 + --> $DIR/duplicate.rs:19:45 | LL | struct SW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -47,7 +47,7 @@ LL | struct SW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:22:48 + --> $DIR/duplicate.rs:21:48 | LL | struct SW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -55,7 +55,7 @@ LL | struct SW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:25:34 + --> $DIR/duplicate.rs:24:34 | LL | enum EI1> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -63,7 +63,7 @@ LL | enum EI1> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:27:34 + --> $DIR/duplicate.rs:26:34 | LL | enum EI2> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -71,7 +71,7 @@ LL | enum EI2> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:29:37 + --> $DIR/duplicate.rs:28:37 | LL | enum EI3> { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -79,7 +79,7 @@ LL | enum EI3> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:31:43 + --> $DIR/duplicate.rs:30:43 | LL | enum EW1 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -87,7 +87,7 @@ LL | enum EW1 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:33:43 + --> $DIR/duplicate.rs:32:43 | LL | enum EW2 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -95,7 +95,7 @@ LL | enum EW2 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:35:46 + --> $DIR/duplicate.rs:34:46 | LL | enum EW3 where T: Iterator { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -103,7 +103,7 @@ LL | enum EW3 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:38:35 + --> $DIR/duplicate.rs:37:35 | LL | union UI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -111,7 +111,7 @@ LL | union UI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:40:35 + --> $DIR/duplicate.rs:39:35 | LL | union UI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -119,7 +119,7 @@ LL | union UI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:42:38 + --> $DIR/duplicate.rs:41:38 | LL | union UI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -127,7 +127,7 @@ LL | union UI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:44:44 + --> $DIR/duplicate.rs:43:44 | LL | union UW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -135,7 +135,7 @@ LL | union UW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:46:44 + --> $DIR/duplicate.rs:45:44 | LL | union UW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -143,7 +143,7 @@ LL | union UW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:48:47 + --> $DIR/duplicate.rs:47:47 | LL | union UW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -151,7 +151,7 @@ LL | union UW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:51:32 + --> $DIR/duplicate.rs:50:32 | LL | fn FI1>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -159,7 +159,7 @@ LL | fn FI1>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:53:32 + --> $DIR/duplicate.rs:52:32 | LL | fn FI2>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -167,7 +167,7 @@ LL | fn FI2>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:55:35 + --> $DIR/duplicate.rs:54:35 | LL | fn FI3>() {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -175,7 +175,7 @@ LL | fn FI3>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:57:43 + --> $DIR/duplicate.rs:56:43 | LL | fn FW1() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -183,7 +183,7 @@ LL | fn FW1() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:59:43 + --> $DIR/duplicate.rs:58:43 | LL | fn FW2() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -191,7 +191,7 @@ LL | fn FW2() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:61:46 + --> $DIR/duplicate.rs:60:46 | LL | fn FW3() where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -199,7 +199,7 @@ LL | fn FW3() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:70:40 + --> $DIR/duplicate.rs:69:40 | LL | fn FAPIT1(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -207,7 +207,7 @@ LL | fn FAPIT1(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:72:40 + --> $DIR/duplicate.rs:71:40 | LL | fn FAPIT2(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -215,7 +215,7 @@ LL | fn FAPIT2(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:74:43 + --> $DIR/duplicate.rs:73:43 | LL | fn FAPIT3(_: impl Iterator) {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -223,7 +223,7 @@ LL | fn FAPIT3(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:64:42 + --> $DIR/duplicate.rs:63:42 | LL | fn FRPIT1() -> impl Iterator { iter::empty() } | ---------- ^^^^^^^^^^ re-bound here @@ -231,7 +231,7 @@ LL | fn FRPIT1() -> impl Iterator { iter::empty() } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:66:42 + --> $DIR/duplicate.rs:65:42 | LL | fn FRPIT2() -> impl Iterator { iter::empty() } | ---------- ^^^^^^^^^^ re-bound here @@ -239,7 +239,7 @@ LL | fn FRPIT2() -> impl Iterator { iter::empty() } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:68:45 + --> $DIR/duplicate.rs:67:45 | LL | fn FRPIT3() -> impl Iterator { iter::empty() } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -247,7 +247,7 @@ LL | fn FRPIT3() -> impl Iterator { iter::empty() | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:77:39 + --> $DIR/duplicate.rs:76:39 | LL | const CIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -255,7 +255,7 @@ LL | const CIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:79:39 + --> $DIR/duplicate.rs:78:39 | LL | const CIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -263,7 +263,7 @@ LL | const CIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:81:42 + --> $DIR/duplicate.rs:80:42 | LL | const CIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -271,7 +271,7 @@ LL | const CIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:83:40 + --> $DIR/duplicate.rs:82:40 | LL | static SIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -279,7 +279,7 @@ LL | static SIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:85:40 + --> $DIR/duplicate.rs:84:40 | LL | static SIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -287,7 +287,7 @@ LL | static SIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:87:43 + --> $DIR/duplicate.rs:86:43 | LL | static SIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -295,7 +295,7 @@ LL | static SIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:90:46 + --> $DIR/duplicate.rs:89:46 | LL | fn lit1() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -303,7 +303,7 @@ LL | fn lit1() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:92:46 + --> $DIR/duplicate.rs:91:46 | LL | fn lit2() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -311,7 +311,7 @@ LL | fn lit2() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:94:49 + --> $DIR/duplicate.rs:93:49 | LL | fn lit3() { let _: impl Iterator = iter::empty(); } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -319,7 +319,7 @@ LL | fn lit3() { let _: impl Iterator = iter::empt | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:97:35 + --> $DIR/duplicate.rs:96:35 | LL | type TAI1> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -327,7 +327,7 @@ LL | type TAI1> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:99:35 + --> $DIR/duplicate.rs:98:35 | LL | type TAI2> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -335,7 +335,7 @@ LL | type TAI2> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:101:38 + --> $DIR/duplicate.rs:100:38 | LL | type TAI3> = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -343,7 +343,7 @@ LL | type TAI3> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:103:44 + --> $DIR/duplicate.rs:102:44 | LL | type TAW1 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -351,7 +351,7 @@ LL | type TAW1 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:105:44 + --> $DIR/duplicate.rs:104:44 | LL | type TAW2 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -359,7 +359,7 @@ LL | type TAW2 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:107:47 + --> $DIR/duplicate.rs:106:47 | LL | type TAW3 where T: Iterator = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -367,13 +367,13 @@ LL | type TAW3 where T: Iterator = T; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:110:1 + --> $DIR/duplicate.rs:109:1 | LL | type ETAI1> = impl Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:110:36 + --> $DIR/duplicate.rs:109:36 | LL | type ETAI1> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -381,13 +381,13 @@ LL | type ETAI1> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:112:1 + --> $DIR/duplicate.rs:114:1 | LL | type ETAI2> = impl Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:112:36 + --> $DIR/duplicate.rs:114:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -395,13 +395,13 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:114:1 + --> $DIR/duplicate.rs:119:1 | LL | type ETAI3> = impl Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:114:39 + --> $DIR/duplicate.rs:119:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -409,13 +409,13 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:116:1 + --> $DIR/duplicate.rs:124:1 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:116:40 + --> $DIR/duplicate.rs:124:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -423,13 +423,13 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:118:1 + --> $DIR/duplicate.rs:129:1 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:118:40 + --> $DIR/duplicate.rs:129:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -437,13 +437,13 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:120:1 + --> $DIR/duplicate.rs:134:1 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:120:43 + --> $DIR/duplicate.rs:134:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -451,7 +451,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:123:36 + --> $DIR/duplicate.rs:140:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -459,7 +459,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:125:36 + --> $DIR/duplicate.rs:142:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -467,7 +467,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:127:39 + --> $DIR/duplicate.rs:144:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -475,7 +475,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:129:34 + --> $DIR/duplicate.rs:146:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -483,7 +483,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:131:34 + --> $DIR/duplicate.rs:148:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -491,7 +491,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:133:37 + --> $DIR/duplicate.rs:150:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -499,7 +499,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:135:45 + --> $DIR/duplicate.rs:152:45 | LL | trait TRW1 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -507,7 +507,7 @@ LL | trait TRW1 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:137:45 + --> $DIR/duplicate.rs:154:45 | LL | trait TRW2 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -515,7 +515,7 @@ LL | trait TRW2 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:139:48 + --> $DIR/duplicate.rs:156:48 | LL | trait TRW3 where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -523,7 +523,7 @@ LL | trait TRW3 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:141:46 + --> $DIR/duplicate.rs:158:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -531,7 +531,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:143:46 + --> $DIR/duplicate.rs:160:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -539,7 +539,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:145:49 + --> $DIR/duplicate.rs:162:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -547,7 +547,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:147:43 + --> $DIR/duplicate.rs:164:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -555,7 +555,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:149:43 + --> $DIR/duplicate.rs:166:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -563,7 +563,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:151:46 + --> $DIR/duplicate.rs:168:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -571,7 +571,7 @@ LL | trait TRA3 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:154:40 + --> $DIR/duplicate.rs:171:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -579,7 +579,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:156:44 + --> $DIR/duplicate.rs:175:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -587,7 +587,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:158:43 + --> $DIR/duplicate.rs:179:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -595,40 +595,112 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error: could not find defining uses + --> $DIR/duplicate.rs:109:24 + | +LL | type ETAI1> = impl Copy; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:109:36 + | +LL | type ETAI1> = impl Copy; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:114:24 + | +LL | type ETAI2> = impl Copy; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:114:36 + | +LL | type ETAI2> = impl Copy; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:119:24 + | +LL | type ETAI3> = impl Copy; + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:119:39 + | +LL | type ETAI3> = impl Copy; + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:124:28 + | +LL | type ETAI4 = impl Iterator; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:124:40 + | +LL | type ETAI4 = impl Iterator; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:129:28 + | +LL | type ETAI5 = impl Iterator; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:129:40 + | +LL | type ETAI5 = impl Iterator; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:134:28 + | +LL | type ETAI6 = impl Iterator; + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:134:43 + | +LL | type ETAI6 = impl Iterator; + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:171:28 + | +LL | type TADyn1 = dyn Iterator; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:171:40 + | +LL | type TADyn1 = dyn Iterator; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:175:32 + | +LL | type TADyn2 = Box>; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:175:44 + | +LL | type TADyn2 = Box>; + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:179:28 + | +LL | type TADyn3 = dyn Iterator; + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/duplicate.rs:179:43 + | +LL | type TADyn3 = dyn Iterator; + | ^^^^^^^^^^^^^ error: aborting due to 93 previous errors diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs index 1257dc6e94b39..83a60825d84cd 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.rs +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -1,36 +1,33 @@ // compile-fail -// ignore-tidy-linelength -// error-pattern:could not find defining uses - #![feature(associated_type_bounds)] #![feature(untagged_unions)] struct S1 { f: dyn Iterator } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses struct S2 { f: Box> } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses struct S3 { f: dyn Iterator } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses enum E1 { V(dyn Iterator) } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses enum E2 { V(Box>) } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses enum E3 { V(dyn Iterator) } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses union U1 { f: dyn Iterator } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses union U2 { f: Box> } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses union U3 { f: dyn Iterator } -//~^ associated type bounds are not allowed within structs, enums, or unions -//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~| ERROR could not find defining uses diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr index 7bdd71b8296ff..d0e0ceccd3725 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.stderr +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -1,53 +1,53 @@ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:8:29 + --> $DIR/inside-adt.rs:5:29 | LL | struct S1 { f: dyn Iterator } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:11:33 + --> $DIR/inside-adt.rs:8:33 | LL | struct S2 { f: Box> } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:14:29 + --> $DIR/inside-adt.rs:11:29 | LL | struct S3 { f: dyn Iterator } | ^^^^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:18:26 + --> $DIR/inside-adt.rs:15:26 | LL | enum E1 { V(dyn Iterator) } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:21:30 + --> $DIR/inside-adt.rs:18:30 | LL | enum E2 { V(Box>) } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:24:26 + --> $DIR/inside-adt.rs:21:26 | LL | enum E3 { V(dyn Iterator) } | ^^^^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:28:28 + --> $DIR/inside-adt.rs:25:28 | LL | union U1 { f: dyn Iterator } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:31:32 + --> $DIR/inside-adt.rs:28:32 | LL | union U2 { f: Box> } | ^^^^^^^^^^ error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:34:28 + --> $DIR/inside-adt.rs:31:28 | LL | union U3 { f: dyn Iterator } | ^^^^^^^^^^^^^ @@ -57,22 +57,58 @@ error[E0601]: `main` function not found in crate `inside_adt` = note: consider adding a `main` function to `$DIR/inside-adt.rs` error: could not find defining uses + --> $DIR/inside-adt.rs:5:29 + | +LL | struct S1 { f: dyn Iterator } + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:8:33 + | +LL | struct S2 { f: Box> } + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:11:29 + | +LL | struct S3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:15:26 + | +LL | enum E1 { V(dyn Iterator) } + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:18:30 + | +LL | enum E2 { V(Box>) } + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:21:26 + | +LL | enum E3 { V(dyn Iterator) } + | ^^^^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:25:28 + | +LL | union U1 { f: dyn Iterator } + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:28:32 + | +LL | union U2 { f: Box> } + | ^^^^^^^^^^ error: could not find defining uses + --> $DIR/inside-adt.rs:31:28 + | +LL | union U3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ error: aborting due to 19 previous errors From 1808e4da68bd94393c03229550b166cafebf38e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Aug 2019 12:24:06 -0700 Subject: [PATCH 9/9] review comments --- src/librustc/hir/lowering.rs | 23 ++++++------- src/librustc/traits/fulfill.rs | 4 +-- .../associated-item-type-issue-63594.rs | 22 ------------- .../assoc-type-eq-with-dyn-atb-fail.rs | 32 +++++++++++++++++++ .../assoc-type-eq-with-dyn-atb-fail.stderr} | 2 +- 5 files changed, 47 insertions(+), 36 deletions(-) delete mode 100644 src/test/ui/associated-item/associated-item-type-issue-63594.rs create mode 100644 src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs rename src/test/ui/{associated-item/associated-item-type-issue-63594.stderr => associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr} (89%) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0ead9671937bf..d1f541afbe9d3 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1033,13 +1033,14 @@ impl<'a> LoweringContext<'a> { /// ``` /// /// returns a `hir::TypeBinding` representing `Item`. - fn lower_assoc_ty_constraint(&mut self, - c: &AssocTyConstraint, - itctx: ImplTraitContext<'_>) - -> hir::TypeBinding { - debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", c, itctx); + fn lower_assoc_ty_constraint( + &mut self, + constraint: &AssocTyConstraint, + itctx: ImplTraitContext<'_>, + ) -> hir::TypeBinding { + debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); - let kind = match c.kind { + let kind = match constraint.kind { AssocTyConstraintKind::Equality { ref ty } => hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) }, @@ -1094,7 +1095,7 @@ impl<'a> LoweringContext<'a> { impl_trait_node_id, DefPathData::ImplTrait, ExpnId::root(), - c.span, + constraint.span, ); self.with_dyn_type_scope(false, |this| { @@ -1102,7 +1103,7 @@ impl<'a> LoweringContext<'a> { &Ty { id: this.sess.next_node_id(), node: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), - span: c.span, + span: constraint.span, }, itctx, ); @@ -1124,10 +1125,10 @@ impl<'a> LoweringContext<'a> { }; hir::TypeBinding { - hir_id: self.lower_node_id(c.id), - ident: c.ident, + hir_id: self.lower_node_id(constraint.id), + ident: constraint.ident, kind, - span: c.span, + span: constraint.span, } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index f3c85277a8ada..c1de4939c1d91 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -427,8 +427,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { ty::Predicate::WellFormed(ty) => { match ty::wf::obligations( self.selcx.infcx(), - obligation.param_env, - obligation.cause.body_id, + obligation.param_env, + obligation.cause.body_id, ty, obligation.cause.span, ) { diff --git a/src/test/ui/associated-item/associated-item-type-issue-63594.rs b/src/test/ui/associated-item/associated-item-type-issue-63594.rs deleted file mode 100644 index 65b58b70e9259..0000000000000 --- a/src/test/ui/associated-item/associated-item-type-issue-63594.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![feature(associated_type_bounds)] - -fn main() {} - -trait Bar { type Assoc; } - -trait Thing { - type Out; - fn func() -> Self::Out; -} - -struct AssocNoCopy; -impl Bar for AssocNoCopy { type Assoc = String; } - -impl Thing for AssocNoCopy { - type Out = Box>; - //~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied - - fn func() -> Self::Out { - Box::new(AssocNoCopy) - } -} diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs new file mode 100644 index 0000000000000..a58cec5342142 --- /dev/null +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs @@ -0,0 +1,32 @@ +// This test documents that `type Out = Box>;` +// is allowed and will correctly reject an opaque `type Out` which +// does not satisfy the bound `::Assoc: Copy`. +// +// FIXME(rust-lang/lang): I think this behavior is logical if we want to allow +// `dyn Trait` but we should decide if we want that. // Centril +// +// Additionally, as reported in https://github.com/rust-lang/rust/issues/63594, +// we check that the spans for the error message are sane here. + +#![feature(associated_type_bounds)] + +fn main() {} + +trait Bar { type Assoc; } + +trait Thing { + type Out; + fn func() -> Self::Out; +} + +struct AssocNoCopy; +impl Bar for AssocNoCopy { type Assoc = String; } + +impl Thing for AssocNoCopy { + type Out = Box>; + //~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied + + fn func() -> Self::Out { + Box::new(AssocNoCopy) + } +} diff --git a/src/test/ui/associated-item/associated-item-type-issue-63594.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr similarity index 89% rename from src/test/ui/associated-item/associated-item-type-issue-63594.stderr rename to src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index 432a761b19157..b6b49c2e90350 100644 --- a/src/test/ui/associated-item/associated-item-type-issue-63594.stderr +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied - --> $DIR/associated-item-type-issue-63594.rs:16:28 + --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:26:28 | LL | type Out = Box>; | ^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`