Change:
} } <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(

Discussion:
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!