Auto merge of #103228 - Dylan-DPC:rollup-31yiauw, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #102863 (Standardize "use parentheses to call" suggestions between typeck and trait selection) - #103034 (Let expressions on RHS shouldn't be terminating scopes) - #103127 (Make transpose const and inline) - #103153 (Allow `Vec::leak` when using `no_global_oom_handling`) - #103182 (Clean up query descriptions) - #103216 (Consider patterns in fn params in an `Elided(Infer)` lifetime rib.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d7dd01fe8b
@ -1,6 +1,6 @@
|
||||
use super::method::probe::{IsSuggestion, Mode, ProbeScope};
|
||||
use super::method::MethodCallee;
|
||||
use super::{DefIdOrName, Expectation, FnCtxt, TupleArgumentsFlag};
|
||||
use super::{Expectation, FnCtxt, TupleArgumentsFlag};
|
||||
use crate::type_error_struct;
|
||||
|
||||
use rustc_ast::util::parser::PREC_POSTFIX;
|
||||
@ -27,6 +27,7 @@
|
||||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::autoderef::Autoderef;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
|
||||
use std::iter;
|
||||
|
@ -2,7 +2,6 @@
|
||||
use crate::astconv::AstConv;
|
||||
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
|
||||
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
@ -19,6 +18,7 @@
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -90,7 +90,7 @@ pub(crate) fn suggest_fn_call(
|
||||
if ty.is_suggestable(self.tcx, false) {
|
||||
format!("/* {ty} */")
|
||||
} else {
|
||||
"".to_string()
|
||||
"/* value */".to_string()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
@ -102,10 +102,8 @@ pub(crate) fn suggest_fn_call(
|
||||
|
||||
let msg = match def_id_or_name {
|
||||
DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
|
||||
DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct".to_string(),
|
||||
DefKind::Ctor(CtorOf::Variant, _) => {
|
||||
"instantiate this tuple variant".to_string()
|
||||
}
|
||||
DefKind::Ctor(CtorOf::Struct, _) => "construct this tuple struct".to_string(),
|
||||
DefKind::Ctor(CtorOf::Variant, _) => "construct this tuple variant".to_string(),
|
||||
kind => format!("call this {}", kind.descr(def_id)),
|
||||
},
|
||||
DefIdOrName::Name(name) => format!("call this {name}"),
|
||||
@ -1209,8 +1207,3 @@ pub(crate) fn consider_removing_semicolon(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DefIdOrName {
|
||||
DefId(DefId),
|
||||
Name(&'static str),
|
||||
}
|
||||
|
@ -252,9 +252,13 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
||||
) => {
|
||||
// For shortcircuiting operators, mark the RHS as a terminating
|
||||
// scope since it only executes conditionally.
|
||||
terminating(r.hir_id.local_id);
|
||||
}
|
||||
|
||||
// `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries
|
||||
// should live beyond the immediate expression
|
||||
if !matches!(r.kind, hir::ExprKind::Let(_)) {
|
||||
terminating(r.hir_id.local_id);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::If(_, ref then, Some(ref otherwise)) => {
|
||||
terminating(then.hir_id.local_id);
|
||||
terminating(otherwise.hir_id.local_id);
|
||||
|
@ -20,19 +20,19 @@
|
||||
// as they will raise an fatal error on query cycles instead.
|
||||
rustc_queries! {
|
||||
query trigger_delay_span_bug(key: DefId) -> () {
|
||||
desc { "trigger a delay span bug" }
|
||||
desc { "triggering a delay span bug" }
|
||||
}
|
||||
|
||||
query resolutions(_: ()) -> &'tcx ty::ResolverOutputs {
|
||||
eval_always
|
||||
no_hash
|
||||
desc { "get the resolver outputs" }
|
||||
desc { "getting the resolver outputs" }
|
||||
}
|
||||
|
||||
query resolver_for_lowering(_: ()) -> &'tcx Steal<ty::ResolverAstLowering> {
|
||||
eval_always
|
||||
no_hash
|
||||
desc { "get the resolver for lowering" }
|
||||
desc { "getting the resolver for lowering" }
|
||||
}
|
||||
|
||||
/// Return the span for a definition.
|
||||
@ -40,7 +40,7 @@
|
||||
/// This span is meant for dep-tracking rather than diagnostics. It should not be used outside
|
||||
/// of rustc_middle::hir::source_map.
|
||||
query source_span(key: LocalDefId) -> Span {
|
||||
desc { "get the source span" }
|
||||
desc { "getting the source span" }
|
||||
}
|
||||
|
||||
/// Represents crate as a whole (as distinct from the top-level crate module).
|
||||
@ -52,14 +52,14 @@
|
||||
query hir_crate(key: ()) -> Crate<'tcx> {
|
||||
arena_cache
|
||||
eval_always
|
||||
desc { "get the crate HIR" }
|
||||
desc { "getting the crate HIR" }
|
||||
}
|
||||
|
||||
/// All items in the crate.
|
||||
query hir_crate_items(_: ()) -> rustc_middle::hir::ModuleItems {
|
||||
arena_cache
|
||||
eval_always
|
||||
desc { "get HIR crate items" }
|
||||
desc { "getting HIR crate items" }
|
||||
}
|
||||
|
||||
/// The items in a module.
|
||||
@ -68,7 +68,7 @@
|
||||
/// Avoid calling this query directly.
|
||||
query hir_module_items(key: LocalDefId) -> rustc_middle::hir::ModuleItems {
|
||||
arena_cache
|
||||
desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||
/// Avoid calling this query directly.
|
||||
query hir_owner(key: hir::OwnerId) -> Option<crate::hir::Owner<'tcx>> {
|
||||
desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Gives access to the HIR ID for the given `LocalDefId` owner `key`.
|
||||
@ -85,7 +85,7 @@
|
||||
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||
/// Avoid calling this query directly.
|
||||
query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
|
||||
desc { |tcx| "HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Gives access to the HIR node's parent for the HIR owner `key`.
|
||||
@ -93,7 +93,7 @@
|
||||
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||
/// Avoid calling this query directly.
|
||||
query hir_owner_parent(key: hir::OwnerId) -> hir::HirId {
|
||||
desc { |tcx| "HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
|
||||
@ -101,7 +101,7 @@
|
||||
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||
/// Avoid calling this query directly.
|
||||
query hir_owner_nodes(key: hir::OwnerId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> {
|
||||
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Gives access to the HIR attributes inside the HIR owner `key`.
|
||||
@ -109,7 +109,7 @@
|
||||
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||
/// Avoid calling this query directly.
|
||||
query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
|
||||
desc { |tcx| "HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
|
||||
@ -138,7 +138,7 @@
|
||||
/// Given the def_id of a const-generic parameter, computes the associated default const
|
||||
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
|
||||
query const_param_default(param: DefId) -> ty::Const<'tcx> {
|
||||
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
|
||||
desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param) }
|
||||
cache_on_disk_if { param.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
@ -167,7 +167,7 @@
|
||||
query collect_trait_impl_trait_tys(key: DefId)
|
||||
-> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>
|
||||
{
|
||||
desc { "compare an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
|
||||
desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
|
||||
cache_on_disk_if { key.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
@ -290,11 +290,11 @@
|
||||
|
||||
query parent_module_from_def_id(key: LocalDefId) -> LocalDefId {
|
||||
eval_always
|
||||
desc { |tcx| "parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
|
||||
desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
|
||||
desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@
|
||||
|
||||
/// Checks whether a type is representable or infinitely sized
|
||||
query representability(_: LocalDefId) -> rustc_middle::ty::Representability {
|
||||
desc { "checking if {:?} is representable", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { "checking if `{}` is representable", tcx.def_path_str(key.to_def_id()) }
|
||||
// infinitely sized types will cause a cycle
|
||||
cycle_delay_bug
|
||||
// we don't want recursive representability calls to be forced with
|
||||
@ -317,7 +317,7 @@
|
||||
|
||||
/// An implementation detail for the `representability` query
|
||||
query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability {
|
||||
desc { "checking if {:?} is representable", key }
|
||||
desc { "checking if `{}` is representable", key }
|
||||
cycle_delay_bug
|
||||
anon
|
||||
}
|
||||
@ -383,7 +383,7 @@
|
||||
/// See the README for the `mir` module for details.
|
||||
query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc {
|
||||
|tcx| "processing MIR for {}`{}`",
|
||||
|tcx| "preparing {}`{}` for borrow checking",
|
||||
if key.const_param_did.is_some() { "the const argument " } else { "" },
|
||||
tcx.def_path_str(key.did.to_def_id()),
|
||||
}
|
||||
@ -395,7 +395,7 @@
|
||||
key: DefId
|
||||
) -> Result<Option<&'tcx [ty::abstract_const::Node<'tcx>]>, ErrorGuaranteed> {
|
||||
desc {
|
||||
|tcx| "building an abstract representation for {}", tcx.def_path_str(key),
|
||||
|tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
|
||||
}
|
||||
separate_provide_extern
|
||||
}
|
||||
@ -405,7 +405,7 @@
|
||||
) -> Result<Option<&'tcx [ty::abstract_const::Node<'tcx>]>, ErrorGuaranteed> {
|
||||
desc {
|
||||
|tcx|
|
||||
"building an abstract representation for the const argument {}",
|
||||
"building an abstract representation for the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id()),
|
||||
}
|
||||
}
|
||||
@ -414,7 +414,7 @@
|
||||
ty::ParamEnvAnd<'tcx, (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>
|
||||
)>) -> bool {
|
||||
desc {
|
||||
|tcx| "trying to unify the generic constants {} and {}",
|
||||
|tcx| "trying to unify the generic constants `{}` and `{}`",
|
||||
tcx.def_path_str(key.value.0.def.did), tcx.def_path_str(key.value.1.def.did)
|
||||
}
|
||||
}
|
||||
@ -436,7 +436,7 @@
|
||||
|
||||
query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
||||
desc {
|
||||
|tcx| "MIR for CTFE of the const argument `{}`",
|
||||
|tcx| "caching MIR for CTFE of the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
@ -448,7 +448,7 @@
|
||||
) {
|
||||
no_hash
|
||||
desc {
|
||||
|tcx| "processing {}`{}`",
|
||||
|tcx| "processing MIR for {}`{}`",
|
||||
if key.const_param_did.is_some() { "the const argument " } else { "" },
|
||||
tcx.def_path_str(key.did.to_def_id()),
|
||||
}
|
||||
@ -459,7 +459,7 @@
|
||||
) -> Vec<rustc_span::Symbol> {
|
||||
arena_cache
|
||||
desc {
|
||||
|tcx| "symbols for captures of closure `{}` in `{}`",
|
||||
|tcx| "finding symbols for captures of closure `{}` in `{}`",
|
||||
tcx.def_path_str(key.1.to_def_id()),
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
@ -521,12 +521,12 @@
|
||||
// queries). Making it anonymous avoids hashing the result, which
|
||||
// may save a bit of time.
|
||||
anon
|
||||
desc { "erasing regions from `{:?}`", ty }
|
||||
desc { "erasing regions from `{}`", ty }
|
||||
}
|
||||
|
||||
query wasm_import_module_map(_: CrateNum) -> FxHashMap<DefId, String> {
|
||||
arena_cache
|
||||
desc { "wasm import module map" }
|
||||
desc { "getting wasm import module map" }
|
||||
}
|
||||
|
||||
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
|
||||
@ -706,7 +706,7 @@
|
||||
/// Collects the associated items defined on a trait or impl.
|
||||
query associated_items(key: DefId) -> ty::AssocItems<'tcx> {
|
||||
arena_cache
|
||||
desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
|
||||
desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
/// Maps from associated items on a trait to the corresponding associated
|
||||
@ -732,7 +732,7 @@
|
||||
///`{ trait_f: impl_f, trait_g: impl_g }`
|
||||
query impl_item_implementor_ids(impl_id: DefId) -> FxHashMap<DefId, DefId> {
|
||||
arena_cache
|
||||
desc { |tcx| "comparing impl items against trait for {}", tcx.def_path_str(impl_id) }
|
||||
desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
|
||||
}
|
||||
|
||||
/// Given an `impl_id`, return the trait it implements.
|
||||
@ -804,7 +804,7 @@
|
||||
/// Note that we've liberated the late bound regions of function signatures, so
|
||||
/// this can not be used to check whether these types are well formed.
|
||||
query assumed_wf_types(key: DefId) -> &'tcx ty::List<Ty<'tcx>> {
|
||||
desc { |tcx| "computing the implied bounds of {}", tcx.def_path_str(key) }
|
||||
desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
/// Computes the signature of the function.
|
||||
@ -853,7 +853,7 @@
|
||||
}
|
||||
|
||||
query check_liveness(key: DefId) {
|
||||
desc { |tcx| "checking liveness of variables in {}", tcx.def_path_str(key) }
|
||||
desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
/// Return the live symbols in the crate for dead code check.
|
||||
@ -865,7 +865,7 @@
|
||||
FxHashMap<LocalDefId, Vec<(DefId, DefId)>>
|
||||
) {
|
||||
arena_cache
|
||||
desc { "find live symbols in crate" }
|
||||
desc { "finding live symbols in crate" }
|
||||
}
|
||||
|
||||
query check_mod_deathness(key: LocalDefId) -> () {
|
||||
@ -913,7 +913,7 @@
|
||||
}
|
||||
|
||||
query used_trait_imports(key: LocalDefId) -> &'tcx FxHashSet<LocalDefId> {
|
||||
desc { |tcx| "used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
|
||||
@ -942,7 +942,7 @@
|
||||
/// Not meant to be used directly outside of coherence.
|
||||
query crate_inherent_impls(k: ()) -> CrateInherentImpls {
|
||||
arena_cache
|
||||
desc { "all inherent impls defined in crate" }
|
||||
desc { "finding all inherent impls defined in crate" }
|
||||
}
|
||||
|
||||
/// Checks all types in the crate for overlap in their inherent impls. Reports errors.
|
||||
@ -1032,7 +1032,7 @@
|
||||
query try_destructure_mir_constant(
|
||||
key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
|
||||
) -> Option<mir::DestructuredConstant<'tcx>> {
|
||||
desc { "destructuring mir constant"}
|
||||
desc { "destructuring MIR constant"}
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1041,12 +1041,12 @@
|
||||
query deref_mir_constant(
|
||||
key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
|
||||
) -> mir::ConstantKind<'tcx> {
|
||||
desc { "dereferencing mir constant" }
|
||||
desc { "dereferencing MIR constant" }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
|
||||
desc { "get a &core::panic::Location referring to a span" }
|
||||
desc { "getting a &core::panic::Location referring to a span" }
|
||||
}
|
||||
|
||||
// FIXME get rid of this with valtrees
|
||||
@ -1068,7 +1068,7 @@
|
||||
/// Performs part of the privacy check and computes "access levels".
|
||||
query privacy_access_levels(_: ()) -> &'tcx AccessLevels {
|
||||
eval_always
|
||||
desc { "privacy access levels" }
|
||||
desc { "checking privacy access levels" }
|
||||
}
|
||||
query check_private_in_public(_: ()) -> () {
|
||||
eval_always
|
||||
@ -1196,12 +1196,12 @@
|
||||
}
|
||||
|
||||
query is_ctfe_mir_available(key: DefId) -> bool {
|
||||
desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) }
|
||||
desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) }
|
||||
cache_on_disk_if { key.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
query is_mir_available(key: DefId) -> bool {
|
||||
desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
|
||||
desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) }
|
||||
cache_on_disk_if { key.is_local() }
|
||||
separate_provide_extern
|
||||
}
|
||||
@ -1209,16 +1209,16 @@
|
||||
query own_existential_vtable_entries(
|
||||
key: ty::PolyExistentialTraitRef<'tcx>
|
||||
) -> &'tcx [DefId] {
|
||||
desc { |tcx| "finding all existential vtable entries for trait {}", tcx.def_path_str(key.def_id()) }
|
||||
desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
|
||||
}
|
||||
|
||||
query vtable_entries(key: ty::PolyTraitRef<'tcx>)
|
||||
-> &'tcx [ty::VtblEntry<'tcx>] {
|
||||
desc { |tcx| "finding all vtable entries for trait {}", tcx.def_path_str(key.def_id()) }
|
||||
desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
|
||||
}
|
||||
|
||||
query vtable_trait_upcasting_coercion_new_vptr_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> {
|
||||
desc { |tcx| "finding the slot within vtable for trait object {} vtable ptr during trait upcasting coercion from {} vtable",
|
||||
desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable",
|
||||
key.1, key.0 }
|
||||
}
|
||||
|
||||
@ -1238,13 +1238,13 @@
|
||||
|
||||
/// Return all `impl` blocks in the current crate.
|
||||
query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap<DefId, Vec<LocalDefId>> {
|
||||
desc { "local trait impls" }
|
||||
desc { "finding local trait impls" }
|
||||
}
|
||||
|
||||
/// Given a trait `trait_id`, return all known `impl` blocks.
|
||||
query trait_impls_of(trait_id: DefId) -> ty::trait_def::TraitImpls {
|
||||
arena_cache
|
||||
desc { |tcx| "trait impls of `{}`", tcx.def_path_str(trait_id) }
|
||||
desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) }
|
||||
}
|
||||
|
||||
query specialization_graph_of(trait_id: DefId) -> specialization_graph::Graph {
|
||||
@ -1253,7 +1253,7 @@
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
|
||||
desc { |tcx| "determine object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
||||
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
||||
}
|
||||
|
||||
/// Gets the ParameterEnvironment for a given item; this environment
|
||||
@ -1311,7 +1311,7 @@
|
||||
/// correctly.
|
||||
query has_structural_eq_impls(ty: Ty<'tcx>) -> bool {
|
||||
desc {
|
||||
"computing whether `{:?}` implements `PartialStructuralEq` and `StructuralEq`",
|
||||
"computing whether `{}` implements `PartialStructuralEq` and `StructuralEq`",
|
||||
ty
|
||||
}
|
||||
}
|
||||
@ -1370,13 +1370,13 @@
|
||||
|
||||
query dylib_dependency_formats(_: CrateNum)
|
||||
-> &'tcx [(CrateNum, LinkagePreference)] {
|
||||
desc { "dylib dependency formats of crate" }
|
||||
desc { "getting dylib dependency formats of crate" }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> {
|
||||
arena_cache
|
||||
desc { "get the linkage format of all dependencies" }
|
||||
desc { "getting the linkage format of all dependencies" }
|
||||
}
|
||||
|
||||
query is_compiler_builtins(_: CrateNum) -> bool {
|
||||
@ -1398,31 +1398,31 @@
|
||||
}
|
||||
query is_profiler_runtime(_: CrateNum) -> bool {
|
||||
fatal_cycle
|
||||
desc { "query a crate is `#![profiler_runtime]`" }
|
||||
desc { "checking if a crate is `#![profiler_runtime]`" }
|
||||
separate_provide_extern
|
||||
}
|
||||
query has_ffi_unwind_calls(key: LocalDefId) -> bool {
|
||||
desc { |tcx| "check if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> {
|
||||
fatal_cycle
|
||||
desc { "query a crate's required panic strategy" }
|
||||
desc { "getting a crate's required panic strategy" }
|
||||
separate_provide_extern
|
||||
}
|
||||
query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy {
|
||||
fatal_cycle
|
||||
desc { "query a crate's configured panic-in-drop strategy" }
|
||||
desc { "getting a crate's configured panic-in-drop strategy" }
|
||||
separate_provide_extern
|
||||
}
|
||||
query is_no_builtins(_: CrateNum) -> bool {
|
||||
fatal_cycle
|
||||
desc { "test whether a crate has `#![no_builtins]`" }
|
||||
desc { "getting whether a crate has `#![no_builtins]`" }
|
||||
separate_provide_extern
|
||||
}
|
||||
query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion {
|
||||
fatal_cycle
|
||||
desc { "query a crate's symbol mangling version" }
|
||||
desc { "getting a crate's symbol mangling version" }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
@ -1437,7 +1437,7 @@
|
||||
}
|
||||
query in_scope_traits_map(_: hir::OwnerId)
|
||||
-> Option<&'tcx FxHashMap<ItemLocalId, Box<[TraitCandidate]>>> {
|
||||
desc { "traits in scope at a block" }
|
||||
desc { "getting traits in scope at a block" }
|
||||
}
|
||||
|
||||
query module_reexports(def_id: LocalDefId) -> Option<&'tcx [ModChild]> {
|
||||
@ -1588,17 +1588,17 @@
|
||||
}
|
||||
|
||||
query is_dllimport_foreign_item(def_id: DefId) -> bool {
|
||||
desc { |tcx| "is_dllimport_foreign_item({})", tcx.def_path_str(def_id) }
|
||||
desc { |tcx| "checking if `{}` is a a dylib", tcx.def_path_str(def_id) }
|
||||
}
|
||||
query is_statically_included_foreign_item(def_id: DefId) -> bool {
|
||||
desc { |tcx| "is_statically_included_foreign_item({})", tcx.def_path_str(def_id) }
|
||||
desc { |tcx| "checking if `{}` is a staticlib", tcx.def_path_str(def_id) }
|
||||
}
|
||||
query native_library_kind(def_id: DefId)
|
||||
-> Option<NativeLibKind> {
|
||||
desc { |tcx| "native_library_kind({})", tcx.def_path_str(def_id) }
|
||||
desc { |tcx| "getting the native library kind of `{}`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
query native_library(def_id: DefId) -> Option<&'tcx NativeLib> {
|
||||
desc { |tcx| "native_library({})", tcx.def_path_str(def_id) }
|
||||
desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
/// Does lifetime resolution, but does not descend into trait items. This
|
||||
@ -1659,7 +1659,7 @@
|
||||
query type_uninhabited_from(
|
||||
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
|
||||
) -> ty::inhabitedness::DefIdForest<'tcx> {
|
||||
desc { "computing the inhabitedness of `{:?}`", key }
|
||||
desc { "computing the inhabitedness of `{}`", key.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1698,7 +1698,7 @@
|
||||
}
|
||||
/// Whether the function is an intrinsic
|
||||
query is_intrinsic(def_id: DefId) -> bool {
|
||||
desc { |tcx| "is_intrinsic({})", tcx.def_path_str(def_id) }
|
||||
desc { |tcx| "checking whether `{}` is an intrinsic", tcx.def_path_str(def_id) }
|
||||
separate_provide_extern
|
||||
}
|
||||
/// Returns the lang items defined in another crate by loading it from metadata.
|
||||
@ -1765,12 +1765,12 @@
|
||||
/// is marked as a private dependency
|
||||
query is_private_dep(c: CrateNum) -> bool {
|
||||
eval_always
|
||||
desc { "check whether crate {} is a private dependency", c }
|
||||
desc { "checking whether crate `{}` is a private dependency", c }
|
||||
separate_provide_extern
|
||||
}
|
||||
query allocator_kind(_: ()) -> Option<AllocatorKind> {
|
||||
eval_always
|
||||
desc { "allocator kind for the current crate" }
|
||||
desc { "getting the allocator kind for the current crate" }
|
||||
}
|
||||
|
||||
query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
|
||||
@ -1783,7 +1783,7 @@
|
||||
desc { "looking up all possibly unused extern crates" }
|
||||
}
|
||||
query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxHashSet<Symbol> {
|
||||
desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||
desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||
}
|
||||
|
||||
query stability_index(_: ()) -> stability::Index {
|
||||
@ -1809,7 +1809,7 @@
|
||||
/// correspond to a publicly visible symbol in `cnum` machine code.
|
||||
/// - The `exported_symbols` sets of different crates do not intersect.
|
||||
query exported_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
|
||||
desc { "exported_symbols" }
|
||||
desc { "collecting exported symbols for crate `{}`", cnum}
|
||||
cache_on_disk_if { *cnum == LOCAL_CRATE }
|
||||
separate_provide_extern
|
||||
}
|
||||
@ -1818,6 +1818,7 @@
|
||||
eval_always
|
||||
desc { "collect_and_partition_mono_items" }
|
||||
}
|
||||
|
||||
query is_codegened_item(def_id: DefId) -> bool {
|
||||
desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) }
|
||||
}
|
||||
@ -1825,12 +1826,13 @@
|
||||
/// All items participating in code generation together with items inlined into them.
|
||||
query codegened_and_inlined_items(_: ()) -> &'tcx DefIdSet {
|
||||
eval_always
|
||||
desc { "codegened_and_inlined_items" }
|
||||
desc { "collecting codegened and inlined items" }
|
||||
}
|
||||
|
||||
query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
|
||||
desc { "codegen_unit" }
|
||||
query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> {
|
||||
desc { "getting codegen unit `{sym}`" }
|
||||
}
|
||||
|
||||
query unused_generic_params(key: ty::InstanceDef<'tcx>) -> FiniteBitSet<u32> {
|
||||
cache_on_disk_if { key.def_id().is_local() }
|
||||
desc {
|
||||
@ -1839,6 +1841,7 @@
|
||||
}
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
query backend_optimization_level(_: ()) -> OptLevel {
|
||||
desc { "optimization level used by backend" }
|
||||
}
|
||||
@ -1849,7 +1852,7 @@
|
||||
/// has been destroyed.
|
||||
query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> {
|
||||
eval_always
|
||||
desc { "output_filenames" }
|
||||
desc { "getting output filenames" }
|
||||
}
|
||||
|
||||
/// Do not call this query directly: invoke `normalize` instead.
|
||||
@ -1859,7 +1862,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "normalizing `{:?}`", goal }
|
||||
desc { "normalizing `{}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1877,7 +1880,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "computing implied outlives bounds for `{:?}`", goal }
|
||||
desc { "computing implied outlives bounds for `{}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1889,7 +1892,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "computing dropck types for `{:?}`", goal }
|
||||
desc { "computing dropck types for `{}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1917,7 +1920,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal }
|
||||
desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1928,7 +1931,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "evaluating `type_op_eq` `{:?}`", goal }
|
||||
desc { "evaluating `type_op_eq` `{:?}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1939,7 +1942,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "evaluating `type_op_subtype` `{:?}`", goal }
|
||||
desc { "evaluating `type_op_subtype` `{:?}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1950,7 +1953,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "evaluating `type_op_prove_predicate` `{:?}`", goal }
|
||||
desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.value.value }
|
||||
}
|
||||
|
||||
/// Do not call this query directly: part of the `Normalize` type-op
|
||||
@ -1960,7 +1963,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "normalizing `{:?}`", goal }
|
||||
desc { "normalizing `{}`", goal.value.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1971,7 +1974,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "normalizing `{:?}`", goal }
|
||||
desc { "normalizing `{:?}`", goal.value.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1982,7 +1985,7 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "normalizing `{:?}`", goal }
|
||||
desc { "normalizing `{:?}`", goal.value.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -1993,20 +1996,20 @@
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
desc { "normalizing `{:?}`", goal }
|
||||
desc { "normalizing `{:?}`", goal.value.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
|
||||
desc { |tcx|
|
||||
"impossible substituted predicates:`{}`",
|
||||
"checking impossible substituted predicates: `{}`",
|
||||
tcx.def_path_str(key.0)
|
||||
}
|
||||
}
|
||||
|
||||
query is_impossible_method(key: (DefId, DefId)) -> bool {
|
||||
desc { |tcx|
|
||||
"checking if {} is impossible to call within {}",
|
||||
"checking if `{}` is impossible to call within `{}`",
|
||||
tcx.def_path_str(key.1),
|
||||
tcx.def_path_str(key.0),
|
||||
}
|
||||
@ -2015,7 +2018,7 @@
|
||||
query method_autoderef_steps(
|
||||
goal: CanonicalTyGoal<'tcx>
|
||||
) -> MethodAutoderefStepsResult<'tcx> {
|
||||
desc { "computing autoderef types for `{:?}`", goal }
|
||||
desc { "computing autoderef types for `{}`", goal.value.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -2063,7 +2066,7 @@
|
||||
}
|
||||
|
||||
query normalize_opaque_types(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
desc { "normalizing opaque types in {:?}", key }
|
||||
desc { "normalizing opaque types in `{:?}`", key }
|
||||
}
|
||||
|
||||
/// Checks whether a type is definitely uninhabited. This is
|
||||
@ -2073,7 +2076,7 @@
|
||||
/// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
|
||||
/// size, to account for partial initialisation. See #49298 for details.)
|
||||
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "conservatively checking if {:?} is privately uninhabited", key }
|
||||
desc { "conservatively checking if `{}` is privately uninhabited", key.value }
|
||||
remap_env_constness
|
||||
}
|
||||
|
||||
@ -2093,7 +2096,7 @@
|
||||
arena_cache
|
||||
eval_always
|
||||
no_hash
|
||||
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
|
||||
desc { "performing HIR wf-checking for predicate `{:?}` at item `{:?}`", key.0, key.1 }
|
||||
}
|
||||
|
||||
|
||||
@ -2112,11 +2115,11 @@
|
||||
}
|
||||
|
||||
query permits_uninit_init(key: TyAndLayout<'tcx>) -> bool {
|
||||
desc { "checking to see if {:?} permits being left uninit", key.ty }
|
||||
desc { "checking to see if `{}` permits being left uninit", key.ty }
|
||||
}
|
||||
|
||||
query permits_zero_init(key: TyAndLayout<'tcx>) -> bool {
|
||||
desc { "checking to see if {:?} permits being left zeroed", key.ty }
|
||||
desc { "checking to see if `{}` permits being left zeroed", key.ty }
|
||||
}
|
||||
|
||||
query compare_assoc_const_impl_item_with_trait_item(
|
||||
|
@ -1862,9 +1862,11 @@ fn resolve_fn_params(
|
||||
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
|
||||
for (index, (pat, ty)) in inputs.enumerate() {
|
||||
debug!(?pat, ?ty);
|
||||
if let Some(pat) = pat {
|
||||
self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
|
||||
}
|
||||
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||
if let Some(pat) = pat {
|
||||
this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
|
||||
}
|
||||
});
|
||||
self.visit_ty(ty);
|
||||
|
||||
if let Some(ref candidates) = self.lifetime_elision_candidates {
|
||||
@ -2834,10 +2836,13 @@ fn check_trait_item<F>(
|
||||
|
||||
fn resolve_params(&mut self, params: &'ast [Param]) {
|
||||
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
|
||||
for Param { pat, ty, .. } in params {
|
||||
self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
|
||||
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||
for Param { pat, .. } in params {
|
||||
this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
|
||||
}
|
||||
});
|
||||
for Param { ty, .. } in params {
|
||||
self.visit_ty(ty);
|
||||
debug!("(resolving function / closure) recorded parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
pub mod suggestions;
|
||||
|
||||
use super::{
|
||||
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
|
||||
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
|
||||
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
|
||||
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||
FulfillmentContext, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
|
||||
Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective,
|
||||
OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation,
|
||||
SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||
};
|
||||
|
||||
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
|
||||
@ -2796,3 +2796,8 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DefIdOrName {
|
||||
DefId(DefId),
|
||||
Name(&'static str),
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
|
||||
DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
|
||||
SelectionContext,
|
||||
};
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::normalize_to;
|
||||
|
||||
use hir::def::CtorOf;
|
||||
use hir::HirId;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
@ -22,6 +23,7 @@
|
||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
|
||||
use rustc_infer::infer::error_reporting::TypeErrCtxt;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_middle::hir::map;
|
||||
use rustc_middle::ty::{
|
||||
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
|
||||
@ -29,7 +31,7 @@
|
||||
ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
||||
};
|
||||
use rustc_middle::ty::{TypeAndMut, TypeckResults};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi;
|
||||
use std::fmt;
|
||||
@ -812,74 +814,136 @@ fn suggest_fn_call(
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool {
|
||||
// Skipping binder here, remapping below
|
||||
let self_ty = trait_pred.self_ty().skip_binder();
|
||||
if let ty::PredicateKind::Trait(trait_pred) = obligation.predicate.kind().skip_binder()
|
||||
&& Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait()
|
||||
{
|
||||
// Don't suggest calling to turn an unsized type into a sized type
|
||||
return false;
|
||||
}
|
||||
|
||||
let (def_id, output_ty, callable) = match *self_ty.kind() {
|
||||
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
|
||||
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
|
||||
_ => return false,
|
||||
};
|
||||
let msg = format!("use parentheses to call the {}", callable);
|
||||
|
||||
// "We should really create a single list of bound vars from the combined vars
|
||||
// from the predicate and function, but instead we just liberate the function bound vars"
|
||||
let output_ty = self.tcx.liberate_late_bound_regions(def_id, output_ty);
|
||||
// This is duplicated from `extract_callable_info` in typeck, which
|
||||
// relies on autoderef, so we can't use it here.
|
||||
let found = trait_pred.self_ty().skip_binder().peel_refs();
|
||||
let Some((def_id_or_name, output, inputs)) = (match *found.kind()
|
||||
{
|
||||
ty::FnPtr(fn_sig) => {
|
||||
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs()))
|
||||
}
|
||||
ty::FnDef(def_id, _) => {
|
||||
let fn_sig = found.fn_sig(self.tcx);
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
|
||||
}
|
||||
ty::Closure(def_id, substs) => {
|
||||
let fn_sig = substs.as_closure().sig();
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
fn_sig.output(),
|
||||
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
|
||||
))
|
||||
}
|
||||
ty::Opaque(def_id, substs) => {
|
||||
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
|
||||
if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
|
||||
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
|
||||
// args tuple will always be substs[1]
|
||||
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
pred.kind().rebind(proj.term.ty().unwrap()),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::Dynamic(data, _, ty::Dyn) => {
|
||||
data.iter().find_map(|pred| {
|
||||
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
|
||||
&& Some(proj.item_def_id) == self.tcx.lang_items().fn_once_output()
|
||||
// for existential projection, substs are shifted over by 1
|
||||
&& let ty::Tuple(args) = proj.substs.type_at(0).kind()
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::Name("trait object"),
|
||||
pred.rebind(proj.term.ty().unwrap()),
|
||||
pred.rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::Param(_) => {
|
||||
obligation.param_env.caller_bounds().iter().find_map(|pred| {
|
||||
if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
|
||||
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
|
||||
&& proj.projection_ty.self_ty() == found
|
||||
// args tuple will always be substs[1]
|
||||
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::Name("type parameter"),
|
||||
pred.kind().rebind(proj.term.ty().unwrap()),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}) else { return false; };
|
||||
let output = self.replace_bound_vars_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
output,
|
||||
);
|
||||
let inputs = inputs.skip_binder().iter().map(|ty| {
|
||||
self.replace_bound_vars_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
inputs.rebind(*ty),
|
||||
)
|
||||
});
|
||||
|
||||
// Remapping bound vars here
|
||||
let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output_ty));
|
||||
let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output));
|
||||
|
||||
let new_obligation =
|
||||
self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self);
|
||||
|
||||
match self.evaluate_obligation(&new_obligation) {
|
||||
Ok(
|
||||
EvaluationResult::EvaluatedToOk
|
||||
| EvaluationResult::EvaluatedToOkModuloRegions
|
||||
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
|
||||
| EvaluationResult::EvaluatedToAmbig,
|
||||
) => {}
|
||||
_ => return false,
|
||||
if !self.predicate_must_hold_modulo_regions(&new_obligation) {
|
||||
return false;
|
||||
}
|
||||
let hir = self.tcx.hir();
|
||||
|
||||
// Get the name of the callable and the arguments to be used in the suggestion.
|
||||
let (snippet, sugg) = match hir.get_if_local(def_id) {
|
||||
Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(hir::Closure { fn_decl, fn_decl_span, .. }),
|
||||
..
|
||||
})) => {
|
||||
err.span_label(*fn_decl_span, "consider calling this closure");
|
||||
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
|
||||
return false;
|
||||
};
|
||||
let args = fn_decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
||||
let sugg = format!("({})", args);
|
||||
(format!("{}{}", name, sugg), sugg)
|
||||
}
|
||||
Some(hir::Node::Item(hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Fn(.., body_id),
|
||||
..
|
||||
})) => {
|
||||
err.span_label(ident.span, "consider calling this function");
|
||||
let body = hir.body(*body_id);
|
||||
let args = body
|
||||
.params
|
||||
.iter()
|
||||
.map(|arg| match &arg.pat.kind {
|
||||
hir::PatKind::Binding(_, _, ident, None)
|
||||
// FIXME: provide a better suggestion when encountering `SelfLower`, it
|
||||
// should suggest a method call.
|
||||
if ident.name != kw::SelfLower => ident.to_string(),
|
||||
_ => "_".to_string(),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let sugg = format!("({})", args);
|
||||
(format!("{}{}", ident, sugg), sugg)
|
||||
}
|
||||
_ => return false,
|
||||
let hir = self.tcx.hir();
|
||||
|
||||
let msg = match def_id_or_name {
|
||||
DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
|
||||
DefKind::Ctor(CtorOf::Struct, _) => {
|
||||
"use parentheses to construct this tuple struct".to_string()
|
||||
}
|
||||
DefKind::Ctor(CtorOf::Variant, _) => {
|
||||
"use parentheses to construct this tuple variant".to_string()
|
||||
}
|
||||
kind => format!("use parentheses to call this {}", kind.descr(def_id)),
|
||||
},
|
||||
DefIdOrName::Name(name) => format!("use parentheses to call this {name}"),
|
||||
};
|
||||
|
||||
let args = inputs
|
||||
.map(|ty| {
|
||||
if ty.is_suggestable(self.tcx, false) {
|
||||
format!("/* {ty} */")
|
||||
} else {
|
||||
"/* value */".to_string()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. })
|
||||
&& obligation.cause.span.can_be_used_for_suggestions()
|
||||
{
|
||||
@ -890,11 +954,36 @@ fn suggest_fn_call(
|
||||
err.span_suggestion_verbose(
|
||||
obligation.cause.span.shrink_to_hi(),
|
||||
&msg,
|
||||
sugg,
|
||||
format!("({args})"),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
} else {
|
||||
err.help(&format!("{}: `{}`", msg, snippet));
|
||||
} else if let DefIdOrName::DefId(def_id) = def_id_or_name {
|
||||
let name = match hir.get_if_local(def_id) {
|
||||
Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
|
||||
..
|
||||
})) => {
|
||||
err.span_label(*fn_decl_span, "consider calling this closure");
|
||||
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
|
||||
return false;
|
||||
};
|
||||
name.to_string()
|
||||
}
|
||||
Some(hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(..), .. })) => {
|
||||
err.span_label(ident.span, "consider calling this function");
|
||||
ident.to_string()
|
||||
}
|
||||
Some(hir::Node::Ctor(..)) => {
|
||||
let name = self.tcx.def_path_str(def_id);
|
||||
err.span_label(
|
||||
self.tcx.def_span(def_id),
|
||||
format!("consider calling the constructor for `{}`", name),
|
||||
);
|
||||
name
|
||||
}
|
||||
_ => return false,
|
||||
};
|
||||
err.help(&format!("{msg}: `{name}({args})`"));
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -2193,7 +2193,6 @@ pub fn resize_with<F>(&mut self, new_len: usize, f: F)
|
||||
/// static_ref[0] += 1;
|
||||
/// assert_eq!(static_ref, &[2, 2, 3]);
|
||||
/// ```
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "vec_leak", since = "1.47.0")]
|
||||
#[inline]
|
||||
pub fn leak<'a>(self) -> &'a mut [T]
|
||||
|
@ -217,6 +217,7 @@
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unsized_fn_params)]
|
||||
#![feature(asm_const)]
|
||||
#![feature(const_transmute_copy)]
|
||||
//
|
||||
// Target features:
|
||||
#![feature(arm_target_feature)]
|
||||
|
@ -1297,7 +1297,8 @@ pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>]
|
||||
/// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().transpose();
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
|
||||
pub fn transpose(self) -> [MaybeUninit<T>; N] {
|
||||
#[inline]
|
||||
pub const fn transpose(self) -> [MaybeUninit<T>; N] {
|
||||
// SAFETY: T and MaybeUninit<T> have the same layout
|
||||
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
|
||||
}
|
||||
@ -1316,7 +1317,8 @@ pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>]
|
||||
/// let data: MaybeUninit<[u8; 1000]> = data.transpose();
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
|
||||
pub fn transpose(self) -> MaybeUninit<[T; N]> {
|
||||
#[inline]
|
||||
pub const fn transpose(self) -> MaybeUninit<[T; N]> {
|
||||
// SAFETY: T and MaybeUninit<T> have the same layout
|
||||
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ note: ...which requires borrow-checking `x`...
|
||||
|
|
||||
LL | pub const async fn x() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `x`...
|
||||
note: ...which requires processing MIR for `x`...
|
||||
--> $DIR/no-const-async.rs:4:1
|
||||
|
|
||||
LL | pub const async fn x() {}
|
||||
|
@ -19,7 +19,7 @@ LL | assert_eq!(foo, y);
|
||||
| ^^^^^^^^^^^^^^^^^^ `for<'a> fn(&'a i32) -> &'a i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
||||
|
|
||||
= help: the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
|
||||
= help: use parentheses to call the function: `foo(s)`
|
||||
= help: use parentheses to call this function: `foo(/* &i32 */)`
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -11,6 +11,10 @@ note: required by a bound in `take_const_owned`
|
||||
|
|
||||
LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
|
||||
| ^^^^ required by this bound in `take_const_owned`
|
||||
help: use parentheses to call this type parameter
|
||||
|
|
||||
LL | take_const_owned(f());
|
||||
| ++
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn give_owned<F>(f: F) where F: FnOnce() + Send + std::marker::Sync {
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0391]: cycle detected when building an abstract representation for test::{constant#0}
|
||||
error[E0391]: cycle detected when building an abstract representation for `test::{constant#0}`
|
||||
--> $DIR/closures.rs:3:35
|
||||
|
|
||||
LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
|
||||
@ -14,7 +14,7 @@ note: ...which requires type-checking `test::{constant#0}`...
|
||||
|
|
||||
LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
|
||||
| ^^^^^^^^^^^^^
|
||||
= note: ...which again requires building an abstract representation for test::{constant#0}, completing the cycle
|
||||
= note: ...which again requires building an abstract representation for `test::{constant#0}`, completing the cycle
|
||||
note: cycle used when checking that `test` is well-formed
|
||||
--> $DIR/closures.rs:3:1
|
||||
|
|
||||
|
@ -129,10 +129,10 @@ fn let_chain(&self) {
|
||||
// take the "else" branch
|
||||
if self.option_loud_drop(6).is_some() // 2
|
||||
&& self.option_loud_drop(5).is_some() // 1
|
||||
&& let None = self.option_loud_drop(7) { // 3
|
||||
&& let None = self.option_loud_drop(8) { // 4
|
||||
unreachable!();
|
||||
} else {
|
||||
self.print(8); // 4
|
||||
self.print(7); // 3
|
||||
}
|
||||
|
||||
// let exprs interspersed
|
||||
|
12
src/test/ui/drop/issue-100276.rs
Normal file
12
src/test/ui/drop/issue-100276.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// check-pass
|
||||
// compile-flags: -Z validate-mir
|
||||
#![feature(let_chains)]
|
||||
|
||||
fn let_chains(entry: std::io::Result<std::fs::DirEntry>) {
|
||||
if let Ok(entry) = entry
|
||||
&& let Some(s) = entry.file_name().to_str()
|
||||
&& s.contains("")
|
||||
{}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -9,12 +9,12 @@ note: ...which requires borrow-checking `cycle1`...
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `cycle1`...
|
||||
note: ...which requires processing MIR for `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:12:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing MIR for `cycle1`...
|
||||
note: ...which requires preparing `cycle1` for borrow checking...
|
||||
--> $DIR/auto-trait-leak.rs:12:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
@ -50,12 +50,12 @@ note: ...which requires borrow-checking `cycle2`...
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `cycle2`...
|
||||
note: ...which requires processing MIR for `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing MIR for `cycle2`...
|
||||
note: ...which requires preparing `cycle2` for borrow checking...
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
|
@ -11,7 +11,7 @@ LL | fn test() -> Foo { Foo }
|
||||
|
|
||||
= note: expected struct `Foo`
|
||||
found fn item `fn(u32) -> Foo {Foo}`
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
help: use parentheses to construct this tuple struct
|
||||
|
|
||||
LL | fn test() -> Foo { Foo(/* u32 */) }
|
||||
| +++++++++++
|
||||
|
@ -29,7 +29,7 @@ LL | assert_eq!(a, 0);
|
||||
| ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
||||
|
|
||||
= help: the trait `Debug` is not implemented for fn item `fn() -> i32 {a}`
|
||||
= help: use parentheses to call the function: `a()`
|
||||
= help: use parentheses to call this function: `a()`
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
11
src/test/ui/lifetimes/elided-lifetime-in-param-pat.rs
Normal file
11
src/test/ui/lifetimes/elided-lifetime-in-param-pat.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// check-pass
|
||||
|
||||
struct S<T> {
|
||||
_t: T,
|
||||
}
|
||||
|
||||
fn f(S::<&i8> { .. }: S<&i8>) {}
|
||||
|
||||
fn main() {
|
||||
f(S { _t: &42_i8 });
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
pub struct DropLogger<'a, T> {
|
||||
extra: T,
|
||||
id: usize,
|
||||
log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>
|
||||
log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>,
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for DropLogger<'a, T> {
|
||||
@ -55,9 +55,9 @@ fn main() {
|
||||
else {
|
||||
// 10 is not constructed
|
||||
d(10, None)
|
||||
}
|
||||
},
|
||||
);
|
||||
assert_eq!(get(), vec![3, 8, 7, 1, 2]);
|
||||
assert_eq!(get(), vec![8, 7, 1, 3, 2]);
|
||||
}
|
||||
assert_eq!(get(), vec![0, 4, 6, 9, 5]);
|
||||
|
||||
@ -89,5 +89,5 @@ fn main() {
|
||||
panic::panic_any(InjectedFailure)
|
||||
);
|
||||
});
|
||||
assert_eq!(get(), vec![14, 19, 20, 17, 15, 11, 18, 16, 12, 13]);
|
||||
assert_eq!(get(), vec![20, 17, 15, 11, 19, 18, 16, 12, 14, 13]);
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ note: ...which requires borrow-checking `main::ff5`...
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ff5() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `main::ff5`...
|
||||
note: ...which requires processing MIR for `main::ff5`...
|
||||
--> $DIR/fn-header-semantic-fail.rs:12:5
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ff5() {}
|
||||
@ -235,7 +235,7 @@ note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
|
||||
note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
|
||||
--> $DIR/fn-header-semantic-fail.rs:33:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn ft5() {}
|
||||
@ -271,7 +271,7 @@ note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-
|
||||
|
|
||||
LL | const async unsafe extern "C" fn fi5() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
|
||||
note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
|
||||
--> $DIR/fn-header-semantic-fail.rs:45:9
|
||||
|
|
||||
LL | const async unsafe extern "C" fn fi5() {}
|
||||
|
@ -327,7 +327,7 @@ LL | let _: Z = Z::Fn;
|
||||
|
|
||||
= note: expected enum `Z`
|
||||
found fn item `fn(u8) -> Z {Z::Fn}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
help: use parentheses to construct this tuple variant
|
||||
|
|
||||
LL | let _: Z = Z::Fn(/* u8 */);
|
||||
| ++++++++++
|
||||
@ -362,7 +362,7 @@ LL | let _: E = m::E::Fn;
|
||||
|
|
||||
= note: expected enum `E`
|
||||
found fn item `fn(u8) -> E {E::Fn}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
help: use parentheses to construct this tuple variant
|
||||
|
|
||||
LL | let _: E = m::E::Fn(/* u8 */);
|
||||
| ++++++++++
|
||||
@ -397,7 +397,7 @@ LL | let _: E = E::Fn;
|
||||
|
|
||||
= note: expected enum `E`
|
||||
found fn item `fn(u8) -> E {E::Fn}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
help: use parentheses to construct this tuple variant
|
||||
|
|
||||
LL | let _: E = E::Fn(/* u8 */);
|
||||
| ++++++++++
|
||||
|
@ -1,9 +1,6 @@
|
||||
error[E0277]: `fn() -> impl Future<Output = ()> {foo}` is not a future
|
||||
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| --- consider calling this function
|
||||
...
|
||||
LL | bar(foo);
|
||||
| --- ^^^ `fn() -> impl Future<Output = ()> {foo}` is not a future
|
||||
| |
|
||||
@ -16,7 +13,7 @@ note: required by a bound in `bar`
|
||||
|
|
||||
LL | fn bar(f: impl Future<Output=()>) {}
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
|
||||
help: use parentheses to call the function
|
||||
help: use parentheses to call this function
|
||||
|
|
||||
LL | bar(foo());
|
||||
| ++
|
||||
@ -24,8 +21,6 @@ LL | bar(foo());
|
||||
error[E0277]: `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]` is not a future
|
||||
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9
|
||||
|
|
||||
LL | let async_closure = async || ();
|
||||
| -------- consider calling this closure
|
||||
LL | bar(async_closure);
|
||||
| --- ^^^^^^^^^^^^^ `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]` is not a future
|
||||
| |
|
||||
@ -38,7 +33,7 @@ note: required by a bound in `bar`
|
||||
|
|
||||
LL | fn bar(f: impl Future<Output=()>) {}
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
|
||||
help: use parentheses to call the closure
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL | bar(async_closure());
|
||||
| ++
|
||||
|
17
src/test/ui/suggestions/call-on-unimplemented-ctor.rs
Normal file
17
src/test/ui/suggestions/call-on-unimplemented-ctor.rs
Normal file
@ -0,0 +1,17 @@
|
||||
fn main() {
|
||||
insert_resource(Marker);
|
||||
insert_resource(Time);
|
||||
//~^ ERROR the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
|
||||
//~| HELP use parentheses to construct this tuple struct
|
||||
}
|
||||
|
||||
trait Resource {}
|
||||
|
||||
fn insert_resource<R: Resource>(resource: R) {}
|
||||
|
||||
struct Marker;
|
||||
impl Resource for Marker {}
|
||||
|
||||
struct Time(u32);
|
||||
|
||||
impl Resource for Time {}
|
21
src/test/ui/suggestions/call-on-unimplemented-ctor.stderr
Normal file
21
src/test/ui/suggestions/call-on-unimplemented-ctor.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0277]: the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
|
||||
--> $DIR/call-on-unimplemented-ctor.rs:3:21
|
||||
|
|
||||
LL | insert_resource(Time);
|
||||
| --------------- ^^^^ the trait `Resource` is not implemented for fn item `fn(u32) -> Time {Time}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `insert_resource`
|
||||
--> $DIR/call-on-unimplemented-ctor.rs:10:23
|
||||
|
|
||||
LL | fn insert_resource<R: Resource>(resource: R) {}
|
||||
| ^^^^^^^^ required by this bound in `insert_resource`
|
||||
help: use parentheses to construct this tuple struct
|
||||
|
|
||||
LL | insert_resource(Time(/* u32 */));
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
15
src/test/ui/suggestions/call-on-unimplemented-fn-ptr.rs
Normal file
15
src/test/ui/suggestions/call-on-unimplemented-fn-ptr.rs
Normal file
@ -0,0 +1,15 @@
|
||||
struct Foo;
|
||||
|
||||
trait Bar {}
|
||||
|
||||
impl Bar for Foo {}
|
||||
|
||||
fn needs_bar<T: Bar>(_: T) {}
|
||||
|
||||
fn blah(f: fn() -> Foo) {
|
||||
needs_bar(f);
|
||||
//~^ ERROR the trait bound `fn() -> Foo: Bar` is not satisfied
|
||||
//~| HELP use parentheses to call this function pointer
|
||||
}
|
||||
|
||||
fn main() {}
|
21
src/test/ui/suggestions/call-on-unimplemented-fn-ptr.stderr
Normal file
21
src/test/ui/suggestions/call-on-unimplemented-fn-ptr.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0277]: the trait bound `fn() -> Foo: Bar` is not satisfied
|
||||
--> $DIR/call-on-unimplemented-fn-ptr.rs:10:15
|
||||
|
|
||||
LL | needs_bar(f);
|
||||
| --------- ^ the trait `Bar` is not implemented for `fn() -> Foo`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `needs_bar`
|
||||
--> $DIR/call-on-unimplemented-fn-ptr.rs:7:17
|
||||
|
|
||||
LL | fn needs_bar<T: Bar>(_: T) {}
|
||||
| ^^^ required by this bound in `needs_bar`
|
||||
help: use parentheses to call this function pointer
|
||||
|
|
||||
LL | needs_bar(f());
|
||||
| ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -1,9 +1,6 @@
|
||||
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
|
||||
|
|
||||
LL | fn foo() -> impl T<O=()> { S }
|
||||
| --- consider calling this function
|
||||
...
|
||||
LL | bar(foo);
|
||||
| --- ^^^ the trait `T` is not implemented for fn item `fn() -> impl T<O = ()> {foo}`
|
||||
| |
|
||||
@ -14,7 +11,7 @@ note: required by a bound in `bar`
|
||||
|
|
||||
LL | fn bar(f: impl T<O=()>) {}
|
||||
| ^^^^^^^ required by this bound in `bar`
|
||||
help: use parentheses to call the function
|
||||
help: use parentheses to call this function
|
||||
|
|
||||
LL | bar(foo());
|
||||
| ++
|
||||
@ -22,8 +19,6 @@ LL | bar(foo());
|
||||
error[E0277]: the trait bound `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]: T` is not satisfied
|
||||
--> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:19:9
|
||||
|
|
||||
LL | let closure = || S;
|
||||
| -- consider calling this closure
|
||||
LL | bar(closure);
|
||||
| --- ^^^^^^^ the trait `T` is not implemented for closure `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]`
|
||||
| |
|
||||
@ -34,7 +29,7 @@ note: required by a bound in `bar`
|
||||
|
|
||||
LL | fn bar(f: impl T<O=()>) {}
|
||||
| ^^^^^^^ required by this bound in `bar`
|
||||
help: use parentheses to call the closure
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL | bar(closure());
|
||||
| ++
|
||||
|
@ -49,7 +49,7 @@ LL | let _: S = S;
|
||||
|
|
||||
= note: expected struct `S`
|
||||
found fn item `fn(usize, usize) -> S {S}`
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
help: use parentheses to construct this tuple struct
|
||||
|
|
||||
LL | let _: S = S(/* usize */, /* usize */);
|
||||
| ++++++++++++++++++++++++++
|
||||
@ -85,7 +85,7 @@ LL | let _: V = V;
|
||||
|
|
||||
= note: expected struct `V`
|
||||
found fn item `fn() -> V {V}`
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
help: use parentheses to construct this tuple struct
|
||||
|
|
||||
LL | let _: V = V();
|
||||
| ++
|
||||
@ -139,7 +139,7 @@ LL | let _: E = E::A;
|
||||
|
|
||||
= note: expected enum `E`
|
||||
found fn item `fn(usize) -> E {E::A}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
help: use parentheses to construct this tuple variant
|
||||
|
|
||||
LL | let _: E = E::A(/* usize */);
|
||||
| +++++++++++++
|
||||
|
@ -1,7 +1,7 @@
|
||||
// compile-flags: -Ztreat-err-as-bug
|
||||
// failure-status: 101
|
||||
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
|
||||
// error-pattern: [trigger_delay_span_bug] trigger a delay span bug
|
||||
// error-pattern: [trigger_delay_span_bug] triggering a delay span bug
|
||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
|
@ -7,5 +7,5 @@ LL | fn main() {}
|
||||
error: internal compiler error: unexpected panic
|
||||
|
||||
query stack during panic:
|
||||
#0 [trigger_delay_span_bug] trigger a delay span bug
|
||||
#0 [trigger_delay_span_bug] triggering a delay span bug
|
||||
end of query stack
|
||||
|
@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the
|
||||
LL | thing.bar.foo();
|
||||
| ^^^ method not found in `fn() -> Foo {Foo}`
|
||||
|
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
help: use parentheses to construct this tuple struct
|
||||
|
|
||||
LL | (thing.bar)().foo();
|
||||
| + +++
|
||||
|
@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` i
|
||||
LL | thing.bar.foo();
|
||||
| ^^^ method not found in `fn() -> Foo {Foo::Tup}`
|
||||
|
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
help: use parentheses to construct this tuple variant
|
||||
|
|
||||
LL | (thing.bar)().foo();
|
||||
| + +++
|
||||
|
@ -4,7 +4,7 @@ error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}`
|
||||
LL | thing.bar.0;
|
||||
| ^
|
||||
|
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
help: use parentheses to construct this tuple struct
|
||||
|
|
||||
LL | (thing.bar)(/* char */, /* u16 */).0;
|
||||
| + ++++++++++++++++++++++++
|
||||
|
Loading…
Reference in New Issue
Block a user