Change:
Consider the following code: This fails with an error that simply states that is not available: The intent is fairly clear: we want to construct a new using a method that follows the for constructors, but that method is not available. Instead the solution is likely to be either or : When is not available it'd be ideal if the compiler could suggest alternatives. A first heuristic for which methods to suggest be methods on the same struct that don't take any params, have as their return type, and aren't implemented through any trait. For this would include and . But not , , and . I'm not too sure how to structure the help message exactly, but I could imagine something along these lines might work: cc/
Seems like es should be to the standard library to fix this.
This seems to be the same as
Closing in favor of that.
For the example I brought up, how would an work? The method does not exist on . So it shouldn't qualify as an alias? Additionally this is intended as an automated mechanism to improve the quality of diagnostics, rather than a manual mechanism (like attributes) which would need to be opted into. While both cases do touch on improving diagnostics for missing methods, I don't think these are equivalent.
No but does exist, so e.g., on it could add the information necessary (see e.g. on ) for the compiler to provide the diagnostic. But I suppose the heuristic you've suggested might work without attributes, although I suspect it would suggest too many false positives, but let's reopen I guess.
what do you think of the following? <img width="779" alt="Screenshot 2023-10-20 at 6 13 57 PM" src=""
oh I love it!

Discussion:
err.downgrade_to_delayed_bug(); } <ins> self.find_builder_fn(&mut err, rcvr_ty, source); </ins> if tcx.ty_is_opaque_future(rcvr_ty) && item_name.name == sym::poll { err.help(format!( "method `poll` found on `Pin<&mut {ty_str}>`, 

} } <ins> /// Look at all the associated functions without receivers in the type's inherent impls /// to look for builders that return `Self`, `Option<Self>` or `Result<Self, _>`. fn find_builder_fn(&self, err: &mut Diagnostic, rcvr_ty: Ty<'tcx>, source: SelfSource<'tcx>) { let ty::Adt(adt_def, _) = rcvr_ty.kind() else { return; }; let SelfSource::QPath(ty) = source else { return; }; let hir = self.tcx.hir(); if let Some(Node::Pat(_)) = hir.find(hir.parent_id(ty.hir_id)) { // Do not suggest a fn call when a pattern is expected. return; } let mut items = self .tcx .inherent_impls(adt_def.did()) .iter() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. .filter(|item| matches!(item.kind, ty::AssocKind::Fn) && !item.fn_has_self_parameter) .filter_map(|item| { // Only assoc fns that return `Self`, `Option<Self>` or `Result<Self, _>`. let ret_ty = self.tcx.fn_sig(item.def_id).skip_binder().output(); let ret_ty = self.tcx.erase_late_bound_regions(ret_ty); let ty::Adt(def, args) = ret_ty.kind() else { return None; }; // Check for `-> Self` if self.can_eq(self.param_env, ret_ty, rcvr_ty) { return Some((item.def_id, ret_ty)); } // Check for `-> Option<Self>` or `-> Result<Self, _>` if ![self.tcx.lang_items().option_type(), self.tcx.get_diagnostic_item(sym::Result)] .contains(&Some(def.did())) { return None; } let arg = args.get(0)?.expect_ty(); if self.can_eq(self.param_env, rcvr_ty, arg) { Some((item.def_id, ret_ty)) } else { None } }) .collect::<Vec<_>>(); let post = if items.len() > 5 { let items_len = items.len(); items.truncate(4); format!("nand {} others", items_len - 4) } else { String::new() }; match &items[..] { [] => {} [(def_id, ret_ty)] => { err.span_note( self.tcx.def_span(def_id), format!( "if you're trying to build a new `{rcvr_ty}`, consider using `{}` which  returns `{ret_ty}`", self.tcx.def_path_str(def_id), ), ); } _ => { let span: MultiSpan = items .iter() .map(|(def_id, _)| self.tcx.def_span(def_id)) .collect::<Vec<Span>>() .into(); err.span_note( span, format!( "if you're trying to build a new `{rcvr_ty}` consider using one of the  following associated functions:n{}{post}", items .iter() .map(|(def_id, _ret_ty)| self.tcx.def_path_str(def_id)) .collect::<Vec<String>>() .join("n") ), ); } } } </ins> /// Suggest calling `Ty::method` if `.method()` isn't found because the method /// doesn't take a `self` receiver. fn suggest_associated_call_syntax(

| LL |     core::sync::atomic::AtomicU64::from_mut(&mut 0u64); |                                    ^^^^^^^^ function or associated item not found in `AtomicU64` <ins> | note: if you're trying to build a new `AtomicU64`, consider using `AtomicU64::new` which returns `AtomicU64` --> $SRC_DIR/core/src/sync/atomic.rs:LL:COL = note: this error originates in the macro `atomic_int` (in Nightly builds, run with -Z macro-backtrace for more info) </ins> error: aborting due to previous error

|         | |         function or associated item not found in `👀` |         help: there is an associated function with a similar name: `full_of_✨` <ins> | note: if you're trying to build a new `👀`, consider using `👀::full_of_✨` which returns `👀` --> $DIR/emoji-identifiers.rs:4:5 | LL |     fn full_of_✨() -> 👀 { |     ^^^^^^^^^^^^^^^^^^^^^ </ins> error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope --> $DIR/emoji-identifiers.rs:13:13

<ins> use std::net::TcpStream; fn main() { let stream = TcpStream::new(); //~ ERROR no function or associated item named `new` found } </ins>

<ins> error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope --> $DIR/fn-new-doesnt-exist.rs:4:28 | LL |    let stream = TcpStream::new(); |                            ^^^ function or associated item not found in `TcpStream` | note: if you're trying to build a new `TcpStream` consider using one of the following associated functions: TcpStream::connect TcpStream::connect_timeout --> $SRC_DIR/std/src/net/tcp.rs:LL:COL error: aborting due to previous error For more information about this error, try `rustc --explain E0599`. </ins>

LL |     mac!(); |     ------ in this macro invocation | <ins> note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions: Box::<T>::new Box::<T>::new_uninit Box::<T>::new_zeroed Box::<T>::try_new and 18 others --> $SRC_DIR/alloc/src/boxed.rs:LL:COL </ins> = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors

LL |     Vec::contains(&vec, &0); |          ^^^^^^^^ function or associated item not found in `Vec<_, _>` | <ins> note: if you're trying to build a new `Vec<_, _>` consider using one of the following associated functions: Vec::<T>::new Vec::<T>::with_capacity Vec::<T>::from_raw_parts Vec::<T, A>::new_in and 2 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL </ins> help: the function `contains` is implemented on `[_]` | LL |     <[_]>::contains(&vec, &0);

|                                                                 | |                                                                 function or associated item not found in `Backtrace` |                                                                 help: there is an associated function with a similar name: `force_capture` <ins> | note: if you're trying to build a new `Backtrace` consider using one of the following associated functions: Backtrace::capture Backtrace::force_capture Backtrace::disabled Backtrace::create --> $SRC_DIR/std/src/backtrace.rs:LL:COL </ins> error: aborting due to previous error