1
Fork 0

Rollup merge of #91096 - compiler-errors:elaborate_opaque_trait, r=estebank

Print associated types on opaque `impl Trait` types

This PR generalizes #91021, printing associated types for all opaque `impl Trait` types instead of just special-casing for future.

before:
```
error[E0271]: type mismatch resolving `<impl Iterator as Iterator>::Item == u32`
```

after:
```
error[E0271]: type mismatch resolving `<impl Iterator<Item = usize> as Iterator>::Item == u32`
```

---

Questions:
1. I'm kinda lost in binders hell with this one. Is all of the `rebind`ing necessary?
2. Is there a map collection type that will give me a stable iteration order? Doesn't seem like TraitRef is Ord, so I can't just sort later..
3. I removed the logic that suppresses printing generator projection types. It creates outputs like this [gist](https://gist.github.com/compiler-errors/d6f12fb30079feb1ad1d5f1ab39a3a8d). Should I put that back?
4. I also added spaces between traits, `impl A+B` -> `impl A + B`. I quite like this change, but is there a good reason to keep it like that?

r? ````@estebank````
This commit is contained in:
Matthias Krüger 2021-11-25 15:05:37 +01:00 committed by GitHub
commit 6970cf5a23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 355 additions and 147 deletions

View file

@ -268,6 +268,7 @@ language_item_table! {
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None; GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None;
Generator, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1); Generator, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1);
GeneratorReturn, sym::generator_return, generator_return, Target::AssocTy, GenericRequirement::None;
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None; Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None; Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;

View file

@ -7,6 +7,7 @@ pub mod query;
pub mod select; pub mod select;
pub mod specialization_graph; pub mod specialization_graph;
mod structural_impls; mod structural_impls;
pub mod util;
use crate::infer::canonical::Canonical; use crate::infer::canonical::Canonical;
use crate::thir::abstract_const::NotConstEvaluatable; use crate::thir::abstract_const::NotConstEvaluatable;

View file

@ -0,0 +1,49 @@
use rustc_data_structures::stable_set::FxHashSet;
use crate::ty::{PolyTraitRef, TyCtxt};
/// Given a PolyTraitRef, get the PolyTraitRefs of the trait's (transitive) supertraits.
///
/// A simplfied version of the same function at `rustc_infer::traits::util::supertraits`.
pub fn supertraits<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: PolyTraitRef<'tcx>,
) -> impl Iterator<Item = PolyTraitRef<'tcx>> {
Elaborator { tcx, visited: FxHashSet::from_iter([trait_ref]), stack: vec![trait_ref] }
}
struct Elaborator<'tcx> {
tcx: TyCtxt<'tcx>,
visited: FxHashSet<PolyTraitRef<'tcx>>,
stack: Vec<PolyTraitRef<'tcx>>,
}
impl<'tcx> Elaborator<'tcx> {
fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
let supertrait_refs = self
.tcx
.super_predicates_of(trait_ref.def_id())
.predicates
.into_iter()
.flat_map(|(pred, _)| {
pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_ref()
})
.map(|t| t.value)
.filter(|supertrait_ref| self.visited.insert(*supertrait_ref));
self.stack.extend(supertrait_refs);
}
}
impl<'tcx> Iterator for Elaborator<'tcx> {
type Item = PolyTraitRef<'tcx>;
fn next(&mut self) -> Option<PolyTraitRef<'tcx>> {
if let Some(trait_ref) = self.stack.pop() {
self.elaborate(trait_ref);
Some(trait_ref)
} else {
None
}
}
}

View file

@ -643,81 +643,8 @@ pub trait PrettyPrinter<'tcx>:
} }
return Ok(self); return Ok(self);
} }
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
// by looking up the projections associated with the def_id.
let bounds = self.tcx().explicit_item_bounds(def_id);
let mut first = true; self.pretty_print_opaque_impl_type(def_id, substs)
let mut is_sized = false;
let mut is_future = false;
let mut future_output_ty = None;
p!("impl");
for (predicate, _) in bounds {
let predicate = predicate.subst(self.tcx(), substs);
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Projection(projection_predicate) => {
let Some(future_trait) = self.tcx().lang_items().future_trait() else { continue };
let future_output_def_id =
self.tcx().associated_item_def_ids(future_trait)[0];
if projection_predicate.projection_ty.item_def_id
== future_output_def_id
{
// We don't account for multiple `Future::Output = Ty` contraints.
is_future = true;
future_output_ty = Some(projection_predicate.ty);
}
}
ty::PredicateKind::Trait(pred) => {
let trait_ref = bound_predicate.rebind(pred.trait_ref);
// Don't print +Sized, but rather +?Sized if absent.
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait()
{
is_sized = true;
continue;
}
if Some(trait_ref.def_id())
== self.tcx().lang_items().future_trait()
{
is_future = true;
continue;
}
p!(
write("{}", if first { " " } else { " + " }),
print(trait_ref.print_only_trait_path())
);
first = false;
}
_ => {}
}
}
if is_future {
p!(write("{}Future", if first { " " } else { " + " }));
first = false;
if let Some(future_output_ty) = future_output_ty {
// Don't print projection types, which we (unfortunately) see often
// in the error outputs involving async blocks.
if !matches!(future_output_ty.kind(), ty::Projection(_)) {
p!("<Output = ", print(future_output_ty), ">");
}
}
}
if !is_sized {
p!(write("{}?Sized", if first { " " } else { " + " }));
} else if first {
p!(" Sized");
}
Ok(self)
}); });
} }
ty::Str => p!("str"), ty::Str => p!("str"),
@ -826,6 +753,225 @@ pub trait PrettyPrinter<'tcx>:
Ok(self) Ok(self)
} }
fn pretty_print_opaque_impl_type(
mut self,
def_id: DefId,
substs: &'tcx ty::List<ty::GenericArg<'tcx>>,
) -> Result<Self::Type, Self::Error> {
define_scoped_cx!(self);
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
// by looking up the projections associated with the def_id.
let bounds = self.tcx().explicit_item_bounds(def_id);
let mut traits = BTreeMap::new();
let mut fn_traits = BTreeMap::new();
let mut is_sized = false;
for (predicate, _) in bounds {
let predicate = predicate.subst(self.tcx(), substs);
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(pred) => {
let trait_ref = bound_predicate.rebind(pred.trait_ref);
// Don't print + Sized, but rather + ?Sized if absent.
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
is_sized = true;
continue;
}
self.insert_trait_and_projection(trait_ref, None, &mut traits, &mut fn_traits);
}
ty::PredicateKind::Projection(pred) => {
let proj_ref = bound_predicate.rebind(pred);
let trait_ref = proj_ref.required_poly_trait_ref(self.tcx());
// Projection type entry -- the def-id for naming, and the ty.
let proj_ty = (proj_ref.projection_def_id(), proj_ref.ty());
self.insert_trait_and_projection(
trait_ref,
Some(proj_ty),
&mut traits,
&mut fn_traits,
);
}
_ => {}
}
}
let mut first = true;
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized;
p!("impl");
for (fn_once_trait_ref, entry) in fn_traits {
// Get the (single) generic ty (the args) of this FnOnce trait ref.
let generics = self.generic_args_to_print(
self.tcx().generics_of(fn_once_trait_ref.def_id()),
fn_once_trait_ref.skip_binder().substs,
);
match (entry.return_ty, generics[0].expect_ty()) {
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
// a return type.
(Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
let name = if entry.fn_trait_ref.is_some() {
"Fn"
} else if entry.fn_mut_trait_ref.is_some() {
"FnMut"
} else {
"FnOnce"
};
p!(
write("{}", if first { " " } else { " + " }),
write("{}{}(", if paren_needed { "(" } else { "" }, name)
);
for (idx, ty) in arg_tys.tuple_fields().enumerate() {
if idx > 0 {
p!(", ");
}
p!(print(ty));
}
p!(")");
if !return_ty.skip_binder().is_unit() {
p!("-> ", print(return_ty));
}
p!(write("{}", if paren_needed { ")" } else { "" }));
first = false;
}
// If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
// trait_refs we collected in the OpaqueFnEntry as normal trait refs.
_ => {
if entry.has_fn_once {
traits.entry(fn_once_trait_ref).or_default().extend(
// Group the return ty with its def id, if we had one.
entry
.return_ty
.map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)),
);
}
if let Some(trait_ref) = entry.fn_mut_trait_ref {
traits.entry(trait_ref).or_default();
}
if let Some(trait_ref) = entry.fn_trait_ref {
traits.entry(trait_ref).or_default();
}
}
}
}
// Print the rest of the trait types (that aren't Fn* family of traits)
for (trait_ref, assoc_items) in traits {
p!(
write("{}", if first { " " } else { " + " }),
print(trait_ref.skip_binder().print_only_trait_name())
);
let generics = self.generic_args_to_print(
self.tcx().generics_of(trait_ref.def_id()),
trait_ref.skip_binder().substs,
);
if !generics.is_empty() || !assoc_items.is_empty() {
p!("<");
let mut first = true;
for ty in generics {
if !first {
p!(", ");
}
p!(print(trait_ref.rebind(*ty)));
first = false;
}
for (assoc_item_def_id, ty) in assoc_items {
if !first {
p!(", ");
}
p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).ident));
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
match ty.skip_binder().kind() {
ty::Projection(ty::ProjectionTy { item_def_id, .. })
if Some(*item_def_id) == self.tcx().lang_items().generator_return() =>
{
p!("[async output]")
}
_ => {
p!(print(ty))
}
}
first = false;
}
p!(">");
}
first = false;
}
if !is_sized {
p!(write("{}?Sized", if first { " " } else { " + " }));
} else if first {
p!(" Sized");
}
Ok(self)
}
/// Insert the trait ref and optionally a projection type associated with it into either the
/// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits.
fn insert_trait_and_projection(
&mut self,
trait_ref: ty::PolyTraitRef<'tcx>,
proj_ty: Option<(DefId, ty::Binder<'tcx, Ty<'tcx>>)>,
traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, BTreeMap<DefId, ty::Binder<'tcx, Ty<'tcx>>>>,
fn_traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
) {
let trait_def_id = trait_ref.def_id();
// If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
// super-trait ref and record it there.
if let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() {
// If we have a FnOnce, then insert it into
if trait_def_id == fn_once_trait {
let entry = fn_traits.entry(trait_ref).or_default();
// Optionally insert the return_ty as well.
if let Some((_, ty)) = proj_ty {
entry.return_ty = Some(ty);
}
entry.has_fn_once = true;
return;
} else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() {
let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();
fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
return;
} else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() {
let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();
fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref);
return;
}
}
// Otherwise, just group our traits and projection types.
traits.entry(trait_ref).or_default().extend(proj_ty);
}
fn pretty_print_bound_var( fn pretty_print_bound_var(
&mut self, &mut self,
debruijn: ty::DebruijnIndex, debruijn: ty::DebruijnIndex,
@ -2553,3 +2699,12 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
pub fn provide(providers: &mut ty::query::Providers) { pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers { trimmed_def_paths, ..*providers }; *providers = ty::query::Providers { trimmed_def_paths, ..*providers };
} }
#[derive(Default)]
pub struct OpaqueFnEntry<'tcx> {
// The trait ref is already stored as a key, so just track if we have it as a real predicate
has_fn_once: bool,
fn_mut_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
return_ty: Option<ty::Binder<'tcx, Ty<'tcx>>>,
}

View file

@ -890,7 +890,7 @@ impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
/// ///
/// Trait references also appear in object types like `Foo<U>`, but in /// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions. /// that case the `Self` parameter is absent from the substitutions.
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable)] #[derive(HashStable, TypeFoldable)]
pub struct TraitRef<'tcx> { pub struct TraitRef<'tcx> {
pub def_id: DefId, pub def_id: DefId,

View file

@ -679,6 +679,7 @@ symbols! {
gen_future, gen_future,
gen_kill, gen_kill,
generator, generator,
generator_return,
generator_state, generator_state,
generators, generators,
generic_arg_infer, generic_arg_infer,

View file

@ -82,6 +82,7 @@ pub trait Generator<R = ()> {
/// `return` statement or implicitly as the last expression of a generator /// `return` statement or implicitly as the last expression of a generator
/// literal. For example futures would use this as `Result<T, E>` as it /// literal. For example futures would use this as `Result<T, E>` as it
/// represents a completed future. /// represents a completed future.
#[cfg_attr(not(bootstrap), lang = "generator_return")]
type Return; type Return;
/// Resumes the execution of this generator. /// Resumes the execution of this generator.

View file

@ -19,16 +19,16 @@
+ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
// mir::Constant // mir::Constant
// + span: $DIR/issue-78442.rs:11:5: 11:13 // + span: $DIR/issue-78442.rs:11:5: 11:13
// + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar(<ZST>)) } // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar(<ZST>)) }
} }
bb1: { bb1: {
_3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 _3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- _2 = <impl Fn<()> as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 - _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- // mir::Constant - // mir::Constant
- // + span: $DIR/issue-78442.rs:11:5: 11:15 - // + span: $DIR/issue-78442.rs:11:5: 11:15
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> <impl std::ops::Fn<()> as std::ops::FnOnce<()>>::Output {<impl std::ops::Fn<()> as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) } - // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as std::ops::FnOnce<()>>::Output {<impl Fn() as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
+ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17 + _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17
} }

View file

@ -5,8 +5,8 @@
debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9 debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9
let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3 let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3
let _2: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 let _2: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- let mut _3: &impl std::ops::Fn<()>; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 - let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
- let _4: impl std::ops::Fn<()>; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 - let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
+ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
+ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17
@ -18,17 +18,17 @@
_4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
// mir::Constant // mir::Constant
// + span: $DIR/issue-78442.rs:11:5: 11:13 // + span: $DIR/issue-78442.rs:11:5: 11:13
// + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar(<ZST>)) } // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar(<ZST>)) }
} }
bb1: { bb1: {
_3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 _3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
nop; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 nop; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
_2 = <impl Fn<()> as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
// mir::Constant // mir::Constant
// + span: $DIR/issue-78442.rs:11:5: 11:15 // + span: $DIR/issue-78442.rs:11:5: 11:15
// + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> <impl std::ops::Fn<()> as std::ops::FnOnce<()>>::Output {<impl std::ops::Fn<()> as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) } // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as std::ops::FnOnce<()>>::Output {<impl Fn() as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
} }
bb2: { bb2: {

View file

@ -83,17 +83,17 @@ fn main() {
//~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
accepts_trait(returns_opaque_foo()); accepts_trait(returns_opaque_foo());
//~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl Foo + Trait as Trait>::Associated == ()`
accepts_trait(returns_opaque_derived_foo()); accepts_trait(returns_opaque_derived_foo());
//~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()` //~^ ERROR type mismatch resolving `<impl Foo + DerivedTrait as Trait>::Associated == ()`
accepts_generic_trait(returns_opaque_generic()); accepts_generic_trait(returns_opaque_generic());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()` //~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
accepts_generic_trait(returns_opaque_generic_foo()); accepts_generic_trait(returns_opaque_generic_foo());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()` //~^ ERROR type mismatch resolving `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
accepts_generic_trait(returns_opaque_generic_duplicate()); accepts_generic_trait(returns_opaque_generic_duplicate());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()` //~^ ERROR type mismatch resolving `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
} }

View file

@ -160,7 +160,7 @@ help: consider constraining the associated type `<impl DerivedTrait as Trait>::A
LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static { LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static {
| +++++++++++++++++ | +++++++++++++++++
error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()` error[E0271]: type mismatch resolving `<impl Foo + Trait as Trait>::Associated == ()`
--> $DIR/issue-87261.rs:85:5 --> $DIR/issue-87261.rs:85:5
| |
LL | fn returns_opaque_foo() -> impl Trait + Foo { LL | fn returns_opaque_foo() -> impl Trait + Foo {
@ -170,18 +170,18 @@ LL | accepts_trait(returns_opaque_foo());
| ^^^^^^^^^^^^^ expected `()`, found associated type | ^^^^^^^^^^^^^ expected `()`, found associated type
| |
= note: expected unit type `()` = note: expected unit type `()`
found associated type `<impl Trait + Foo as Trait>::Associated` found associated type `<impl Foo + Trait as Trait>::Associated`
note: required by a bound in `accepts_trait` note: required by a bound in `accepts_trait`
--> $DIR/issue-87261.rs:43:27 --> $DIR/issue-87261.rs:43:27
| |
LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {} LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
help: consider constraining the associated type `<impl Trait + Foo as Trait>::Associated` to `()` help: consider constraining the associated type `<impl Foo + Trait as Trait>::Associated` to `()`
| |
LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo { LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
| +++++++++++++++++ | +++++++++++++++++
error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()` error[E0271]: type mismatch resolving `<impl Foo + DerivedTrait as Trait>::Associated == ()`
--> $DIR/issue-87261.rs:88:5 --> $DIR/issue-87261.rs:88:5
| |
LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo { LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
@ -191,8 +191,8 @@ LL | accepts_trait(returns_opaque_derived_foo());
| ^^^^^^^^^^^^^ expected `()`, found associated type | ^^^^^^^^^^^^^ expected `()`, found associated type
| |
= note: expected unit type `()` = note: expected unit type `()`
found associated type `<impl DerivedTrait + Foo as Trait>::Associated` found associated type `<impl Foo + DerivedTrait as Trait>::Associated`
= help: consider constraining the associated type `<impl DerivedTrait + Foo as Trait>::Associated` to `()` = help: consider constraining the associated type `<impl Foo + DerivedTrait as Trait>::Associated` to `()`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
note: required by a bound in `accepts_trait` note: required by a bound in `accepts_trait`
--> $DIR/issue-87261.rs:43:27 --> $DIR/issue-87261.rs:43:27
@ -221,7 +221,7 @@ help: consider constraining the associated type `<impl GenericTrait<()> as Gener
LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static { LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static {
| +++++++++++++++++ | +++++++++++++++++
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()` error[E0271]: type mismatch resolving `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
--> $DIR/issue-87261.rs:94:5 --> $DIR/issue-87261.rs:94:5
| |
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo { LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
@ -231,18 +231,18 @@ LL | accepts_generic_trait(returns_opaque_generic_foo());
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
| |
= note: expected unit type `()` = note: expected unit type `()`
found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated` found associated type `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated`
note: required by a bound in `accepts_generic_trait` note: required by a bound in `accepts_generic_trait`
--> $DIR/issue-87261.rs:44:46 --> $DIR/issue-87261.rs:44:46
| |
LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {} LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
help: consider constraining the associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated` to `()` help: consider constraining the associated type `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated` to `()`
| |
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo { LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo {
| +++++++++++++++++ | +++++++++++++++++
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()` error[E0271]: type mismatch resolving `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
--> $DIR/issue-87261.rs:97:5 --> $DIR/issue-87261.rs:97:5
| |
LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> { LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
@ -252,8 +252,8 @@ LL | accepts_generic_trait(returns_opaque_generic_duplicate());
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
| |
= note: expected unit type `()` = note: expected unit type `()`
found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated` found associated type `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated`
= help: consider constraining the associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated` to `()` = help: consider constraining the associated type `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated` to `()`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
note: required by a bound in `accepts_generic_trait` note: required by a bound in `accepts_generic_trait`
--> $DIR/issue-87261.rs:44:46 --> $DIR/issue-87261.rs:44:46

View file

@ -15,16 +15,16 @@ fn return_targets_async_block_not_fn() -> u8 {
return 0u8; return 0u8;
}; };
let _: &dyn Future<Output = ()> = &block; let _: &dyn Future<Output = ()> = &block;
//~^ ERROR type mismatch resolving `<impl Future as Future>::Output == ()` //~^ ERROR type mismatch
} }
async fn return_targets_async_block_not_async_fn() -> u8 { async fn return_targets_async_block_not_async_fn() -> u8 {
//~^ ERROR mismatched types //~^ ERROR mismatched types [E0308]
let block = async { let block = async {
return 0u8; return 0u8;
}; };
let _: &dyn Future<Output = ()> = &block; let _: &dyn Future<Output = ()> = &block;
//~^ ERROR type mismatch resolving `<impl Future as Future>::Output == ()` //~^ ERROR type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
} }
fn no_break_in_async_block() { fn no_break_in_async_block() {

View file

@ -31,7 +31,7 @@ LL | |
LL | | } LL | | }
| |_^ expected `u8`, found `()` | |_^ expected `u8`, found `()`
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()` error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:26:39 --> $DIR/async-block-control-flow-static-semantics.rs:26:39
| |
LL | let _: &dyn Future<Output = ()> = &block; LL | let _: &dyn Future<Output = ()> = &block;
@ -47,7 +47,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
| | | |
| implicitly returns `()` as its body has no tail or `return` expression | implicitly returns `()` as its body has no tail or `return` expression
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()` error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:17:39 --> $DIR/async-block-control-flow-static-semantics.rs:17:39
| |
LL | let _: &dyn Future<Output = ()> = &block; LL | let _: &dyn Future<Output = ()> = &block;

View file

@ -46,8 +46,8 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| the expected opaque type | the expected opaque type
| the found opaque type | the found opaque type
| |
= note: expected opaque type `impl Future` (`async` closure body) = note: expected opaque type `impl Future<Output = [async output]>` (`async` closure body)
found opaque type `impl Future` (`async` closure body) found opaque type `impl Future<Output = [async output]>` (`async` closure body)
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
LL | spawn(async { LL | spawn(async {
| ^^^^^ future created by async block is not `Send` | ^^^^^ future created by async block is not `Send`
| |
= help: within `impl Future`, the trait `Send` is not implemented for `*mut ()` = help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-67252-unnamed-future.rs:20:9 --> $DIR/issue-67252-unnamed-future.rs:20:9
| |

View file

@ -44,13 +44,13 @@ LL | require_send(send_fut);
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>` = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]` = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]`
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>` = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>`
= note: required because it appears within the type `impl Future` = note: required because it appears within the type `impl Future<Output = [async output]>`
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>` = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>` = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
= note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}` = note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}`
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]` = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]`
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>` = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>`
= note: required because it appears within the type `impl Future` = note: required because it appears within the type `impl Future<Output = [async output]>`
note: required by a bound in `require_send` note: required by a bound in `require_send`
--> $DIR/issue-68112.rs:11:25 --> $DIR/issue-68112.rs:11:25
| |

View file

@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
LL | assert_send(async { LL | assert_send(async {
| ^^^^^^^^^^^ future created by async block is not `Send` | ^^^^^^^^^^^ future created by async block is not `Send`
| |
= help: within `impl Future`, the trait `Send` is not implemented for `*const u8` = help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:9 --> $DIR/issue-65436-raw-ptr-not-send.rs:14:9
| |

View file

@ -21,7 +21,7 @@ LL | type MainFn = impl Fn();
LL | pub const BAR: MainFn = bar; LL | pub const BAR: MainFn = bar;
| ^^^ expected opaque type, found fn item | ^^^ expected opaque type, found fn item
| |
= note: expected opaque type `impl Fn<()>` = note: expected opaque type `impl Fn()`
found fn item `fn() {bar}` found fn item `fn() {bar}`
error: could not find defining uses error: could not find defining uses

View file

@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield
--> $DIR/issue-68112.rs:31:9 --> $DIR/issue-68112.rs:31:9
| |
LL | let _non_send_gen = make_non_send_generator(); LL | let _non_send_gen = make_non_send_generator();
| ------------- has type `impl Generator` which is not `Send` | ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
LL | yield; LL | yield;
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
LL | }; LL | };
@ -29,9 +29,9 @@ LL | require_send(send_gen);
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>` = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6]` = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6]`
= note: required because it appears within the type `impl Generator` = note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
= note: required because it appears within the type `impl Generator` = note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
= note: required because it appears within the type `{impl Generator, ()}` = note: required because it appears within the type `{impl Generator<Return = Arc<RefCell<i32>>>, ()}`
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6]` = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6]`
note: required by a bound in `require_send` note: required by a bound in `require_send`
--> $DIR/issue-68112.rs:22:25 --> $DIR/issue-68112.rs:22:25

View file

@ -2,16 +2,16 @@ error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
--> $DIR/auto-trait-leak2.rs:13:10 --> $DIR/auto-trait-leak2.rs:13:10
| |
LL | fn before() -> impl Fn(i32) { LL | fn before() -> impl Fn(i32) {
| ------------ within this `impl Fn<(i32,)>` | ------------ within this `impl Fn(i32)`
... ...
LL | send(before()); LL | send(before());
| ---- ^^^^^^^^ `Rc<Cell<i32>>` cannot be sent between threads safely | ---- ^^^^^^^^ `Rc<Cell<i32>>` cannot be sent between threads safely
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc<Cell<i32>>` = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]`
= note: required because it appears within the type `impl Fn<(i32,)>` = note: required because it appears within the type `impl Fn(i32)`
note: required by a bound in `send` note: required by a bound in `send`
--> $DIR/auto-trait-leak2.rs:10:12 --> $DIR/auto-trait-leak2.rs:10:12
| |
@ -27,11 +27,11 @@ LL | send(after());
| required by a bound introduced by this call | required by a bound introduced by this call
... ...
LL | fn after() -> impl Fn(i32) { LL | fn after() -> impl Fn(i32) {
| ------------ within this `impl Fn<(i32,)>` | ------------ within this `impl Fn(i32)`
| |
= help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc<Cell<i32>>` = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]`
= note: required because it appears within the type `impl Fn<(i32,)>` = note: required because it appears within the type `impl Fn(i32)`
note: required by a bound in `send` note: required by a bound in `send`
--> $DIR/auto-trait-leak2.rs:10:12 --> $DIR/auto-trait-leak2.rs:10:12
| |

View file

@ -13,7 +13,7 @@ impl<S> Bar for S {
type E = impl std::marker::Copy; type E = impl std::marker::Copy;
fn foo<T>() -> Self::E { fn foo<T>() -> Self::E {
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
//~| ERROR the trait bound `impl Future: Copy` is not satisfied [E0277] //~| ERROR the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
async {} async {}
} }
} }

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `impl Future: Copy` is not satisfied error[E0277]: the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
--> $DIR/issue-55872-2.rs:14:20 --> $DIR/issue-55872-2.rs:14:20
| |
LL | fn foo<T>() -> Self::E { LL | fn foo<T>() -> Self::E {
| ^^^^^^^ the trait `Copy` is not implemented for `impl Future` | ^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = [async output]>`
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-55872-2.rs:14:28 --> $DIR/issue-55872-2.rs:14:28

View file

@ -19,14 +19,14 @@ LL |
LL | lint_files().flat_map(|f| gather_from_file(&f)) LL | lint_files().flat_map(|f| gather_from_file(&f))
| ----------------------------------------------- | -----------------------------------------------
| | | |
| returning here with type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` | returning here with type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
| returning here with type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` | returning here with type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
... ...
LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint> { LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint> {
| -------------------------- returning this opaque type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` | -------------------------- returning this opaque type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
... ...
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> { LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
| -------------------------------------- returning this opaque type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` | -------------------------------------- returning this opaque type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -17,10 +17,10 @@ LL | fn foo() -> impl Fn() {
| ^^^^^^^^^ recursive opaque type | ^^^^^^^^^ recursive opaque type
... ...
LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo()))))))) LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
| ----------------------------------------------- returning here with type `impl Fn<()>` | ----------------------------------------------- returning here with type `impl Fn()`
... ...
LL | fn wrap(f: impl Fn()) -> impl Fn() { LL | fn wrap(f: impl Fn()) -> impl Fn() {
| --------- returning this opaque type `impl Fn<()>` | --------- returning this opaque type `impl Fn()`
error: aborting due to previous error; 1 warning emitted error: aborting due to previous error; 1 warning emitted

View file

@ -15,7 +15,7 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type | ------------------------------- the found opaque type
| |
= note: expected opaque type `impl Future<Output = u8>` = note: expected opaque type `impl Future<Output = u8>`
found opaque type `impl Future` found opaque type `impl Future<Output = [async output]>`
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
error: aborting due to previous error error: aborting due to previous error

View file

@ -19,5 +19,5 @@ fn main() {
let g = |(a, _)| a; let g = |(a, _)| a;
let t7 = |env| |a| |b| t7p(f, g)(((env, a), b)); let t7 = |env| |a| |b| t7p(f, g)(((env, a), b));
let t8 = t8n(t7, t7p(f, g)); let t8 = t8n(t7, t7p(f, g));
//~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)> //~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))` [E0277]
} }

View file

@ -1,12 +1,12 @@
error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))`
--> $DIR/issue-59494.rs:21:22 --> $DIR/issue-59494.rs:21:22
| |
LL | let t8 = t8n(t7, t7p(f, g)); LL | let t8 = t8n(t7, t7p(f, g));
| --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` | --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn(((_, _), _))`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Fn<(_,)>` is not implemented for `impl Fn<(((_, _), _),)>` = help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))`
note: required by a bound in `t8n` note: required by a bound in `t8n`
--> $DIR/issue-59494.rs:5:45 --> $DIR/issue-59494.rs:5:45
| |

View file

@ -33,7 +33,7 @@ fn use_of_b() -> AliasB {
} }
extern "C" { extern "C" {
pub fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `impl TraitA` pub fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `impl TraitA<Assoc = u32>`
} }
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error: `extern` block uses type `impl TraitA`, which is not FFI-safe error: `extern` block uses type `impl TraitA<Assoc = u32>`, which is not FFI-safe
--> $DIR/lint-ctypes-73251-2.rs:36:25 --> $DIR/lint-ctypes-73251-2.rs:36:25
| |
LL | pub fn lint_me() -> <AliasB as TraitB>::Assoc; LL | pub fn lint_me() -> <AliasB as TraitB>::Assoc;

View file

@ -9,7 +9,7 @@ pub fn ret_closure() -> A {
extern "C" { extern "C" {
pub fn a(_: A); pub fn a(_: A);
//~^ ERROR `extern` block uses type `impl Fn<()>`, which is not FFI-safe //~^ ERROR `extern` block uses type `impl Fn()`, which is not FFI-safe [improper_ctypes]
} }
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error: `extern` block uses type `impl Fn<()>`, which is not FFI-safe error: `extern` block uses type `impl Fn()`, which is not FFI-safe
--> $DIR/opaque-ty-ffi-unsafe.rs:11:17 --> $DIR/opaque-ty-ffi-unsafe.rs:11:17
| |
LL | pub fn a(_: A); LL | pub fn a(_: A);

View file

@ -4,7 +4,7 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:22]` cannot be used
LL | const { || {} } => {}, LL | const { || {} } => {},
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: `impl Future` cannot be used in patterns error: `impl Future<Output = [async output]>` cannot be used in patterns
--> $DIR/non-structural-match-types.rs:12:9 --> $DIR/non-structural-match-types.rs:12:9
| |
LL | const { async {} } => {}, LL | const { async {} } => {},

View file

@ -81,7 +81,7 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type | ------------------------------- the found opaque type
| |
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` = note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
found opaque type `impl Future` found opaque type `impl Future<Output = [async output]>`
help: you need to pin and box this expression help: you need to pin and box this expression
| |
LL ~ Box::pin(async { LL ~ Box::pin(async {

View file

@ -1,11 +1,11 @@
error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied error[E0277]: the trait bound `fn() -> impl T<O = ()> {foo}: T` is not satisfied
--> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9 --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9
| |
LL | fn foo() -> impl T<O=()> { S } LL | fn foo() -> impl T<O=()> { S }
| --- consider calling this function | --- consider calling this function
... ...
LL | bar(foo); LL | bar(foo);
| --- ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}` | --- ^^^ the trait `T` is not implemented for `fn() -> impl T<O = ()> {foo}`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |

View file

@ -5,7 +5,7 @@
use std::future::Future; use std::future::Future;
type G<'a, T> = impl Future<Output = ()>; type G<'a, T> = impl Future<Output = ()>;
//~^ ERROR: type mismatch resolving `<impl Future as Future>::Output == ()` //~^ ERROR: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
//~| ERROR: the trait bound `T: Trait` is not satisfied //~| ERROR: the trait bound `T: Trait` is not satisfied
trait Trait { trait Trait {

View file

@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()` error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
--> $DIR/issue-89686.rs:7:17 --> $DIR/issue-89686.rs:7:17
| |
LL | type G<'a, T> = impl Future<Output = ()>; LL | type G<'a, T> = impl Future<Output = ()>;
@ -13,8 +13,8 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type | ------------------------------- the found opaque type
| |
= note: expected unit type `()` = note: expected unit type `()`
found associated type `<impl Future as Future>::Output` found associated type `<impl Future<Output = [async output]> as Future>::Output`
= help: consider constraining the associated type `<impl Future as Future>::Output` to `()` = help: consider constraining the associated type `<impl Future<Output = [async output]> as Future>::Output` to `()`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error[E0277]: the trait bound `T: Trait` is not satisfied error[E0277]: the trait bound `T: Trait` is not satisfied