diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index 96e33184658a..e3fa587985df 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -70,6 +70,10 @@ where pub fn iter_mut(&mut self) -> impl Iterator { self.into_iter() } + + pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) { + self.0.retain(f) + } } impl Default for VecMap { diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index aa3ff98f7ff9..de327047a872 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts}; +use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts}; use rustc_middle::ty::{ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness, @@ -60,7 +60,6 @@ use crate::borrow_check::{ LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, }, region_infer::{ClosureRegionRequirementsExt, TypeTest}, - renumber, type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, universal_regions::{DefiningTy, UniversalRegions}, Upvar, @@ -180,7 +179,66 @@ pub(crate) fn type_check<'mir, 'tcx>( liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table); translate_outlives_facts(&mut cx); - cx.opaque_type_values + let mut opaque_type_values = cx.opaque_type_values; + + for (_, revealed_ty) in &mut opaque_type_values { + // FIXME(oli-obk): Instead of looping, implement a visitor like + // FullTypeResolver. We can't use FullTypeResolver here, as that will + // resolve lifetimes lexically, which it can't because we didn't do old + // borrowck stuff. We want to use MIR borrowck information instead. + + while revealed_ty.has_infer_types_or_consts() { + let prev = *revealed_ty; + trace!(prev=?prev.kind()); + let type_resolved = infcx.shallow_resolve(prev); + trace!(type_resolved=?type_resolved.kind()); + if prev == type_resolved { + infcx.tcx.sess.delay_span_bug( + body.span, + &format!("could not resolve {:#?}", type_resolved.kind()), + ); + *revealed_ty = infcx.tcx.ty_error(); + break; + } + *revealed_ty = type_resolved; + } + } + + opaque_type_values.retain(|(opaque_type_key, resolved_ty)| { + let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() { + *def_id == opaque_type_key.def_id + } else { + false + }; + + if concrete_is_opaque { + // We're using an opaque `impl Trait` type without + // 'revealing' it. For example, code like this: + // + // type Foo = impl Debug; + // fn foo1() -> Foo { ... } + // fn foo2() -> Foo { foo1() } + // + // In `foo2`, we're not revealing the type of `Foo` - we're + // just treating it as the opaque type. + // + // When this occurs, we do *not* want to try to equate + // the concrete type with the underlying defining type + // of the opaque type - this will always fail, since + // the defining type of an opaque type is always + // some other type (e.g. not itself) + // Essentially, none of the normal obligations apply here - + // we're just passing around some unknown opaque type, + // without actually looking at the underlying type it + // gets 'revealed' into + debug!( + "eq_opaque_type_and_type: non-defining use of {:?}", + opaque_type_key.def_id, + ); + } + !concrete_is_opaque + }); + opaque_type_values }, ); @@ -1240,13 +1298,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } let infcx = self.infcx; - let tcx = infcx.tcx; let param_env = self.param_env; let body = self.body; let mir_def_id = body.source.def_id().expect_local(); - // the "concrete opaque types" maps - let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types; let mut opaque_type_values = VecMap::new(); debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id); @@ -1296,88 +1351,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .eq(output_ty, revealed_ty)?, ); - // For each opaque type `Foo` inferred by this value, we want to equate - // the inference variable `?T` with the revealed type that was computed - // earlier by type check. for &(opaque_type_key, opaque_decl) in &opaque_type_map { - let resolved_ty = infcx.resolve_vars_if_possible(opaque_decl.concrete_ty); - let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() { - *def_id == opaque_type_key.def_id - } else { - false - }; - - // The revealed type computed by the earlier phase of type check. - // In our example, this would be `(U, u32)`. Note that this references - // the type parameter `U` from the definition of `Foo`. - let concrete_ty = match concrete_opaque_types - .get_by(|(key, _)| key.def_id == opaque_type_key.def_id) - { - None => { - if !concrete_is_opaque { - tcx.sess.delay_span_bug( - body.span, - &format!( - "Non-defining use of {:?} with revealed type", - opaque_type_key.def_id, - ), - ); - } - continue; - } - Some(concrete_ty) => concrete_ty, - }; - debug!("concrete_ty = {:?}", concrete_ty); - - // Apply the substitution, in this case `[U -> T]`, so that the - // concrete type becomes `Foo<(T, u32)>` - let subst_opaque_defn_ty = concrete_ty.subst(tcx, opaque_type_key.substs); - - // "Renumber" this, meaning that we replace all the regions - // with fresh inference variables. Not relevant to our example. - let renumbered_opaque_defn_ty = - renumber::renumber_regions(infcx, subst_opaque_defn_ty); - - debug!( - "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}", - concrete_ty, resolved_ty, renumbered_opaque_defn_ty, - ); - - if !concrete_is_opaque { - // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`, - // in our example) with the renumbered version that we took from - // the type check results (`Foo<(T, u32)>`). - obligations.add( - infcx - .at(&ObligationCause::dummy(), param_env) - .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?, - ); - opaque_type_values.insert(opaque_type_key, renumbered_opaque_defn_ty); - } else { - // We're using an opaque `impl Trait` type without - // 'revealing' it. For example, code like this: - // - // type Foo = impl Debug; - // fn foo1() -> Foo { ... } - // fn foo2() -> Foo { foo1() } - // - // In `foo2`, we're not revealing the type of `Foo` - we're - // just treating it as the opaque type. - // - // When this occurs, we do *not* want to try to equate - // the concrete type with the underlying defining type - // of the opaque type - this will always fail, since - // the defining type of an opaque type is always - // some other type (e.g. not itself) - // Essentially, none of the normal obligations apply here - - // we're just passing around some unknown opaque type, - // without actually looking at the underlying type it - // gets 'revealed' into - debug!( - "eq_opaque_type_and_type: non-defining use of {:?}", - opaque_type_key.def_id, - ); - } + opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty); } debug!("eq_opaque_type_and_type: equated"); 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 index 73b23da5bcb6..7950dd3e99e2 100644 --- 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 @@ -29,7 +29,6 @@ impl Bar for AssocNoCopy { impl Thing for AssocNoCopy { type Out = Box>; //~^ ERROR the trait bound `String: Copy` is not satisfied - //~| ERROR the trait bound `String: 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.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index 414d74d4786d..0f1d35be0eb7 100644 --- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -4,12 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied LL | type Out = Box>; | ^^^^^^^^^^^ the trait `Copy` is not implemented for `String` -error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28 - | -LL | type Out = Box>; - | ^^^^^^^^^^^ the trait `Copy` is not implemented for `String` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index 087f4582b21c..c2fbbf94fd66 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -12,7 +12,6 @@ fn main() { fn cycle1() -> impl Clone { //~^ ERROR cycle detected send(cycle2().clone()); - //~^ ERROR cannot be sent between threads safely Rc::new(Cell::new(5)) } diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index e578c4b4f819..3eb141cc2bb5 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires computing type of `cycle2::{opaque#0}`... - --> $DIR/auto-trait-leak.rs:20:16 + --> $DIR/auto-trait-leak.rs:19:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,22 +84,6 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leak.rs:14:5 - | -LL | fn send(_: T) {} - | ---- required by this bound in `send` -... -LL | send(cycle2().clone()); - | ^^^^ `Rc` cannot be sent between threads safely -... -LL | fn cycle2() -> impl Clone { - | ---------- within this `impl Clone` - | - = help: within `impl Clone`, the trait `Send` is not implemented for `Rc` - = note: required because it appears within the type `impl Clone` +error: aborting due to previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0277, E0391. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr index 6394a1f8e850..90a753b5a6de 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr @@ -36,16 +36,7 @@ LL | type WrongGeneric = impl 'static; LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound...: `T: 'static` -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:12:24 - | -LL | type WrongGeneric = impl 'static; - | ^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `T: 'static`... - = note: ...so that the type `T` will meet its required lifetime bounds - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0308, E0310. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr index 49ead8b094c1..e50282201074 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr @@ -27,16 +27,7 @@ LL | type WrongGeneric = impl 'static; LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound...: `T: 'static` -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:12:24 - | -LL | type WrongGeneric = impl 'static; - | ^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `T: 'static`... - = note: ...so that the type `T` will meet its required lifetime bounds - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0308, E0310. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index 3dda34ff668c..9f647d9e737f 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -11,7 +11,6 @@ fn main() { type WrongGeneric = impl 'static; //~^ ERROR the parameter type `T` may not live long enough -//~| ERROR the parameter type `T` may not live long enough //~| ERROR: at least one trait must be specified fn wrong_generic(t: T) -> WrongGeneric { diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr index d90f328708a7..61e8da91bbaa 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr @@ -16,52 +16,5 @@ LL | type Bar = impl Baz; = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ +error: aborting due to previous error; 1 warning emitted -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error: aborting due to 5 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr index d019f40757ee..f65e91e52c71 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr @@ -7,52 +7,5 @@ LL | type Bar = impl Baz; = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ +error: aborting due to previous error -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index ccc727e0bf01..508ecdd88a48 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -19,10 +19,6 @@ struct X; impl Foo for X { type Bar = impl Baz; //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types - //~| ERROR mismatched types fn bar(&self) -> Self::Bar { |x| x diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs index b7c8a58a6562..cee5e5a01cc2 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -9,7 +9,6 @@ trait Bug { impl Bug for &() { type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable //~^ ERROR the trait bound `(): Bug` is not satisfied - //~^^ ERROR the trait bound `(): Bug` is not satisfied const FUN: fn() -> Self::Item = || (); //~^ ERROR type alias impl trait is not permitted here diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr index 4906ea9c2e26..a9df74689df2 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -8,7 +8,7 @@ LL | type Item = impl Bug; = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: type alias impl trait is not permitted here - --> $DIR/issue-60371.rs:14:40 + --> $DIR/issue-60371.rs:13:40 | LL | const FUN: fn() -> Self::Item = || (); | ^ @@ -25,16 +25,7 @@ LL | type Item = impl Bug; = help: the following implementations were found: <&() as Bug> -error[E0277]: the trait bound `(): Bug` is not satisfied - --> $DIR/issue-60371.rs:10:17 - | -LL | type Item = impl Bug; - | ^^^^^^^^ the trait `Bug` is not implemented for `()` - | - = help: the following implementations were found: - <&() as Bug> - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0658. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs new file mode 100644 index 000000000000..4b0f2afee548 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs @@ -0,0 +1,19 @@ +#![feature(member_constraints)] +#![feature(type_alias_impl_trait)] +//~^ WARN incomplete + +pub trait A { + type B; + fn f(&self) -> Self::B; +} +impl<'a, 'b> A for () { + //~^ ERROR the lifetime parameter `'a` is not constrained + //~| ERROR the lifetime parameter `'b` is not constrained + type B = impl core::fmt::Debug; + //~^ ERROR is unstable + + + fn f(&self) -> Self::B {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr new file mode 100644 index 000000000000..4506a6e23d5c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -0,0 +1,34 @@ +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/issue-74761-2.rs:12:14 + | +LL | type B = impl core::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable + +warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-74761-2.rs:2:12 + | +LL | #![feature(type_alias_impl_trait)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #63063 for more information + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761-2.rs:9:6 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761-2.rs:9:10 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0658. +For more information about an error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs index 38aa18fe40ee..11756017ad84 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs @@ -5,9 +5,9 @@ #![feature(min_type_alias_impl_trait)] type X = impl ToString; -//~^ ERROR could not find defining uses fn f(a: A, b: B) -> (X, X) { + //~^ ERROR concrete type differs from previous defining opaque type (a.clone(), a) } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr index c00973c0761b..52b0462de988 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr @@ -1,8 +1,14 @@ -error: could not find defining uses - --> $DIR/multiple-def-uses-in-one-fn2.rs:7:52 +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1 | -LL | type X = impl ToString; - | ^^^^^^^^^^^^^ +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B` + | +note: previous use here + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs index 17e900058113..5f25365666c7 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -11,6 +11,7 @@ fn f(a: A, b: B) -> (X, X) } fn g(a: A, b: B) -> (X, X) { + //~^ ERROR concrete type differs from previous defining opaque type (a, b) //~^ ERROR mismatched types } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index bbe709dccab4..3d943b77af57 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -1,10 +1,11 @@ error[E0308]: mismatched types - --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9 + --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9 | LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter | | | expected type parameter +LL | LL | (a, b) | ^ expected type parameter `A`, found type parameter `B` | @@ -13,6 +14,18 @@ LL | (a, b) = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error: aborting due to previous error +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1 + | +LL | fn g(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]` + | +note: previous use here + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.