diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index bc8753f4dcaa7..c14ad62e9a60b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -294,6 +294,14 @@ impl GenericArg { GenericArg::Const(ct) => ct.value.span, } } + + pub fn is_maybe_parenthesised_infer(&self) -> bool { + match self { + GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime, + GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(), + GenericArg::Const(_) => false, + } + } } /// A path like `Foo<'a, T>`. diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index 867ed364433e7..7cb904ab5c353 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -1,3 +1,5 @@ +use std::assert_matches; + use hir::HirId; use hir::def::{DefKind, Res}; use rustc_ast::*; @@ -11,7 +13,10 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, sym}; use crate::LoweringContext; use crate::delegation::resolution::resolver::DelegationResolver; -use crate::diagnostics::DelegationInfersMismatch; +use crate::diagnostics::{ + DelegationInfersMismatch, DelegationToInherentImplMustContainParentGenerics, + DelegationToInherentImplParentContainsInfer, +}; #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub(super) enum GenericsPosition { @@ -25,6 +30,7 @@ pub(super) enum GenericArgSlot { Generate(T, Option /* Infer arg index from AST */), } +#[derive(Debug)] pub(super) struct DelegationGenerics { data: T, pos: GenericsPosition, @@ -57,11 +63,13 @@ impl<'hir> DelegationGenerics> { /// meaning we did not propagate them and thus we do not need to generate generic params /// (i.e., method call scenarios), in such a case this approach helps /// a lot as if `into_hir_generics` will not be called then uplifting will not happen. +#[derive(Debug)] pub(super) enum HirOrTyGenerics<'hir> { Ty(DelegationGenerics>), Hir(DelegationGenerics<&'hir hir::Generics<'hir>>), } +#[derive(Debug)] pub(super) struct GenericsGenerationResult<'hir> { pub(super) generics: HirOrTyGenerics<'hir>, pub(super) args_segment_id: HirId, @@ -80,6 +88,7 @@ pub(super) struct GenericsGenerationResults<'hir> { pub(super) self_ty_propagation_kind: Option, } +#[derive(Debug)] pub(super) struct DelegationGenericArgsIterator<'hir> { index: usize = Default::default(), params: &'hir [hir::GenericParam<'hir>], @@ -145,6 +154,7 @@ impl<'hir> DelegationGenericArgsIterator<'hir> { ctx: &mut LoweringContext<'_, 'hir>, ) -> Vec> { let mut args = vec![]; + while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) { args.push(arg); } @@ -238,6 +248,7 @@ impl<'hir> GenericsGenerationResult<'hir> { } } +#[derive(Debug)] enum ParentSegmentArgs<'a> { /// Parent segment is valid and generic args are specified: /// `reuse Trait::<'static, ()>::foo;`. @@ -273,7 +284,7 @@ struct GenericsResolution<'a, 'tcx> { /// `reuse <_ as Trait>::foo;`. qself_is_infer: bool, /// Whether we should generate `Self` generic param. - generate_self: bool, + generate_free_to_trait_self: bool, } impl<'hir> DelegationResolver<'_, 'hir> { @@ -288,8 +299,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { let delegation_in_free_ctx = !matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. }); - let sig_parent = tcx.parent(sig_id); - let sig_in_trait = matches!(tcx.def_kind(sig_parent), DefKind::Trait); + let sig_in_trait = matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Trait); let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait; let mut sig_parent_params: &[ty::GenericParamDef] = &[]; @@ -301,8 +311,13 @@ impl<'hir> DelegationResolver<'_, 'hir> { let parent_args = if let [.., parent_segment, _] = &delegation.path.segments[..] { let res = self.get_resolution_id(parent_segment.id)?; - if matches!(tcx.def_kind(res), DefKind::Trait | DefKind::TraitAlias) { - sig_parent_params = &tcx.generics_of(sig_parent).own_params; + if !matches!(tcx.def_kind(res), DefKind::Mod) { + assert_matches!( + tcx.def_kind(res), + DefKind::Trait | DefKind::Struct | DefKind::Enum + ); + + sig_parent_params = &tcx.generics_of(res).own_params; self.get_user_args(parent_segment) .map(|args| ParentSegmentArgs::Specified(args)) .unwrap_or(ParentSegmentArgs::NotSpecified) @@ -319,7 +334,8 @@ impl<'hir> DelegationResolver<'_, 'hir> { qself_is_none, qself_is_infer, free_to_trait_delegation, - generate_self: free_to_trait_delegation && (qself_is_none || qself_is_infer), + generate_free_to_trait_self: free_to_trait_delegation + && (qself_is_none || qself_is_infer), trait_impl: matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }), sig_child_params: &tcx.generics_of(sig_id).own_params, child_args: self.get_user_args( @@ -349,10 +365,11 @@ impl<'hir> DelegationResolver<'_, 'hir> { &self, delegation: &Delegation, sig_id: DefId, + span: Span, ) -> Result, ErrorGuaranteed> { let res @ GenericsResolution { trait_impl, - generate_self, + generate_free_to_trait_self, sig_child_params, sig_parent_params, .. @@ -376,20 +393,27 @@ impl<'hir> DelegationResolver<'_, 'hir> { return Ok(GenericsGenerationResults { parent, child, self_ty_propagation_kind: None }); } + self.check_delegation_to_inherent_impl(&res.parent_args, sig_id, span)?; + let tcx = self.tcx(); + + // If parent is inherent impl then there is no `Self` param to skip, so add additional check. + let skip_self = + !generate_free_to_trait_self && tcx.def_kind(tcx.parent(sig_id)) == DefKind::Trait; + let parent_generics = match res.parent_args { ParentSegmentArgs::Specified(args) => DelegationGenerics { data: Self::create_slots_from_args( tcx, args, - &sig_parent_params[usize::from(!generate_self)..], - generate_self, + &sig_parent_params[usize::from(skip_self)..], + generate_free_to_trait_self, ), pos: GenericsPosition::Parent, trait_impl, }, ParentSegmentArgs::NotSpecified => DelegationGenerics::generate_all( - &sig_parent_params[usize::from(!generate_self)..], + &sig_parent_params[usize::from(skip_self)..], GenericsPosition::Parent, trait_impl, ), @@ -437,6 +461,46 @@ impl<'hir> DelegationResolver<'_, 'hir> { }) } + fn check_delegation_to_inherent_impl( + &self, + parent_args: &ParentSegmentArgs<'_>, + sig_id: DefId, + span: Span, + ) -> Result<(), ErrorGuaranteed> { + let tcx = self.tcx(); + + if !(tcx.def_kind(sig_id) == DefKind::AssocFn + && matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Impl { of_trait: false })) + { + return Ok(()); + } + + let ty::Adt(def, _) = tcx.type_of(tcx.parent(sig_id)).skip_binder().kind() else { + unreachable!("parent of inherent function can be only struct or enum") + }; + + match parent_args { + ParentSegmentArgs::Invalid => unreachable!(), + ParentSegmentArgs::Specified(args) => args + .args + .iter() + .all(|arg| { + let AngleBracketedArg::Arg(arg) = arg else { return false }; + !arg.is_maybe_parenthesised_infer() + }) + .ok_or_else(|| { + self.tcx().dcx().emit_err(DelegationToInherentImplParentContainsInfer { span }) + }), + ParentSegmentArgs::NotSpecified => match tcx.generics_of(def.did()).own_params.len() { + 0 => Ok(()), + _ => Err(self + .tcx() + .dcx() + .emit_err(DelegationToInherentImplMustContainParentGenerics { span })), + }, + } + } + /// Generates generic argument slots for user-specified `args` and /// generic `params` of the signature function. This function checks whether /// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in @@ -459,12 +523,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { let params = ¶ms[usize::from(add_first_self)..]; for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() { let AngleBracketedArg::Arg(arg) = arg else { continue }; - - let is_infer = match arg { - GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime, - GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(), - GenericArg::Const(_) => false, - }; + let is_infer = arg.is_maybe_parenthesised_infer(); // If `'_` is used instead of `_` (or vice versa) we emit a meaningful // error instead of processing this infer or leaving it as is for signature diff --git a/compiler/rustc_ast_lowering/src/delegation/mod.rs b/compiler/rustc_ast_lowering/src/delegation/mod.rs index a92b62517e61d..0e94016963c78 100644 --- a/compiler/rustc_ast_lowering/src/delegation/mod.rs +++ b/compiler/rustc_ast_lowering/src/delegation/mod.rs @@ -47,7 +47,7 @@ use rustc_ast as ast; use rustc_ast::*; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::DefKind; -use rustc_hir::{self as hir, FnDeclFlags}; +use rustc_hir::{self as hir, FnDeclFlags, QPath}; use rustc_middle::ty::Asyncness; use rustc_span::def_id::DefId; use rustc_span::symbol::kw; @@ -62,7 +62,7 @@ use crate::{ mod attributes; mod generics; -mod resolution; +pub(crate) mod resolution; pub(crate) struct DelegationResults<'hir> { pub body_id: hir::BodyId, @@ -416,7 +416,37 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::QPath::Resolved(ty, self.arena.alloc(new_path)) } - hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"), + hir::QPath::TypeRelative(mut ty, segment) => { + let mut segment = self.process_segment(span, segment, &mut generics.child); + segment.res = Res::Def(self.tcx.def_kind(res.call_path_res), res.call_path_res); + + let ty_hir_id = ty.hir_id; + + // Propagating child generics if needed. + ty = if let hir::TyKind::Path(QPath::Resolved(ty, path)) = ty.kind { + let mut new_path = path.clone(); + + new_path.segments = self.arena.alloc_from_iter( + new_path.segments.iter().enumerate().map(|(idx, segment)| { + if idx + 1 == new_path.segments.len() { + self.process_segment(span, segment, &mut generics.parent) + } else { + segment.clone() + } + }), + ); + + self.arena.alloc(hir::Ty { + hir_id: ty_hir_id, + span, + kind: hir::TyKind::Path(QPath::Resolved(ty, self.arena.alloc(new_path))), + }) + } else { + ty + }; + + hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) + } }; if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) = @@ -491,6 +521,7 @@ impl<'hir> LoweringContext<'_, 'hir> { result.generics.into_hir_generics(self, span); let mut segment = segment.clone(); + let mut args_iter = result.generics.create_args_iterator(); let new_args = segment diff --git a/compiler/rustc_ast_lowering/src/delegation/resolution.rs b/compiler/rustc_ast_lowering/src/delegation/resolution.rs index 85604223c8509..0e4992267b250 100644 --- a/compiler/rustc_ast_lowering/src/delegation/resolution.rs +++ b/compiler/rustc_ast_lowering/src/delegation/resolution.rs @@ -2,22 +2,143 @@ use std::ops::ControlFlow; use ast::visit::Visitor; use hir::def::DefKind; -use rustc_ast::{self as ast, Delegation, DelegationSource, NodeId}; -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_ast::{self as ast, AssocItemKind, Delegation, DelegationSource, Item, ItemKind, NodeId}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::steal::Steal; use rustc_hir as hir; -use rustc_middle::ty::{Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use rustc_middle::{span_bug, ty}; +use rustc_middle::middle::resolve::{ + self as mid_res, AstOwner, DelegationInherentFnKind, TypeRelativeDelegationRes, +}; +use rustc_middle::ty::{ + self as ty, AssocKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, +}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; use crate::delegation::generics::GenericsGenerationResults; use crate::delegation::resolution::resolver::DelegationResolver; use crate::diagnostics::{ - CycleInDelegationSignatureResolution, DelegationAttemptedBlockWithDefsDeletion, - DelegationAttemptedBlockWithDefsRelowering, DelegationBlockSpecifiedWhenNoParams, - UnresolvedDelegationCallee, + AmbiguousDelegationToInherentImpl, CycleInDelegationSignatureResolution, + DelegationAttemptedBlockWithDefsDeletion, DelegationAttemptedBlockWithDefsRelowering, + DelegationBlockSpecifiedWhenNoParams, UnresolvedDelegationCallee, }; +/// Simple (hack or heuristic) resolution of some delegations to inherent impls +/// while correct resolution through `ProbeContext` is not available +/// during AST -> HIR lowering due to query cycles. +/// Successful resolutions from this heuristics are not a subset of +/// successful resolutions from the correct approach, if we want to stabilize +/// delegations to inherent impls with this approach we need a second pass in type checking +/// (i.e., when there's no cycles) that makes sure that resolutions from +/// the heuristic match the correct resolutions, or report errors otherwise. +/// FIXME(fn_delegation): correct resolution through `ProbeContext` engine +pub(crate) fn resolve_type_relative_delegations( + tcx: TyCtxt<'_>, + _: (), +) -> FxIndexMap { + let ast_index = tcx.index_ast(()); + let resolutions = tcx.resolutions(()); + + let infos = &resolutions.delegation_infos; + let inh_fns = &resolutions.delegation_inherent_fn_map; + + let mut type_relative_resolutions: FxIndexMap = + Default::default(); + + for (&def_id, res) in infos { + match res.resolution { + mid_res::DelegationResolution::Error(..) | mid_res::DelegationResolution::Full(_) => { + continue; + } + // Also record resolutions for cases when signature is resolved but call path is not. + mid_res::DelegationResolution::Partial + | mid_res::DelegationResolution::PartialCall(_) => { + let Some(r_and_owner) = ast_index.get(def_id).map(Steal::borrow) else { + unreachable!("ast index must contain delegations"); + }; + + let (r, owner) = &*r_and_owner; + + let delegation = match owner { + AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. }) + | AstOwner::TraitItem(Item { kind: AssocItemKind::Delegation(d), .. }) + | AstOwner::ImplItem(Item { kind: AssocItemKind::Delegation(d), .. }) => d, + _ => unreachable!("we are processing only delegations"), + }; + + let res = r.partial_res_map.get(&delegation.id); + let res = res.and_then(|res| res.base_res().opt_def_id()); + let ident = delegation.path.segments.last().map(|s| s.ident); + + let span = delegation.last_segment_span(); + + let ambig_error_res = || { + TypeRelativeDelegationRes::Ambig( + tcx.dcx().span_delayed_bug(span, "ambiguous delegation to inherent impl"), + ) + }; + + let default_error_res = + || { + TypeRelativeDelegationRes::Error(tcx.dcx().span_delayed_bug( + span, + "failed to resolve delegation to inherent impl", + )) + }; + + let res = if let Some(res) = res + && let Some(ident) = ident + { + match res.as_local() { + Some(local_def_id) => { + let res = inh_fns.get(&local_def_id).and_then(|map| map.get(&ident)); + + match res { + Some(res) => match res { + DelegationInherentFnKind::Ambig => ambig_error_res(), + DelegationInherentFnKind::Single(res) => { + TypeRelativeDelegationRes::Ok(res.to_def_id()) + } + }, + _ => default_error_res(), + } + } + None => { + let mut sig_res = None; + 'inh_loop: for inh_impl_id in tcx.inherent_impls(res) { + let assoc_items = tcx.associated_items(*inh_impl_id); + + // FIXME(fn_delegation): use correct identifier hygiene + let mut candidates = assoc_items + .filter_by_name_unhygienic(ident.name) + .filter(|it| matches!(it.kind, AssocKind::Fn { .. })); + + while let Some(candidate) = candidates.next() { + if sig_res.is_some() { + sig_res = Some(ambig_error_res()); + break 'inh_loop; + } else { + sig_res = + Some(TypeRelativeDelegationRes::Ok(candidate.def_id)); + } + } + } + + sig_res.unwrap_or_else(default_error_res) + } + } + } else { + default_error_res() + }; + + type_relative_resolutions.insert(def_id, res); + } + } + } + + type_relative_resolutions +} + /// Summary info about function parameters. #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub(super) struct ParamInfo { @@ -114,26 +235,34 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { // Delegation can be missing from the `delegations_resolutions` table // in illegal places such as function bodies in extern blocks (see #151356). - let sig_id = tcx - .resolutions(()) - .delegation_infos - .get(&def_id) - .map(|info| { - info.resolution_id.and_then(|id| self.check_for_cycles(id, span).map(|_| id)) - }) - .unwrap_or_else(|| { - Err(tcx.dcx().span_delayed_bug( - span, - format!("delegation resolution record was not found for {:?}", def_id), - )) - })?; - - let is_method = match tcx.def_kind(sig_id) { - DefKind::Fn => false, - DefKind::AssocFn => tcx.associated_item(sig_id).is_method(), - _ => span_bug!(span, "unexpected DefKind for delegation item"), - }; + let sig_id = self.resolve_delegation_sig(def_id, span)?; + + let create_invalid_path_error = + || tcx.dcx().span_delayed_bug(span, "invalid delegation path"); + match &delegation.path.segments[..] { + [] => return Err(create_invalid_path_error()), + [child] => { + let res = self.get_resolution_id(child.id)?; + if tcx.def_kind(res) != DefKind::Fn { + return Err(create_invalid_path_error()); + } + } + [.., parent, _] => { + let child_res = self.get_call_path_res(delegation, span)?; + let parent_res = self.get_resolution_id(parent.id)?; + + match (tcx.def_kind(child_res), tcx.def_kind(parent_res)) { + (DefKind::Fn, DefKind::Mod) => {} + (DefKind::AssocFn, DefKind::Trait | DefKind::Struct | DefKind::Enum) => {} + _ => return Err(create_invalid_path_error()), + } + } + } + + self.check_for_cycles(sig_id, span)?; + + let is_method = tcx.is_method(sig_id); let sig = tcx.fn_sig(sig_id).skip_binder().skip_binder(); let param_count = sig.inputs().len() + usize::from(sig.c_variadic()); let parent = tcx.local_parent(def_id); @@ -149,7 +278,7 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { // FIXME(splat): use `sig.splatted()` once FnSig has it param_info: ParamInfo { param_count, c_variadic: sig.c_variadic(), splatted: None }, source: delegation.source, - call_path_res: self.get_resolution_id(delegation.id)?, + call_path_res: self.get_call_path_res(delegation, span)?, sig_mapping: self.create_sig_mapping( delegation, span, @@ -160,12 +289,73 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { )?, }; - Ok((res, self.resolve_and_generate_generics(delegation, sig_id)?)) + Ok((res, self.resolve_and_generate_generics(delegation, sig_id, span)?)) + } + + fn get_call_path_res( + &self, + delegation: &Delegation, + span: Span, + ) -> Result { + let def_id = self.owner_id(); + + match self.tcx().resolutions(()).delegation_infos[&def_id].resolution { + mid_res::DelegationResolution::Full(_) => self.get_resolution_id(delegation.id), + mid_res::DelegationResolution::Partial + | mid_res::DelegationResolution::PartialCall(_) => { + self.resolve_type_relative_delegation_sig(def_id, span) + } + mid_res::DelegationResolution::Error(err) => Err(err), + } + } + + fn resolve_delegation_sig( + &self, + def_id: LocalDefId, + span: Span, + ) -> Result { + let tcx = self.tcx(); + + match tcx.resolutions(()).delegation_infos.get(&def_id) { + Some(res) => match res.resolution { + mid_res::DelegationResolution::Error(err) => Err(err), + mid_res::DelegationResolution::Full(def_id) + | mid_res::DelegationResolution::PartialCall(def_id) => Ok(def_id), + mid_res::DelegationResolution::Partial => { + self.resolve_type_relative_delegation_sig(def_id, span) + } + }, + None => Err(self.create_unresolved_error(def_id, span)), + } + } + + fn create_unresolved_error(&self, def_id: LocalDefId, span: Span) -> ErrorGuaranteed { + self.tcx().dcx().span_delayed_bug(span, format!("unresolved delegation {def_id:?}")) + } + + fn resolve_type_relative_delegation_sig( + &self, + def_id: LocalDefId, + span: Span, + ) -> Result { + let tcx = self.tcx(); + + match tcx.resolve_type_relative_delegations(()).get(&def_id) { + Some(res) => match *res { + TypeRelativeDelegationRes::Ok(sig_id) => Ok(sig_id), + TypeRelativeDelegationRes::Error(err) => Err(err), + TypeRelativeDelegationRes::Ambig(_) => { + Err(tcx.dcx().emit_err(AmbiguousDelegationToInherentImpl { span })) + } + }, + None => Err(self.create_unresolved_error(def_id, span)), + } } fn check_for_cycles(&self, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); let mut visited: FxHashSet = Default::default(); + let delegation_infos = &tcx.resolutions(()).delegation_infos; loop { visited.insert(def_id); @@ -174,8 +364,8 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { // it means that we refer to another delegation as a callee, so in order to obtain // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. if let Some(local_id) = def_id.as_local() - && let Some(info) = tcx.resolutions(()).delegation_infos.get(&local_id) - && let Ok(id) = info.resolution_id + && delegation_infos.contains_key(&local_id) + && let Ok(id) = self.resolve_delegation_sig(local_id, span) { def_id = id; if visited.contains(&def_id) { @@ -253,7 +443,7 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { mapping.arguments_to_map.insert(0); } - if self.can_perform_self_mapping(delegation, parent)? { + if self.can_perform_self_mapping(delegation, parent, span) { /// Finds `Self` generic param only in ADT or references, so we avoid cases like /// `Self::Item` which will return true if `output.contains(...)` will be used. struct SelfFinder; @@ -307,10 +497,9 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { // We can't yet map more than one argument if there are definitions inside. // FIXME(fn_delegation): support relowering with defs inside if contains_defs && mapping.arguments_to_map.len() > 1 { - return Err(self - .tcx() - .dcx() - .emit_err(DelegationAttemptedBlockWithDefsRelowering { span })); + let err = DelegationAttemptedBlockWithDefsRelowering { span }; + let err = self.tcx().dcx().emit_err(err); + return Err(err); } Ok(mapping) @@ -320,10 +509,11 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { &self, delegation: &Delegation, parent: LocalDefId, - ) -> Result { + span: Span, + ) -> bool { // Heuristic: don't do wrapping if there is no target expression. if delegation.body.is_none() { - return Ok(false); + return false; } let tcx = self.tcx(); @@ -339,13 +529,17 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { // 2) Inherent methods when delegating to trait, as we change the type of // `Self` to type of struct or enum we delegate from. if !matches!(tcx.def_kind(parent), DefKind::Impl { .. }) { - return Ok(false); + return false; } // Check that delegation path resolves to a trait AssocFn, not to a free method. // After previous check we are sure that `sig_id` and `delegation.id` // point to the same function. - let id = self.get_resolution_id(delegation.id)?; - Ok(tcx.def_kind(id) == DefKind::AssocFn && tcx.def_kind(tcx.parent(id)) == DefKind::Trait) + let id = self + .get_call_path_res(delegation, span) + .ok() + .expect("invalid paths are filtered out earlier"); + + tcx.def_kind(id) == DefKind::AssocFn && tcx.def_kind(tcx.parent(id)) == DefKind::Trait } } diff --git a/compiler/rustc_ast_lowering/src/diagnostics.rs b/compiler/rustc_ast_lowering/src/diagnostics.rs index b0fada9d3cd9e..2542268712f98 100644 --- a/compiler/rustc_ast_lowering/src/diagnostics.rs +++ b/compiler/rustc_ast_lowering/src/diagnostics.rs @@ -609,3 +609,24 @@ pub(crate) struct RestrictionAncestorOnly { pub(crate) span: Span, pub(crate) kind: ResolvingRestrictionKind, } + +#[derive(Diagnostic)] +#[diag("ambiguous delegation to inherent impl function")] +pub(crate) struct AmbiguousDelegationToInherentImpl { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("delegation to inherent impl must contain parent generics")] +pub(crate) struct DelegationToInherentImplMustContainParentGenerics { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("parent segment of delegation to inherent impl can not contain infers")] +pub(crate) struct DelegationToInherentImplParentContainsInfer { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ef6995d9c11d6..ac79703e63c01 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -102,6 +102,8 @@ pub mod stability; pub fn provide(providers: &mut Providers) { providers.index_ast = index_ast; providers.lower_to_hir = lower_to_hir; + providers.resolve_type_relative_delegations = + delegation::resolution::resolve_type_relative_delegations; } #[cfg(debug_assertions)] @@ -739,6 +741,8 @@ fn index_ast<'tcx>( #[instrument(level = "trace", skip(tcx))] fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { + tcx.ensure_done().resolve_type_relative_delegations(()); + let ast_index = tcx.index_ast(()); let resolver_and_node = ast_index.get(def_id).map(Steal::steal); diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs index 11b8890346dfb..bdb30090925d0 100644 --- a/compiler/rustc_borrowck/src/handle_placeholders.rs +++ b/compiler/rustc_borrowck/src/handle_placeholders.rs @@ -246,8 +246,16 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>( mut outlives_constraints, universe_causes, type_tests, + solver_constraints, } = constraints; + // These have already been destructured into `outlives_constraints` at the + // end of MIR type checking. + assert!( + solver_constraints.is_true(), + "solver region constraints not lowered to NLL = {solver_constraints:#?}", + ); + let fr_static = universal_regions.fr_static; let compute_sccs = |constraints: &OutlivesConstraintSet<'tcx>, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index e20f9a646a953..113908fba6702 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -67,7 +67,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) { - let QueryRegionConstraints { constraints, assumptions } = query_constraints; + let QueryRegionConstraints { constraints, assumptions, solver_constraints } = + query_constraints; let assumptions = elaborate::elaborate_outlives_assumptions(self.infcx.tcx, assumptions.iter().copied()); @@ -76,6 +77,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { self.convert(predicate, category, &assumptions); }); } + + self.constraints + .register_solver_constraint(solver_constraints.clone().with_spans(self.span)); } /// Given an instance of the closure type, this method instantiates the "extra" requirements diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9f23a0d5ab631..ed080c26d60f3 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -17,6 +17,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::{ BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, + SolverRegionConstraint, }; use rustc_infer::traits::{Obligation, ObligationCause, PredicateObligations}; use rustc_middle::bug; @@ -113,6 +114,7 @@ pub(crate) fn type_check<'tcx>( outlives_constraints: OutlivesConstraintSet::default(), type_tests: Vec::default(), universe_causes: FxIndexMap::default(), + solver_constraints: SolverRegionConstraint::new_true(), }; let CreateResult { @@ -134,6 +136,13 @@ pub(crate) fn type_check<'tcx>( pre_assumptions.is_empty(), "there should be no incoming region assumptions = {pre_assumptions:#?}", ); + // Solver region constraints from computing the implied bounds went through + // `ConstraintConversion` and are already stored in `constraints`. + let pre_solver_constraints = infcx.take_solver_region_constraints(); + assert!( + pre_solver_constraints.is_true(), + "there should be no incoming solver region constraints = {pre_solver_constraints:#?}", + ); } debug!(?normalized_inputs_and_output); @@ -174,6 +183,10 @@ pub(crate) fn type_check<'tcx>( let polonius_context = typeck.polonius_context; if infcx.tcx.assumptions_on_binders() { + let solver_constraints = mem::replace( + &mut typeck.constraints.solver_constraints, + SolverRegionConstraint::new_true(), + ); let mut converter = constraint_conversion::ConstraintConversion::new( typeck.infcx, typeck.universal_regions, @@ -185,6 +198,7 @@ pub(crate) fn type_check<'tcx>( typeck.constraints, ); typeck.infcx.destructure_solver_region_constraints_for_borrowck( + solver_constraints, &mut converter, typeck.known_type_outlives_obligations, universal_region_relations.outlives.clone(), @@ -293,9 +307,25 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { pub(crate) universe_causes: FxIndexMap>, pub(crate) type_tests: Vec>, + + /// The region constraints emitted by the next solver under + /// `-Zassumptions-on-binders`. Unlike the constraints above these are not yet + /// lowered to NLL, we destructure them into `outlives_constraints` at the end + /// of MIR type checking. + pub(crate) solver_constraints: SolverRegionConstraint<'tcx>, } impl<'tcx> MirTypeckRegionConstraints<'tcx> { + /// Adds `constraint` to the constraints we've accumulated so far. + pub(crate) fn register_solver_constraint(&mut self, constraint: SolverRegionConstraint<'tcx>) { + // FIXME(-Zassumptions-on-binders): This is pretty bad for perf, we rebuild the + // entire constraint every time instead of updating it incrementally. + self.solver_constraints = SolverRegionConstraint::build_and( + constraint, + mem::replace(&mut self.solver_constraints, SolverRegionConstraint::new_true()), + ); + } + /// Creates a `Region` for a given `PlaceholderRegion`, or returns the /// region that corresponds to a previously created one. pub(crate) fn placeholder_region( diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b8952ffc6bf81..90b2cab5b63e2 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -612,6 +612,8 @@ pub(crate) unsafe fn llvm_optimize( let pgo_use_path = get_pgo_use_path(config); let pgo_sample_use_path = get_pgo_sample_use_path(config); let is_lto = opt_stage == llvm::OptStage::ThinLTO || opt_stage == llvm::OptStage::FatLTO; + let is_final_stage = + !matches!(opt_stage, llvm::OptStage::PreLinkFatLTO | llvm::OptStage::PreLinkThinLTO); let instr_profile_output_path = get_instr_profile_output_path(config); let sanitize_dataflow_abilist: Vec<_> = config .sanitizer_dataflow_abilist @@ -840,7 +842,7 @@ pub(crate) unsafe fn llvm_optimize( // don't need any other artifacts from the previous run. We will embed this artifact into our // LLVM-IR host module, to create a `host.o` ObjectFile, which we will write to disk. // The last, not yet automated steps uses the `clang-linker-wrapper` to process `host.o`. - if !cgcx.target_is_like_gpu { + if !cgcx.target_is_like_gpu && is_final_stage { if let Some(device_path) = config .offload .iter() @@ -866,10 +868,11 @@ pub(crate) unsafe fn llvm_optimize( // 2) Finalize host: lib.bc + device.bin -> host.o (host TM) // We create a full clone of our LLVM host module, since we will embed the device IR // into it, and this might break caching or incremental compilation otherwise. - let llmod2 = llvm::LLVMCloneModule(module.module_llvm.llmod()); let ok = unsafe { - llvm::RustOffloadWrapper::get_instance() - .llvm_rust_offload_embed_buffer_in_module(llmod2, device_bin_c.as_c_str()) + llvm::RustOffloadWrapper::get_instance().llvm_rust_offload_embed_buffer_in_module( + module.module_llvm.llmod(), + device_bin_c.as_c_str(), + ) }; if !ok { dcx.emit_err(crate::diagnostics::OffloadEmbedFailed); @@ -878,7 +881,7 @@ pub(crate) unsafe fn llvm_optimize( dcx, module.module_llvm.tm.raw(), config.no_builtins, - llmod2, + module.module_llvm.llmod(), &out_obj, None, llvm::FileType::ObjectFile, @@ -888,6 +891,16 @@ pub(crate) unsafe fn llvm_optimize( // We ignore cgcx.save_temps here and unconditionally always keep our `device.bin` artifact. // Otherwise, recompiling the host code would fail since we deleted that device artifact // in the previous host compilation, which would be confusing at best. + + let ok = unsafe { + llvm::RustOffloadWrapper::get_instance().llvm_rust_offload_wrap_images( + module.module_llvm.llmod(), + device_bin_c.as_c_str(), + ) + }; + if !ok { + dcx.emit_err(crate::diagnostics::OffloadWrapImagesFailed); + } } } result.into_result().unwrap_or_else(|()| llvm_err(dcx, LlvmError::RunLlvmPasses)) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index d20a73e8e6825..e2ec20226e3ce 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -57,80 +57,6 @@ impl<'ll> OffloadGlobals<'ll> { } } -// We need to register offload before using it. We also should unregister it once we are done, for -// good measures. Previously we have done so before and after each individual offload intrinsic -// call, but that comes at a performance cost. The repeated (un)register calls might also confuse -// the LLVM ompOpt pass, which tries to move operations to a better location. The easiest solution, -// which we copy from clang, is to just have those two calls once, in the global ctor/dtor section -// of the final binary. -pub(crate) fn register_offload<'ll>(cx: &CodegenCx<'ll, '_>) { - // First we check quickly whether we already have done our setup, in which case we return early. - // Shouldn't be needed for correctness. - let register_lib_name = "__tgt_register_lib"; - if cx.get_function(register_lib_name).is_some() { - return; - } - - let reg_lib_decl = cx.type_func(&[cx.type_ptr()], cx.type_void()); - let register_lib = declare_offload_fn(&cx, register_lib_name, reg_lib_decl); - let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", reg_lib_decl); - - let ptr_null = cx.const_null(cx.type_ptr()); - let const_struct = cx.const_struct(&[cx.get_const_i32(0), ptr_null, ptr_null, ptr_null], false); - let omp_descriptor = - add_global(cx, ".omp_offloading.descriptor", const_struct, InternalLinkage); - // @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries } - // @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 0, ptr null, ptr null, ptr null } - - let atexit = cx.type_func(&[cx.type_ptr()], cx.type_i32()); - let atexit_fn = declare_offload_fn(cx, "atexit", atexit); - - // FIXME(offload): Drop this, once we fully automated our offload compilation pipeline, since - // LLVM will initialize them for us if it sees gpu kernels being registered. - let init_ty = cx.type_func(&[], cx.type_void()); - let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); - - let desc_ty = cx.type_func(&[], cx.type_void()); - let reg_name = ".omp_offloading.descriptor_reg"; - let unreg_name = ".omp_offloading.descriptor_unreg"; - let desc_reg_fn = declare_offload_fn(cx, reg_name, desc_ty); - let desc_unreg_fn = declare_offload_fn(cx, unreg_name, desc_ty); - llvm::set_linkage(desc_reg_fn, InternalLinkage); - llvm::set_linkage(desc_unreg_fn, InternalLinkage); - llvm::set_section(desc_reg_fn, c".text.startup"); - llvm::set_section(desc_unreg_fn, c".text.startup"); - - // define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { - // entry: - // call void @__tgt_register_lib(ptr @.omp_offloading.descriptor) - // call void @__tgt_init_all_rtls() - // %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg) - // ret void - // } - let bb = Builder::append_block(cx, desc_reg_fn, "entry"); - let mut a = Builder::build(cx, bb); - a.call(reg_lib_decl, None, None, register_lib, &[omp_descriptor], None, None); - a.call(init_ty, None, None, init_rtls, &[], None, None); - a.call(atexit, None, None, atexit_fn, &[desc_unreg_fn], None, None); - a.ret_void(); - - // define internal void @.omp_offloading.descriptor_unreg() section ".text.startup" { - // entry: - // call void @__tgt_unregister_lib(ptr @.omp_offloading.descriptor) - // ret void - // } - let bb = Builder::append_block(cx, desc_unreg_fn, "entry"); - let mut a = Builder::build(cx, bb); - a.call(reg_lib_decl, None, None, unregister_lib, &[omp_descriptor], None, None); - a.ret_void(); - - // @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] - let args = vec![cx.get_const_i32(101), desc_reg_fn, ptr_null]; - let const_struct = cx.const_struct(&args, false); - let arr = cx.const_array(cx.val_ty(const_struct), &[const_struct]); - add_global(cx, "llvm.global_ctors", arr, AppendingLinkage); -} - pub(crate) struct OffloadKernelDims<'ll> { num_workgroups: &'ll Value, threads_per_block: &'ll Value, diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 08a74774305c6..9e127edbd2ff9 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -918,11 +918,6 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { self.get_const_int(self.type_i8(), n) } - pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> { - let name = SmallCStr::new(name); - unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) } - } - pub(crate) fn get_md_kind_id(&self, name: &str) -> llvm::MetadataKindId { unsafe { llvm::LLVMGetMDKindIDInContext( diff --git a/compiler/rustc_codegen_llvm/src/diagnostics.rs b/compiler/rustc_codegen_llvm/src/diagnostics.rs index fb43b36fe39b9..70a14288aec0c 100644 --- a/compiler/rustc_codegen_llvm/src/diagnostics.rs +++ b/compiler/rustc_codegen_llvm/src/diagnostics.rs @@ -107,6 +107,10 @@ pub(crate) struct OffloadBundleImagesFailed; #[diag("call to EmbedBufferInModule failed, `host.o` was not created")] pub(crate) struct OffloadEmbedFailed; +#[derive(Diagnostic)] +#[diag("call to WrapImages failed, device image was not wrapped into the host module")] +pub(crate) struct OffloadWrapImagesFailed; + #[derive(Diagnostic)] #[diag("failed to get bitcode from object file for LTO ({$err})")] pub(crate) struct LtoBitcodeFromRlib { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c4255652146ad..1844a8e5c0bca 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -36,9 +36,7 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; -use crate::builder::gpu_offload::{ - self, OffloadKernelDims, declare_omp_get_num_devices, register_offload, -}; +use crate::builder::gpu_offload::{self, OffloadKernelDims, declare_omp_get_num_devices}; use crate::context::CodegenCx; use crate::declare::declare_raw_fn; use crate::diagnostics::{ @@ -1900,7 +1898,6 @@ fn codegen_offload<'ll, 'tcx>( return; } }; - register_offload(cx); let offload_data = gpu_offload::gen_define_handling(&cx, &metadata, target_symbol, offload_globals); gpu_offload::gen_call_handling( diff --git a/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs index 46d9320248a9b..7ecf450ab1dba 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs @@ -1,4 +1,5 @@ use std::ffi::{CStr, c_char}; +use std::path::PathBuf; use std::sync::OnceLock; use super::ffi::{Module, TargetMachine, Value}; @@ -6,7 +7,10 @@ use super::ffi::{Module, TargetMachine, Value}; type LLVMRustBundleImagesFn = unsafe extern "C" fn(&Module, &TargetMachine, *const c_char) -> bool; type LLVMRustOffloadEmbedBufferInModuleFn = unsafe extern "C" fn(&Module, *const c_char) -> bool; type LLVMRustOffloadMapperFn = unsafe extern "C" fn(&Value, &Value, *const &Value); +type LLVMRustOffloadWrapImagesFn = + unsafe extern "C" fn(&Module, *const c_char, *const c_char) -> bool; +use rustc_fs_util::path_to_c_string; use rustc_session::config::host_tuple; use rustc_session::filesearch; @@ -16,6 +20,8 @@ pub(crate) struct RustOffloadWrapper { LLVMRustBundleImages: LLVMRustBundleImagesFn, LLVMRustOffloadEmbedBufferInModule: LLVMRustOffloadEmbedBufferInModuleFn, LLVMRustOffloadMapper: LLVMRustOffloadMapperFn, + LLVMRustOffloadWrapImages: LLVMRustOffloadWrapImagesFn, + lld_path: Option, // Keep the dynamic library loaded while the function pointers are used. _lib: libloading::Library, } @@ -71,10 +77,21 @@ impl RustOffloadWrapper { unsafe { (self.LLVMRustOffloadMapper)(v1, v2, vs.as_ptr()) } } + pub(crate) unsafe fn llvm_rust_offload_wrap_images( + &self, + host_m: &Module, + device_bin_path: &CStr, + ) -> bool { + let lld_c = self.lld_path.as_deref().map(path_to_c_string).unwrap_or_default(); + unsafe { + (self.LLVMRustOffloadWrapImages)(host_m, lld_c.as_ptr(), device_bin_path.as_ptr()) + } + } + fn call_dynamic( sysroot: &rustc_session::config::Sysroot, ) -> Result { - let rust_offload_path = Self::get_rust_offload_path(sysroot)?; + let (rust_offload_path, lld_path) = Self::get_offload_and_lld_paths(sysroot)?; let lib = unsafe { libloading::Library::new(rust_offload_path)? }; let llvm_rust_bundle_images = @@ -86,48 +103,47 @@ impl RustOffloadWrapper { }; let llvm_rust_offload_wrapper = *unsafe { lib.get::(b"LLVMRustOffloadMapper\0")? }; + let llvm_rust_offload_wrap_images = + *unsafe { lib.get::(b"LLVMRustOffloadWrapImages\0")? }; Ok(Self { LLVMRustBundleImages: llvm_rust_bundle_images, LLVMRustOffloadEmbedBufferInModule: llvm_rust_offload_embed_buffer_in_module, LLVMRustOffloadMapper: llvm_rust_offload_wrapper, + LLVMRustOffloadWrapImages: llvm_rust_offload_wrap_images, + lld_path, _lib: lib, }) } - fn get_rust_offload_path( + fn get_offload_and_lld_paths( sysroot: &rustc_session::config::Sysroot, - ) -> Result { + ) -> Result<(PathBuf, Option), RustOffloadLibraryError> { let llvm_version_major = unsafe { LLVMRustVersionMajor() }; - - let path_buf = sysroot - .all_paths() - .find_map(|p| { - let candidate = filesearch::make_target_lib_path(p, host_tuple()) - .join(format!("libRustOffload-{}", llvm_version_major)) - .with_extension(std::env::consts::DLL_EXTENSION); - - candidate.exists().then_some(candidate) - }) - .ok_or_else(|| { - let candidates = sysroot - .all_paths() - .map(|p| p.join("lib").display().to_string()) - .collect::>() - .join("\n* "); - RustOffloadLibraryError::NotFound { - err: format!( - "failed to find a `libRustOffload-{llvm_version_major}` \ - in the sysroot candidates:\n* {candidates}" - ), - } - })?; - - Ok(path_buf - .to_str() - .ok_or_else(|| RustOffloadLibraryError::LoadFailed { - err: format!("invalid UTF-8 in path: {}", path_buf.display()), - })? - .to_string()) + let mut searched = Vec::new(); + + for root in sysroot.all_paths() { + let rust_offload_path = filesearch::make_target_lib_path(root, host_tuple()) + .join(format!("libRustOffload-{llvm_version_major}")) + .with_extension(std::env::consts::DLL_EXTENSION); + + if !rust_offload_path.is_file() { + searched.push(rust_offload_path); + continue; + } + + let lld_path = filesearch::make_target_bin_path(root, host_tuple()) + .join(format!("rust-lld{}", std::env::consts::EXE_SUFFIX)); + let lld_path = lld_path.is_file().then_some(lld_path); + + return Ok((rust_offload_path, lld_path)); + } + + Err(RustOffloadLibraryError::NotFound { + err: format!( + "could not find libRustOffload-{llvm_version_major} in the sysroot candidates:\n* {}", + searched.iter().map(|p| p.display().to_string()).collect::>().join("\n* ") + ), + }) } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8c6998407e89e..08eb2280fdb52 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3029,6 +3029,14 @@ fn linker_with_args( link_output_kind, ); + if sess.opts.unstable_opts.offload.iter().any(|o| matches!(o, config::Offload::Host(_))) { + cmd.link_dylib_by_name("omptarget", false, true); + cmd.link_dylib_by_name("omp", false, true); + cmd.link_args(["-z", "nostart-stop-gc"]); + cmd.link_arg("-rpath"); + cmd.link_arg(std::path::absolute(&*sess.target_tlib_path.dir).unwrap()); + } + // Upstream rust crates and their non-dynamic native libraries. add_upstream_rust_crates( cmd, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 4874eacd79b63..b3fbdc03e8478 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -2,8 +2,8 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::{ - self, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, - Upcast, shift_vars, + self, GenericArgs, PredicateProxy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, Upcast, shift_vars, }; use rustc_middle::{bug, span_bug}; use rustc_span::Span; @@ -347,7 +347,7 @@ impl<'tcx> TypeFolder> for MapAndCompressBoundVars<'tcx> { } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if !p.has_bound_vars() { p } else { p.super_fold_with(self) } } } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 1ae3fecf92096..2ffd335fb67b9 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -2,12 +2,15 @@ //! //! For more information about delegation design, see the tracking issue #118212. +use std::assert_matches; + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment}; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, ConstKind, EarlyBinder, GenericArg, GenericArgKind, RegionKind, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::{ErrorGuaranteed, Span, kw}; @@ -121,8 +124,6 @@ fn fn_kinds(tcx: TyCtxt<'_>, def_id: LocalDefId, sig_id: DefId) -> (FnKind, FnKi // For trait impl's `sig_id` is always equal to the corresponding trait method. assert!(!matches!(kinds, (_, FnKind::AssocTraitImpl))); - // Delegation to inherent impls is not yet supported. - assert!(!matches!(kinds, (_, FnKind::AssocInherentImpl))); kinds } @@ -176,20 +177,80 @@ fn create_mapping<'tcx>( args_index += is_self_at_zero as usize; args_index += get_delegation_parent_args_count_without_self(tcx, def_id, sig_id); - let sig_generics = tcx.generics_of(sig_id); - let process_sig_parent_generics = matches!(fn_kind(tcx, sig_id), FnKind::AssocTrait); + let parent_kind = fn_kind(tcx, sig_id); + let process_parent = matches!(parent_kind, FnKind::AssocTrait | FnKind::AssocInherentImpl); + let parent_generics = process_parent.then(|| tcx.generics_of(tcx.parent(sig_id))); + + // In case of delegations to inherent impls indices of generic params which are passed + // to ADT can be random numbers not from range 0..parent_params_count, so we need to + // use original indices in mapping: + // impl<'a, 'b, 'c, A: 'a, const C: usize> S<'a, A, C> { + // fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + // fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + // }, + // 'a has index 0, A index 3, C index 4. If we encounter not a generic param as generic arg, + // then we do not need to map it (i.e. consts like `1`, `2`, `3`; `'static`, etc.). + let parent_params = match parent_kind { + FnKind::AssocInherentImpl => { + let ty::Adt(_, args) = tcx.type_of(tcx.parent(sig_id)).skip_binder().kind() else { + unreachable!("parent of inherent function in delegation can be only struct or enum") + }; + + let opt_param_info = |arg: GenericArg<'_>| match arg.kind() { + GenericArgKind::Lifetime(r) => ( + match r.kind() { + RegionKind::ReEarlyParam(p) => Some(p.index), + _ => None, + }, + false, + ), + GenericArgKind::Type(t) => ( + match t.kind() { + ty::Param(p) => Some(p.index), + _ => None, + }, + true, + ), + GenericArgKind::Const(c) => ( + match c.kind() { + ConstKind::Param(p) => Some(p.index), + _ => None, + }, + true, + ), + }; + + args.iter().map(opt_param_info).collect::>() + } + FnKind::AssocTrait => parent_generics + .expect("trait must have generics") + .own_params + .iter() + .map(|p| (Some(p.index as u32), p.kind.is_ty_or_const())) + .collect::>(), + _ => vec![], + }; + + let has_self = match parent_kind { + FnKind::AssocTrait => parent_generics.expect("trait must have generics").has_self, + _ => false, + }; + + if process_parent { + for i in (has_self as usize)..parent_params.len() { + let (index, is_ty_or_const) = parent_params[i]; + if !is_ty_or_const { + if let Some(index) = index { + mapping.insert(index, args_index as u32); + } - if process_sig_parent_generics { - for i in (sig_generics.has_self as usize)..sig_generics.parent_count { - let param = sig_generics.param_at(i, tcx); - if !param.kind.is_ty_or_const() { - mapping.insert(param.index, args_index as u32); args_index += 1; } } } - for param in &sig_generics.own_params { + let child_generics = tcx.generics_of(sig_id); + for param in &child_generics.own_params { if !param.kind.is_ty_or_const() { mapping.insert(param.index, args_index as u32); args_index += 1; @@ -204,17 +265,20 @@ fn create_mapping<'tcx>( args_index += 1; } - if process_sig_parent_generics { - for i in (sig_generics.has_self as usize)..sig_generics.parent_count { - let param = sig_generics.param_at(i, tcx); - if param.kind.is_ty_or_const() { - mapping.insert(param.index, args_index as u32); + if process_parent { + for i in (has_self as usize)..parent_params.len() { + let (index, is_ty_or_const) = parent_params[i]; + if is_ty_or_const { + if let Some(index) = index { + mapping.insert(index, args_index as u32); + } + args_index += 1; } } } - for param in &sig_generics.own_params { + for param in &child_generics.own_params { if param.kind.is_ty_or_const() { mapping.insert(param.index, args_index as u32); args_index += 1; @@ -339,7 +403,7 @@ fn create_generic_args<'tcx>( let delegation_args = &delegation_args[delegation_generics.parent_count..]; - let kinds = fn_kinds(tcx, def_id, sig_id); + let kinds @ (_, parent_kind) = fn_kinds(tcx, def_id, sig_id); if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) { // Special case, as user specifies Trait args in trait impl header, we want to treat // them as parent args. We always generate a function whose generics match @@ -357,10 +421,14 @@ fn create_generic_args<'tcx>( let self_type = get_delegation_self_ty(tcx, def_id).map(ty::GenericArg::from); - // Remove `Self` from parent args (it is always at the `0th` index) as it is - // added manually. if self_type.is_some() && !parent_args.is_empty() { - parent_args = &parent_args[1..]; + parent_args = match parent_kind { + FnKind::AssocInherentImpl => parent_args, + // Remove `Self` from parent args (it is always at the `0th` index) as it is + // added manually. + FnKind::AssocTrait => &parent_args[1..], + _ => unreachable!("if parent args are non-empty then the parent must exist"), + } } let (zero_self, after_lifetimes_self) = @@ -582,8 +650,66 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( let caller_sig = EarlyBinder::bind(tcx, caller_sig.skip_binder().fold_with(&mut folder)); let sig = caller_sig.instantiate(tcx, args.as_slice()).skip_binder(); - let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output())); - tcx.arena.alloc_from_iter(sig_iter) + let output = std::iter::once(sig.output()); + let mut sig = sig.inputs().iter().cloned().chain(output).collect::>(); + + adjust_sig_in_inherent_impl_cases(tcx, sig_id, def_id, parent_args, &mut sig); + + tcx.arena.alloc_from_iter(sig) +} + +/// We need to replace `Self` type of the signature function parent with +/// either type of parent of delegation (which is either `Self` param in case of trait) +/// and other ADT in case of inherent impl. We do the same thing when delegating to trait, +/// in this case replacement happens during signature instantiation (as we can replace `Self` +/// generic param with other type from `args` when instantiating). +fn adjust_sig_in_inherent_impl_cases<'tcx>( + tcx: TyCtxt<'tcx>, + sig_id: DefId, + def_id: LocalDefId, + parent_args: &[ty::GenericArg<'tcx>], + sig: &mut [Ty<'tcx>], +) { + if !tcx.is_method(sig_id) { + return; + } + + let kinds @ (def_kind, _) = fn_kinds(tcx, def_id, sig_id); + if def_kind == FnKind::Free || !matches!(kinds, (_, FnKind::AssocInherentImpl)) { + return; + } + + let ty::Adt(def, _) = tcx.type_of(tcx.parent(sig_id)).skip_binder().kind() else { + unreachable!("delegation is supported only to struct or enums") + }; + + for i in 0..sig.len() { + let to_replace = Ty::new_adt(tcx, *def, tcx.mk_args(parent_args)); + let replacement = match def_kind { + FnKind::Free => unreachable!(), + + FnKind::AssocTrait => Ty::new_param(tcx, 0, kw::SelfUpper), + _ => tcx.type_of(tcx.parent(def_id.to_def_id())).instantiate_identity().skip_norm_wip(), + }; + + struct Replacer<'tcx> { + tcx: TyCtxt<'tcx>, + to_replace: Ty<'tcx>, + replacement: Ty<'tcx>, + } + + impl<'tcx> TypeFolder> for Replacer<'tcx> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if t == self.to_replace { self.replacement } else { t.super_fold_with(self) } + } + + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + } + + sig[i] = sig[i].fold_with(&mut Replacer { tcx, to_replace, replacement }) + } } // Creates user-specified generic arguments from delegation path, @@ -603,11 +729,16 @@ pub(crate) fn delegation_user_specified_args<'tcx>( let ctx = ItemCtxt::new_for_delegation(tcx, def_id); let lowerer = ctx.lowerer(); + let parent_args = info .parent_seg_id_for_sig .and_then(get_segment) - .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Trait)) + .filter(|(_, def_id)| !matches!(tcx.def_kind(*def_id), DefKind::Mod)) .map(|(segment, def_id)| { + // After lowering parent segment can be resolved only to those variants (and `DefKind::Mod`), + // which we do not process here. + assert_matches!(tcx.def_kind(def_id), DefKind::Trait | DefKind::Struct | DefKind::Enum); + let self_ty = (tcx.def_kind(def_id) == DefKind::Trait) .then(|| Ty::new_param(tcx, 0, kw::SelfUpper)); @@ -617,29 +748,26 @@ pub(crate) fn delegation_user_specified_args<'tcx>( .as_slice() }); - let child_args = info - .child_seg_id_for_sig - .and_then(get_segment) - .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn)) - .map(|(segment, def_id)| { - let parent_args = if let Some(parent_args) = parent_args { + let child_args = info.child_seg_id_for_sig.and_then(get_segment).map(|(segment, def_id)| { + assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn); + let parent = tcx.parent(def_id); + + let parent_args = + if matches!(tcx.def_kind(parent), DefKind::Impl { of_trait: false } | DefKind::Trait) { + ty::GenericArgs::identity_for_item(tcx, parent).as_slice() + } else if let Some(parent_args) = parent_args { parent_args } else { - let parent = tcx.parent(def_id); - if matches!(tcx.def_kind(parent), DefKind::Trait) { - ty::GenericArgs::identity_for_item(tcx, parent).as_slice() - } else { - &[] - } + &[] }; - let args = lowerer - .lower_generic_args_of_path(segment.ident.span, def_id, parent_args, segment, None) - .0; + let args = lowerer + .lower_generic_args_of_path(segment.ident.span, def_id, parent_args, segment, None) + .0; - let synth_params_count = tcx.generics_of(def_id).own_synthetic_params_count(); - &args[parent_args.len()..args.len() - synth_params_count] - }); + let synth_params_count = tcx.generics_of(def_id).own_synthetic_params_count(); + &args[parent_args.len()..args.len() - synth_params_count] + }); (parent_args.unwrap_or_default(), child_args.unwrap_or_default()) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 40bf435e6d110..6e6ded6c59ea1 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1,7 +1,7 @@ use std::cell::{Cell, RefCell}; use std::cmp::max; -use std::debug_assert_matches; use std::ops::Deref; +use std::{assert_matches, debug_assert_matches}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; @@ -595,8 +595,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ProbeScope::Single(def_id, self_ty_override) => { let item = self.tcx.associated_item(def_id); - // FIXME(fn_delegation): Delegation to inherent methods is not yet supported. - assert_eq!(item.container, AssocContainer::Trait); + assert_matches!( + item.container, + AssocContainer::Trait | AssocContainer::InherentImpl + ); let trait_def_id = self.tcx.parent(def_id); let trait_span = self.tcx.def_span(trait_def_id); @@ -608,10 +610,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { probe_cx.push_candidate( Candidate { item, - kind: CandidateKind::TraitCandidate( - ty::Binder::dummy(trait_ref), - false, - ), + kind: match item.container { + AssocContainer::Trait => CandidateKind::TraitCandidate( + ty::Binder::dummy(trait_ref), + false, + ), + AssocContainer::InherentImpl => { + CandidateKind::InherentImplCandidate { + impl_def_id: self.tcx.parent(def_id), + receiver_steps: 0, + } + } + _ => unreachable!(), + }, import_ids: &[], }, false, diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 7b1f38f882747..b71290b658744 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -21,9 +21,9 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::{ - self, DefiningScopeKind, DefinitionSiteHiddenType, Flags, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, - Unnormalized, fold_regions, + self, DefiningScopeKind, DefinitionSiteHiddenType, Flags, PredicateProxy, Ty, TyCtxt, + TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, Unnormalized, fold_regions, }; use rustc_span::Span; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; @@ -1032,7 +1032,7 @@ impl<'cx, 'tcx> TypeFolder> for Resolver<'cx, 'tcx> { self.handle_term(ct, ty::Const::outer_exclusive_binder, ty::Const::new_error) } - fn fold_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, predicate: P) -> P { assert!( !self.should_normalize, "normalizing predicates in writeback is not generally sound" diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 770520413c666..9b3deac32222b 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::{ self, BoundVar, Flags, GenericArg, InferConst, List, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypingModeEqWrapper, }; +use rustc_type_ir::PredicateProxy; use smallvec::SmallVec; use tracing::debug; @@ -483,7 +484,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if p.flags().intersects(self.needs_canonical_flags) { p.super_fold_with(self) } else { p } } diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index 7e670cc233752..2bc7e269efc9d 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::{ self, DelayedMap, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; +use rustc_type_ir::PredicateProxy; use crate::infer::canonical::{Canonical, CanonicalVarValues}; @@ -124,7 +125,7 @@ impl<'tcx> TypeFolder> for CanonicalInstantiator<'tcx> { } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if p.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) { p.super_fold_with(self) } else { p } } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index cd35af8be73cf..d1c4480b59347 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -146,11 +146,13 @@ impl<'tcx> InferCtxt<'tcx> { let region_obligations = self.take_registered_region_obligations(); let region_assumptions = self.take_registered_region_assumptions(); debug!(?region_obligations); + let solver_constraints = self.take_solver_region_constraints(); let region_constraints = self.with_region_constraints(|region_constraints| { make_query_region_constraints( region_obligations, region_constraints, region_assumptions, + solver_constraints, ) }); debug!(?region_constraints); @@ -195,9 +197,10 @@ impl<'tcx> InferCtxt<'tcx> { let InferOk { value: result_args, obligations } = self.query_response_instantiation(cause, param_env, original_values, query_response)?; - for QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in - &query_response.value.region_constraints.constraints - { + let QueryRegionConstraints { constraints, assumptions, solver_constraints } = + &query_response.value.region_constraints; + + for QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in constraints { let constraint = instantiate_value(self.tcx, &result_args, *constraint); match constraint { ty::RegionConstraint::Outlives(clause) => { @@ -209,11 +212,15 @@ impl<'tcx> InferCtxt<'tcx> { } } - for assumption in &query_response.value.region_constraints.assumptions { + for assumption in assumptions { let assumption = instantiate_value(self.tcx, &result_args, *assumption); self.register_region_assumption(assumption); } + let solver_constraints = + instantiate_value(self.tcx, &result_args, solver_constraints.clone()); + self.register_solver_region_constraint(solver_constraints.with_spans(cause.span)); + let user_result: R = query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); @@ -325,27 +332,31 @@ impl<'tcx> InferCtxt<'tcx> { } } + let QueryRegionConstraints { constraints, assumptions, solver_constraints } = + &query_response.value.region_constraints; + // ...also include the other query region constraints from the query. - output_query_region_constraints.constraints.extend( - query_response.value.region_constraints.constraints.iter().filter_map(|&r_c| { - let r_c = instantiate_value(self.tcx, &result_args, r_c); + output_query_region_constraints.constraints.extend(constraints.iter().filter_map(|&r_c| { + let r_c = instantiate_value(self.tcx, &result_args, r_c); - // Screen out `'a: 'a` or `'a == 'a` cases. - if r_c.constraint.is_trivial() { None } else { Some(r_c) } - }), - ); + // Screen out `'a: 'a` or `'a == 'a` cases. + if r_c.constraint.is_trivial() { None } else { Some(r_c) } + })); // FIXME(higher_ranked_auto): Optimize this to instantiate all assumptions // at once, rather than calling `instantiate_value` repeatedly which may // create more universes. - output_query_region_constraints.assumptions.extend( - query_response - .value - .region_constraints - .assumptions - .iter() - .map(|&r_c| instantiate_value(self.tcx, &result_args, r_c)), - ); + output_query_region_constraints + .assumptions + .extend(assumptions.iter().map(|&r_c| instantiate_value(self.tcx, &result_args, r_c))); + + let solver_constraints = + instantiate_value(self.tcx, &result_args, solver_constraints.clone()); + output_query_region_constraints.solver_constraints = + ty::region_constraint::RegionConstraint::build_and( + std::mem::take(&mut output_query_region_constraints.solver_constraints), + solver_constraints, + ); let user_result: R = query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); @@ -619,6 +630,7 @@ pub fn make_query_region_constraints<'tcx>( outlives_obligations: Vec>, region_constraints: &RegionConstraintData<'tcx>, assumptions: Vec>, + solver_constraints: ty::region_constraint::RegionConstraint>, ) -> QueryRegionConstraints<'tcx> { let RegionConstraintData { constraints, verifys } = region_constraints; @@ -663,5 +675,5 @@ pub fn make_query_region_constraints<'tcx>( )) .collect(); - QueryRegionConstraints { constraints, assumptions } + QueryRegionConstraints { constraints, assumptions, solver_constraints } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index cbbf5e3c91c42..7e6297c7225e3 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -238,11 +238,16 @@ impl<'tcx> InferCtxt<'tcx> { outlives_env.known_type_outlives().into_iter().cloned().collect(), outlives_env.free_region_map().relation.clone(), ); - self.destructure_solver_region_constraints(assumptions, self); + let constraint = self.inner.borrow().solver_region_constraint_storage.get_constraint(); + self.destructure_solver_region_constraints(constraint, assumptions, self); } + /// Unlike regionck, borrowck doesn't keep these constraints in the `InferCtxt`. + /// It stores them in `MirTypeckRegionConstraints` alongside its other region + /// constraints, so it hands us the constraint to destructure. pub fn destructure_solver_region_constraints_for_borrowck( &self, + constraint: SolverRegionConstraint<'tcx>, // this is always ConstraintConversion but lol conversion: impl TypeOutlivesDelegate<'tcx>, known_type_outlives: &[PolyTypeOutlivesClause<'tcx>], @@ -252,19 +257,19 @@ impl<'tcx> InferCtxt<'tcx> { known_type_outlives.into_iter().cloned().collect(), region_outlives.maybe_map(|r| Some(Region::new_var(self.tcx, r))).unwrap(), ); - self.destructure_solver_region_constraints(assumptions, conversion); + self.destructure_solver_region_constraints(constraint, assumptions, conversion); } #[instrument(level = "debug", skip(self, conversion))] pub fn destructure_solver_region_constraints( &self, + constraint: SolverRegionConstraint<'tcx>, assumptions: rustc_type_ir::region_constraint::Assumptions>, mut conversion: impl TypeOutlivesDelegate<'tcx>, ) { assert!(self.tcx.assumptions_on_binders()); assert!(self.next_trait_solver()); - let constraint = self.inner.borrow().solver_region_constraint_storage.get_constraint(); debug!(?constraint); let constraint = region_constraint::destructure_type_outlives_constraints_in_root( self, diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 13df23a39b967..db4f313903a5a 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -3,6 +3,7 @@ use rustc_middle::ty::{ self, Const, DelayedMap, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; +use rustc_type_ir::PredicateProxy; use super::{FixupError, FixupResult, InferCtxt}; use crate::infer::TyOrConstInferVar; @@ -57,7 +58,7 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if !p.has_non_region_infer() { p } else { p.super_fold_with(self) } } diff --git a/compiler/rustc_infer/src/infer/solver_region_constraints.rs b/compiler/rustc_infer/src/infer/solver_region_constraints.rs index 09baae2ca8a42..965ccf70442b8 100644 --- a/compiler/rustc_infer/src/infer/solver_region_constraints.rs +++ b/compiler/rustc_infer/src/infer/solver_region_constraints.rs @@ -1,9 +1,11 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; +use rustc_type_ir::region_constraint::RegionConstraint; use tracing::instrument; -pub type SolverRegionConstraint<'tcx> = - rustc_type_ir::region_constraint::RegionConstraint, Span>; +use super::InferCtxt; + +pub type SolverRegionConstraint<'tcx> = RegionConstraint, Span>; #[derive(Clone, Debug)] pub(crate) struct SolverRegionConstraintStorage<'tcx>(SolverRegionConstraint<'tcx>); @@ -17,11 +19,24 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> { self.0.clone() } + pub(crate) fn take(&mut self) -> SolverRegionConstraint<'tcx> { + core::mem::replace(&mut self.0, SolverRegionConstraint::new_true()) + } + #[instrument(level = "debug", skip(self))] pub(crate) fn overwrite(&mut self, constraint: SolverRegionConstraint<'tcx>) { self.0 = constraint; } } +impl<'tcx> InferCtxt<'tcx> { + /// Trait queries just want to pass back the solver region constraints "as is", + /// mirroring `take_registered_region_obligations`. + pub fn take_solver_region_constraints(&self) -> RegionConstraint> { + assert!(!self.in_snapshot(), "cannot take solver region constraints in a snapshot"); + self.inner.borrow_mut().solver_region_constraint_storage.take().without_spans() + } +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs b/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs index 529ecf43f5ee1..540aa5e4f8cb2 100644 --- a/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs +++ b/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs @@ -1,7 +1,29 @@ +use rustc_middle::infer::canonical::QueryRegionConstraints; use rustc_middle::ty::TyCtxt; use rustc_span::{BytePos, Span}; use rustc_type_ir::region_constraint::{And, LeafRegionConstraint, Or}; +use super::{SolverRegionConstraint, SolverRegionConstraintStorage}; + +#[test] +fn true_constraint_keeps_query_response_empty() { + // Mirrors `register_solver_region_constraint`, which registers unconditionally: + // anding a trivially true constraint into an empty store has to leave the store + // trivially true, as the resulting query response would otherwise no longer be + // empty. This relies on `And`/`Or` being kept in canonical form. + let mut storage = SolverRegionConstraintStorage::<'static>::new(); + storage.overwrite(SolverRegionConstraint::build_and( + SolverRegionConstraint::new_true(), + storage.get_constraint(), + )); + + let constraints = QueryRegionConstraints { + solver_constraints: storage.get_constraint().without_spans(), + ..Default::default() + }; + assert!(constraints.is_empty()); +} + #[test] fn canonicalization_preserves_only_one_ambiguity() { let first = Span::with_root_ctxt(BytePos(1), BytePos(2)); diff --git a/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp index 8c18f2453e9d8..bed54da0a7045 100644 --- a/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp @@ -1,18 +1,41 @@ #include "../SuppressLLVMWarnings.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" +#include "llvm/Frontend/Offloading/OffloadWrapper.h" +#include "llvm/Frontend/Offloading/Utility.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Object/OffloadBinary.h" -#include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MemoryBufferRef.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/ValueMapper.h" +#include +#include +#include +#include + using namespace llvm; using namespace llvm::object; @@ -115,3 +138,214 @@ extern "C" void LLVMRustOffloadMapper(LLVMValueRef OldFn, LLVMValueRef NewFn, IRBuilder<> B(&entry); B.CreateBr(&clonedEntry); } + +static Error extractImages(StringRef DeviceBinPath, + SmallVectorImpl &Binaries) { + ErrorOr> BufOrErr = + MemoryBuffer::getFile(DeviceBinPath); + if (std::error_code EC = BufOrErr.getError()) + return createFileError(DeviceBinPath, EC); + std::unique_ptr Buf = std::move(*BufOrErr); + + if (!isAddrAligned(Align(OffloadBinary::getAlignment()), + Buf->getBufferStart())) + Buf = MemoryBuffer::getMemBufferCopy(Buf->getBuffer(), + Buf->getBufferIdentifier()); + + return extractOffloadBinaries(*Buf, Binaries); +} + +static bool hasOffloadEntries(Module &M) { + for (GlobalVariable &GV : M.globals()) + if (GV.hasSection() && GV.getSection() == "llvm_offload_entries") + return true; + return false; +} + +static bool reportAndFailWrappingImages(Error E, const char *What) { + handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) { + errs() << "LLVMRustOffloadWrapImages: " << What << ": " << EI.message() + << "\n"; + }); + return false; +} + +static Expected> +assembleWithPtxas(StringRef Ptx, StringRef Arch) { + const ErrorOr Ptxas = sys::findProgramByName("ptxas"); + if (!Ptxas) + return createStringError(Ptxas.getError(), "ptxas not found in PATH"); + + SmallString<128> PtxFilePath; + if (std::error_code E = + sys::fs::createTemporaryFile("rust-offload", "ptx", PtxFilePath)) + return errorCodeToError(E); + + SmallString<128> CubinFilePath; + if (std::error_code E = + sys::fs::createTemporaryFile("rust-offload", "cubin", CubinFilePath)) + return errorCodeToError(E); + + auto Cleanup = scope_exit([&] { + if (std::error_code E = sys::fs::remove(PtxFilePath)) + (void)reportAndFailWrappingImages( + errorCodeToError(E), "assembleWithPtxas: PtxFilePath cleanup"); + if (std::error_code E = sys::fs::remove(CubinFilePath)) + (void)reportAndFailWrappingImages( + errorCodeToError(E), "assembleWithPtxas: CubinFilePath cleanup"); + }); + + if (Error E = writeFile(PtxFilePath, Ptx)) + return std::move(E); + + const StringRef Args[] = { + *Ptxas, "-m64", "-O3", "--gpu-name", + Arch, "--output-file", CubinFilePath, PtxFilePath, + }; + + std::string ErrorMsg; + const int Status = + sys::ExecuteAndWait(*Ptxas, Args, std::nullopt, {}, 0, 0, &ErrorMsg); + + if (Status != 0) + return createStringError("assembleWithPtxas: status %d: %s", Status, + ErrorMsg.c_str()); + + ErrorOr> CubinOrError = + MemoryBuffer::getFileAsStream(CubinFilePath); + if (!CubinOrError) + return errorCodeToError(CubinOrError.getError()); + + return std::move(*CubinOrError); +} + +static Expected> +linkWithRustLld(StringRef Obj, StringRef LldPath) { + SmallString<128> ObjFilePath; + if (std::error_code E = + sys::fs::createTemporaryFile("rust-offload", "o", ObjFilePath)) + return errorCodeToError(E); + + SmallString<128> SoFilePath; + if (std::error_code E = + sys::fs::createTemporaryFile("rust-offload", "so", SoFilePath)) + return errorCodeToError(E); + + auto Cleanup = scope_exit([&] { + if (std::error_code E = sys::fs::remove(ObjFilePath)) + (void)reportAndFailWrappingImages(errorCodeToError(E), + "linkWithRustLld: ObjFilePath cleanup"); + if (std::error_code E = sys::fs::remove(SoFilePath)) + (void)reportAndFailWrappingImages(errorCodeToError(E), + "linkWithRustLld: SoFilePath cleanup"); + }); + + if (Error E = writeFile(ObjFilePath, Obj)) + return std::move(E); + + const StringRef Args[] = { + LldPath, "-flavor", "gnu", "-shared", + "--no-undefined", "-o", SoFilePath, ObjFilePath, + }; + + std::string ErrorMsg; + const int Status = + sys::ExecuteAndWait(LldPath, Args, std::nullopt, {}, 0, 0, &ErrorMsg); + + if (Status != 0) + return createStringError("linkWithRustLld: status %d: %s", Status, + ErrorMsg.c_str()); + + ErrorOr> ElfOrError = + MemoryBuffer::getFileAsStream(SoFilePath); + if (!ElfOrError) + return errorCodeToError(ElfOrError.getError()); + + return std::move(*ElfOrError); +} + +static Expected> +compileDeviceImage(const OffloadBinary &Input, const char *LldPath) { + const Triple DeviceTriple(Input.getTriple()); + const StringRef Arch = Input.getArch(); + + LLVMContext Ctx; + Expected> ImageObjOrError = + parseBitcodeFile(MemoryBufferRef(Input.getImage(), "device.bc"), Ctx); + if (!ImageObjOrError) + return ImageObjOrError.takeError(); + + std::string ErrorMsg; + const Target *DeviceTarget = + TargetRegistry::lookupTarget(DeviceTriple, ErrorMsg); + if (!DeviceTarget) + return createStringError(ErrorMsg); + + std::unique_ptr TM(DeviceTarget->createTargetMachine( + DeviceTriple, Arch, /*Features=*/"", TargetOptions(), Reloc::PIC_)); + if (!TM) + return createStringError("createTargetMachine failed for %s", + DeviceTriple.str().c_str()); + + const bool IsNvptx = DeviceTriple.isNVPTX(); + + legacy::PassManager PM; + SmallString<0> Emitted; + raw_svector_ostream OS(Emitted); + const CodeGenFileType FileType = + IsNvptx ? CodeGenFileType::AssemblyFile : CodeGenFileType::ObjectFile; + if (TM->addPassesToEmitFile(PM, OS, nullptr, FileType)) + return createStringError("target %s cannot emit %s", + DeviceTriple.str().c_str(), + IsNvptx ? "assembly" : "object"); + + PM.run(**ImageObjOrError); + + if (IsNvptx) + return assembleWithPtxas(Emitted, Arch); + if (DeviceTriple.isAMDGPU()) { + if (!LldPath || !*LldPath) + return createStringError("rust-lld path was not provided for %s", + DeviceTriple.str().c_str()); + return linkWithRustLld(Emitted, LldPath); + } + + return createStringError("unsupported offload target %s", + DeviceTriple.str().c_str()); +} + +extern "C" bool LLVMRustOffloadWrapImages(LLVMModuleRef HostMRef, + const char *LldPath, + const char *DeviceBinPath) { + Module &M = *unwrap(HostMRef); + if (!hasOffloadEntries(M)) + return true; + + SmallVector Binaries; + if (Error E = extractImages(DeviceBinPath, Binaries)) + return reportAndFailWrappingImages(std::move(E), "extract"); + + // LLVMRustBundleImages writes exactly one device image + if (Binaries.size() != 1) + return reportAndFailWrappingImages( + createStringError("expected exactly one device image, found %zu", + Binaries.size()), + "extract"); + + const OffloadBinary &Input = *Binaries.front().getBinary(); + + auto ImageOrErr = compileDeviceImage(Input, LldPath); + if (!ImageOrErr) + return reportAndFailWrappingImages(ImageOrErr.takeError(), + "device compile"); + + StringRef ImageBuf = (*ImageOrErr)->getBuffer(); + ArrayRef Image(ImageBuf.data(), ImageBuf.size()); + + if (Error E = offloading::wrapOpenMPBinaries( + M, {Image}, offloading::getOffloadEntryArray(M), /*Suffix=*/"", + /*Relocatable=*/ + false)) + return reportAndFailWrappingImages(std::move(E), "wrap"); + return true; +} diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 46429f7adfb12..f99280bb744a1 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -76,13 +76,21 @@ pub struct QueryResponse<'tcx, R> { pub value: R, } -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Hash)] #[derive(StableHash, TypeFoldable, TypeVisitable)] pub struct QueryRegionConstraints<'tcx> { pub constraints: Vec>, pub assumptions: Vec>, + /// Region constraints emitted by the next solver under + /// `-Zassumptions-on-binders`. + /// + /// These stay unspanned while passing through a canonical query. The type-op + /// caller attaches its origin span when consuming the response. + pub solver_constraints: ir::region_constraint::RegionConstraint>, } +impl Eq for QueryRegionConstraints<'_> {} + impl QueryRegionConstraints<'_> { /// Represents an empty (trivially true) set of region constraints. /// @@ -91,8 +99,23 @@ impl QueryRegionConstraints<'_> { /// discharge a requirement from another query, which is a potential problem if we did throw /// away these assumptions because there were no constraints. pub fn is_empty(&self) -> bool { - let QueryRegionConstraints { constraints, assumptions } = self; - constraints.is_empty() && assumptions.is_empty() + let QueryRegionConstraints { constraints, assumptions, solver_constraints } = self; + constraints.is_empty() && assumptions.is_empty() && solver_constraints.is_true() + } + + pub fn extend(&mut self, other: &Self) { + let QueryRegionConstraints { constraints, assumptions, solver_constraints } = self; + let QueryRegionConstraints { + constraints: other_constraints, + assumptions: other_assumptions, + solver_constraints: other_solver_constraints, + } = other; + constraints.extend(other_constraints.iter().cloned()); + assumptions.extend(other_assumptions.iter().cloned()); + *solver_constraints = ir::region_constraint::RegionConstraint::build_and( + std::mem::take(solver_constraints), + other_solver_constraints.clone(), + ); } } diff --git a/compiler/rustc_middle/src/middle/resolve.rs b/compiler/rustc_middle/src/middle/resolve.rs index 2958048103320..8267cde89ad27 100644 --- a/compiler/rustc_middle/src/middle/resolve.rs +++ b/compiler/rustc_middle/src/middle/resolve.rs @@ -190,6 +190,8 @@ pub struct ResolverGlobalCtxt { // Information about delegations which is used when handling recursive delegations // and ensures easy access to delegation-only `LocalDefId`s. pub delegation_infos: FxIndexMap, + pub delegation_inherent_fn_map: + FxIndexMap>, } #[derive(Debug)] @@ -261,14 +263,44 @@ pub struct ResolverAstLowering<'tcx> { pub disambiguators: LocalDefIdMap>, } +#[derive(Debug, Clone, Copy, StableHash)] +pub enum DelegationResolution { + /// Corresponds to paths that are fully resolved by resolver (i.e., `reuse Trait::foo`). + Full(DefId /* Signature and call path resolutions are the same */), + + /// We can encounter cases like delegation to inherent impl function from trait impl, + /// in this case we will have resolved signature id, but the call-path itself will + /// not be resolved, so we will need to use type-relative resolution routine during + /// AST -> HIR lowering. + PartialCall(DefId /* Signature resolution, call path is unresolved */), + + /// Corresponds to paths that are partially resolved by resolver (i.e., `reuse Struct::foo`). + Partial, + + Error(ErrorGuaranteed), +} + #[derive(Debug, StableHash)] pub struct DelegationInfo { - // `DefId` (either the resolution at delegation.id or item_id in case of a trait impl) for - // signature resolution, for details see - // https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914. - /// Refers to the next element in a delegation resolution chain. Usually points to the final - /// resolution, as most "chains" are just one step to a trait or an impl. - pub resolution_id: Result, + // `DefId` (either the resolution at delegation.id or item_id in case of a trait impl) for signature resolution, + // for details see https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914 + /// Refers to the next element in a delegation resolution chain. + /// Usually points to the final resolution, as most "chains" are just + /// one step to a trait or an impl. + pub resolution: DelegationResolution, +} + +#[derive(Debug, StableHash)] +pub enum TypeRelativeDelegationRes { + Ok(DefId), + Ambig(ErrorGuaranteed), + Error(ErrorGuaranteed), +} + +#[derive(Debug, StableHash)] +pub enum DelegationInherentFnKind { + Single(LocalDefId), + Ambig, } #[derive(Clone, Copy, Debug, StableHash)] diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index e127693a2e231..aa354e1ab8df0 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -71,6 +71,7 @@ use rustc_hir::{ItemLocalId, PreciseCapturingArgKind}; use rustc_index::{IndexSlice, IndexVec}; use rustc_lint_defs::{LintId, StableLintExpectationId}; use rustc_macros::rustc_queries; +use rustc_middle::middle::resolve::TypeRelativeDelegationRes; use rustc_session::Limits; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use rustc_span::def_id::{LOCAL_CRATE, ModId}; @@ -227,6 +228,11 @@ rustc_queries! { desc { "getting the source span" } } + query resolve_type_relative_delegations(_: ()) -> &'tcx FxIndexMap { + arena_cache + desc { "resolving type relative delegations" } + } + query lower_to_hir(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { eval_always desc { "lowering HIR for `{}`", tcx.def_path_str(def_id) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5ff5c05de734a..93e407570f04c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1283,6 +1283,10 @@ impl<'tcx> TyCtxt<'tcx> { None => Err(VarError::NotPresent), } } + + pub fn is_method(self, id: DefId) -> bool { + self.opt_associated_item(id).is_some_and(|item| item.is_method()) + } } impl<'tcx> TyCtxtAt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 74b4adda7fdd4..e1e138374209c 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,3 +1,4 @@ +use rustc_type_ir::PredicateProxy; use tracing::debug; use crate::query::Providers; @@ -79,7 +80,7 @@ impl<'tcx> TypeFolder> for RegionEraserAndAnonymizerVisitor<'tcx> { } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if p.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) { p.super_fold_with(self) } else { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 3d9148d6ed7ba..c19cda4f3edea 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; +use rustc_type_ir::PredicateProxy; use rustc_type_ir::data_structures::DelayedMap; use crate::ty::{ @@ -180,7 +181,7 @@ where } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index eb3a53d8fa968..0ea7e403ee111 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -9,14 +9,14 @@ use rustc_abi::TyAndLayout; use rustc_hir::def::Namespace; use rustc_hir::def_id::LocalDefId; use rustc_span::Spanned; -use rustc_type_ir::{ConstKind, TypeFolder, VisitorResult, try_visit}; +use rustc_type_ir::{ConstKind, PredicateProxy, TypeFolder, Upcast, VisitorResult, try_visit}; use super::{GenericArg, GenericArgKind, Pattern}; use crate::mir::PlaceElem; use crate::ty::print::{FmtPrinter, Printer, with_no_trimmed_paths}; use crate::ty::{ - self, FallibleTypeFolder, Lift, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, Binder, FallibleTypeFolder, Lift, ProjectionClause, Term, TermKind, Ty, TyCtxt, + TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; impl fmt::Debug for ty::TraitDef { @@ -491,17 +491,84 @@ impl<'tcx> TypeFoldable> for ty::Predicate<'tcx> { } } +impl<'tcx> PredicateProxy> for ty::Predicate<'tcx> { + fn allow_normalization(&self) -> bool { + rustc_type_ir::inherent::Predicate::allow_normalization(*self) + } + + fn map_projection( + self, + tcx: TyCtxt<'tcx>, + f: impl FnOnce(Binder<'tcx, ProjectionClause<'tcx>>) -> Binder<'tcx, ProjectionClause<'tcx>>, + ) -> Option { + self.as_projection_clause().map(|kind| f(kind).upcast(tcx)) + } + + fn clause_kind_unchecked(&self) -> Option>> { + self.as_clause().map(|clause| clause.kind()) + } +} + // FIXME(clause): This is wonky impl<'tcx> TypeFoldable> for ty::Clause<'tcx> { fn try_fold_with>>( self, folder: &mut F, ) -> Result { - Ok(folder.try_fold_predicate(self.as_predicate())?.expect_clause()) + Ok(folder.try_fold_predicate(self)?) } fn fold_with>>(self, folder: &mut F) -> Self { - folder.fold_predicate(self.as_predicate()).expect_clause() + folder.fold_predicate(self) + } +} + +// follow `Predicate`'s implementation (by deferring to it) +impl<'tcx> TypeSuperFoldable> for ty::Clause<'tcx> { + fn try_super_fold_with>>( + self, + folder: &mut F, + ) -> Result { + as TypeSuperFoldable>>::try_super_fold_with( + self.as_predicate(), + folder, + ) + .map(|i| i.expect_clause()) + } + + fn super_fold_with>>(self, folder: &mut F) -> Self { + as TypeSuperFoldable>>::super_fold_with( + self.as_predicate(), + folder, + ) + .expect_clause() + } +} + +impl<'tcx> TypeSuperVisitable> for ty::Clause<'tcx> { + fn super_visit_with>>(&self, visitor: &mut V) -> V::Result { + as TypeSuperVisitable>>::super_visit_with( + &self.as_predicate(), + visitor, + ) + } +} + +impl<'tcx> PredicateProxy> for ty::Clause<'tcx> { + fn allow_normalization(&self) -> bool { + self.as_predicate().allow_normalization() + } + + fn map_projection( + self, + tcx: TyCtxt<'tcx>, + f: impl FnOnce(Binder<'tcx, ProjectionClause<'tcx>>) -> Binder<'tcx, ProjectionClause<'tcx>>, + ) -> Option { + self.as_projection_clause().map(|kind| f(kind).upcast(tcx)) + } + + fn clause_kind_unchecked(&self) -> Option>> { + Some(self.kind()) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 622086b56c638..5361d9268f6a6 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -15,6 +15,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{StableHash, TyDecodable, TyEncodable, extension}; use rustc_span::sym; use rustc_structures::Limit; +use rustc_type_ir::PredicateProxy; use rustc_type_ir::solve::SizedTraitKind; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; @@ -27,7 +28,7 @@ use crate::traits::ObligationCause; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable, - TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, }; #[derive(Copy, Clone, Debug)] @@ -1037,24 +1038,23 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { } } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - if let ty::PredicateKind::Clause(clause) = p.kind().skip_binder() - && let ty::ClauseKind::Projection(projection_pred) = clause - { - p.kind() - .rebind(ty::ProjectionClause { - projection_term: projection_pred.projection_term.fold_with(self), - // Don't fold the term on the RHS of the projection predicate. - // This is because for default trait methods with RPITITs, we - // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` - // predicate, which would trivially cause a cycle when we do - // anything that requires `TypingEnv::with_post_analysis_normalized`. - term: projection_pred.term, - }) - .upcast(self.tcx) - } else { - p.super_fold_with(self) - } + fn fold_predicate>>(&mut self, p: P) -> P { + // We use `map_projection` to execute the closure only if `p` is a projection clause, + // to implement the logic described below (i.e. avoid folding the `term`). + // In all other cases, fold recursively, as normal. + p.map_projection(self.tcx, |bound_clause| { + let projection_clause = bound_clause.skip_binder(); + bound_clause.rebind(ty::ProjectionClause { + projection_term: projection_clause.projection_term.fold_with(self), + // Don't fold the term on the RHS of the projection predicate. + // This is because for default trait methods with RPITITs, we + // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` + // predicate, which would trivially cause a cycle when we do + // anything that requires `TypingEnv::with_post_analysis_normalized`. + term: projection_clause.term, + }) + }) + .unwrap_or_else(|| p.super_fold_with(self)) } } diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index cf36b1922b8c1..6047966248bb2 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -5,8 +5,8 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::solve::{Goal, QueryInput}; use rustc_type_ir::{ self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalVarKind, CanonicalizerState, - Flags, InferCtxtLike, Interner, PlaceholderConst, PlaceholderType, Region, TypeFlags, - TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + Flags, InferCtxtLike, Interner, PlaceholderConst, PlaceholderType, PredicateProxy, Region, + TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use thin_vec::ThinVec; @@ -583,7 +583,7 @@ impl, I: Interner> TypeFolder for Canonicaliz Const::new_canonical_bound(self.cx(), var) } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if !p.flags().intersects(NEEDS_CANONICAL) { p } else { p.super_fold_with(self) } } diff --git a/compiler/rustc_next_trait_solver/src/normalize.rs b/compiler/rustc_next_trait_solver/src/normalize.rs index ff9ed6cb06cfd..1fd62213b735a 100644 --- a/compiler/rustc_next_trait_solver/src/normalize.rs +++ b/compiler/rustc_next_trait_solver/src/normalize.rs @@ -2,8 +2,8 @@ use std::fmt::Debug; use rustc_type_ir::inherent::*; use rustc_type_ir::{ - self as ty, AliasTerm, Binder, FallibleTypeFolder, InferCtxtLike, Interner, TypeFoldable, - TypeSuperFoldable, TypeVisitableExt, UniverseIndex, eager_resolve_vars, + self as ty, AliasTerm, Binder, FallibleTypeFolder, InferCtxtLike, Interner, PredicateProxy, + TypeFoldable, TypeSuperFoldable, TypeVisitableExt, UniverseIndex, eager_resolve_vars, }; use tracing::instrument; @@ -197,7 +197,7 @@ where Ok(normalized) } - fn try_fold_predicate(&mut self, p: I::Predicate) -> Result { + fn try_fold_predicate>(&mut self, p: P) -> Result { if p.allow_normalization() { p.try_super_fold_with(self) } else { Ok(p) } } } diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index 83b2eb6ac6295..e24037e2da7cd 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -4,7 +4,7 @@ use rustc_type_ir::data_structures::IndexMap; use rustc_type_ir::inherent::*; use rustc_type_ir::{ self as ty, InferCtxtLike, Interner, PlaceholderConst, PlaceholderRegion, PlaceholderType, - Region, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + PredicateProxy, Region, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use tracing::debug; @@ -183,7 +183,7 @@ where } } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 697a7ad53464b..ae5cf61aac91e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -18,8 +18,9 @@ use rustc_type_ir::solve::{ }; use rustc_type_ir::{ self as ty, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, MayBeErased, - OpaqueTypeKey, PredicateKind, Region, RegionVid, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, eager_resolve_vars, max_universe, + OpaqueTypeKey, PredicateKind, PredicateProxy, Region, RegionVid, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + eager_resolve_vars, max_universe, }; use thin_vec::ThinVec; use tracing::{Level, debug, instrument, trace, warn}; @@ -1177,7 +1178,7 @@ where } } - fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result { + fn visit_predicate>(&mut self, p: P) -> Self::Result { if p.has_non_region_infer() || p.has_placeholders() { p.super_visit_with(self) } else { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9f1ff3fa6bc6b..5eea894c19c37 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -31,8 +31,8 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, use rustc_middle::query::Providers; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ - self, AssocContainer, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, - TypeVisitable, TypeVisitor, + self, AssocContainer, Const, GenericParamDefKind, PredicateProxy, TraitRef, Ty, TyCtxt, + TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_middle::{bug, span_bug}; use rustc_span::{Ident, Span, Symbol, sym}; @@ -130,8 +130,8 @@ where } } - fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> V::Result { - match clause.kind().skip_binder() { + fn visit_clause(&mut self, clause: ty::Binder<'tcx, ty::ClauseKind<'tcx>>) -> V::Result { + match clause.skip_binder() { ty::ClauseKind::Trait(ty::TraitClause { trait_ref, polarity: _ }) => { self.visit_trait(trait_ref) } @@ -160,7 +160,7 @@ where fn visit_clauses(&mut self, clauses: &[(ty::Clause<'tcx>, Span)]) -> V::Result { for &(clause, _) in clauses { - try_visit!(self.visit_clause(clause)); + try_visit!(self.visit_clause(clause.kind())); } V::Result::output() } @@ -172,8 +172,8 @@ where { type Result = V::Result; - fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> Self::Result { - self.visit_clause(p.as_clause().unwrap()) + fn visit_predicate>>(&mut self, p: P) -> Self::Result { + self.visit_clause(p.clause_kind_unchecked().unwrap()) } fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2966e3ad24a07..9b879d9a443fa 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -29,7 +29,9 @@ use rustc_hir::def::{CtorKind, DefKind, NonMacroAttrKind, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_lint_defs::builtin::{ELIDED_LIFETIMES_IN_PATHS, UNUSED_LABELS}; -use rustc_middle::middle::resolve::{DelegationInfo, LifetimeRes, PartialRes}; +use rustc_middle::middle::resolve::{ + DelegationInfo, DelegationInherentFnKind, DelegationResolution, LifetimeRes, PartialRes, +}; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::ty::{AssocTag, Visibility}; use rustc_middle::{bug, span_bug}; @@ -501,11 +503,11 @@ impl PathSource<'_, '_, '_> { | PathSource::Pat | PathSource::Struct(_) | PathSource::TupleStruct(..) + | PathSource::Delegation | PathSource::ReturnTypeNotation => true, PathSource::Trait(_) | PathSource::TraitItem(..) | PathSource::DefineOpaques - | PathSource::Delegation | PathSource::ExternItemImpl | PathSource::PreciseCapturingArg(..) | PathSource::Macro @@ -3603,7 +3605,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let mut seen_trait_items = Default::default(); for item in impl_items { with_owner(this, item.id, |this| { - this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id, of_trait.is_some()); + this.resolve_impl_item( + &**item, + &mut seen_trait_items, + trait_id, + of_trait.is_some(), + self_type.id, + ); }) } }); @@ -3646,6 +3654,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { seen_trait_items: &mut FxHashMap, trait_id: Option, is_in_trait_impl: bool, + self_type_id: NodeId, ) { use crate::ResolutionError::*; self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis))); @@ -3747,6 +3756,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, ); + if !is_in_trait_impl { + self.fill_delegation_inherent_fn_map(self_type_id, ident); + } + self.resolve_define_opaques(define_opaque); } AssocItemKind::Type(TyAlias { ident, generics, .. }) => { @@ -3789,6 +3802,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeBinderKind::Function, delegation.path.segments.last().unwrap().ident.span, |this| { + if !is_in_trait_impl { + this.fill_delegation_inherent_fn_map( + self_type_id, + // If rename is specified then ident equals rename. + &delegation.ident, + ); + } + this.check_trait_item( item.id, delegation.ident, @@ -3813,6 +3834,34 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.diag_metadata.current_impl_item = prev; } + /// A heuristic to resolve delegations to inherent impls during AST -> HIR lowering. + /// Ideally we would do it through `ProbeContext`, however now it is impossible due to + /// query cycles even in the code without errors. + /// Not all paths will be properly resolved this way (i.e., type aliases). + /// FIXME(fn_delegation): remove it when resolution through `ProbeContext` will be ready + fn fill_delegation_inherent_fn_map(&mut self, self_type_id: NodeId, ident: &Ident) { + let res = self.r.partial_res_map.get(&self_type_id); + + let Some(self_type_def_id) = res.and_then(|res| { + res.full_res().and_then(|r| r.opt_def_id()).and_then(|id| id.as_local()) + }) else { + return; + }; + + // FIXME(fn_delegation): use correct identifier hygiene + let map = self.r.delegation_inherent_fn_map.entry(self_type_def_id).or_default(); + + match map.get(ident) { + None => { + map.insert(*ident, DelegationInherentFnKind::Single(self.r.current_owner.def_id)); + } + Some(DelegationInherentFnKind::Single(..)) => { + map.insert(*ident, DelegationInherentFnKind::Ambig); + } + _ => {} + }; + } + fn check_trait_item( &mut self, id: NodeId, @@ -3985,22 +4034,39 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }); let resolution_node_id = if is_in_trait_impl { item_id } else { delegation.id }; - let def_id = self + let resolution = self .r .partial_res_map .get(&resolution_node_id) - .and_then(|r| r.expect_full_res().opt_def_id()); + .map(|r| match r.full_res().and_then(|r| r.opt_def_id()) { + None => { + // If we are inside trait impl delegation is either resolved or not. + assert!(!is_in_trait_impl); + DelegationResolution::Partial + } + Some(def_id) => { + // If we are inside trait impl do additional check if call path is resolved, + // this will later be used to decide if we should apply type-relative resolution + // routine during call path resolution in AST -> HIR lowering. + if is_in_trait_impl { + let path_res = self.r.partial_res_map[&delegation.id]; + + if path_res.full_res().and_then(|r| r.opt_def_id()).is_none() { + return DelegationResolution::PartialCall(def_id); + } + } - let resolution_id = def_id.ok_or_else(|| { - self.r.tcx.dcx().span_delayed_bug( - delegation.path.span, - format!( - "LateResolutionVisitor: couldn't resolve node {resolution_node_id:?} in delegation item", - ), - ) - }); + DelegationResolution::Full(def_id) + } + }) + .unwrap_or_else(|| { + DelegationResolution::Error(self.r.tcx.dcx().span_delayed_bug( + delegation.path.span, + format!("bad resolution for delegation {item_id:?}"), + )) + }); - let info = DelegationInfo { resolution_id }; + let info = DelegationInfo { resolution }; self.r.delegation_infos.insert(self.r.current_owner.def_id, info); let Some(body) = &delegation.body else { return }; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index d5b1457865891..baadbc644582b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -62,8 +62,8 @@ use rustc_lint_defs::builtin::PRIVATE_MACRO_USE; use rustc_metadata::creader::CStore; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::resolve::{ - AmbigModChild, DelegationInfo, DocLinkResMap, MainDefinition, ModChild, PartialRes, - PerOwnerResolverData, Reexport, ResolverAstLowering, ResolverGlobalCtxt, + AmbigModChild, DelegationInfo, DelegationInherentFnKind, DocLinkResMap, MainDefinition, + ModChild, PartialRes, PerOwnerResolverData, Reexport, ResolverAstLowering, ResolverGlobalCtxt, }; use rustc_middle::query::Providers; use rustc_middle::ty::{self, RegisteredTools, TyCtxt, TyCtxtFeed, Visibility}; @@ -1515,6 +1515,7 @@ pub struct Resolver<'ra, 'tcx> { item_required_generic_args_suggestions: FxHashMap = default::fx_hash_map(), delegation_fn_sigs: LocalDefIdMap = Default::default(), delegation_infos: FxIndexMap, + delegation_inherent_fn_map: FxIndexMap>, main_def: Option = None, trait_impls: FxIndexMap>, @@ -1887,6 +1888,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { current_crate_outer_attr_insert_span, disambiguators: Default::default(), delegation_infos: Default::default(), + delegation_inherent_fn_map: Default::default(), features: tcx.features(), .. }; @@ -1991,6 +1993,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { all_macro_rules: self.all_macro_rules, stripped_cfg_items, delegation_infos: self.delegation_infos, + delegation_inherent_fn_map: self.delegation_inherent_fn_map, }; let ast_lowering = ResolverAstLowering { partial_res_map: self.partial_res_map, diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index 5db5fb95924c5..751927fcac0a7 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs @@ -13,13 +13,14 @@ pub(crate) fn opts() -> TargetOptions { // but LLVM maintainers rejected it: https://reviews.llvm.org/D51440 let pre_link_args = TargetOptions::link_args( LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &["-nolibc", "--unwindlib=none"], + &["-nolibc", "--unwindlib=libunwind", "-static-libgcc"], ); // Order of `late_link_args*` does not matter with LLD. let mingw_libs = &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"]; let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); + add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::No, Lld::No), &["-l:libunwind.a"]); add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); TargetOptions { @@ -46,8 +47,6 @@ pub(crate) fn opts() -> TargetOptions { eh_frame_header: false, no_default_libraries: false, has_thread_local: true, - crt_static_allows_dylibs: true, - crt_static_respected: true, debuginfo_kind: DebuginfoKind::Dwarf, // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to // output DWO, despite using DWARF, doesn't use ELF.. diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 818d8e1a4e0c3..60339b1982233 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -374,6 +374,11 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< region_obligations, region_constraints, region_assumptions, + // We're only called with `-Zassumptions-on-binders` disabled, in which + // case the solver never emits new-style region constraints. With it + // enabled the solver instead returns `ExternalRegionConstraints::NextGen`, + // reading the constraint straight out of the `InferCtxt`. + Default::default(), ) }); diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 56df5d917e108..2d2c4ff38acee 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -10,8 +10,8 @@ use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ - self, AliasTerm, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, - TypeVisitableExt, TypingMode, Unnormalized, + self, AliasTerm, PredicateProxy, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitable, TypeVisitableExt, TypingMode, Unnormalized, }; use thin_vec::ThinVec; use tracing::{debug, instrument}; @@ -512,7 +512,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } #[inline] - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate>>(&mut self, p: P) -> P { if p.allow_normalization() && needs_normalization(self.selcx.infcx, &p) { p.super_fold_with(self) } else { diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 84cae1e7bfa0a..bcb932f74b1f8 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -82,7 +82,10 @@ fn implied_outlives_bounds<'a, 'tcx>( // FIXME(higher_ranked_auto): Should we register assumptions here? // We otherwise would get spurious errors if normalizing an implied // outlives bound required proving some higher-ranked coroutine obl. - let QueryRegionConstraints { constraints, assumptions: _ } = constraints; + let QueryRegionConstraints { constraints, assumptions: _, solver_constraints } = + constraints; + infcx.register_solver_region_constraint(solver_constraints.with_spans(span)); + let cause = ObligationCause::misc(span, body_def_id); for &QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in &constraints { match constraint { diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 96e41f89be573..c4994fa5c4b7a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::{ - self, FallibleTypeFolder, Flags, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, + self, FallibleTypeFolder, Flags, PredicateProxy, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, }; use rustc_span::DUMMY_SP; @@ -290,10 +290,10 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { } #[inline] - fn try_fold_predicate( + fn try_fold_predicate>>( &mut self, - p: ty::Predicate<'tcx>, - ) -> Result, Self::Error> { + p: P, + ) -> Result { if p.allow_normalization() && needs_normalization(self.infcx, &p) { p.try_super_fold_with(self) } else { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 25385d15e36f4..39f439cad64d3 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -60,8 +60,8 @@ impl fmt::Debug for CustomTypeOp { } } -/// Executes `op` and then scrapes out all the "old style" region -/// constraints that result, creating query-region-constraints. +/// Executes `op` and then scrapes out all resulting region constraints +/// in the `infcx`, creating query-region-constraints. pub fn scrape_region_constraints<'tcx, Op, R>( infcx: &InferCtxt<'tcx>, root_def_id: LocalDefId, @@ -88,6 +88,11 @@ where pre_assumptions.is_empty(), "scrape_region_constraints: incoming region assumptions = {pre_assumptions:#?}", ); + let pre_solver_constraints = infcx.take_solver_region_constraints(); + assert!( + pre_solver_constraints.is_true(), + "scrape_region_constraints: incoming solver constraints = {pre_solver_constraints:#?}", + ); let value = infcx.commit_if_ok(|_| { let ocx = ObligationCtxt::new(infcx); @@ -144,11 +149,13 @@ where let region_obligations = infcx.take_registered_region_obligations(); let region_assumptions = infcx.take_registered_region_assumptions(); + let solver_constraints = infcx.take_solver_region_constraints(); let region_constraint_data = infcx.take_and_reset_region_constraints(); let region_constraints = query_response::make_query_region_constraints( region_obligations, ®ion_constraint_data, region_assumptions, + solver_constraints, ); if region_constraints.is_empty() { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 250579a2b064a..ac516afbc783c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -151,9 +151,8 @@ where Ok(output) })?; output.error_info = error_info; - if let Some(QueryRegionConstraints { constraints, assumptions }) = output.constraints { - region_constraints.constraints.extend(constraints.iter().cloned()); - region_constraints.assumptions.extend(assumptions.iter().cloned()); + if let Some(constraints) = output.constraints { + region_constraints.extend(constraints); } output.constraints = if region_constraints.is_empty() { None diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5fc9e57795b72..632e805388eb6 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -10,8 +10,8 @@ use rustc_hir::attrs::lang_items::LangItem; use rustc_infer::traits::{ObligationCauseCode, PredicateObligation, PredicateObligations}; use rustc_middle::bug; use rustc_middle::ty::{ - self, DelayedSet, GenericArgsRef, Term, TermKind, Ty, TyCtxt, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, + self, DelayedSet, GenericArgsRef, PredicateProxy, Term, TermKind, Ty, TyCtxt, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_session::diagnostics::feature_err; use rustc_span::def_id::{DefId, LocalDefId}; @@ -1003,7 +1003,10 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { let kind = obligation.predicate.kind().skip_binder(); let keep = match kind { ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) - if matches!(ct.kind(), ty::ConstKind::Param(..)) => + if matches!( + ct.kind(), + ty::ConstKind::Param(..) | ty::ConstKind::Placeholder(..) + ) => { // ConstArgHasType clauses are not higher kinded. Assert as // such so we can fix this up if that ever changes. @@ -1240,7 +1243,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { c.super_visit_with(self) } - fn visit_predicate(&mut self, _p: ty::Predicate<'tcx>) -> Self::Result { + fn visit_predicate>>(&mut self, _p: P) -> Self::Result { bug!("predicate should not be checked for well-formedness"); } } diff --git a/compiler/rustc_traits/src/coroutine_witnesses.rs b/compiler/rustc_traits/src/coroutine_witnesses.rs index 762471eefe4dd..b7ff4cca0bb1f 100644 --- a/compiler/rustc_traits/src/coroutine_witnesses.rs +++ b/compiler/rustc_traits/src/coroutine_witnesses.rs @@ -84,6 +84,10 @@ fn compute_assumptions<'tcx>( region_obligations, ®ion_constraints, region_assumptions, + // We return early above unless the old solver is used globally, while + // `-Zassumptions-on-binders` enables the next solver globally. So there + // are never any new-style region constraints to pass along here. + Default::default(), ) .constraints .fold_with(&mut OpportunisticRegionResolver::new(&infcx)); diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 7fc29cd8ebcf1..a16610a520406 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -15,7 +15,9 @@ use crate::data_structures::SsoHashSet; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, DebruijnIndex, Interner, Region, UniverseIndex, Unnormalized}; +use crate::{ + self as ty, DebruijnIndex, Interner, PredicateProxy, Region, UniverseIndex, Unnormalized, +}; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -747,7 +749,7 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if p.has_param() { p.super_fold_with(self) } else { p } } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index f57a9aba69302..2b25de4132e62 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -55,7 +55,10 @@ use tracing::{debug, instrument}; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; -use crate::{self as ty, BoundVarIndexKind, Interner, Region}; +use crate::{ + self as ty, Binder, BoundVarIndexKind, ClauseKind, Flags, Interner, ProjectionClause, Region, + TypeSuperVisitable, +}; /// This trait is implemented for every type that can be folded, /// providing the skeleton of the traversal. @@ -145,7 +148,7 @@ pub trait TypeFolder: Sized { c.super_fold_with(self) } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { p.super_fold_with(self) } @@ -154,6 +157,33 @@ pub trait TypeFolder: Sized { } } +/// [Fold predicate](TypeFolder::fold_predicate) deliberately doesn't get access +/// to an actual predicate. This way, we can compress lists of predicates, and hide +/// this detail to folders. Instead, some type implementing this trait, [`PredicateProxy`] +/// is passed, with its limited API. +/// +/// Most [`TypeFolder`]s only use `fold_predicate` to inspect type flags. +pub trait PredicateProxy: + TypeSuperFoldable + TypeSuperVisitable + Flags + Copy +{ + fn allow_normalization(&self) -> bool; + + /// Gets the underlying clause kind (if this predicate is a clause, otherwise `None`). + /// The fact that it's `unchecked`, is because no attempt is made to hide implementation + /// details. For example, in the future we may compress clauses together. Code calling + /// `clause_kind_unchecked` will have to correctly deal with these implementation details, + /// and have code handling any edgecase arising as a result. + fn clause_kind_unchecked(&self) -> Option>>; + + /// If self is a projection clause, call `f` with it. The result will be rebound and returned as `Some`. + /// Otherwise, when self is not a projection clause, `None` is returned. + fn map_projection( + self, + cx: I, + f: impl FnOnce(Binder>) -> Binder>, + ) -> Option; +} + /// This trait is implemented for every folding traversal. There is a fold /// method defined for every type of interest. Each such method has a default /// that does an "identity" fold. @@ -187,7 +217,7 @@ pub trait FallibleTypeFolder: Sized { c.try_super_fold_with(self) } - fn try_fold_predicate(&mut self, p: I::Predicate) -> Result { + fn try_fold_predicate>(&mut self, p: P) -> Result { p.try_super_fold_with(self) } @@ -430,7 +460,7 @@ impl TypeFolder for Shifter { } } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p } } @@ -546,7 +576,7 @@ where if ct.has_regions() { ct.super_fold_with(self) } else { ct } } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if p.has_regions() { p.super_fold_with(self) } else { p } } @@ -692,7 +722,7 @@ impl TypeFolder for RigidnessFolder { } } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if self.mode.needs_change(&p) { p.super_fold_with(self) } else { p } } diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 31fe3cf99d88c..8d1d3372fac69 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -11,8 +11,8 @@ use crate::relate::RelateResult; use crate::relate::combine::PredicateEmittingRelation; use crate::solve::{TyOrConstInferVar, VisibleForLeakCheck}; use crate::{ - self as ty, Interner, Region, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, + self as ty, Interner, PredicateProxy, Region, TyVid, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, }; mod private { @@ -717,7 +717,7 @@ impl, I: Interner> TypeFolder for EagerRes } } - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + fn fold_predicate>(&mut self, p: P) -> P { if p.has_infer() { p.super_fold_with(self) } else { p } } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 360687f530690..1138d8cf9edad 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -52,7 +52,7 @@ use smallvec::SmallVec; use thin_vec::ThinVec; use crate::inherent::*; -use crate::{self as ty, Interner, Region, TypeFlags}; +use crate::{self as ty, Interner, PredicateProxy, Region, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -116,7 +116,7 @@ pub trait TypeVisitor: Sized { c.super_visit_with(self) } - fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result { + fn visit_predicate>(&mut self, p: P) -> Self::Result { p.super_visit_with(self) } @@ -485,7 +485,7 @@ impl TypeVisitor for HasTypeFlagsVisitor { } #[inline] - fn visit_predicate(&mut self, predicate: I::Predicate) -> Self::Result { + fn visit_predicate>(&mut self, predicate: P) -> Self::Result { // Note: no `super_visit_with` call. if predicate.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) @@ -597,7 +597,7 @@ impl TypeVisitor for HasEscapingVarsVisitor { } #[inline] - fn visit_predicate(&mut self, predicate: I::Predicate) -> Self::Result { + fn visit_predicate>(&mut self, predicate: P) -> Self::Result { if predicate.outer_exclusive_binder() > self.outer_index { ControlFlow::Break(FoundEscapingVars) } else { diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index a64049a440d58..043f854ea79fd 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -247,8 +247,3 @@ unsafe extern "C" {} #[cfg(all(target_os = "wasi", panic = "unwind"))] #[link(name = "unwind")] unsafe extern "C" {} - -#[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))] -#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] -#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] -unsafe extern "C" {} diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index a335172631307..f9c6efe35bc48 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -350,7 +350,6 @@ fn make_win_llvm_dist(plat_root: &Path, target: TargetSelection, builder: &Build let target_libs = [ // MinGW libs "libunwind.a", - "libunwind.dll.a", "libmingw32.a", "libmingwex.a", "libmsvcrt.a", diff --git a/src/doc/rustc/src/platform-support/windows-gnullvm.md b/src/doc/rustc/src/platform-support/windows-gnullvm.md index fccde2da99f55..80794294a994b 100644 --- a/src/doc/rustc/src/platform-support/windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/windows-gnullvm.md @@ -19,7 +19,7 @@ Target triples available so far: ## Requirements Building those targets requires an LLVM-based C toolchain, for example, [llvm-mingw][1] or [MSYS2][2] with CLANG* -environment. +environment, with static libunwind library available. Binaries for this target should be at least on par with `*-windows-gnu` in terms of requirements and functionality, except for implicit self-contained mode (explained in [the section below](#building-rust-programs)). diff --git a/tests/ui/assumptions_on_binders/alias_outlives.rs b/tests/ui/assumptions_on_binders/alias_outlives.rs index 0c2ed6585cf45..9e1516132dd9d 100644 --- a/tests/ui/assumptions_on_binders/alias_outlives.rs +++ b/tests/ui/assumptions_on_binders/alias_outlives.rs @@ -23,11 +23,11 @@ where } fn borrowck_env_fail<'a, T: AliasHaver>() -// FIXME: ^ this should raise an ERROR: unsatisfied lifetime constraint from -Zassumptions-on-binders where ::Assoc: 'a, { let _: ReqTrait; + //~^ ERROR: higher-ranked lifetime bound could not be satisfied } const REGIONCK_ENV_PASS<'a, T: AliasHaver>: ReqTrait = todo!() @@ -39,4 +39,30 @@ const REGIONCK_ENV_FAIL<'a, T: AliasHaver>: ReqTrait = todo!() where ::Assoc: 'a; +// Solver constraints produced while normalizing implied bounds must be returned +// to lexical regionck. +trait Project { + type Assoc; +} + +impl Project for (T,) +where + T::Assoc: for<'a> Trait<'a>, +{ + type Assoc = (); +} + +struct Normalizes(T) +where + T::Assoc: Clone; + +trait TestTrait {} + +impl<'a, T: AliasHaver> TestTrait for [Normalizes<(T,)>; 1] +//~^ ERROR: higher-ranked lifetime bound could not be satisfied +where + T::Assoc: 'a, +{ +} + fn main() {} diff --git a/tests/ui/assumptions_on_binders/alias_outlives.stderr b/tests/ui/assumptions_on_binders/alias_outlives.stderr index 1787c1912ae4f..a6eaf3e11bad7 100644 --- a/tests/ui/assumptions_on_binders/alias_outlives.stderr +++ b/tests/ui/assumptions_on_binders/alias_outlives.stderr @@ -4,5 +4,20 @@ error: higher-ranked lifetime bound could not be satisfied LL | const REGIONCK_ENV_FAIL<'a, T: AliasHaver>: ReqTrait = todo!() | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: higher-ranked lifetime bound could not be satisfied + --> $DIR/alias_outlives.rs:61:1 + | +LL | / impl<'a, T: AliasHaver> TestTrait for [Normalizes<(T,)>; 1] +LL | | +LL | | where +LL | | T::Assoc: 'a, + | |_________________^ + +error: higher-ranked lifetime bound could not be satisfied + --> $DIR/alias_outlives.rs:29:12 + | +LL | let _: ReqTrait; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/dyn-trait-ill-typed.rs b/tests/ui/const-generics/dyn-trait-ill-typed.rs new file mode 100644 index 0000000000000..3dba700a7fa39 --- /dev/null +++ b/tests/ui/const-generics/dyn-trait-ill-typed.rs @@ -0,0 +1,15 @@ +//! Regression test for . +//@ compile-flags: -Znext-solver=globally +//@ check-fail + +// CHECK PASS TO SHOW IT PASSES, BUT IT SHOULD NOT +// THIS CODE SEGFAULTS, WITH REASON + +//~v ERROR: the constant `M` is not of type `usize` +fn foo() -> Box> { + loop {} +} + +trait Tr {} + +fn main() {} diff --git a/tests/ui/const-generics/dyn-trait-ill-typed.stderr b/tests/ui/const-generics/dyn-trait-ill-typed.stderr new file mode 100644 index 0000000000000..8917b53d4d826 --- /dev/null +++ b/tests/ui/const-generics/dyn-trait-ill-typed.stderr @@ -0,0 +1,14 @@ +error: the constant `M` is not of type `usize` + --> $DIR/dyn-trait-ill-typed.rs:9:27 + | +LL | fn foo() -> Box> { + | ^^^^^^^^^^^^^^ expected `usize`, found `u32` + | +note: required by a const generic parameter in `Tr` + --> $DIR/dyn-trait-ill-typed.rs:13:10 + | +LL | trait Tr {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Tr` + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index eb31c20081461..0864776ab49fd 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -33,10 +33,12 @@ impl Trait for S { reuse foo { &self.0 } //~^ ERROR cannot find function `foo` in this scope - //~| ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl + //~| ERROR method `foo` has a `&self` declaration in the trait, but not in the impl reuse Trait::foo2 { self.0 } - //~^ ERROR cannot find function `foo2` in trait `Trait` - //~| ERROR method `foo2` is not a member of trait `Trait` + //~^ ERROR: method `foo2` is not a member of trait `Trait` + //~| WARN: trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| ERROR: the trait `Trait` is not dyn compatible [E0038] } mod prefix {} diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index 44cf5149d08dd..9740442e4b9f3 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -71,25 +71,8 @@ error[E0425]: cannot find function `foo` in this scope LL | reuse foo { &self.0 } | ^^^ not found in this scope -error[E0425]: cannot find function `foo2` in trait `Trait` - --> $DIR/bad-resolve.rs:37:18 - | -LL | reuse Trait::foo2 { self.0 } - | ^^^^ not found in `Trait` - | -note: similarly named associated function `foo` defined here - --> $DIR/bad-resolve.rs:7:5 - | -LL | fn foo(&self, x: i32) -> i32 { x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: an associated function with a similar name exists - | -LL - reuse Trait::foo2 { self.0 } -LL + reuse Trait::foo { self.0 } - | - error[E0423]: cannot find function `self` in module `prefix` - --> $DIR/bad-resolve.rs:44:16 + --> $DIR/bad-resolve.rs:46:16 | LL | reuse prefix::{self, super, crate}; | ^^^^ not found in `prefix` @@ -114,8 +97,54 @@ LL | type Type; LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ missing `Type` in implementation +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/bad-resolve.rs:37:11 + | +LL | reuse Trait::foo2 { self.0 } + | ^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | reuse ::foo2 { self.0 } + | ++++ + + +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/bad-resolve.rs:37:11 + | +LL | reuse Trait::foo2 { self.0 } + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/bad-resolve.rs:4:11 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | const C: u32 = 0; + | ^ ...because it contains associated const `C` +LL | type Type; +LL | fn bar() {} + | ^^^ ...because associated function `bar` has no `self` parameter + = help: consider moving `C` to another trait + = help: the following types implement `Trait`: + F + S + consider defining an enum where each variant holds one of these types, + implementing `Trait` for this new enum and using it instead +help: consider turning `bar` into a method by giving it a `&self` argument, so that it is accessible through the trait object's vtable + | +LL | fn bar(&self) {} + | +++++ +help: alternatively, consider constraining `bar` so it is explicitly marked as not applying to trait objects + | +LL | fn bar() where Self: Sized {} + | +++++++++++++++++ + error[E0433]: cannot find module or crate `unresolved_prefix` in this scope - --> $DIR/bad-resolve.rs:43:7 + --> $DIR/bad-resolve.rs:45:7 | LL | reuse unresolved_prefix::{a, b, c}; | ^^^^^^^^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved_prefix` @@ -123,12 +152,12 @@ LL | reuse unresolved_prefix::{a, b, c}; = help: you might be missing a crate named `unresolved_prefix` error[E0433]: `crate` in paths can only be used in start position - --> $DIR/bad-resolve.rs:44:29 + --> $DIR/bad-resolve.rs:46:29 | LL | reuse prefix::{self, super, crate}; | ^^^^^ can only be used in path start position -error: aborting due to 14 previous errors +error: aborting due to 14 previous errors; 1 warning emitted -Some errors have detailed explanations: E0046, E0186, E0324, E0407, E0423, E0425, E0433, E0575, E0576. -For more information about an error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0038, E0046, E0186, E0324, E0407, E0423, E0425, E0433, E0575... +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/delegation/explicit-paths.rs b/tests/ui/delegation/explicit-paths.rs index 2592d3d2698fc..e9530ec9d2314 100644 --- a/tests/ui/delegation/explicit-paths.rs +++ b/tests/ui/delegation/explicit-paths.rs @@ -25,7 +25,7 @@ mod fn_to_other { reuse ::foo2; reuse to_reuse::foo3; reuse S::foo4; - //~^ ERROR cannot find function `foo4` in `S` + //~^ ERROR: method `foo4` is private } mod inherent_impl_assoc_fn_to_other { @@ -36,7 +36,6 @@ mod inherent_impl_assoc_fn_to_other { reuse ::foo2; reuse to_reuse::foo3; reuse F::foo4 { &self.0 } - //~^ ERROR cannot find function `foo4` in `F` } } @@ -50,7 +49,6 @@ mod trait_impl_assoc_fn_to_other { //~^ ERROR method `foo3` is not a member of trait `Trait` reuse F::foo4 { &self.0 } //~^ ERROR method `foo4` is not a member of trait `Trait` - //~| ERROR cannot find function `foo4` in `F` } } @@ -63,7 +61,6 @@ mod trait_assoc_fn_to_other { reuse ::foo2; reuse to_reuse::foo3; reuse F::foo4 { &F } - //~^ ERROR cannot find function `foo4` in `F` } } diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr index 30239f3648a53..f92bfd73266c3 100644 --- a/tests/ui/delegation/explicit-paths.stderr +++ b/tests/ui/delegation/explicit-paths.stderr @@ -1,5 +1,5 @@ error[E0407]: method `foo3` is not a member of trait `Trait` - --> $DIR/explicit-paths.rs:49:9 + --> $DIR/explicit-paths.rs:48:9 | LL | reuse to_reuse::foo3; | ^^^^^^^^^^^^^^^^----^ @@ -8,7 +8,7 @@ LL | reuse to_reuse::foo3; | not a member of trait `Trait` error[E0407]: method `foo4` is not a member of trait `Trait` - --> $DIR/explicit-paths.rs:51:9 + --> $DIR/explicit-paths.rs:50:9 | LL | reuse F::foo4 { &self.0 } | ^^^^^^^^^----^^^^^^^^^^^^ @@ -16,50 +16,8 @@ LL | reuse F::foo4 { &self.0 } | | help: there is an associated function with a similar name: `foo1` | not a member of trait `Trait` -error[E0425]: cannot find function `foo4` in `S` - --> $DIR/explicit-paths.rs:27:14 - | -LL | reuse S::foo4; - | ^^^^ not found in `S` - -error[E0425]: cannot find function `foo4` in `F` - --> $DIR/explicit-paths.rs:38:18 - | -LL | reuse F::foo4 { &self.0 } - | ^^^^ not found in `F` - | -note: function `fn_to_other::foo4` exists but is inaccessible - --> $DIR/explicit-paths.rs:27:5 - | -LL | reuse S::foo4; - | ^^^^^^^^^^^^^^ not accessible - -error[E0425]: cannot find function `foo4` in `F` - --> $DIR/explicit-paths.rs:51:18 - | -LL | reuse F::foo4 { &self.0 } - | ^^^^ not found in `F` - | -note: function `fn_to_other::foo4` exists but is inaccessible - --> $DIR/explicit-paths.rs:27:5 - | -LL | reuse S::foo4; - | ^^^^^^^^^^^^^^ not accessible - -error[E0425]: cannot find function `foo4` in `F` - --> $DIR/explicit-paths.rs:65:18 - | -LL | reuse F::foo4 { &F } - | ^^^^ not found in `F` - | -note: function `fn_to_other::foo4` exists but is inaccessible - --> $DIR/explicit-paths.rs:27:5 - | -LL | reuse S::foo4; - | ^^^^^^^^^^^^^^ not accessible - error[E0119]: conflicting implementations of trait `Trait` for type `S` - --> $DIR/explicit-paths.rs:74:5 + --> $DIR/explicit-paths.rs:71:5 | LL | impl Trait for S { | ---------------- first implementation here @@ -67,8 +25,17 @@ LL | impl Trait for S { LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ conflicting implementation for `S` +error[E0624]: method `foo4` is private + --> $DIR/explicit-paths.rs:27:14 + | +LL | reuse S::foo4; + | ^^^^ private method +... +LL | reuse F::foo4 { &self.0 } + | ---- private method defined here + error[E0308]: mismatched types - --> $DIR/explicit-paths.rs:61:36 + --> $DIR/explicit-paths.rs:59:36 | LL | trait Trait2 : Trait { | -------------------- found this type parameter @@ -86,13 +53,13 @@ LL | fn foo1(&self, x: i32) -> i32 { x } | ^^^^ ----- error[E0277]: the trait bound `S2: Trait` is not satisfied - --> $DIR/explicit-paths.rs:76:16 + --> $DIR/explicit-paths.rs:73:16 | LL | reuse ::foo1; | ^^ unsatisfied trait bound | help: the trait `Trait` is not implemented for `S2` - --> $DIR/explicit-paths.rs:73:5 + --> $DIR/explicit-paths.rs:70:5 | LL | struct S2; | ^^^^^^^^^ @@ -109,7 +76,7 @@ LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ `S` error[E0308]: mismatched types - --> $DIR/explicit-paths.rs:76:30 + --> $DIR/explicit-paths.rs:73:30 | LL | reuse ::foo1; | ^^^^ @@ -125,7 +92,7 @@ note: method defined here LL | fn foo1(&self, x: i32) -> i32 { x } | ^^^^ ----- -error: aborting due to 10 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0425. +Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0624. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/delegation/glob-non-fn.rs b/tests/ui/delegation/glob-non-fn.rs index 939c5db6a0e8f..72111fc81d7f0 100644 --- a/tests/ui/delegation/glob-non-fn.rs +++ b/tests/ui/delegation/glob-non-fn.rs @@ -31,7 +31,9 @@ impl Trait for Bad { //~ ERROR not all trait items implemented, missing: `CONST` //~| ERROR item `Type` is an associated method, which doesn't match its trait `Trait` //~| ERROR duplicate definitions with name `method` //~| ERROR expected function, found associated constant `Trait::CONST` - //~| ERROR cannot find function `Type` in trait `Trait` + //~| ERROR the trait `Trait` is not dyn compatible + //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! } fn main() {} diff --git a/tests/ui/delegation/glob-non-fn.stderr b/tests/ui/delegation/glob-non-fn.stderr index 6f7010d43d8ae..e1a4ffce5ac17 100644 --- a/tests/ui/delegation/glob-non-fn.stderr +++ b/tests/ui/delegation/glob-non-fn.stderr @@ -34,14 +34,6 @@ error[E0423]: expected function, found associated constant `Trait::CONST` LL | reuse Trait::* { &self.0 } | ^^^^^ not a function -error[E0423]: cannot find function `Type` in trait `Trait` - --> $DIR/glob-non-fn.rs:29:18 - | -LL | reuse Trait::* { &self.0 } - | ^ not found in `Trait` - | - = note: an associated type named `Trait::Type` exists in another namespace - error[E0046]: not all trait items implemented, missing: `CONST`, `Type`, `method` --> $DIR/glob-non-fn.rs:28:1 | @@ -56,7 +48,44 @@ LL | type method; LL | impl Trait for Bad { | ^^^^^^^^^^^^^^^^^^ missing `CONST`, `Type`, `method` in implementation -error: aborting due to 6 previous errors +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/glob-non-fn.rs:29:11 + | +LL | reuse Trait::* { &self.0 } + | ^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | reuse ::* { &self.0 } + | ++++ + + +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/glob-non-fn.rs:29:11 + | +LL | reuse Trait::* { &self.0 } + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/glob-non-fn.rs:5:11 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | fn method(&self); +LL | const CONST: u8; + | ^^^^^ ...because it contains associated const `CONST` + = help: consider moving `CONST` to another trait + = help: the following types implement `Trait`: + u8 + Good + Bad + consider defining an enum where each variant holds one of these types, + implementing `Trait` for this new enum and using it instead + +error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0046, E0201, E0324, E0423. -For more information about an error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0038, E0046, E0201, E0324, E0423. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/delegation/impl-reuse-non-reuse-items.rs b/tests/ui/delegation/impl-reuse-non-reuse-items.rs index 23c22a61cbb0a..517e2b26a36f9 100644 --- a/tests/ui/delegation/impl-reuse-non-reuse-items.rs +++ b/tests/ui/delegation/impl-reuse-non-reuse-items.rs @@ -23,9 +23,11 @@ mod non_delegatable_items { //~^ ERROR item `CONST` is an associated method, which doesn't match its trait `Trait` //~| ERROR item `Type` is an associated method, which doesn't match its trait `Trait` //~| ERROR duplicate definitions with name `method` - //~| ERROR expected function, found associated constant `Trait::CONST` - //~| ERROR cannot find function `Type` in trait `Trait` //~| ERROR not all trait items implemented, missing: `CONST`, `Type`, `method` + //~| ERROR expected function, found associated constant `Trait::CONST` + //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| ERROR the trait `non_delegatable_items::Trait` is not dyn compatible } fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-reuse-items.stderr b/tests/ui/delegation/impl-reuse-non-reuse-items.stderr index 2bd488e9fb3d8..2a33982cc6730 100644 --- a/tests/ui/delegation/impl-reuse-non-reuse-items.stderr +++ b/tests/ui/delegation/impl-reuse-non-reuse-items.stderr @@ -34,14 +34,6 @@ error[E0423]: expected function, found associated constant `Trait::CONST` LL | reuse impl Trait for S { &self.0 } | ^^^^^ not a function -error[E0423]: cannot find function `Type` in trait `Trait` - --> $DIR/impl-reuse-non-reuse-items.rs:22:5 - | -LL | reuse impl Trait for S { &self.0 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `Trait` - | - = note: an associated type named `Trait::Type` exists in another namespace - error[E0046]: not all trait items implemented, missing: `CONST`, `Type`, `method` --> $DIR/impl-reuse-non-reuse-items.rs:22:5 | @@ -56,7 +48,43 @@ LL | type method; LL | reuse impl Trait for S { &self.0 } | ^^^^^^^^^^^^^^^^^^^^^^ missing `CONST`, `Type`, `method` in implementation -error: aborting due to 6 previous errors +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/impl-reuse-non-reuse-items.rs:22:16 + | +LL | reuse impl Trait for S { &self.0 } + | ^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | reuse impl for S { &self.0 } + | ++++ + + +error[E0038]: the trait `non_delegatable_items::Trait` is not dyn compatible + --> $DIR/impl-reuse-non-reuse-items.rs:22:16 + | +LL | reuse impl Trait for S { &self.0 } + | ^^^^^ `non_delegatable_items::Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/impl-reuse-non-reuse-items.rs:6:15 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | fn method(&self); +LL | const CONST: u8; + | ^^^^^ ...because it contains associated const `CONST` + = help: consider moving `CONST` to another trait + = help: the following types implement `non_delegatable_items::Trait`: + non_delegatable_items::F + non_delegatable_items::S + consider defining an enum where each variant holds one of these types, + implementing `non_delegatable_items::Trait` for this new enum and using it instead + +error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0046, E0201, E0324, E0423. -For more information about an error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0038, E0046, E0201, E0324, E0423. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/delegation/inherent-impls-ambig.rs b/tests/ui/delegation/inherent-impls-ambig.rs index 1c419034d2446..1b7c9a6fcef0f 100644 --- a/tests/ui/delegation/inherent-impls-ambig.rs +++ b/tests/ui/delegation/inherent-impls-ambig.rs @@ -14,16 +14,19 @@ mod test_1 { } reuse X::foo; - //~^ ERROR: cannot find function `foo` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function + //~| ERROR: multiple applicable items in scope [E0034] reuse X::foo_self; - //~^ ERROR: cannot find function `foo_self` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function + //~| ERROR: multiple applicable items in scope [E0034] reuse X::<()>::foo as foo1; - //~^ ERROR: cannot find function `foo` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function reuse X::::foo_self as foo_self1; - //~^ ERROR: cannot find function `foo_self` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function + //~| ERROR: this function takes 1 argument but 0 arguments were supplied } mod test_2 { @@ -47,16 +50,19 @@ mod test_2 { impl Marker2 for M2 {} reuse X::foo; - //~^ ERROR: cannot find function `foo` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function + //~| ERROR: multiple applicable items in scope [E0034] reuse X::foo_self; - //~^ ERROR: cannot find function `foo_self` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function + //~| ERROR: multiple applicable items in scope [E0034] reuse X::::foo as foo1; - //~^ ERROR: cannot find function `foo` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function reuse X::::foo_self as foo_self1; - //~^ ERROR: cannot find function `foo_self` in `X` + //~^ ERROR: ambiguous delegation to inherent impl function + //~| ERROR: no associated function or constant named `foo_self` found for struct `test_2::X` in the current scope } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-ambig.stderr b/tests/ui/delegation/inherent-impls-ambig.stderr index 0be82bcdd6f74..a15fc0f2af268 100644 --- a/tests/ui/delegation/inherent-impls-ambig.stderr +++ b/tests/ui/delegation/inherent-impls-ambig.stderr @@ -1,99 +1,145 @@ -error[E0425]: cannot find function `foo` in `X` +error: ambiguous delegation to inherent impl function --> $DIR/inherent-impls-ambig.rs:16:14 | LL | reuse X::foo; - | ^^^ not found in `X` - | -note: function `test_2::foo` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:49:5 - | -LL | reuse X::foo; - | ^^^^^^^^^^^^^ not accessible + | ^^^ -error[E0425]: cannot find function `foo_self` in `X` - --> $DIR/inherent-impls-ambig.rs:19:14 - | -LL | reuse X::foo_self; - | ^^^^^^^^ not found in `X` - | -note: function `test_2::foo_self` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:52:5 +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:20:14 | LL | reuse X::foo_self; - | ^^^^^^^^^^^^^^^^^^ not accessible + | ^^^^^^^^ -error[E0425]: cannot find function `foo` in `X` - --> $DIR/inherent-impls-ambig.rs:22:20 +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:24:20 | LL | reuse X::<()>::foo as foo1; - | ^^^ not found in `X` + | ^^^ + +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:27:23 | -note: function `test_2::foo` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:49:5 +LL | reuse X::::foo_self as foo_self1; + | ^^^^^^^^ + +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:52:14 | LL | reuse X::foo; - | ^^^^^^^^^^^^^ not accessible + | ^^^ -error[E0425]: cannot find function `foo_self` in `X` - --> $DIR/inherent-impls-ambig.rs:25:23 +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:56:14 | -LL | reuse X::::foo_self as foo_self1; - | ^^^^^^^^ not found in `X` +LL | reuse X::foo_self; + | ^^^^^^^^ + +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:60:27 | -note: function `test_2::foo_self` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:52:5 +LL | reuse X::::foo as foo1; + | ^^^ + +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-ambig.rs:63:28 | -LL | reuse X::foo_self; - | ^^^^^^^^^^^^^^^^^^ not accessible +LL | reuse X::::foo_self as foo_self1; + | ^^^^^^^^ -error[E0425]: cannot find function `foo` in `X` - --> $DIR/inherent-impls-ambig.rs:49:14 +error[E0034]: multiple applicable items in scope + --> $DIR/inherent-impls-ambig.rs:16:14 | LL | reuse X::foo; - | ^^^ not found in `X` + | ^^^ multiple `foo` found | -note: function `test_1::foo` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:16:5 +note: candidate #1 is defined in an impl for the type `test_1::X<()>` + --> $DIR/inherent-impls-ambig.rs:7:9 | -LL | reuse X::foo; - | ^^^^^^^^^^^^^ not accessible +LL | fn foo() {} + | ^^^^^^^^ +note: candidate #2 is defined in an impl for the type `test_1::X` + --> $DIR/inherent-impls-ambig.rs:12:9 + | +LL | fn foo() {} + | ^^^^^^^^ -error[E0425]: cannot find function `foo_self` in `X` - --> $DIR/inherent-impls-ambig.rs:52:14 +error[E0034]: multiple applicable items in scope + --> $DIR/inherent-impls-ambig.rs:20:14 | LL | reuse X::foo_self; - | ^^^^^^^^ not found in `X` + | ^^^^^^^^ multiple `foo_self` found | -note: function `test_1::foo_self` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:19:5 +note: candidate #1 is defined in an impl for the type `test_1::X<()>` + --> $DIR/inherent-impls-ambig.rs:8:9 | -LL | reuse X::foo_self; - | ^^^^^^^^^^^^^^^^^^ not accessible +LL | fn foo_self(self) {} + | ^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `test_1::X` + --> $DIR/inherent-impls-ambig.rs:13:9 + | +LL | fn foo_self(self) {} + | ^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find function `foo` in `X` - --> $DIR/inherent-impls-ambig.rs:55:27 +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-ambig.rs:27:23 | -LL | reuse X::::foo as foo1; - | ^^^ not found in `X` +LL | reuse X::::foo_self as foo_self1; + | ^^^^^^^^ argument #1 of type `test_1::X` is missing | -note: function `test_1::foo` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:16:5 +note: method defined here + --> $DIR/inherent-impls-ambig.rs:13:12 | -LL | reuse X::foo; - | ^^^^^^^^^^^^^ not accessible +LL | fn foo_self(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse X::::foo_self(/* X */) as foo_self1; + | ++++++++++++++++ -error[E0425]: cannot find function `foo_self` in `X` - --> $DIR/inherent-impls-ambig.rs:58:28 +error[E0034]: multiple applicable items in scope + --> $DIR/inherent-impls-ambig.rs:52:14 | -LL | reuse X::::foo_self as foo_self1; - | ^^^^^^^^ not found in `X` +LL | reuse X::foo; + | ^^^ multiple `foo` found | -note: function `test_1::foo_self` exists but is inaccessible - --> $DIR/inherent-impls-ambig.rs:19:5 +note: candidate #1 is defined in an impl for the type `test_2::X` + --> $DIR/inherent-impls-ambig.rs:43:9 + | +LL | fn foo() {} + | ^^^^^^^^ +note: candidate #2 is defined in an impl for the type `test_2::X` + --> $DIR/inherent-impls-ambig.rs:38:9 + | +LL | fn foo() {} + | ^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/inherent-impls-ambig.rs:56:14 | LL | reuse X::foo_self; - | ^^^^^^^^^^^^^^^^^^ not accessible + | ^^^^^^^^ multiple `foo_self` found + | +note: candidate #1 is defined in an impl for the type `test_2::X` + --> $DIR/inherent-impls-ambig.rs:44:9 + | +LL | fn foo_self(self) {} + | ^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `test_2::X` + --> $DIR/inherent-impls-ambig.rs:39:9 + | +LL | fn foo_self(self) {} + | ^^^^^^^^^^^^^^^^^ + +error[E0599]: no associated function or constant named `foo_self` found for struct `test_2::X` in the current scope + --> $DIR/inherent-impls-ambig.rs:63:28 + | +LL | struct X(T, U); + | -------------- associated function or constant `foo_self` not found for this struct +... +LL | reuse X::::foo_self as foo_self1; + | ^^^^^^^^ associated function or constant not found in `test_2::X` -error: aborting due to 8 previous errors +error: aborting due to 14 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0034, E0061, E0599. +For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/delegation/inherent-impls-enums.rs b/tests/ui/delegation/inherent-impls-enums.rs index 301cbe32b6f88..e8c7ba891b5ef 100644 --- a/tests/ui/delegation/inherent-impls-enums.rs +++ b/tests/ui/delegation/inherent-impls-enums.rs @@ -11,80 +11,58 @@ impl<'a, 'b, 'c, A: 'a, const C: usize> S<'a, A, C> { } reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; -//~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static as foo_static_3; -//~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; -//~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1; -//~^ ERROR: cannot find function `foo_self` in enum `S` reuse S::<'static, (), 1>::foo_self as foo_self_3; -//~^ ERROR: cannot find function `foo_self` in enum `S` reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; -//~^ ERROR: cannot find function `foo_self` in enum `S` trait Trait<'a, AA, BB> where Self: Sized, { reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - //~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static as foo_static_3; - //~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - //~^ ERROR: cannot find function `foo_static` in enum `S` fn get_s(self) -> S<'static, (), 1> { panic!(); } reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in enum `S` reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in enum `S` reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - //~^ ERROR: cannot find function `foo_self` in enum `S` + //~^ ERROR: mismatched types [E0308] } struct X; impl<'a, A, B> Trait<'a, A, B> for X { reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - //~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static as foo_static_3; - //~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - //~^ ERROR: cannot find function `foo_static` in enum `S` + //~^ ERROR: type annotations needed [E0284] reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in enum `S` - //~| ERROR: delegation's target expression is specified for function with no params reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in enum `S` - //~| ERROR: delegation's target expression is specified for function with no params reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - //~^ ERROR: cannot find function `foo_self` in enum `S` + //~^ ERROR: mismatched types [E0308] } impl X { reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - //~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static as foo_static_3; - //~^ ERROR: cannot find function `foo_static` in enum `S` reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - //~^ ERROR: cannot find function `foo_static` in enum `S` fn get_s(self) -> S<'static, (), 1> { panic!(); } reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in enum `S` reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in enum `S` reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - //~^ ERROR: cannot find function `foo_self` in enum `S` + //~^ ERROR: mismatched types [E0308] } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-enums.stderr b/tests/ui/delegation/inherent-impls-enums.stderr index 0016488386017..d76aba9517ee4 100644 --- a/tests/ui/delegation/inherent-impls-enums.stderr +++ b/tests/ui/delegation/inherent-impls-enums.stderr @@ -1,159 +1,70 @@ -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:13:28 - | -LL | reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:15:28 - | -LL | reuse S::<'static, (), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:17:28 - | -LL | reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:20:28 - | -LL | reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:22:28 - | -LL | reuse S::<'static, (), 1>::foo_self as foo_self_3; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:24:28 - | -LL | reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:31:32 - | -LL | reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:33:32 - | -LL | reuse S::<'static, (), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` +error[E0308]: mismatched types --> $DIR/inherent-impls-enums.rs:35:32 | -LL | reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:42:32 - | -LL | reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:44:32 - | -LL | reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:46:32 - | +LL | trait Trait<'a, AA, BB> + | ----------------------- found this type parameter +... LL | reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:53:32 + | ^^^^^^^^ + | | + | expected `S<'_, (), 1>`, found type parameter `Self` + | arguments to this function are incorrect | -LL | reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:55:32 + = note: expected enum `S<'_, (), 1>` + found type parameter `Self` +note: method defined here + --> $DIR/inherent-impls-enums.rs:10:8 | -LL | reuse S::<'static, (), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:57:32 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-enums.rs:44:32 | LL | reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:60:32 + | ^^^^^^^^^^ cannot infer the value of const parameter `B` declared on the associated function `foo_static` | -LL | reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:63:32 +note: required by a const generic parameter in `S::<'a, A, C>::foo_static` + --> $DIR/inherent-impls-enums.rs:9:34 | -LL | reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^ not found in `S` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ^^^^^^^^^^^^^ required by this const generic parameter in `S::<'a, A, C>::foo_static` -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:66:32 +error[E0308]: mismatched types + --> $DIR/inherent-impls-enums.rs:49:32 | LL | reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:71:32 + | ^^^^^^^^ + | | + | expected `S<'_, (), 1>`, found `X` + | arguments to this function are incorrect | -LL | reuse S::<'static, (), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:73:32 - | -LL | reuse S::<'static, (), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in enum `S` - --> $DIR/inherent-impls-enums.rs:75:32 - | -LL | reuse S::<'static, (), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:82:32 - | -LL | reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:84:32 + = note: expected enum `S<'_, (), 1>` + found struct `X` +note: method defined here + --> $DIR/inherent-impls-enums.rs:10:8 | -LL | reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^ not found in `S` +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- -error[E0425]: cannot find function `foo_self` in enum `S` - --> $DIR/inherent-impls-enums.rs:86:32 +error[E0308]: mismatched types + --> $DIR/inherent-impls-enums.rs:64:32 | LL | reuse S::<'static, (), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-enums.rs:60:76 + | ^^^^^^^^ + | | + | expected `S<'_, (), 1>`, found `X` + | arguments to this function are incorrect | -LL | reuse S::<'static, (), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^^^^^^^^^ - -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-enums.rs:63:55 + = note: expected enum `S<'_, (), 1>` + found struct `X` +note: method defined here + --> $DIR/inherent-impls-enums.rs:10:8 | -LL | reuse S::<'static, (), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^^^^^^^^^ +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- -error: aborting due to 26 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/delegation/inherent-impls-glob-list.rs b/tests/ui/delegation/inherent-impls-glob-list.rs index 51d24e6838df0..d983711102dde 100644 --- a/tests/ui/delegation/inherent-impls-glob-list.rs +++ b/tests/ui/delegation/inherent-impls-glob-list.rs @@ -11,8 +11,6 @@ struct Y; impl Y { reuse X::{foo, foo2} { X } - //~^ ERROR: cannot find function `foo` in `X` - //~| ERROR: cannot find function `foo2` in `X` } impl Y { diff --git a/tests/ui/delegation/inherent-impls-glob-list.stderr b/tests/ui/delegation/inherent-impls-glob-list.stderr index d2dfce86f860a..7972e598e1853 100644 --- a/tests/ui/delegation/inherent-impls-glob-list.stderr +++ b/tests/ui/delegation/inherent-impls-glob-list.stderr @@ -1,21 +1,8 @@ error: expected trait, found struct `X` - --> $DIR/inherent-impls-glob-list.rs:19:11 + --> $DIR/inherent-impls-glob-list.rs:17:11 | LL | reuse X::*; | ^ not a trait -error[E0425]: cannot find function `foo` in `X` - --> $DIR/inherent-impls-glob-list.rs:13:15 - | -LL | reuse X::{foo, foo2} { X } - | ^^^ not found in `X` - -error[E0425]: cannot find function `foo2` in `X` - --> $DIR/inherent-impls-glob-list.rs:13:20 - | -LL | reuse X::{foo, foo2} { X } - | ^^^^ not found in `X` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/delegation/inherent-impls-mixed-generics.rs b/tests/ui/delegation/inherent-impls-mixed-generics.rs index 027dcace3ab0d..b24acff6187eb 100644 --- a/tests/ui/delegation/inherent-impls-mixed-generics.rs +++ b/tests/ui/delegation/inherent-impls-mixed-generics.rs @@ -10,7 +10,8 @@ impl<'a, 'b, 'c, A, const C: usize> S<'static, A, usize, C> { trait Trait<'a, AA, BB> where Self: Sized { reuse S::foo_self; - //~^ ERROR: cannot find function `foo_self` in `S` + //~^ ERROR: delegation to inherent impl must contain parent generics + //~| ERROR: this function takes 1 argument but 0 arguments were supplied } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-mixed-generics.stderr b/tests/ui/delegation/inherent-impls-mixed-generics.stderr index f515b52ca45ab..f730d5360eef7 100644 --- a/tests/ui/delegation/inherent-impls-mixed-generics.stderr +++ b/tests/ui/delegation/inherent-impls-mixed-generics.stderr @@ -1,9 +1,25 @@ -error[E0425]: cannot find function `foo_self` in `S` +error: delegation to inherent impl must contain parent generics --> $DIR/inherent-impls-mixed-generics.rs:12:14 | LL | reuse S::foo_self; - | ^^^^^^^^ not found in `S` + | ^^^^^^^^ -error: aborting due to 1 previous error +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-mixed-generics.rs:12:14 + | +LL | reuse S::foo_self; + | ^^^^^^^^ argument #1 of type `S<'static, _, usize, _>` is missing + | +note: method defined here + --> $DIR/inherent-impls-mixed-generics.rs:8:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse S::foo_self(/* value */); + | +++++++++++++ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/inherent-impls-non-local-crate.rs b/tests/ui/delegation/inherent-impls-non-local-crate.rs index c2f07fd8e7ae7..27b8d387a7e63 100644 --- a/tests/ui/delegation/inherent-impls-non-local-crate.rs +++ b/tests/ui/delegation/inherent-impls-non-local-crate.rs @@ -3,23 +3,21 @@ #![feature(fn_delegation)] reuse inherent_impl::S::foo; -//~^ ERROR: cannot find function `foo` in `inherent_impl::S` reuse inherent_impl::S::not_existing; -//~^ ERROR: cannot find function `not_existing` in `inherent_impl::S` - +//~^ ERROR: no associated function or constant named `not_existing` found for struct `S` in the current scope reuse inherent_impl::S::TYPE; -//~^ ERROR: cannot find function `TYPE` in `inherent_impl::S` - +//~^ ERROR: no associated function or constant named `TYPE` found for struct `S` in the current scope reuse inherent_impl::S::CONST; -//~^ ERROR: cannot find function `CONST` in `inherent_impl::S` +//~^ ERROR: expected function, found `usize` [E0618] reuse inherent_impl::S::bar; -//~^ ERROR: cannot find function `bar` in `inherent_impl::S` +//~^ ERROR: no associated function or constant named `bar` found for struct `S` in the current scope reuse ::bar as trait_bar; reuse inherent_impl::X::foo as x_foo; -//~^ ERROR: cannot find function `foo` in `inherent_impl::X` +//~^ ERROR: ambiguous delegation to inherent impl function +//~| ERROR: multiple applicable items in scope fn main() {} diff --git a/tests/ui/delegation/inherent-impls-non-local-crate.stderr b/tests/ui/delegation/inherent-impls-non-local-crate.stderr index 983c8b8f3cb9b..31358b1d7144e 100644 --- a/tests/ui/delegation/inherent-impls-non-local-crate.stderr +++ b/tests/ui/delegation/inherent-impls-non-local-crate.stderr @@ -1,39 +1,49 @@ -error[E0425]: cannot find function `foo` in `inherent_impl::S` - --> $DIR/inherent-impls-non-local-crate.rs:5:25 +error: ambiguous delegation to inherent impl function + --> $DIR/inherent-impls-non-local-crate.rs:19:25 | -LL | reuse inherent_impl::S::foo; - | ^^^ not found in `inherent_impl::S` +LL | reuse inherent_impl::X::foo as x_foo; + | ^^^ -error[E0425]: cannot find function `not_existing` in `inherent_impl::S` - --> $DIR/inherent-impls-non-local-crate.rs:8:25 +error[E0599]: no associated function or constant named `not_existing` found for struct `S` in the current scope + --> $DIR/inherent-impls-non-local-crate.rs:7:25 | LL | reuse inherent_impl::S::not_existing; - | ^^^^^^^^^^^^ not found in `inherent_impl::S` + | ^^^^^^^^^^^^ associated function or constant not found in `S` -error[E0425]: cannot find function `TYPE` in `inherent_impl::S` - --> $DIR/inherent-impls-non-local-crate.rs:11:25 +error[E0599]: no associated function or constant named `TYPE` found for struct `S` in the current scope + --> $DIR/inherent-impls-non-local-crate.rs:9:25 | LL | reuse inherent_impl::S::TYPE; - | ^^^^ not found in `inherent_impl::S` + | ^^^^ associated function or constant not found in `S` -error[E0425]: cannot find function `CONST` in `inherent_impl::S` - --> $DIR/inherent-impls-non-local-crate.rs:14:25 +error[E0618]: expected function, found `usize` + --> $DIR/inherent-impls-non-local-crate.rs:11:25 | LL | reuse inherent_impl::S::CONST; - | ^^^^^ not found in `inherent_impl::S` + | ^^^^^ call expression requires function -error[E0425]: cannot find function `bar` in `inherent_impl::S` - --> $DIR/inherent-impls-non-local-crate.rs:17:25 +error[E0599]: no associated function or constant named `bar` found for struct `S` in the current scope + --> $DIR/inherent-impls-non-local-crate.rs:14:25 | LL | reuse inherent_impl::S::bar; - | ^^^ not found in `inherent_impl::S` + | ^^^ associated function or constant not found in `S` + | + = help: items from traits can only be used if the trait is in scope +help: trait `Trait` which provides `bar` is implemented but not in scope; perhaps you want to import it + | +LL + use inherent_impl::Trait; + | -error[E0425]: cannot find function `foo` in `inherent_impl::X` - --> $DIR/inherent-impls-non-local-crate.rs:22:25 +error[E0034]: multiple applicable items in scope + --> $DIR/inherent-impls-non-local-crate.rs:19:25 | LL | reuse inherent_impl::X::foo as x_foo; - | ^^^ not found in `inherent_impl::X` + | ^^^ multiple `foo` found + | + = note: candidate #1 is defined in an impl for the type `X` + = note: candidate #2 is defined in an impl for the type `X` error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0034, E0599, E0618. +For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/delegation/inherent-impls-parent-generics.rs b/tests/ui/delegation/inherent-impls-parent-generics.rs index 0f95540643bd7..1c303e16a0272 100644 --- a/tests/ui/delegation/inherent-impls-parent-generics.rs +++ b/tests/ui/delegation/inherent-impls-parent-generics.rs @@ -12,32 +12,36 @@ impl<'a, 'b, 'c, A: 'a, const C: usize> E<'a, A, C> { } reuse E::foo_static as e; -//~^ ERROR: cannot find function `foo_static` in enum `E` - +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed reuse E::foo_self as e1; -//~^ ERROR: cannot find function `foo_self` in enum `E` +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: this function takes 1 argument but 0 arguments were supplied reuse E::foo_static::<'static, (), true> as e2; -//~^ ERROR: cannot find function `foo_static` in enum `E` - +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed reuse E::foo_self::<'static, (), true> as e3; -//~^ ERROR: cannot find function `foo_self` in enum `E` +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: this function takes 1 argument but 0 arguments were supplied reuse E::<'static, (), 123>::foo_static as e4; -//~^ ERROR: cannot find function `foo_static` in enum `E` reuse E::<'static, (), 123>::foo_self as e5; -//~^ ERROR: cannot find function `foo_self` in enum `E` reuse E::<'static, (), 123>::foo_static::<'static, (), true> as e6; -//~^ ERROR: cannot find function `foo_static` in enum `E` reuse E::<'static, (), 123>::foo_self::<'static, (), true> as e7; -//~^ ERROR: cannot find function `foo_self` in enum `E` reuse E::<'_, (), _>::foo_static as e8; -//~^ ERROR: cannot find function `foo_static` in enum `E` - +//~^ ERROR: parent segment of delegation to inherent impl can not contain infers +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed reuse E::<'_, _, _>::foo_self as e9; -//~^ ERROR: cannot find function `foo_self` in enum `E` +//~^ ERROR: parent segment of delegation to inherent impl can not contain infers +//~| ERROR: this function takes 1 argument but 0 arguments were supplied struct S { xd: [A; C], @@ -49,32 +53,35 @@ impl<'a, 'b, 'c, A, const C: usize> S { } reuse S::foo_static as s; -//~^ ERROR: cannot find function `foo_static` in `S` - +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed reuse S::foo_self as s1; -//~^ ERROR: cannot find function `foo_self` in `S` +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: this function takes 1 argument but 0 arguments were supplied reuse S::foo_static::<'static, (), true> as s2; -//~^ ERROR: cannot find function `foo_static` in `S` - +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed reuse S::foo_self::<'static, (), true> as s3; -//~^ ERROR: cannot find function `foo_self` in `S` +//~^ ERROR: delegation to inherent impl must contain parent generics +//~| ERROR: this function takes 1 argument but 0 arguments were supplied reuse S::<(), 123>::foo_static as s4; -//~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 123>::foo_self as s5; -//~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), 123>::foo_static::<'static, (), true> as s6; -//~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 123>::foo_self::<'static, (), true> as s7; -//~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), _>::foo_static as s8; -//~^ ERROR: cannot find function `foo_static` in `S` - +//~^ ERROR: parent segment of delegation to inherent impl can not contain infers +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed +//~| ERROR: type annotations needed reuse S::<_, 123>::foo_self as s9; -//~^ ERROR: cannot find function `foo_self` in `S` - +//~^ ERROR: parent segment of delegation to inherent impl can not contain infers +//~| ERROR: this function takes 1 argument but 0 arguments were supplied fn main() {} diff --git a/tests/ui/delegation/inherent-impls-parent-generics.stderr b/tests/ui/delegation/inherent-impls-parent-generics.stderr index 508ca65316457..b1001e193a9cd 100644 --- a/tests/ui/delegation/inherent-impls-parent-generics.stderr +++ b/tests/ui/delegation/inherent-impls-parent-generics.stderr @@ -1,123 +1,440 @@ -error[E0425]: cannot find function `foo_static` in enum `E` +error: delegation to inherent impl must contain parent generics --> $DIR/inherent-impls-parent-generics.rs:14:10 | LL | reuse E::foo_static as e; - | ^^^^^^^^^^ not found in `E` + | ^^^^^^^^^^ -error[E0425]: cannot find function `foo_self` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:17:10 +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:19:10 | LL | reuse E::foo_self as e1; - | ^^^^^^^^ not found in `E` + | ^^^^^^^^ -error[E0425]: cannot find function `foo_static` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:20:10 +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:23:10 | LL | reuse E::foo_static::<'static, (), true> as e2; - | ^^^^^^^^^^ not found in `E` + | ^^^^^^^^^^ -error[E0425]: cannot find function `foo_self` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:23:10 +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:27:10 | LL | reuse E::foo_self::<'static, (), true> as e3; - | ^^^^^^^^ not found in `E` + | ^^^^^^^^ + +error: parent segment of delegation to inherent impl can not contain infers + --> $DIR/inherent-impls-parent-generics.rs:37:23 + | +LL | reuse E::<'_, (), _>::foo_static as e8; + | ^^^^^^^^^^ -error[E0425]: cannot find function `foo_static` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:26:30 +error: parent segment of delegation to inherent impl can not contain infers + --> $DIR/inherent-impls-parent-generics.rs:42:22 + | +LL | reuse E::<'_, _, _>::foo_self as e9; + | ^^^^^^^^ + +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:55:10 + | +LL | reuse S::foo_static as s; + | ^^^^^^^^^^ + +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:60:10 + | +LL | reuse S::foo_self as s1; + | ^^^^^^^^ + +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:64:10 + | +LL | reuse S::foo_static::<'static, (), true> as s2; + | ^^^^^^^^^^ + +error: delegation to inherent impl must contain parent generics + --> $DIR/inherent-impls-parent-generics.rs:68:10 + | +LL | reuse S::foo_self::<'static, (), true> as s3; + | ^^^^^^^^ + +error: parent segment of delegation to inherent impl can not contain infers + --> $DIR/inherent-impls-parent-generics.rs:78:19 + | +LL | reuse S::<(), _>::foo_static as s8; + | ^^^^^^^^^^ + +error: parent segment of delegation to inherent impl can not contain infers + --> $DIR/inherent-impls-parent-generics.rs:83:20 + | +LL | reuse S::<_, 123>::foo_self as s9; + | ^^^^^^^^ + +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:14:10 + | +LL | reuse E::foo_static as e; + | - ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the enum `E` + | | + | type must be known at this point + | +note: required by a const generic parameter in `E` + --> $DIR/inherent-impls-parent-generics.rs:4:23 + | +LL | enum E<'a: 'a, A: 'a, const C: usize> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `E` +help: consider specifying the generic arguments + | +LL - reuse E::foo_static as e; +LL + reuse E:: as e; + | + +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:14:10 + | +LL | reuse E::foo_static as e; + | ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the enum `E` + | +note: required by a const generic parameter in `E::<'a, A, C>::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:9:25 + | +LL | impl<'a, 'b, 'c, A: 'a, const C: usize> E<'a, A, C> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `E::<'a, A, C>::foo_static` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ---------- required by a bound in this associated function +help: consider specifying the generic arguments + | +LL - reuse E::foo_static as e; +LL + reuse E:: as e; + | + +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:14:10 + | +LL | reuse E::foo_static as e; + | ^^^^^^^^^^ cannot infer the value of the const parameter `B` declared on the associated function `foo_static` + | +note: required by a const generic parameter in `E::<'a, A, C>::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:10:34 + | +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ^^^^^^^^^^^^^ required by this const generic parameter in `E::<'a, A, C>::foo_static` +help: consider specifying the generic arguments + | +LL | reuse E::foo_static:: as e; + | ++++++++ + +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-parent-generics.rs:19:10 + | +LL | reuse E::foo_self as e1; + | ^^^^^^^^ argument #1 of type `E<'_, _, _>` is missing + | +note: method defined here + --> $DIR/inherent-impls-parent-generics.rs:11:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse E::foo_self(/* value */) as e1; + | +++++++++++++ + +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:23:10 + | +LL | reuse E::foo_static::<'static, (), true> as e2; + | - ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the enum `E` + | | + | type must be known at this point + | +note: required by a const generic parameter in `E` + --> $DIR/inherent-impls-parent-generics.rs:4:23 + | +LL | enum E<'a: 'a, A: 'a, const C: usize> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `E` +help: consider specifying the generic arguments + | +LL - reuse E::foo_static::<'static, (), true> as e2; +LL + reuse E:: as e2; + | + +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:23:10 + | +LL | reuse E::foo_static::<'static, (), true> as e2; + | ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the enum `E` + | +note: required by a const generic parameter in `E::<'a, A, C>::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:9:25 + | +LL | impl<'a, 'b, 'c, A: 'a, const C: usize> E<'a, A, C> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `E::<'a, A, C>::foo_static` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ---------- required by a bound in this associated function +help: consider specifying the generic arguments + | +LL - reuse E::foo_static::<'static, (), true> as e2; +LL + reuse E:: as e2; | -LL | reuse E::<'static, (), 123>::foo_static as e4; - | ^^^^^^^^^^ not found in `E` -error[E0425]: cannot find function `foo_self` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:28:30 +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-parent-generics.rs:27:10 + | +LL | reuse E::foo_self::<'static, (), true> as e3; + | ^^^^^^^^ argument #1 of type `E<'_, _, _>` is missing + | +note: method defined here + --> $DIR/inherent-impls-parent-generics.rs:11:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument | -LL | reuse E::<'static, (), 123>::foo_self as e5; - | ^^^^^^^^ not found in `E` +LL | reuse E::foo_self(/* value */)::<'static, (), true> as e3; + | +++++++++++++ -error[E0425]: cannot find function `foo_static` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:31:30 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:37:23 | -LL | reuse E::<'static, (), 123>::foo_static::<'static, (), true> as e6; - | ^^^^^^^^^^ not found in `E` +LL | reuse E::<'_, (), _>::foo_static as e8; + | -------------- ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the enum `E` + | | + | type must be known at this point + | +note: required by a const generic parameter in `E` + --> $DIR/inherent-impls-parent-generics.rs:4:23 + | +LL | enum E<'a: 'a, A: 'a, const C: usize> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `E` -error[E0425]: cannot find function `foo_self` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:33:30 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:37:23 + | +LL | reuse E::<'_, (), _>::foo_static as e8; + | ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the enum `E` + | +note: required by a const generic parameter in `E::<'a, A, C>::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:9:25 | -LL | reuse E::<'static, (), 123>::foo_self::<'static, (), true> as e7; - | ^^^^^^^^ not found in `E` +LL | impl<'a, 'b, 'c, A: 'a, const C: usize> E<'a, A, C> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `E::<'a, A, C>::foo_static` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ---------- required by a bound in this associated function -error[E0425]: cannot find function `foo_static` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:36:23 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:37:23 | LL | reuse E::<'_, (), _>::foo_static as e8; - | ^^^^^^^^^^ not found in `E` + | ^^^^^^^^^^ cannot infer the value of the const parameter `B` declared on the associated function `foo_static` + | +note: required by a const generic parameter in `E::<'a, A, C>::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:10:34 + | +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ^^^^^^^^^^^^^ required by this const generic parameter in `E::<'a, A, C>::foo_static` +help: consider specifying the generic arguments + | +LL | reuse E::<'_, (), _>::foo_static:: as e8; + | ++++++++ -error[E0425]: cannot find function `foo_self` in enum `E` - --> $DIR/inherent-impls-parent-generics.rs:39:22 +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-parent-generics.rs:42:22 | LL | reuse E::<'_, _, _>::foo_self as e9; - | ^^^^^^^^ not found in `E` + | ^^^^^^^^ argument #1 of type `E<'_, _, _>` is missing + | +note: method defined here + --> $DIR/inherent-impls-parent-generics.rs:11:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse E::<'_, _, _>::foo_self(/* value */) as e9; + | +++++++++++++ -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-parent-generics.rs:51:10 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:55:10 | LL | reuse S::foo_static as s; - | ^^^^^^^^^^ not found in `S` + | - ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the struct `S` + | | + | type must be known at this point + | +note: required by a const generic parameter in `S` + --> $DIR/inherent-impls-parent-generics.rs:46:13 + | +LL | struct S { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `S` +help: consider specifying the generic arguments + | +LL | reuse S::::foo_static as s; + | ++++++++ -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-parent-generics.rs:54:10 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:55:10 | -LL | reuse S::foo_self as s1; - | ^^^^^^^^ not found in `S` +LL | reuse S::foo_static as s; + | ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the struct `S` + | +note: required by a const generic parameter in `S::::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:50:21 + | +LL | impl<'a, 'b, 'c, A, const C: usize> S { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `S::::foo_static` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ---------- required by a bound in this associated function +help: consider specifying the generic arguments + | +LL | reuse S::::foo_static as s; + | ++++++++ -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-parent-generics.rs:57:10 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:55:10 | -LL | reuse S::foo_static::<'static, (), true> as s2; - | ^^^^^^^^^^ not found in `S` +LL | reuse S::foo_static as s; + | ^^^^^^^^^^ cannot infer the value of the const parameter `B` declared on the associated function `foo_static` + | +note: required by a const generic parameter in `S::::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:51:34 + | +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ^^^^^^^^^^^^^ required by this const generic parameter in `S::::foo_static` +help: consider specifying the generic arguments + | +LL | reuse S::foo_static:: as s; + | ++++++++ -error[E0425]: cannot find function `foo_self` in `S` +error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/inherent-impls-parent-generics.rs:60:10 | -LL | reuse S::foo_self::<'static, (), true> as s3; - | ^^^^^^^^ not found in `S` +LL | reuse S::foo_self as s1; + | ^^^^^^^^ argument #1 of type `S<_, _>` is missing + | +note: method defined here + --> $DIR/inherent-impls-parent-generics.rs:52:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse S::foo_self(/* value */) as s1; + | +++++++++++++ + +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:64:10 + | +LL | reuse S::foo_static::<'static, (), true> as s2; + | - ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the struct `S` + | | + | type must be known at this point + | +note: required by a const generic parameter in `S` + --> $DIR/inherent-impls-parent-generics.rs:46:13 + | +LL | struct S { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `S` +help: consider specifying the generic arguments + | +LL | reuse S::::foo_static::<'static, (), true> as s2; + | ++++++++ -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-parent-generics.rs:63:21 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:64:10 + | +LL | reuse S::foo_static::<'static, (), true> as s2; + | ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the struct `S` + | +note: required by a const generic parameter in `S::::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:50:21 + | +LL | impl<'a, 'b, 'c, A, const C: usize> S { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `S::::foo_static` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ---------- required by a bound in this associated function +help: consider specifying the generic arguments | -LL | reuse S::<(), 123>::foo_static as s4; - | ^^^^^^^^^^ not found in `S` +LL | reuse S::::foo_static::<'static, (), true> as s2; + | ++++++++ -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-parent-generics.rs:65:21 +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-parent-generics.rs:68:10 | -LL | reuse S::<(), 123>::foo_self as s5; - | ^^^^^^^^ not found in `S` +LL | reuse S::foo_self::<'static, (), true> as s3; + | ^^^^^^^^ argument #1 of type `S<_, _>` is missing + | +note: method defined here + --> $DIR/inherent-impls-parent-generics.rs:52:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse S::foo_self(/* value */)::<'static, (), true> as s3; + | +++++++++++++ -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-parent-generics.rs:68:21 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:78:19 | -LL | reuse S::<(), 123>::foo_static::<'static, (), true> as s6; - | ^^^^^^^^^^ not found in `S` +LL | reuse S::<(), _>::foo_static as s8; + | ---------- ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the struct `S` + | | + | type must be known at this point + | +note: required by a const generic parameter in `S` + --> $DIR/inherent-impls-parent-generics.rs:46:13 + | +LL | struct S { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `S` -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-parent-generics.rs:70:21 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:78:19 + | +LL | reuse S::<(), _>::foo_static as s8; + | ^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the struct `S` + | +note: required by a const generic parameter in `S::::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:50:21 | -LL | reuse S::<(), 123>::foo_self::<'static, (), true> as s7; - | ^^^^^^^^ not found in `S` +LL | impl<'a, 'b, 'c, A, const C: usize> S { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `S::::foo_static` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ---------- required by a bound in this associated function -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-parent-generics.rs:73:19 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-parent-generics.rs:78:19 | LL | reuse S::<(), _>::foo_static as s8; - | ^^^^^^^^^^ not found in `S` + | ^^^^^^^^^^ cannot infer the value of the const parameter `B` declared on the associated function `foo_static` + | +note: required by a const generic parameter in `S::::foo_static` + --> $DIR/inherent-impls-parent-generics.rs:51:34 + | +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ^^^^^^^^^^^^^ required by this const generic parameter in `S::::foo_static` +help: consider specifying the generic arguments + | +LL | reuse S::<(), _>::foo_static:: as s8; + | ++++++++ -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-parent-generics.rs:76:20 +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/inherent-impls-parent-generics.rs:83:20 | LL | reuse S::<_, 123>::foo_self as s9; - | ^^^^^^^^ not found in `S` + | ^^^^^^^^ argument #1 of type `S<_, 123>` is missing + | +note: method defined here + --> $DIR/inherent-impls-parent-generics.rs:52:8 + | +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- +help: provide the argument + | +LL | reuse S::<_, 123>::foo_self(/* value */) as s9; + | +++++++++++++ -error: aborting due to 20 previous errors +error: aborting due to 34 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0061, E0284. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/inherent-impls-receiver-mapping.rs b/tests/ui/delegation/inherent-impls-receiver-mapping.rs index 05a9c350af746..d4678134e5de1 100644 --- a/tests/ui/delegation/inherent-impls-receiver-mapping.rs +++ b/tests/ui/delegation/inherent-impls-receiver-mapping.rs @@ -15,36 +15,27 @@ mod receiver_mapping { impl Y { fn get_x(&self) -> X { X } reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - //~^ ERROR: cannot find function `by_mut_ref` in `X` - //~| ERROR: cannot find function `by_ref` in `X` - //~| ERROR: cannot find function `by_value` in `X` - //~| ERROR: cannot find function `static_f` in `X` } fn check() { let y = Y; y.by_ref(); - //~^ ERROR: no method named `by_ref` found for struct `Y` in the current scope y.by_mut_ref(); - //~^ ERROR: no method named `by_mut_ref` found for struct `Y` in the current scope + //~^ ERROR: cannot borrow `y` as mutable, as it is not declared as mutable y.by_value(); - //~^ ERROR: no method named `by_value` found for struct `Y` in the current scope let y = &Y; y.by_value(); - //~^ ERROR: no method named `by_value` found for reference `&Y` in the current scope + //~^ ERROR: cannot move out of `*y` which is behind a shared reference y.by_ref(); - //~^ ERROR: no method named `by_ref` found for reference `&Y` in the current scope y.by_mut_ref(); - //~^ ERROR: no method named `by_mut_ref` found for reference `&Y` in the current scope + //~^ ERROR: cannot borrow `*y` as mutable, as it is behind a `&` reference let y = &mut Y; y.by_value(); - //~^ ERROR: no method named `by_value` found for mutable reference `&mut Y` in the current scope + //~^ ERROR: cannot move out of `*y` which is behind a mutable reference y.by_ref(); - //~^ ERROR: the method `by_ref` exists for mutable reference `&mut Y`, but its trait bounds were not satisfied y.by_mut_ref(); - //~^ ERROR: no method named `by_mut_ref` found for mutable reference `&mut Y` in the current scope } } @@ -59,12 +50,12 @@ mod self_type_mapping { struct W(X); impl W { reuse X::add { self.0 } - //~^ ERROR: cannot find function `add` in `X` + //~^ ERROR: mismatched types + //~| ERROR: mismatched types } fn check() { W(X).add(W(X)); - //~^ ERROR: no method named `add` found for struct `W` in the current scope } } diff --git a/tests/ui/delegation/inherent-impls-receiver-mapping.stderr b/tests/ui/delegation/inherent-impls-receiver-mapping.stderr index 92baa5ff53ed0..60982076f4acd 100644 --- a/tests/ui/delegation/inherent-impls-receiver-mapping.stderr +++ b/tests/ui/delegation/inherent-impls-receiver-mapping.stderr @@ -1,256 +1,90 @@ -error[E0425]: cannot find function `static_f` in `X` - --> $DIR/inherent-impls-receiver-mapping.rs:17:19 +error[E0308]: mismatched types + --> $DIR/inherent-impls-receiver-mapping.rs:52:18 | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^ not found in `X` - -error[E0425]: cannot find function `by_value` in `X` - --> $DIR/inherent-impls-receiver-mapping.rs:17:29 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^ not found in `X` - -error[E0425]: cannot find function `by_ref` in `X` - --> $DIR/inherent-impls-receiver-mapping.rs:17:39 +LL | reuse X::add { self.0 } + | ^^^ + | | + | expected `X`, found `W` + | arguments to this function are incorrect | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^ not found in `X` - -error[E0425]: cannot find function `by_mut_ref` in `X` - --> $DIR/inherent-impls-receiver-mapping.rs:17:47 +note: method defined here + --> $DIR/inherent-impls-receiver-mapping.rs:45:12 | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^^^ not found in `X` +LL | fn add(self, other: Self) -> Self { + | ^^^ ----------- -error[E0425]: cannot find function `add` in `X` - --> $DIR/inherent-impls-receiver-mapping.rs:61:18 +error[E0308]: mismatched types + --> $DIR/inherent-impls-receiver-mapping.rs:52:18 | LL | reuse X::add { self.0 } - | ^^^ not found in `X` - -error[E0599]: no method named `by_ref` found for struct `Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:26:11 - | -LL | struct Y; - | -------- method `by_ref` not found for this struct -... -LL | y.by_ref(); - | ^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:39 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^ - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following traits define an item `by_ref`, perhaps you need to implement one of them: - candidate #1: `Iterator` - candidate #2: `std::io::Read` - candidate #3: `std::io::Write` -help: use associated function syntax instead + | ^^^ + | | + | expected `W`, found `X` + | expected `W` because of return type | -LL - y.by_ref(); -LL + Y::by_ref(); +help: try wrapping the expression in `self_type_mapping::W` | +LL | reuse X::self_type_mapping::W(add) { self.0 } + | +++++++++++++++++++++ + -error[E0599]: no method named `by_mut_ref` found for struct `Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:28:11 +error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable + --> $DIR/inherent-impls-receiver-mapping.rs:23:9 | -LL | struct Y; - | -------- method `by_mut_ref` not found for this struct -... LL | y.by_mut_ref(); - | ^^^^^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:47 + | ^ cannot borrow as mutable | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^^^ -help: use associated function syntax instead - | -LL - y.by_mut_ref(); -LL + Y::by_mut_ref(); +help: consider changing this to be mutable | +LL | let mut y = Y; + | +++ -error[E0599]: no method named `by_value` found for struct `Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:30:11 +error[E0507]: cannot move out of `*y` which is behind a shared reference + --> $DIR/inherent-impls-receiver-mapping.rs:28:9 | -LL | struct Y; - | -------- method `by_value` not found for this struct -... LL | y.by_value(); - | ^^^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:29 + | ^ ---------- `*y` moved due to this method call + | | + | move occurs because `*y` has type `Y`, which does not implement the `Copy` trait | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^ -help: use associated function syntax instead - | -LL - y.by_value(); -LL + Y::by_value(); - | - -error[E0599]: no method named `by_value` found for reference `&Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:34:11 + = note: `receiver_mapping::Y::by_value` takes ownership of the receiver `self`, which moves `*y` +note: if `Y` implemented `Clone`, you could clone the value + --> $DIR/inherent-impls-receiver-mapping.rs:13:5 | +LL | struct Y; + | ^^^^^^^^ consider implementing `Clone` for this type +... LL | y.by_value(); - | ^^^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:29 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^ -help: use associated function syntax instead - | -LL - y.by_value(); -LL + Y::by_value(); - | + | - you could clone this value -error[E0599]: no method named `by_ref` found for reference `&Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:36:11 - | -LL | y.by_ref(); - | ^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:39 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^ - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following traits define an item `by_ref`, perhaps you need to implement one of them: - candidate #1: `std::io::Read` - candidate #2: `std::io::Write` - = note: the trait `Iterator` defines an item `by_ref`, but is explicitly unimplemented -help: use associated function syntax instead - | -LL - y.by_ref(); -LL + Y::by_ref(); - | - -error[E0599]: no method named `by_mut_ref` found for reference `&Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:38:11 +error[E0596]: cannot borrow `*y` as mutable, as it is behind a `&` reference + --> $DIR/inherent-impls-receiver-mapping.rs:31:9 | LL | y.by_mut_ref(); - | ^^^^^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:47 + | ^ `y` is a `&` reference, so it cannot be borrowed as mutable | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^^^ -help: use associated function syntax instead - | -LL - y.by_mut_ref(); -LL + Y::by_mut_ref(); +help: consider changing this to be a mutable reference | +LL | let y = &mut Y; + | +++ -error[E0599]: no method named `by_value` found for mutable reference `&mut Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:42:11 +error[E0507]: cannot move out of `*y` which is behind a mutable reference + --> $DIR/inherent-impls-receiver-mapping.rs:35:9 | LL | y.by_value(); - | ^^^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:29 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^ -help: use associated function syntax instead - | -LL - y.by_value(); -LL + Y::by_value(); + | ^ ---------- `*y` moved due to this method call + | | + | move occurs because `*y` has type `Y`, which does not implement the `Copy` trait | - -error[E0599]: the method `by_ref` exists for mutable reference `&mut Y`, but its trait bounds were not satisfied - --> $DIR/inherent-impls-receiver-mapping.rs:44:11 +note: if `Y` implemented `Clone`, you could clone the value + --> $DIR/inherent-impls-receiver-mapping.rs:13:5 | LL | struct Y; - | -------- doesn't satisfy `Y: Iterator` + | ^^^^^^^^ consider implementing `Clone` for this type ... -LL | y.by_ref(); - | ^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:39 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^ - = note: the following trait bounds were not satisfied: - `Y: Iterator` - which is required by `&mut Y: Iterator` -note: the trait `Iterator` must be implemented - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following traits define an item `by_ref`, perhaps you need to implement one of them: - candidate #1: `std::io::Read` - candidate #2: `std::io::Write` - = note: the trait `Iterator` defines an item `by_ref`, but is explicitly unimplemented -help: use associated function syntax instead - | -LL - y.by_ref(); -LL + Y::by_ref(); - | - -error[E0599]: no method named `by_mut_ref` found for mutable reference `&mut Y` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:46:11 - | -LL | y.by_mut_ref(); - | ^^^^^^^^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `Y` - --> $DIR/inherent-impls-receiver-mapping.rs:17:47 - | -LL | reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() } - | ^^^^^^^^^^ -help: use associated function syntax instead - | -LL - y.by_mut_ref(); -LL + Y::by_mut_ref(); - | - -error[E0599]: no method named `add` found for struct `W` in the current scope - --> $DIR/inherent-impls-receiver-mapping.rs:66:14 - | -LL | struct W(X); - | -------- method `add` not found for this struct -... -LL | W(X).add(W(X)); - | ^^^ this is an associated function, not a method - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `W` - --> $DIR/inherent-impls-receiver-mapping.rs:61:18 - | -LL | reuse X::add { self.0 } - | ^^^ - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `add`, perhaps you need to implement it: - candidate #1: `Add` -help: use associated function syntax instead - | -LL - W(X).add(W(X)); -LL + W::add(W(X)); - | -help: one of the expressions' fields has a method of the same name - | -LL | W(X).0.add(W(X)); - | ++ +LL | y.by_value(); + | - you could clone this value -error: aborting due to 15 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0425, E0599. -For more information about an error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0308, E0507, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/delegation/inherent-impls-recursive-cycle.rs b/tests/ui/delegation/inherent-impls-recursive-cycle.rs index 0860ff39f51ee..81a59b63874fb 100644 --- a/tests/ui/delegation/inherent-impls-recursive-cycle.rs +++ b/tests/ui/delegation/inherent-impls-recursive-cycle.rs @@ -2,6 +2,7 @@ trait Trait1 { reuse trait_foo_reused as foo; + //~^ ERROR: encountered a cycle during delegation signature resolution } impl Trait1 for () {} @@ -9,44 +10,49 @@ impl Trait1 for () {} struct S1(T); impl S1 { reuse Trait1::foo { self.0 } - //~^ ERROR: delegation's target expression is specified for function with no params + //~^ ERROR: encountered a cycle during delegation signature resolution //~| ERROR: this function takes 0 arguments but 1 argument was supplied } struct S2(S1<()>); impl S2 { reuse S1::<()>::foo { self.0 } - //~^ ERROR: cannot find function `foo` in `S1` + //~^ ERROR: encountered a cycle during delegation signature resolution + //~| ERROR: this function takes 0 arguments but 1 argument was supplied } reuse S2::foo; -//~^ ERROR: cannot find function `foo` in `S2` +//~^ ERROR: encountered a cycle during delegation signature resolution struct S3; impl S3 { reuse foo; + //~^ ERROR: encountered a cycle during delegation signature resolution } impl Trait1 for S3 { reuse S2::foo { S2(S1(())) } - //~^ ERROR: delegation's target expression is specified for function with no params - //~| ERROR: cannot find function `foo` in `S2` + //~^ ERROR: encountered a cycle during delegation signature resolution + //~| ERROR: this function takes 0 arguments but 1 argument was supplied } trait Trait2 { reuse ::foo { S3 } - //~^ ERROR: delegation's target expression is specified for function with no params + //~^ ERROR: encountered a cycle during delegation signature resolution //~| ERROR: this function takes 0 arguments but 1 argument was supplied } reuse Trait2::foo as trait_foo; +//~^ ERROR: encountered a cycle during delegation signature resolution +//~| ERROR: type annotations needed struct S4; impl S4 { reuse trait_foo; + //~^ ERROR: encountered a cycle during delegation signature resolution } reuse S4::trait_foo as trait_foo_reused; -//~^ ERROR: cannot find function `trait_foo` in `S4` +//~^ ERROR: encountered a cycle during delegation signature resolution fn main() {} diff --git a/tests/ui/delegation/inherent-impls-recursive-cycle.stderr b/tests/ui/delegation/inherent-impls-recursive-cycle.stderr index a68931f8abce7..9c88b8e7cacc4 100644 --- a/tests/ui/delegation/inherent-impls-recursive-cycle.stderr +++ b/tests/ui/delegation/inherent-impls-recursive-cycle.stderr @@ -1,47 +1,65 @@ -error[E0425]: cannot find function `foo` in `S1` - --> $DIR/inherent-impls-recursive-cycle.rs:18:21 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:4:11 + | +LL | reuse trait_foo_reused as foo; + | ^^^^^^^^^^^^^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:12:19 + | +LL | reuse Trait1::foo { self.0 } + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:19:21 | LL | reuse S1::<()>::foo { self.0 } - | ^^^ not found in `S1` + | ^^^ -error[E0425]: cannot find function `foo` in `S2` - --> $DIR/inherent-impls-recursive-cycle.rs:22:11 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:24:11 | LL | reuse S2::foo; - | ^^^ not found in `S2` + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:29:11 + | +LL | reuse foo; + | ^^^ -error[E0425]: cannot find function `foo` in `S2` - --> $DIR/inherent-impls-recursive-cycle.rs:31:15 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:34:15 | LL | reuse S2::foo { S2(S1(())) } - | ^^^ not found in `S2` + | ^^^ -error[E0425]: cannot find function `trait_foo` in `S4` - --> $DIR/inherent-impls-recursive-cycle.rs:49:11 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:40:27 | -LL | reuse S4::trait_foo as trait_foo_reused; - | ^^^^^^^^^ not found in `S4` +LL | reuse ::foo { S3 } + | ^^^ -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-recursive-cycle.rs:11:23 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:45:15 | -LL | reuse Trait1::foo { self.0 } - | ^^^^^^^^^^ +LL | reuse Trait2::foo as trait_foo; + | ^^^ -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-recursive-cycle.rs:31:19 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:51:11 | -LL | reuse S2::foo { S2(S1(())) } - | ^^^^^^^^^^^^^^ +LL | reuse trait_foo; + | ^^^^^^^^^ -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-recursive-cycle.rs:37:31 +error: encountered a cycle during delegation signature resolution + --> $DIR/inherent-impls-recursive-cycle.rs:55:11 | -LL | reuse ::foo { S3 } - | ^^^^^^ +LL | reuse S4::trait_foo as trait_foo_reused; + | ^^^^^^^^^ error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/inherent-impls-recursive-cycle.rs:11:19 + --> $DIR/inherent-impls-recursive-cycle.rs:12:19 | LL | reuse Trait1::foo { self.0 } | ^^^ ---------- unexpected argument @@ -58,7 +76,41 @@ LL + reuse Trait1::fo{ self.0 } | error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/inherent-impls-recursive-cycle.rs:37:27 + --> $DIR/inherent-impls-recursive-cycle.rs:19:21 + | +LL | reuse S1::<()>::foo { self.0 } + | ^^^ ---------- unexpected argument + | +note: associated function defined here + --> $DIR/inherent-impls-recursive-cycle.rs:12:19 + | +LL | reuse Trait1::foo { self.0 } + | ^^^ +help: remove the extra argument + | +LL - reuse S1::<()>::foo { self.0 } +LL + reuse S1::<()>::fo{ self.0 } + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/inherent-impls-recursive-cycle.rs:34:15 + | +LL | reuse S2::foo { S2(S1(())) } + | ^^^ -------------- unexpected argument of type `S2` + | +note: associated function defined here + --> $DIR/inherent-impls-recursive-cycle.rs:19:21 + | +LL | reuse S1::<()>::foo { self.0 } + | ^^^ +help: remove the extra argument + | +LL - reuse S2::foo { S2(S1(())) } +LL + reuse S2::fo{ S2(S1(())) } + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/inherent-impls-recursive-cycle.rs:40:27 | LL | reuse ::foo { S3 } | ^^^ ------ unexpected argument of type `S3` @@ -74,7 +126,15 @@ LL - reuse ::foo { S3 } LL + reuse ::fo{ S3 } | -error: aborting due to 9 previous errors +error[E0283]: type annotations needed + --> $DIR/inherent-impls-recursive-cycle.rs:45:15 + | +LL | reuse Trait2::foo as trait_foo; + | ^^^ cannot infer type + | + = note: the type must implement `Trait2` + +error: aborting due to 15 previous errors -Some errors have detailed explanations: E0061, E0425. +Some errors have detailed explanations: E0061, E0283. For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/inherent-impls-recursive.rs b/tests/ui/delegation/inherent-impls-recursive.rs index c57ef40642346..7d86cf93a4660 100644 --- a/tests/ui/delegation/inherent-impls-recursive.rs +++ b/tests/ui/delegation/inherent-impls-recursive.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(fn_delegation)] mod test_1 { @@ -9,13 +11,11 @@ mod test_1 { struct S2; impl S2 { reuse S1::foo; - //~^ ERROR: cannot find function `foo` in `S1` } struct S3; impl S3 { reuse S2::foo; - //~^ ERROR: cannot find function `foo` in `S2` } } @@ -34,11 +34,9 @@ mod test_2 { struct S2(S1<()>); impl S2 { reuse S1::<()>::foo { self.0 } - //~^ ERROR: cannot find function `foo` in `S1` } reuse S2::foo; - //~^ ERROR: cannot find function `foo` in `S2` struct S3; impl S3 { @@ -47,8 +45,6 @@ mod test_2 { impl Trait1 for S3 { reuse S2::foo { &S2(S1(())) } - //~^ ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl - //~| ERROR: cannot find function `foo` in `S2` } trait Trait2 { @@ -63,7 +59,6 @@ mod test_2 { } reuse S4::trait_foo as trait_foo_reused; - //~^ ERROR: cannot find function `trait_foo` in `S4` } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-recursive.stderr b/tests/ui/delegation/inherent-impls-recursive.stderr deleted file mode 100644 index f80d9d3b84097..0000000000000 --- a/tests/ui/delegation/inherent-impls-recursive.stderr +++ /dev/null @@ -1,61 +0,0 @@ -error[E0425]: cannot find function `foo` in `S1` - --> $DIR/inherent-impls-recursive.rs:11:19 - | -LL | reuse S1::foo; - | ^^^ not found in `S1` - | -note: function `test_2::foo` exists but is inaccessible - --> $DIR/inherent-impls-recursive.rs:40:5 - | -LL | reuse S2::foo; - | ^^^^^^^^^^^^^^ not accessible - -error[E0425]: cannot find function `foo` in `S2` - --> $DIR/inherent-impls-recursive.rs:17:19 - | -LL | reuse S2::foo; - | ^^^ not found in `S2` - | -note: function `test_2::foo` exists but is inaccessible - --> $DIR/inherent-impls-recursive.rs:40:5 - | -LL | reuse S2::foo; - | ^^^^^^^^^^^^^^ not accessible - -error[E0425]: cannot find function `foo` in `S1` - --> $DIR/inherent-impls-recursive.rs:36:25 - | -LL | reuse S1::<()>::foo { self.0 } - | ^^^ not found in `S1` - -error[E0425]: cannot find function `foo` in `S2` - --> $DIR/inherent-impls-recursive.rs:40:15 - | -LL | reuse S2::foo; - | ^^^ not found in `S2` - -error[E0425]: cannot find function `foo` in `S2` - --> $DIR/inherent-impls-recursive.rs:49:19 - | -LL | reuse S2::foo { &S2(S1(())) } - | ^^^ not found in `S2` - -error[E0425]: cannot find function `trait_foo` in `S4` - --> $DIR/inherent-impls-recursive.rs:65:15 - | -LL | reuse S4::trait_foo as trait_foo_reused; - | ^^^^^^^^^ not found in `S4` - -error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl - --> $DIR/inherent-impls-recursive.rs:49:19 - | -LL | fn foo(&self) {} - | ------------- `&self` used in trait -... -LL | reuse S2::foo { &S2(S1(())) } - | ^^^ expected `&self` in impl - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0186, E0425. -For more information about an error, try `rustc --explain E0186`. diff --git a/tests/ui/delegation/inherent-impls-rename.rs b/tests/ui/delegation/inherent-impls-rename.rs index 7b6e1e4b7cddc..6a0fd672cf8e5 100644 --- a/tests/ui/delegation/inherent-impls-rename.rs +++ b/tests/ui/delegation/inherent-impls-rename.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(fn_delegation)] struct X; @@ -9,6 +11,5 @@ impl X { } reuse X::bar; -//~^ ERROR: cannot find function `bar` in `X` fn main() {} diff --git a/tests/ui/delegation/inherent-impls-rename.stderr b/tests/ui/delegation/inherent-impls-rename.stderr deleted file mode 100644 index e2e8946412e93..0000000000000 --- a/tests/ui/delegation/inherent-impls-rename.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0425]: cannot find function `bar` in `X` - --> $DIR/inherent-impls-rename.rs:11:10 - | -LL | reuse X::bar; - | ^^^ not found in `X` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/delegation/inherent-impls-self-mapping.rs b/tests/ui/delegation/inherent-impls-self-mapping.rs index 36aef3a7bc7d8..9c13c13786fa7 100644 --- a/tests/ui/delegation/inherent-impls-self-mapping.rs +++ b/tests/ui/delegation/inherent-impls-self-mapping.rs @@ -11,10 +11,10 @@ impl X { trait Trait { reuse X::foo; - //~^ ERROR: cannot find function `foo` in `X` + //~^ ERROR: arguments to this function are incorrect + //~| ERROR: mismatched types } reuse X::foo; -//~^ ERROR: cannot find function `foo` in `X` fn main() {} diff --git a/tests/ui/delegation/inherent-impls-self-mapping.stderr b/tests/ui/delegation/inherent-impls-self-mapping.stderr index 9ecf04626d29c..82ea263a8513b 100644 --- a/tests/ui/delegation/inherent-impls-self-mapping.stderr +++ b/tests/ui/delegation/inherent-impls-self-mapping.stderr @@ -1,15 +1,41 @@ -error[E0425]: cannot find function `foo` in `X` +error[E0308]: arguments to this function are incorrect --> $DIR/inherent-impls-self-mapping.rs:13:14 | +LL | trait Trait { + | ----------- + | | + | found this type parameter + | found this type parameter LL | reuse X::foo; - | ^^^ not found in `X` + | ^^^ + | | + | expected `Rc>`, found `Rc>` + | expected `Box>`, found `Box>` + | + = note: expected struct `Rc>` + found struct `Rc>` + = note: expected struct `Box>` + found struct `Box>` +note: method defined here + --> $DIR/inherent-impls-self-mapping.rs:7:8 + | +LL | fn foo(self: Rc>, other: Box>) -> Option> { + | ^^^ ---- -------------------- -error[E0425]: cannot find function `foo` in `X` - --> $DIR/inherent-impls-self-mapping.rs:17:10 +error[E0308]: mismatched types + --> $DIR/inherent-impls-self-mapping.rs:13:14 + | +LL | trait Trait { + | ----------- expected this type parameter +LL | reuse X::foo; + | ^^^ + | | + | expected `Option>`, found `Option>` + | expected `Option>` because of return type | -LL | reuse X::foo; - | ^^^ not found in `X` + = note: expected enum `Option>` + found enum `Option>` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/delegation/inherent-impls-self-replacement.rs b/tests/ui/delegation/inherent-impls-self-replacement.rs index e6aa7458993fd..65ecccf766719 100644 --- a/tests/ui/delegation/inherent-impls-self-replacement.rs +++ b/tests/ui/delegation/inherent-impls-self-replacement.rs @@ -20,37 +20,36 @@ trait Trait: Sized { fn get_s(self) -> S<(), 123>; reuse S::<(), 123>::by_value { self.get_s() } - //~^ ERROR: cannot find function `by_value` in `S` reuse S::<(), 123>::by_ref { self.get_s() } - //~^ ERROR: cannot find function `by_ref` in `S` + //~^ ERROR: cannot move out of `*self` which is behind a shared reference reuse S::<(), 123>::by_mut_ref { self.get_s() } - //~^ ERROR: cannot find function `by_mut_ref` in `S` + //~^ ERROR: cannot move out of `*self` which is behind a mutable reference reuse S::<(), 123>::by_box { self.get_s() } - //~^ ERROR: cannot find function `by_box` in `S` + //~^ ERROR: mismatched types reuse S::<(), 123>::by_rc { self.get_s() } - //~^ ERROR: cannot find function `by_rc` in `S` + //~^ ERROR: mismatched types reuse S::<(), 123>::by_pin { self.get_s() } - //~^ ERROR: cannot find function `by_pin` in `S` + //~^ ERROR: mismatched types } trait Trait2: Sized { reuse S::<(), 123>::by_value { self.get_s() } - //~^ ERROR: cannot find function `by_value` in `S` + //~^ ERROR: no method named `get_s` found for type parameter `Self` in the current scope reuse S::<(), 123>::by_ref { self.get_s() } - //~^ ERROR: cannot find function `by_ref` in `S` + //~^ ERROR: no method named `get_s` found for reference `&Self` in the current scope reuse S::<(), 123>::by_mut_ref { self.get_s() } - //~^ ERROR: cannot find function `by_mut_ref` in `S` + //~^ ERROR: no method named `get_s` found for mutable reference `&mut Self` in the current scope reuse S::<(), 123>::by_box { self.get_s() } - //~^ ERROR: cannot find function `by_box` in `S` + //~^ ERROR: no method named `get_s` found for struct `Box` in the current scope reuse S::<(), 123>::by_rc { self.get_s() } - //~^ ERROR: cannot find function `by_rc` in `S` + //~^ ERROR: no method named `get_s` found for struct `Rc` in the current scope reuse S::<(), 123>::by_pin { self.get_s() } - //~^ ERROR: cannot find function `by_pin` in `S` + //~^ ERROR: no method named `get_s` found for struct `Pin>` in the current scope } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-self-replacement.stderr b/tests/ui/delegation/inherent-impls-self-replacement.stderr index e293635e4a1ea..e017bee8af540 100644 --- a/tests/ui/delegation/inherent-impls-self-replacement.stderr +++ b/tests/ui/delegation/inherent-impls-self-replacement.stderr @@ -1,75 +1,186 @@ -error[E0425]: cannot find function `by_value` in `S` - --> $DIR/inherent-impls-self-replacement.rs:22:25 +error[E0308]: mismatched types + --> $DIR/inherent-impls-self-replacement.rs:30:34 | -LL | reuse S::<(), 123>::by_value { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `by_ref` in `S` - --> $DIR/inherent-impls-self-replacement.rs:25:25 +LL | reuse S::<(), 123>::by_box { self.get_s() } + | ------ ^^^^^^^^^^^^ expected `Box>`, found `S<(), 123>` + | | + | arguments to this function are incorrect | -LL | reuse S::<(), 123>::by_ref { self.get_s() } - | ^^^^^^ not found in `S` - -error[E0425]: cannot find function `by_mut_ref` in `S` - --> $DIR/inherent-impls-self-replacement.rs:28:25 + = note: expected struct `Box>` + found struct `S<_, _>` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: method defined here + --> $DIR/inherent-impls-self-replacement.rs:14:8 | -LL | reuse S::<(), 123>::by_mut_ref { self.get_s() } - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `by_box` in `S` - --> $DIR/inherent-impls-self-replacement.rs:31:25 +LL | fn by_box<'d: 'd, 'e, T, const B: bool>(self: Box) {} + | ^^^^^^ ---- +help: store this in the heap by calling `Box::new` | -LL | reuse S::<(), 123>::by_box { self.get_s() } - | ^^^^^^ not found in `S` +LL | reuse S::<(), 123>::by_box { Box::new(self.get_s()) } + | +++++++++ + -error[E0425]: cannot find function `by_rc` in `S` - --> $DIR/inherent-impls-self-replacement.rs:34:25 +error[E0308]: mismatched types + --> $DIR/inherent-impls-self-replacement.rs:33:33 | LL | reuse S::<(), 123>::by_rc { self.get_s() } - | ^^^^^ not found in `S` + | ----- ^^^^^^^^^^^^ expected `Rc>`, found `S<(), 123>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc>` + found struct `S<_, _>` +note: method defined here + --> $DIR/inherent-impls-self-replacement.rs:15:8 + | +LL | fn by_rc<'d: 'd, 'e, T, const B: bool>(self: Rc) {} + | ^^^^^ ---- +help: call `Into::into` on this expression to convert `S<(), 123>` into `Rc>` + | +LL | reuse S::<(), 123>::by_rc { self.get_s().into() } + | +++++++ -error[E0425]: cannot find function `by_pin` in `S` - --> $DIR/inherent-impls-self-replacement.rs:37:25 +error[E0308]: mismatched types + --> $DIR/inherent-impls-self-replacement.rs:36:34 | LL | reuse S::<(), 123>::by_pin { self.get_s() } - | ^^^^^^ not found in `S` + | ------ ^^^^^^^^^^^^ expected `Pin>>`, found `S<(), 123>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>>` + found struct `S<(), 123>` +note: method defined here + --> $DIR/inherent-impls-self-replacement.rs:16:8 + | +LL | fn by_pin<'d: 'd, 'e, T, const B: bool>(self: Pin>) {} + | ^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse S::<(), 123>::by_pin { Box::pin(self.get_s()) } + | +++++++++ + -error[E0425]: cannot find function `by_value` in `S` - --> $DIR/inherent-impls-self-replacement.rs:42:25 +error[E0599]: no method named `get_s` found for type parameter `Self` in the current scope + --> $DIR/inherent-impls-self-replacement.rs:41:41 | +LL | trait Trait2: Sized { + | ------------------- method `get_s` not found for this type parameter LL | reuse S::<(), 123>::by_value { self.get_s() } - | ^^^^^^^^ not found in `S` + | ^^^^^ method not found in `Self` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `get_s`, perhaps you need to add another supertrait for it: + | +LL | trait Trait2: Sized + Trait { + | +++++++ -error[E0425]: cannot find function `by_ref` in `S` - --> $DIR/inherent-impls-self-replacement.rs:44:25 +error[E0599]: no method named `get_s` found for reference `&Self` in the current scope + --> $DIR/inherent-impls-self-replacement.rs:43:39 | LL | reuse S::<(), 123>::by_ref { self.get_s() } - | ^^^^^^ not found in `S` + | ^^^^^ method not found in `&Self` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `get_s`, perhaps you need to add another supertrait for it: + | +LL | trait Trait2: Sized + Trait { + | +++++++ -error[E0425]: cannot find function `by_mut_ref` in `S` - --> $DIR/inherent-impls-self-replacement.rs:46:25 +error[E0599]: no method named `get_s` found for mutable reference `&mut Self` in the current scope + --> $DIR/inherent-impls-self-replacement.rs:45:43 | LL | reuse S::<(), 123>::by_mut_ref { self.get_s() } - | ^^^^^^^^^^ not found in `S` + | ^^^^^ method not found in `&mut Self` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `get_s`, perhaps you need to add another supertrait for it: + | +LL | trait Trait2: Sized + Trait { + | +++++++ -error[E0425]: cannot find function `by_box` in `S` - --> $DIR/inherent-impls-self-replacement.rs:48:25 +error[E0599]: no method named `get_s` found for struct `Box` in the current scope + --> $DIR/inherent-impls-self-replacement.rs:47:39 | LL | reuse S::<(), 123>::by_box { self.get_s() } - | ^^^^^^ not found in `S` + | ^^^^^ method not found in `Box` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Trait` defines an item `get_s`, perhaps you need to implement it + --> $DIR/inherent-impls-self-replacement.rs:19:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find function `by_rc` in `S` - --> $DIR/inherent-impls-self-replacement.rs:50:25 +error[E0599]: no method named `get_s` found for struct `Rc` in the current scope + --> $DIR/inherent-impls-self-replacement.rs:49:38 | LL | reuse S::<(), 123>::by_rc { self.get_s() } - | ^^^^^ not found in `S` + | ^^^^^ method not found in `Rc` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Trait` defines an item `get_s`, perhaps you need to implement it + --> $DIR/inherent-impls-self-replacement.rs:19:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find function `by_pin` in `S` - --> $DIR/inherent-impls-self-replacement.rs:52:25 +error[E0599]: no method named `get_s` found for struct `Pin>` in the current scope + --> $DIR/inherent-impls-self-replacement.rs:51:39 | LL | reuse S::<(), 123>::by_pin { self.get_s() } - | ^^^^^^ not found in `S` + | ^^^^^ method not found in `Pin>` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Trait` defines an item `get_s`, perhaps you need to implement it + --> $DIR/inherent-impls-self-replacement.rs:19:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ + +error[E0507]: cannot move out of `*self` which is behind a shared reference + --> $DIR/inherent-impls-self-replacement.rs:24:34 + | +LL | reuse S::<(), 123>::by_ref { self.get_s() } + | ^^^^ ------- `*self` moved due to this method call + | | + | move occurs because `*self` has type `Self`, which does not implement the `Copy` trait + | +note: `Trait::get_s` takes ownership of the receiver `self`, which moves `*self` + --> $DIR/inherent-impls-self-replacement.rs:20:14 + | +LL | fn get_s(self) -> S<(), 123>; + | ^^^^ +help: if `Self` implemented `Clone`, you could clone the value + --> $DIR/inherent-impls-self-replacement.rs:19:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ consider constraining this type parameter with `Clone` +... +LL | reuse S::<(), 123>::by_ref { self.get_s() } + | ---- you could clone this value + +error[E0507]: cannot move out of `*self` which is behind a mutable reference + --> $DIR/inherent-impls-self-replacement.rs:27:38 + | +LL | reuse S::<(), 123>::by_mut_ref { self.get_s() } + | ^^^^ ------- `*self` moved due to this method call + | | + | move occurs because `*self` has type `Self`, which does not implement the `Copy` trait + | +note: `Trait::get_s` takes ownership of the receiver `self`, which moves `*self` + --> $DIR/inherent-impls-self-replacement.rs:20:14 + | +LL | fn get_s(self) -> S<(), 123>; + | ^^^^ +help: if `Self` implemented `Clone`, you could clone the value + --> $DIR/inherent-impls-self-replacement.rs:19:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ consider constraining this type parameter with `Clone` +... +LL | reuse S::<(), 123>::by_mut_ref { self.get_s() } + | ---- you could clone this value -error: aborting due to 12 previous errors +error: aborting due to 11 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0308, E0507, E0599. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/delegation/inherent-impls-structs.rs b/tests/ui/delegation/inherent-impls-structs.rs index a5950185b6dad..f7a9d362dd9ca 100644 --- a/tests/ui/delegation/inherent-impls-structs.rs +++ b/tests/ui/delegation/inherent-impls-structs.rs @@ -10,77 +10,55 @@ impl<'a, 'b, 'c, A, const C: usize> S { } reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; -//~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static as foo_static_3; -//~^ ERROR: cannot find function `foo_static` in `S` reuse S::::foo_static::<'static, _, _> as foo_static_4; -//~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1; -//~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), 1>::foo_self as foo_self_3; -//~^ ERROR: cannot find function `foo_self` in `S` reuse S::::foo_self::<'static, _, _> as foo_self_4; -//~^ ERROR: cannot find function `foo_self` in `S` trait Trait<'a, AA, BB> where Self: Sized { reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - //~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static as foo_static_3; - //~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static::<'static, _, _> as foo_static_4; - //~^ ERROR: cannot find function `foo_static` in `S` fn get_s(self) -> S<(), 1> { panic!(); } reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), 1>::foo_self::<'static, _, _> as foo_self_4; - //~^ ERROR: cannot find function `foo_self` in `S` + //~^ ERROR: mismatched types [E0308] } struct X; impl<'a, A, B> Trait<'a, A, B> for X { reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - //~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static as foo_static_3; - //~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static::<'static, _, _> as foo_static_4; - //~^ ERROR: cannot find function `foo_static` in `S` + //~^ ERROR: type annotations needed [E0284] reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in `S` - //~| ERROR: delegation's target expression is specified for function with no params reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in `S` - //~| ERROR: delegation's target expression is specified for function with no params reuse S::<(), 1>::foo_self::<'static, _, _> as foo_self_4; - //~^ ERROR: cannot find function `foo_self` in `S` + //~^ ERROR: mismatched types [E0308] } impl X { reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - //~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static as foo_static_3; - //~^ ERROR: cannot find function `foo_static` in `S` reuse S::<(), 1>::foo_static::<'static, _, _> as foo_static_4; - //~^ ERROR: cannot find function `foo_static` in `S` fn get_s(self) -> S<(), 1> { panic!(); } reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - //~^ ERROR: cannot find function `foo_self` in `S` reuse S::<(), 1>::foo_self::<'static, _, _> as foo_self_4; - //~^ ERROR: cannot find function `foo_self` in `S` + //~^ ERROR: mismatched types [E0308] } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-structs.stderr b/tests/ui/delegation/inherent-impls-structs.stderr index 6a426564a6e3a..29963431b1451 100644 --- a/tests/ui/delegation/inherent-impls-structs.stderr +++ b/tests/ui/delegation/inherent-impls-structs.stderr @@ -1,159 +1,70 @@ -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:12:19 - | -LL | reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:14:19 - | -LL | reuse S::<(), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:16:22 - | -LL | reuse S::::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:19:19 - | -LL | reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:21:19 - | -LL | reuse S::<(), 1>::foo_self as foo_self_3; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:23:23 - | -LL | reuse S::::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:27:23 - | -LL | reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:29:23 - | -LL | reuse S::<(), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` +error[E0308]: mismatched types --> $DIR/inherent-impls-structs.rs:31:23 | -LL | reuse S::<(), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:38:23 - | -LL | reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:40:23 - | -LL | reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:42:23 - | +LL | trait Trait<'a, AA, BB> where Self: Sized { + | ----------------------- found this type parameter +... LL | reuse S::<(), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:49:23 + | ^^^^^^^^ + | | + | expected `S<(), 1>`, found type parameter `Self` + | arguments to this function are incorrect | -LL | reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:51:23 + = note: expected struct `S<(), 1>` + found type parameter `Self` +note: method defined here + --> $DIR/inherent-impls-structs.rs:9:8 | -LL | reuse S::<(), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:53:23 +error[E0284]: type annotations needed + --> $DIR/inherent-impls-structs.rs:40:23 | LL | reuse S::<(), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:56:23 + | ^^^^^^^^^^ cannot infer the value of const parameter `B` declared on the associated function `foo_static` | -LL | reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:59:23 +note: required by a const generic parameter in `S::::foo_static` + --> $DIR/inherent-impls-structs.rs:8:34 | -LL | reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^ not found in `S` +LL | fn foo_static<'d: 'd, 'e, T, const B: bool>() {} + | ^^^^^^^^^^^^^ required by this const generic parameter in `S::::foo_static` -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:62:23 +error[E0308]: mismatched types + --> $DIR/inherent-impls-structs.rs:45:23 | LL | reuse S::<(), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:67:23 + | ^^^^^^^^ + | | + | expected `S<(), 1>`, found `X` + | arguments to this function are incorrect | -LL | reuse S::<(), 1>::foo_static::<'static, (), true> as foo_static_1; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:69:23 - | -LL | reuse S::<(), 1>::foo_static as foo_static_3; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_static` in `S` - --> $DIR/inherent-impls-structs.rs:71:23 - | -LL | reuse S::<(), 1>::foo_static::<'static, _, _> as foo_static_4; - | ^^^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:78:23 - | -LL | reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^ not found in `S` - -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:80:23 + = note: expected struct `S<(), 1>` + found struct `X` +note: method defined here + --> $DIR/inherent-impls-structs.rs:9:8 | -LL | reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^ not found in `S` +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-structs.rs:82:23 +error[E0308]: mismatched types + --> $DIR/inherent-impls-structs.rs:60:23 | LL | reuse S::<(), 1>::foo_self::<'static, _, _> as foo_self_4; - | ^^^^^^^^ not found in `S` - -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-structs.rs:56:67 + | ^^^^^^^^ + | | + | expected `S<(), 1>`, found `X` + | arguments to this function are incorrect | -LL | reuse S::<(), 1>::foo_self::<'static, (), true> as foo_self_1 { self.get_s() } - | ^^^^^^^^^^^^^^^^ - -error: delegation's target expression is specified for function with no params - --> $DIR/inherent-impls-structs.rs:59:46 + = note: expected struct `S<(), 1>` + found struct `X` +note: method defined here + --> $DIR/inherent-impls-structs.rs:9:8 | -LL | reuse S::<(), 1>::foo_self as foo_self_3 { self.get_s() } - | ^^^^^^^^^^^^^^^^ +LL | fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {} + | ^^^^^^^^ ---- -error: aborting due to 26 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/delegation/inherent-impls-wrong-header-args-ice.rs b/tests/ui/delegation/inherent-impls-wrong-header-args-ice.rs index 8375df5f26587..90c329ea6a69c 100644 --- a/tests/ui/delegation/inherent-impls-wrong-header-args-ice.rs +++ b/tests/ui/delegation/inherent-impls-wrong-header-args-ice.rs @@ -11,7 +11,9 @@ impl<'a, 'b, 'c, A, const C: usize> S { trait Trait<'a, AA, BB> where Self: Sized { reuse S::<(), ()>::foo_self; - //~^ ERROR: cannot find function `foo_self` in `S` + //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: type provided when a constant was expected + //~| ERROR: type provided when a constant was expected } fn main() {} diff --git a/tests/ui/delegation/inherent-impls-wrong-header-args-ice.stderr b/tests/ui/delegation/inherent-impls-wrong-header-args-ice.stderr index bfa377dcc2db6..bda4c7ceab9e8 100644 --- a/tests/ui/delegation/inherent-impls-wrong-header-args-ice.stderr +++ b/tests/ui/delegation/inherent-impls-wrong-header-args-ice.stderr @@ -9,13 +9,27 @@ help: indicate the anonymous lifetime LL | impl<'a, 'b, 'c, A, const C: usize> S<'_, A, C> { | +++ -error[E0425]: cannot find function `foo_self` in `S` - --> $DIR/inherent-impls-wrong-header-args-ice.rs:13:24 +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/inherent-impls-wrong-header-args-ice.rs:13:15 | LL | reuse S::<(), ()>::foo_self; - | ^^^^^^^^ not found in `S` + | ^ -error: aborting due to 2 previous errors +error[E0747]: type provided when a constant was expected + --> $DIR/inherent-impls-wrong-header-args-ice.rs:13:19 + | +LL | reuse S::<(), ()>::foo_self; + | ^^ + +error[E0747]: type provided when a constant was expected + --> $DIR/inherent-impls-wrong-header-args-ice.rs:13:19 + | +LL | reuse S::<(), ()>::foo_self; + | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0425, E0726. -For more information about an error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0726, E0747. +For more information about an error, try `rustc --explain E0726`. diff --git a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr index 594f6cc66690e..da16e49a777eb 100644 --- a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr +++ b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr @@ -2,6 +2,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` = note: ...which requires lowering HIR for `Default`... + = note: ...which requires resolving type relative delegations... = note: ...which requires getting the AST for lowering... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... @@ -13,6 +14,7 @@ error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... = note: ...which requires lowering HIR for `Default`... + = note: ...which requires resolving type relative delegations... = note: ...which requires getting the AST for lowering... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle diff --git a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr index 594f6cc66690e..da16e49a777eb 100644 --- a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr +++ b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr @@ -2,6 +2,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` = note: ...which requires lowering HIR for `Default`... + = note: ...which requires resolving type relative delegations... = note: ...which requires getting the AST for lowering... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... @@ -13,6 +14,7 @@ error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... = note: ...which requires lowering HIR for `Default`... + = note: ...which requires resolving type relative delegations... = note: ...which requires getting the AST for lowering... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr index 594f6cc66690e..da16e49a777eb 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.stderr +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -2,6 +2,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting owner for `Default` = note: ...which requires lowering HIR for `Default`... + = note: ...which requires resolving type relative delegations... = note: ...which requires getting the AST for lowering... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... @@ -13,6 +14,7 @@ error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting owner for `Default`... = note: ...which requires lowering HIR for `Default`... + = note: ...which requires resolving type relative delegations... = note: ...which requires getting the AST for lowering... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle