diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1245d48975470..fb42cfea30b41 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -98,7 +98,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } let expr_hir_id = self.lower_node_id(e.id); - self.lower_attrs(expr_hir_id, &e.attrs, e.span); + let attrs = self.lower_attrs(expr_hir_id, &e.attrs, e.span); let kind = match &e.kind { ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), @@ -232,10 +232,10 @@ impl<'hir> LoweringContext<'_, 'hir> { *fn_arg_span, ), None => self.lower_expr_closure( + attrs, binder, *capture_clause, e.id, - expr_hir_id, *constness, *movability, fn_decl, @@ -1052,10 +1052,10 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_closure( &mut self, + attrs: &[rustc_hir::Attribute], binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, - closure_hir_id: hir::HirId, constness: Const, movability: Movability, decl: &FnDecl, @@ -1067,15 +1067,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let (binder_clause, generic_params) = self.lower_closure_binder(binder); let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| { - let mut coroutine_kind = if this - .attrs - .get(&closure_hir_id.local_id) - .is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine))) - { - Some(hir::CoroutineKind::Coroutine(Movability::Movable)) - } else { - None - }; + + let mut coroutine_kind = find_attr!(attrs, AttributeKind::Coroutine(_) => hir::CoroutineKind::Coroutine(Movability::Movable)); + // FIXME(contracts): Support contracts on closures? let body_id = this.lower_fn_body(decl, None, |this| { this.coroutine_kind = coroutine_kind; diff --git a/compiler/rustc_attr_parsing/src/attributes/body.rs b/compiler/rustc_attr_parsing/src/attributes/body.rs new file mode 100644 index 0000000000000..ab9330216f6c6 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/body.rs @@ -0,0 +1,15 @@ +//! Attributes that can be found in function body. + +use rustc_hir::attrs::AttributeKind; +use rustc_span::{Symbol, sym}; + +use super::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; + +pub(crate) struct CoroutineParser; + +impl NoArgsAttributeParser for CoroutineParser { + const PATH: &[Symbol] = &[sym::coroutine]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(rustc_span::Span) -> AttributeKind = |span| AttributeKind::Coroutine(span); +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index c574ef78bdf79..f7946ade6d2b2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -26,6 +26,7 @@ use crate::parser::ArgParser; use crate::session_diagnostics::UnusedMultiple; pub(crate) mod allow_unstable; +pub(crate) mod body; pub(crate) mod cfg; pub(crate) mod cfg_old; pub(crate) mod codegen_attrs; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c6599f20c2d1f..911d2e133107d 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -16,6 +16,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{ AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser, }; +use crate::attributes::body::CoroutineParser; use crate::attributes::codegen_attrs::{ ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser, TrackCallerParser, UsedParser, @@ -184,6 +185,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index f5fedbf95c1c1..148d0de3bab28 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -769,9 +769,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } TerminatorKind::Call { func, args, .. } | TerminatorKind::TailCall { func, args, .. } => { - let call_source = match term.kind { - TerminatorKind::Call { call_source, .. } => call_source, - TerminatorKind::TailCall { .. } => CallSource::Normal, + let (call_source, destination, is_diverging) = match term.kind { + TerminatorKind::Call { call_source, destination, target, .. } => { + (call_source, destination, target.is_none()) + } + TerminatorKind::TailCall { .. } => { + (CallSource::Normal, RETURN_PLACE.into(), false) + } _ => unreachable!(), }; @@ -845,9 +849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } - if let TerminatorKind::Call { destination, target, .. } = term.kind { - self.check_call_dest(term, &sig, destination, target, term_location); - } + self.check_call_dest(term, &sig, destination, is_diverging, term_location); // The ordinary liveness rules will ensure that all // regions in the type of the callee are live here. We @@ -1874,65 +1876,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { term: &Terminator<'tcx>, sig: &ty::FnSig<'tcx>, destination: Place<'tcx>, - target: Option, + is_diverging: bool, term_location: Location, ) { let tcx = self.tcx(); - match target { - Some(_) => { - let dest_ty = destination.ty(self.body, tcx).ty; - let dest_ty = self.normalize(dest_ty, term_location); - let category = match destination.as_local() { - Some(RETURN_PLACE) => { - if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = - self.universal_regions.defining_ty - { - if tcx.is_static(def_id) { - ConstraintCategory::UseAsStatic - } else { - ConstraintCategory::UseAsConst - } + if is_diverging { + // The signature in this call can reference region variables, + // so erase them before calling a query. + let output_ty = self.tcx().erase_regions(sig.output()); + if !output_ty + .is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env)) + { + span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); + } + } else { + let dest_ty = destination.ty(self.body, tcx).ty; + let dest_ty = self.normalize(dest_ty, term_location); + let category = match destination.as_local() { + Some(RETURN_PLACE) => { + if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = + self.universal_regions.defining_ty + { + if tcx.is_static(def_id) { + ConstraintCategory::UseAsStatic } else { - ConstraintCategory::Return(ReturnConstraint::Normal) + ConstraintCategory::UseAsConst } + } else { + ConstraintCategory::Return(ReturnConstraint::Normal) } - Some(l) if !self.body.local_decls[l].is_user_variable() => { - ConstraintCategory::Boring - } - // The return type of a call is interesting for diagnostics. - _ => ConstraintCategory::Assignment, - }; - - let locations = term_location.to_locations(); - - if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { - span_mirbug!( - self, - term, - "call dest mismatch ({:?} <- {:?}): {:?}", - dest_ty, - sig.output(), - terr - ); } - - // When `unsized_fn_params` is not enabled, - // this check is done at `check_local`. - if self.unsized_feature_enabled() { - let span = term.source_info.span; - self.ensure_place_sized(dest_ty, span); + Some(l) if !self.body.local_decls[l].is_user_variable() => { + ConstraintCategory::Boring } + // The return type of a call is interesting for diagnostics. + _ => ConstraintCategory::Assignment, + }; + + let locations = term_location.to_locations(); + + if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { + span_mirbug!( + self, + term, + "call dest mismatch ({:?} <- {:?}): {:?}", + dest_ty, + sig.output(), + terr + ); } - None => { - // The signature in this call can reference region variables, - // so erase them before calling a query. - let output_ty = self.tcx().erase_regions(sig.output()); - if !output_ty.is_privately_uninhabited( - self.tcx(), - self.infcx.typing_env(self.infcx.param_env), - ) { - span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); - } + + // When `unsized_fn_params` is not enabled, + // this check is done at `check_local`. + if self.unsized_feature_enabled() { + let span = term.source_info.span; + self.ensure_place_sized(dest_ty, span); } } } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 80618422b56d6..d9d2ec48948e7 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -297,6 +297,9 @@ pub enum AttributeKind { /// Represents `#[const_trait]`. ConstTrait(Span), + /// Represents `#[coroutine]`. + Coroutine(Span), + /// Represents `#[coverage(..)]`. Coverage(Span, CoverageAttrKind), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 9644a597a3117..b66e5bbeabe73 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -28,6 +28,7 @@ impl AttributeKind { ConstStability { .. } => Yes, ConstStabilityIndirect => No, ConstTrait(..) => No, + Coroutine(..) => No, Coverage(..) => No, DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index e2462c2d46590..ce0e51f106f59 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -223,60 +223,27 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { "synthetic HIR should have its `generics_of` explicitly fed" ), - _ => span_bug!(tcx.def_span(def_id), "unhandled node {node:?}"), + _ => span_bug!(tcx.def_span(def_id), "generics_of: unexpected node kind {node:?}"), }; - enum Defaults { - Allowed, - // See #36887 - FutureCompatDisallowed, - Deny, - } - - let hir_generics = node.generics().unwrap_or(hir::Generics::empty()); - let (opt_self, allow_defaults) = match node { - Node::Item(item) => { - match item.kind { - ItemKind::Trait(..) | ItemKind::TraitAlias(..) => { - // Add in the self type parameter. - // - // Something of a hack: use the node id for the trait, also as - // the node id for the Self type parameter. - let opt_self = Some(ty::GenericParamDef { - index: 0, - name: kw::SelfUpper, - def_id: def_id.to_def_id(), - pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { - has_default: false, - synthetic: false, - }, - }); - - (opt_self, Defaults::Allowed) - } - ItemKind::TyAlias(..) - | ItemKind::Enum(..) - | ItemKind::Struct(..) - | ItemKind::Union(..) => (None, Defaults::Allowed), - ItemKind::Const(..) => (None, Defaults::Deny), - _ => (None, Defaults::FutureCompatDisallowed), - } - } - - Node::OpaqueTy(..) => (None, Defaults::Allowed), - - // GATs - Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => { - (None, Defaults::Deny) - } - Node::ImplItem(item) if matches!(item.kind, ImplItemKind::Type(..)) => { - (None, Defaults::Deny) - } - - _ => (None, Defaults::FutureCompatDisallowed), + // Add in the self type parameter. + let opt_self = if let Node::Item(item) = node + && let ItemKind::Trait(..) | ItemKind::TraitAlias(..) = item.kind + { + // Something of a hack: We reuse the node ID of the trait for the self type parameter. + Some(ty::GenericParamDef { + index: 0, + name: kw::SelfUpper, + def_id: def_id.to_def_id(), + pure_wrt_drop: false, + kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, + }) + } else { + None }; + let param_default_policy = param_default_policy(node); + let hir_generics = node.generics().unwrap_or(hir::Generics::empty()); let has_self = opt_self.is_some(); let mut parent_has_self = false; let mut own_start = has_self as u32; @@ -312,60 +279,53 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { prev + type_start }; - const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions"; - - own_params.extend(hir_generics.params.iter().filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => None, - GenericParamKind::Type { default, synthetic, .. } => { - if default.is_some() { - match allow_defaults { - Defaults::Allowed => {} - Defaults::FutureCompatDisallowed => { - tcx.node_span_lint( - lint::builtin::INVALID_TYPE_PARAM_DEFAULT, - param.hir_id, - param.span, - |lint| { - lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED); - }, - ); - } - Defaults::Deny => { - tcx.dcx().span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED); + own_params.extend(hir_generics.params.iter().filter_map(|param| { + const MESSAGE: &str = "defaults for generic parameters are not allowed here"; + let kind = match param.kind { + GenericParamKind::Lifetime { .. } => return None, + GenericParamKind::Type { default, synthetic } => { + if default.is_some() { + match param_default_policy.expect("no policy for generic param default") { + ParamDefaultPolicy::Allowed => {} + ParamDefaultPolicy::FutureCompatForbidden => { + tcx.node_span_lint( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + param.hir_id, + param.span, + |lint| { + lint.primary_message(MESSAGE); + }, + ); + } + ParamDefaultPolicy::Forbidden => { + tcx.dcx().span_err(param.span, MESSAGE); + } } } - } - - let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic }; - Some(ty::GenericParamDef { - index: next_index(), - name: param.name.ident().name, - def_id: param.def_id.to_def_id(), - pure_wrt_drop: param.pure_wrt_drop, - kind, - }) - } - GenericParamKind::Const { ty: _, default, synthetic } => { - if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() { - tcx.dcx().span_err( - param.span, - "defaults for const parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions", - ); + ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic } } + GenericParamKind::Const { ty: _, default, synthetic } => { + if default.is_some() { + match param_default_policy.expect("no policy for generic param default") { + ParamDefaultPolicy::Allowed => {} + ParamDefaultPolicy::FutureCompatForbidden + | ParamDefaultPolicy::Forbidden => { + tcx.dcx().span_err(param.span, MESSAGE); + } + } + } - let index = next_index(); - - Some(ty::GenericParamDef { - index, - name: param.name.ident().name, - def_id: param.def_id.to_def_id(), - pure_wrt_drop: param.pure_wrt_drop, - kind: ty::GenericParamDefKind::Const { has_default: default.is_some(), synthetic }, - }) - } + ty::GenericParamDefKind::Const { has_default: default.is_some(), synthetic } + } + }; + Some(ty::GenericParamDef { + index: next_index(), + name: param.name.ident().name, + def_id: param.def_id.to_def_id(), + pure_wrt_drop: param.pure_wrt_drop, + kind, + }) })); // provide junk type parameter defs - the only place that @@ -438,6 +398,48 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } } +#[derive(Clone, Copy)] +enum ParamDefaultPolicy { + Allowed, + /// Tracked in . + FutureCompatForbidden, + Forbidden, +} + +fn param_default_policy(node: Node<'_>) -> Option { + use rustc_hir::*; + + Some(match node { + Node::Item(item) => match item.kind { + ItemKind::Trait(..) + | ItemKind::TraitAlias(..) + | ItemKind::TyAlias(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::Union(..) => ParamDefaultPolicy::Allowed, + ItemKind::Fn { .. } | ItemKind::Impl(_) => ParamDefaultPolicy::FutureCompatForbidden, + // Re. GCI, we're not bound by backward compatibility. + ItemKind::Const(..) => ParamDefaultPolicy::Forbidden, + _ => return None, + }, + Node::TraitItem(item) => match item.kind { + // Re. GATs and GACs (generic_const_items), we're not bound by backward compatibility. + TraitItemKind::Const(..) | TraitItemKind::Type(..) => ParamDefaultPolicy::Forbidden, + TraitItemKind::Fn(..) => ParamDefaultPolicy::FutureCompatForbidden, + }, + Node::ImplItem(item) => match item.kind { + // Re. GATs and GACs (generic_const_items), we're not bound by backward compatibility. + ImplItemKind::Const(..) | ImplItemKind::Type(..) => ParamDefaultPolicy::Forbidden, + ImplItemKind::Fn(..) => ParamDefaultPolicy::FutureCompatForbidden, + }, + // Generic params are (semantically) invalid on foreign items. Still, for maximum forward + // compatibility, let's hard-reject defaults on them. + Node::ForeignItem(_) => ParamDefaultPolicy::Forbidden, + Node::OpaqueTy(..) => ParamDefaultPolicy::Allowed, + _ => return None, + }) +} + fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option { struct LateBoundRegionsDetector<'tcx> { tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 929ebe1aee181..42a68b29ec754 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1205,18 +1205,19 @@ macro_rules! visit_place_fns { self.super_projection_elem(place_ref, elem, context, location); } - fn super_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { - let mut context = context; - - if !place.projection.is_empty() { - if context.is_use() { - // ^ Only change the context if it is a real use, not a "use" in debuginfo. - context = if context.is_mutating_use() { - PlaceContext::MutatingUse(MutatingUseContext::Projection) - } else { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) - }; - } + fn super_place( + &mut self, + place: &Place<'tcx>, + mut context: PlaceContext, + location: Location, + ) { + if !place.projection.is_empty() && context.is_use() { + // ^ Only change the context if it is a real use, not a "use" in debuginfo. + context = if context.is_mutating_use() { + PlaceContext::MutatingUse(MutatingUseContext::Projection) + } else { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) + }; } self.visit_local(place.local, context, location); @@ -1239,7 +1240,7 @@ macro_rules! visit_place_fns { &mut self, _place_ref: PlaceRef<'tcx>, elem: PlaceElem<'tcx>, - _context: PlaceContext, + context: PlaceContext, location: Location, ) { match elem { @@ -1252,7 +1253,12 @@ macro_rules! visit_place_fns { ProjectionElem::Index(local) => { self.visit_local( local, - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), + if context.is_use() { + // ^ Only change the context if it is a real use, not a "use" in debuginfo. + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) + } else { + context + }, location, ); } diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b4c8b20e50f9c..3ecccb422c463 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -60,9 +60,13 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { let BodyTy::Fn(caller_sig) = self.thir.body_type else { span_bug!( call.span, - "`become` outside of functions should have been disallowed by hit_typeck" + "`become` outside of functions should have been disallowed by hir_typeck" ) }; + // While the `caller_sig` does have its regions erased, it does not have its + // binders anonymized. We call `erase_regions` once again to anonymize any binders + // within the signature, such as in function pointer or `dyn Trait` args. + let caller_sig = self.tcx.erase_regions(caller_sig); let ExprKind::Scope { value, .. } = call.kind else { span_bug!(call.span, "expected scope, found: {call:?}") diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index db933da641371..468ef742dfb73 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -225,6 +225,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { current = target; } let last = current; + *changed |= *start != last; *start = last; while let Some((current, mut terminator)) = terminators.pop() { let Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } = terminator diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 231fb3e2964a9..5e08c3a03d8ac 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -959,36 +959,23 @@ where // Even when a trait bound has been proven using a where-bound, we // still need to consider alias-bounds for normalization, see // `tests/ui/next-solver/alias-bound-shadowed-by-env.rs`. - let candidates_from_env_and_bounds: Vec<_> = self + let mut candidates: Vec<_> = self .assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::EnvAndBounds); // We still need to prefer where-bounds over alias-bounds however. // See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`. - let mut considered_candidates: Vec<_> = if candidates_from_env_and_bounds - .iter() - .any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - { - candidates_from_env_and_bounds - .into_iter() - .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - .map(|c| c.result) - .collect() - } else { - candidates_from_env_and_bounds.into_iter().map(|c| c.result).collect() - }; - - // If the trait goal has been proven by using the environment, we want to treat - // aliases as rigid if there are no applicable projection bounds in the environment. - if considered_candidates.is_empty() { - if let Ok(response) = inject_normalize_to_rigid_candidate(self) { - considered_candidates.push(response); - } + if candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) { + candidates.retain(|c| matches!(c.source, CandidateSource::ParamEnv(_))); + } else if candidates.is_empty() { + // If the trait goal has been proven by using the environment, we want to treat + // aliases as rigid if there are no applicable projection bounds in the environment. + return inject_normalize_to_rigid_candidate(self); } - if let Some(response) = self.try_merge_responses(&considered_candidates) { + if let Some(response) = self.try_merge_candidates(&candidates) { Ok(response) } else { - self.flounder(&considered_candidates) + self.flounder(&candidates) } } TraitGoalProvenVia::Misc => { @@ -998,11 +985,9 @@ where // Prefer "orphaned" param-env normalization predicates, which are used // (for example, and ideally only) when proving item bounds for an impl. let candidates_from_env: Vec<_> = candidates - .iter() - .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - .map(|c| c.result) + .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_))) .collect(); - if let Some(response) = self.try_merge_responses(&candidates_from_env) { + if let Some(response) = self.try_merge_candidates(&candidates_from_env) { return Ok(response); } @@ -1012,12 +997,10 @@ where // means we can just ignore inference constraints and don't have to special-case // constraining the normalized-to `term`. self.filter_specialized_impls(AllowInferenceConstraints::Yes, &mut candidates); - - let responses: Vec<_> = candidates.iter().map(|c| c.result).collect(); - if let Some(response) = self.try_merge_responses(&responses) { + if let Some(response) = self.try_merge_candidates(&candidates) { Ok(response) } else { - self.flounder(&responses) + self.flounder(&candidates) } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index aec9594b834be..2feebe270a6bb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -29,6 +29,7 @@ use tracing::instrument; pub use self::eval_ctxt::{EvalCtxt, GenerateProofTree, SolverDelegateEvalExt}; use crate::delegate::SolverDelegate; +use crate::solve::assembly::Candidate; /// How many fixpoint iterations we should attempt inside of the solver before bailing /// with overflow. @@ -244,50 +245,51 @@ where /// /// In this case we tend to flounder and return ambiguity by calling `[EvalCtxt::flounder]`. #[instrument(level = "trace", skip(self), ret)] - fn try_merge_responses( + fn try_merge_candidates( &mut self, - responses: &[CanonicalResponse], + candidates: &[Candidate], ) -> Option> { - if responses.is_empty() { + if candidates.is_empty() { return None; } - let one = responses[0]; - if responses[1..].iter().all(|&resp| resp == one) { + let one: CanonicalResponse = candidates[0].result; + if candidates[1..].iter().all(|candidate| candidate.result == one) { return Some(one); } - responses + candidates .iter() - .find(|response| { - response.value.certainty == Certainty::Yes - && has_no_inference_or_external_constraints(**response) + .find(|candidate| { + candidate.result.value.certainty == Certainty::Yes + && has_no_inference_or_external_constraints(candidate.result) }) - .copied() + .map(|candidate| candidate.result) } - fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse]) -> CanonicalResponse { - debug_assert!(responses.len() > 1); - let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| { - // Pull down the certainty of `Certainty::Yes` to ambiguity when combining - // these responses, b/c we're combining more than one response and this we - // don't know which one applies. - let candidate = match response.value.certainty { - Certainty::Yes => MaybeCause::Ambiguity, - Certainty::Maybe(candidate) => candidate, - }; - maybe_cause.or(candidate) - }); + fn bail_with_ambiguity(&mut self, candidates: &[Candidate]) -> CanonicalResponse { + debug_assert!(candidates.len() > 1); + let maybe_cause = + candidates.iter().fold(MaybeCause::Ambiguity, |maybe_cause, candidates| { + // Pull down the certainty of `Certainty::Yes` to ambiguity when combining + // these responses, b/c we're combining more than one response and this we + // don't know which one applies. + let candidate = match candidates.result.value.certainty { + Certainty::Yes => MaybeCause::Ambiguity, + Certainty::Maybe(candidate) => candidate, + }; + maybe_cause.or(candidate) + }); self.make_ambiguous_response_no_constraints(maybe_cause) } /// If we fail to merge responses we flounder and return overflow or ambiguity. #[instrument(level = "trace", skip(self), ret)] - fn flounder(&mut self, responses: &[CanonicalResponse]) -> QueryResult { - if responses.is_empty() { + fn flounder(&mut self, candidates: &[Candidate]) -> QueryResult { + if candidates.is_empty() { return Err(NoSolution); } else { - Ok(self.bail_with_ambiguity(responses)) + Ok(self.bail_with_ambiguity(candidates)) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f760c2c07ffb6..60bae738e61b8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1346,11 +1346,10 @@ where mut candidates: Vec>, ) -> Result<(CanonicalResponse, Option), NoSolution> { if let TypingMode::Coherence = self.typing_mode() { - let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); - return if let Some(response) = self.try_merge_responses(&all_candidates) { + return if let Some(response) = self.try_merge_candidates(&candidates) { Ok((response, Some(TraitGoalProvenVia::Misc))) } else { - self.flounder(&all_candidates).map(|r| (r, None)) + self.flounder(&candidates).map(|r| (r, None)) }; } @@ -1375,11 +1374,9 @@ where .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal))); if has_non_global_where_bounds { let where_bounds: Vec<_> = candidates - .iter() - .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) - .map(|c| c.result) + .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_))) .collect(); - return if let Some(response) = self.try_merge_responses(&where_bounds) { + return if let Some(response) = self.try_merge_candidates(&where_bounds) { Ok((response, Some(TraitGoalProvenVia::ParamEnv))) } else { Ok((self.bail_with_ambiguity(&where_bounds), None)) @@ -1388,11 +1385,9 @@ where if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)) { let alias_bounds: Vec<_> = candidates - .iter() - .filter(|c| matches!(c.source, CandidateSource::AliasBound)) - .map(|c| c.result) + .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound)) .collect(); - return if let Some(response) = self.try_merge_responses(&alias_bounds) { + return if let Some(response) = self.try_merge_candidates(&alias_bounds) { Ok((response, Some(TraitGoalProvenVia::AliasBound))) } else { Ok((self.bail_with_ambiguity(&alias_bounds), None)) @@ -1417,11 +1412,10 @@ where TraitGoalProvenVia::Misc }; - let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); - if let Some(response) = self.try_merge_responses(&all_candidates) { + if let Some(response) = self.try_merge_candidates(&candidates) { Ok((response, Some(proven_via))) } else { - self.flounder(&all_candidates).map(|r| (r, None)) + self.flounder(&candidates).map(|r| (r, None)) } } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 859118a4adee5..7059ffbf375f7 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -71,6 +71,17 @@ parse_attr_without_generics = attribute without generic parameters parse_attribute_on_param_type = attributes cannot be applied to a function parameter's type .label = attributes are not allowed here +parse_attribute_on_type = attributes cannot be applied to types + .label = attributes are not allowed here + .suggestion = remove attribute from here + +parse_attribute_on_generic_arg = attributes cannot be applied to generic arguments + .label = attributes are not allowed here + .suggestion = remove attribute from here + +parse_attribute_on_empty_type = attributes cannot be applied here + .label = attributes are not allowed here + parse_bad_assoc_type_bounds = bounds on associated types do not belong here .label = belongs in `where` clause diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 4aaaba01faeb3..48ff0394d463b 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1489,6 +1489,34 @@ pub(crate) struct AttributeOnParamType { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_attribute_on_type)] +pub(crate) struct AttributeOnType { + #[primary_span] + #[label] + pub span: Span, + #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + pub fix_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_attribute_on_generic_arg)] +pub(crate) struct AttributeOnGenericArg { + #[primary_span] + #[label] + pub span: Span, + #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + pub fix_span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_attribute_on_empty_type)] +pub(crate) struct AttributeOnEmptyType { + #[primary_span] + #[label] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_pattern_method_param_without_body, code = E0642)] pub(crate) struct PatternMethodParamWithoutBody { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 65d84b3e3d9d5..cb7c56494332c 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -885,6 +885,9 @@ impl<'a> Parser<'a> { /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> { let constness = self.parse_constness(Case::Sensitive); + if let Const::Yes(span) = constness { + self.psess.gated_spans.gate(sym::const_trait_impl, span); + } let safety = self.parse_safety(Case::Sensitive); // Parse optional `auto` prefix. let is_auto = if self.eat_keyword(exp!(Auto)) { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 1f4049f197fa8..8e65ab99c5e65 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -17,11 +17,11 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::ast::{PatKind, TyKind}; use crate::errors::{ - self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams, - PathSingleColon, PathTripleColon, + self, AttributeOnEmptyType, AttributeOnGenericArg, FnPathFoundNamedParams, + PathFoundAttributeInParams, PathFoundCVariadicParams, PathSingleColon, PathTripleColon, }; use crate::exp; -use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; +use crate::parser::{CommaRecoveryMode, ExprKind, RecoverColon, RecoverComma}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -880,6 +880,12 @@ impl<'a> Parser<'a> { &mut self, ty_generics: Option<&Generics>, ) -> PResult<'a, Option> { + let mut attr_span: Option = None; + if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { + let attrs_wrapper = self.parse_outer_attributes()?; + let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); + attr_span = Some(raw_attrs[0].span.to(raw_attrs.last().unwrap().span)); + } let start = self.token.span; let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. @@ -934,6 +940,9 @@ impl<'a> Parser<'a> { } } else if self.token.is_keyword(kw::Const) { return self.recover_const_param_declaration(ty_generics); + } else if let Some(attr_span) = attr_span { + let diag = self.dcx().create_err(AttributeOnEmptyType { span: attr_span }); + return Err(diag); } else { // Fall back by trying to parse a const-expr expression. If we successfully do so, // then we should report an error that it needs to be wrapped in braces. @@ -953,6 +962,22 @@ impl<'a> Parser<'a> { } } }; + + if let Some(attr_span) = attr_span { + let guar = self.dcx().emit_err(AttributeOnGenericArg { + span: attr_span, + fix_span: attr_span.until(arg.span()), + }); + return Ok(Some(match arg { + GenericArg::Type(_) => GenericArg::Type(self.mk_ty(attr_span, TyKind::Err(guar))), + GenericArg::Const(_) => { + let error_expr = self.mk_expr(attr_span, ExprKind::Err(guar)); + GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value: error_expr }) + } + GenericArg::Lifetime(lt) => GenericArg::Lifetime(lt), + })); + } + Ok(Some(arg)) } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 740dd10ea8ba1..59048e42e6f2b 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -14,10 +14,10 @@ use thin_vec::{ThinVec, thin_vec}; use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; use crate::errors::{ - self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, - FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidDynKeyword, - LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, - ReturnTypesUseThinArrow, + self, AttributeOnEmptyType, AttributeOnType, DynAfterMut, ExpectedFnPathFoundFnKeyword, + ExpectedMutOrConstInRawPointerType, FnPtrWithGenerics, FnPtrWithGenericsSugg, + HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, + NestedCVariadicType, ReturnTypesUseThinArrow, }; use crate::parser::item::FrontMatterParsingMode; use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; @@ -253,7 +253,27 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); + if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { + let attrs_wrapper = self.parse_outer_attributes()?; + let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); + let attr_span = raw_attrs[0].span.to(raw_attrs.last().unwrap().span); + let (full_span, guar) = match self.parse_ty() { + Ok(ty) => { + let full_span = attr_span.until(ty.span); + let guar = self + .dcx() + .emit_err(AttributeOnType { span: attr_span, fix_span: full_span }); + (attr_span, guar) + } + Err(err) => { + err.cancel(); + let guar = self.dcx().emit_err(AttributeOnEmptyType { span: attr_span }); + (attr_span, guar) + } + }; + return Ok(self.mk_ty(full_span, TyKind::Err(guar))); + } if let Some(ty) = self.eat_metavar_seq_with_matcher( |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }), |this| this.parse_ty_no_question_mark_recover(), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2663d5fe99c7a..890028d977d30 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -324,6 +324,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::Coverage(attr_span, _)) => { self.check_coverage(attr_span, span, target) } + &Attribute::Parsed(AttributeKind::Coroutine(attr_span)) => { + self.check_coroutine(attr_span, target) + } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { @@ -390,9 +393,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) } - [sym::coroutine, ..] => { - self.check_coroutine(attr, target); - } [sym::linkage, ..] => self.check_linkage(attr, span, target), [ // ok @@ -2651,11 +2651,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_coroutine(&self, attr: &Attribute, target: Target) { + fn check_coroutine(&self, attr_span: Span, target: Target) { match target { Target::Closure => return, _ => { - self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr.span() }); + self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr_span }); } } } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 72ad7c244eeba..b3ca118a45295 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1111,6 +1111,11 @@ impl File { /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this /// [may change in the future][changes]. /// + /// On most platforms, including UNIX and Windows platforms, this function can also change the + /// timestamps of a directory. To get a `File` representing a directory in order to call + /// `set_times`, open the directory with `File::open` without attempting to obtain write + /// permission. + /// /// [changes]: io#platform-specific-behavior /// /// # Errors @@ -1128,7 +1133,7 @@ impl File { /// use std::fs::{self, File, FileTimes}; /// /// let src = fs::metadata("src")?; - /// let dest = File::options().write(true).open("dest")?; + /// let dest = File::open("dest")?; /// let times = FileTimes::new() /// .set_accessed(src.accessed()?) /// .set_modified(src.modified()?); diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 913ef72f67464..cff4f20b5a812 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -108,8 +108,6 @@ impl<'a> PanicHookInfo<'a> { /// # Example /// /// ```should_panic - /// #![feature(panic_payload_as_str)] - /// /// std::panic::set_hook(Box::new(|panic_info| { /// if let Some(s) = panic_info.payload_as_str() { /// println!("panic occurred: {s:?}"); @@ -122,7 +120,7 @@ impl<'a> PanicHookInfo<'a> { /// ``` #[must_use] #[inline] - #[unstable(feature = "panic_payload_as_str", issue = "125175")] + #[stable(feature = "panic_payload_as_str", since = "CURRENT_RUSTC_VERSION")] pub fn payload_as_str(&self) -> Option<&str> { if let Some(s) = self.payload.downcast_ref::<&str>() { Some(s) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 055e7f814800d..e7ba693643581 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2683,6 +2683,8 @@ impl Path { /// /// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap()); /// assert_eq!("foo", Path::new("foo.tar.gz").file_prefix().unwrap()); + /// assert_eq!(".config", Path::new(".config").file_prefix().unwrap()); + /// assert_eq!(".config", Path::new(".config.toml").file_prefix().unwrap()); /// ``` /// /// # See Also diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f6653ed899bfc..f931aae3c2e04 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -84,7 +84,7 @@ impl Step for Std { Kind::Check, ); - std_cargo(builder, target, stage, &mut cargo); + std_cargo(builder, target, &mut cargo); if matches!(builder.config.cmd, Subcommand::Fix) { // By default, cargo tries to fix all targets. Tell it not to fix tests until we've added `test` to the sysroot. cargo.arg("--lib"); @@ -125,7 +125,7 @@ impl Step for Std { Kind::Check, ); - std_cargo(builder, target, build_compiler.stage, &mut cargo); + std_cargo(builder, target, &mut cargo); // Explicitly pass -p for all dependencies krates -- this will force cargo // to also check the tests/benches/examples for these crates, rather diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index b119f2dc3ce84..93c767bdd253d 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -154,7 +154,7 @@ impl Step for Std { Kind::Clippy, ); - std_cargo(builder, target, compiler.stage, &mut cargo); + std_cargo(builder, target, &mut cargo); for krate in &*self.crates { cargo.arg("-p").arg(krate); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 95707e37018e9..7039f31cdde01 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -269,7 +269,7 @@ impl Step for Std { target, Kind::Build, ); - std_cargo(builder, target, compiler.stage, &mut cargo); + std_cargo(builder, target, &mut cargo); for krate in &*self.crates { cargo.arg("-p").arg(krate); } @@ -497,7 +497,7 @@ fn compiler_rt_for_profiler(builder: &Builder<'_>) -> PathBuf { /// Configure cargo to compile the standard library, adding appropriate env vars /// and such. -pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) { +pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, cargo: &mut Cargo) { // rustc already ensures that it builds with the minimum deployment // target, so ideally we shouldn't need to do anything here. // @@ -645,12 +645,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car // built with bitcode so that the produced rlibs can be used for both LTO // builds (which use bitcode) and non-LTO builds (which use object code). // So we override the override here! - // - // But we don't bother for the stage 0 compiler because it's never used - // with LTO. - if stage >= 1 { - cargo.rustflag("-Cembed-bitcode=yes"); - } + cargo.rustflag("-Cembed-bitcode=yes"); + if builder.config.rust_lto == RustcLto::Off { cargo.rustflag("-Clto=off"); } diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index d4539a0eb34d1..9f3524905d760 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -722,7 +722,7 @@ fn doc_std( let mut cargo = builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, Kind::Doc); - compile::std_cargo(builder, target, compiler.stage, &mut cargo); + compile::std_cargo(builder, target, &mut cargo); cargo .arg("--no-deps") .arg("--target-dir") diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 09d2657b666d4..b6199c74fb17f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2858,7 +2858,7 @@ impl Step for Crate { .arg("--manifest-path") .arg(builder.src.join("library/sysroot/Cargo.toml")); } else { - compile::std_cargo(builder, target, compiler.stage, &mut cargo); + compile::std_cargo(builder, target, &mut cargo); } } Mode::Rustc => { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 782311e593bb4..26b087feb1684 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -480,10 +480,28 @@ impl Item { } } + /// If the item has doc comments from a reexport, returns the item id of that reexport, + /// otherwise returns returns the item id. + /// + /// This is used as a key for caching intra-doc link resolution, + /// to prevent two reexports of the same item from using the same cache. + pub(crate) fn item_or_reexport_id(&self) -> ItemId { + // added documentation on a reexport is always prepended. + self.attrs + .doc_strings + .first() + .map(|x| x.item_id) + .flatten() + .map(ItemId::from) + .unwrap_or(self.item_id) + } + pub(crate) fn links(&self, cx: &Context<'_>) -> Vec { use crate::html::format::{href, link_tooltip}; - let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] }; + let Some(links) = cx.cache().intra_doc_links.get(&self.item_or_reexport_id()) else { + return vec![]; + }; links .iter() .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index fed4296fa2221..c52c7236883af 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -804,8 +804,7 @@ impl Options { let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx); let with_examples = matches.opt_strs("with-examples"); - let call_locations = - crate::scrape_examples::load_call_locations(with_examples, dcx, &mut loaded_paths); + let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx); let doctest_build_args = matches.opt_strs("doctest-build-arg"); let unstable_features = diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c9fa3a4837f29..bcb676cd1f17e 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1082,7 +1082,12 @@ impl LinkCollector<'_, '_> { for md_link in preprocessed_markdown_links(&doc) { let link = self.resolve_link(&doc, item, item_id, module_id, &md_link); if let Some(link) = link { - self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link); + self.cx + .cache + .intra_doc_links + .entry(item.item_or_reexport_id()) + .or_default() + .insert(link); } } } diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index 4d29c74e1eb53..9f71d6ae78992 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -333,11 +333,14 @@ pub(crate) fn run( pub(crate) fn load_call_locations( with_examples: Vec, dcx: DiagCtxtHandle<'_>, - loaded_paths: &mut Vec, ) -> AllCallLocations { let mut all_calls: AllCallLocations = FxIndexMap::default(); for path in with_examples { - loaded_paths.push(path.clone().into()); + // FIXME: Figure out why this line is causing this feature to crash in specific contexts. + // Full issue backlog is available here: . + // + // Can be checked with `tests/run-make/rustdoc-scrape-examples-paths`. + // loaded_paths.push(path.clone().into()); let bytes = match fs::read(&path) { Ok(bytes) => bytes, Err(e) => dcx.fatal(format!("failed to load examples: {e}")), diff --git a/tests/run-make/rustdoc-scrape-examples-paths/foo/Cargo.toml b/tests/run-make/rustdoc-scrape-examples-paths/foo/Cargo.toml new file mode 100644 index 0000000000000..6962028375bb7 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-paths/foo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "foo" +version = "0.0.1" +edition = "2024" + +[[example]] +name = "complex" +doc-scrape-examples = true diff --git a/tests/run-make/rustdoc-scrape-examples-paths/foo/examples/complex.rs b/tests/run-make/rustdoc-scrape-examples-paths/foo/examples/complex.rs new file mode 100644 index 0000000000000..1cda7e098f455 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-paths/foo/examples/complex.rs @@ -0,0 +1,3 @@ +fn main() { + let mut x = foo::X::new(); +} diff --git a/tests/run-make/rustdoc-scrape-examples-paths/foo/examples/tester.rs b/tests/run-make/rustdoc-scrape-examples-paths/foo/examples/tester.rs new file mode 100644 index 0000000000000..fbd1906ec0997 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-paths/foo/examples/tester.rs @@ -0,0 +1 @@ +// This file MUST exist to trigger the original bug. diff --git a/tests/run-make/rustdoc-scrape-examples-paths/foo/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-paths/foo/src/lib.rs new file mode 100644 index 0000000000000..a9bb0272c7870 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-paths/foo/src/lib.rs @@ -0,0 +1,7 @@ +pub struct X; + +impl X { + pub fn new() -> Self { + X + } +} diff --git a/tests/run-make/rustdoc-scrape-examples-paths/rmake.rs b/tests/run-make/rustdoc-scrape-examples-paths/rmake.rs new file mode 100644 index 0000000000000..03888f69eab13 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-paths/rmake.rs @@ -0,0 +1,16 @@ +//! Test to ensure that the rustdoc `scrape-examples` feature is not panicking. +//! Regression test for . + +use run_make_support::{cargo, path, rfs}; + +fn main() { + // We copy the crate to be documented "outside" to prevent documenting + // the whole compiler. + let tmp = std::env::temp_dir(); + let test_crate = tmp.join("foo"); + rfs::copy_dir_all(path("foo"), &test_crate); + + // The `scrape-examples` feature is also implemented in `cargo` so instead of reproducing + // what `cargo` does, better to just let `cargo` do it. + cargo().current_dir(&test_crate).args(["doc", "-p", "foo", "-Zrustdoc-scrape-examples"]).run(); +} diff --git a/tests/rustdoc/intra-doc/macro-caching-144965.rs b/tests/rustdoc/intra-doc/macro-caching-144965.rs new file mode 100644 index 0000000000000..e14b465aeea6d --- /dev/null +++ b/tests/rustdoc/intra-doc/macro-caching-144965.rs @@ -0,0 +1,35 @@ +// regression test for https://github.com/rust-lang/rust/issues/144965 + +#![crate_name = "foo"] +#![no_std] + +#[doc(hidden)] +pub struct MyStruct; + +macro_rules! my_macro { + () => { + pub fn my_function() {} + + /// Incorrect: [`my_function()`]. + #[doc(inline)] + pub use $crate::MyStruct; + + /// Correct: [`my_function`]. + pub struct AnotherStruct; + }; +} + + +pub mod one { + //@ has 'foo/one/index.html' + //@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function' + //@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()' + my_macro!(); +} + +pub mod two { + //@ has 'foo/two/index.html' + //@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function' + //@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()' + my_macro!(); +} diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 1b51075b4e888..e8ae4715398f4 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -55,12 +55,6 @@ error: malformed `patchable_function_entry` attribute input LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` -error: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:108:5 - | -LL | #[coroutine = 63] || {} - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` - error: malformed `must_not_suspend` attribute input --> $DIR/malformed-attrs.rs:129:1 | @@ -436,6 +430,15 @@ LL | #[proc_macro = 18] | | didn't expect any arguments here | help: must be of the form: `#[proc_macro]` +error[E0565]: malformed `coroutine` attribute input + --> $DIR/malformed-attrs.rs:108:5 + | +LL | #[coroutine = 63] || {} + | ^^^^^^^^^^^^----^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[coroutine]` + error[E0565]: malformed `proc_macro_attribute` attribute input --> $DIR/malformed-attrs.rs:113:1 | diff --git a/tests/ui/const-generics/defaults/default-on-impl.rs b/tests/ui/const-generics/defaults/default-on-impl.rs index 9ce46aa09dee6..85d0c58396592 100644 --- a/tests/ui/const-generics/defaults/default-on-impl.rs +++ b/tests/ui/const-generics/defaults/default-on-impl.rs @@ -1,6 +1,6 @@ struct Foo; impl Foo {} -//~^ ERROR defaults for const parameters are only allowed +//~^ ERROR defaults for generic parameters are not allowed here fn main() {} diff --git a/tests/ui/const-generics/defaults/default-on-impl.stderr b/tests/ui/const-generics/defaults/default-on-impl.stderr index 691e0354eddc2..eb5d57e14bf89 100644 --- a/tests/ui/const-generics/defaults/default-on-impl.stderr +++ b/tests/ui/const-generics/defaults/default-on-impl.stderr @@ -1,4 +1,4 @@ -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/default-on-impl.rs:3:6 | LL | impl Foo {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs index a107556fd79dd..85a28f2b3303b 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs @@ -1,10 +1,10 @@ #![feature(generic_const_exprs)] -#![allow(incomplete_features)] +#![expect(incomplete_features)] trait Trait { - fn fnc(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + fn fnc(&self) {} //~ERROR defaults for generic parameters are not allowed here //~^ ERROR: mismatched types - fn foo() }>(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + fn foo() }>(&self) {} //~ERROR defaults for generic parameters are not allowed here } fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr index d7ded0f1f748b..1d0ab56519cfb 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr @@ -1,10 +1,10 @@ -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/issue-105257.rs:5:12 | LL | fn fnc(&self) {} | ^^^^^^^^^^^^^^^^^^^ -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/issue-105257.rs:7:12 | LL | fn foo() }>(&self) {} diff --git a/tests/ui/const-generics/min_const_generics/default_function_param.rs b/tests/ui/const-generics/min_const_generics/default_function_param.rs index 92d495ef6653b..153cd94849eb5 100644 --- a/tests/ui/const-generics/min_const_generics/default_function_param.rs +++ b/tests/ui/const-generics/min_const_generics/default_function_param.rs @@ -1,4 +1,4 @@ #![crate_type = "lib"] fn foo() {} -//~^ ERROR defaults for const parameters are +//~^ ERROR defaults for generic parameters are not allowed here diff --git a/tests/ui/const-generics/min_const_generics/default_function_param.stderr b/tests/ui/const-generics/min_const_generics/default_function_param.stderr index 247eea3d98995..261298a1c6340 100644 --- a/tests/ui/const-generics/min_const_generics/default_function_param.stderr +++ b/tests/ui/const-generics/min_const_generics/default_function_param.stderr @@ -1,4 +1,4 @@ -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/default_function_param.rs:3:8 | LL | fn foo() {} diff --git a/tests/ui/explicit-tail-calls/higher-ranked-arg.rs b/tests/ui/explicit-tail-calls/higher-ranked-arg.rs new file mode 100644 index 0000000000000..e60686ab5111d --- /dev/null +++ b/tests/ui/explicit-tail-calls/higher-ranked-arg.rs @@ -0,0 +1,13 @@ +// Regression test for . +//@ check-pass + +#![feature(explicit_tail_calls)] +#![expect(incomplete_features)] + +fn foo(x: fn(&i32)) { + become bar(x); +} + +fn bar(_: fn(&i32)) {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs new file mode 100644 index 0000000000000..111ae849c0f6a --- /dev/null +++ b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs @@ -0,0 +1,16 @@ +#![feature(explicit_tail_calls)] +#![expect(incomplete_features)] + +fn link(x: &str) -> &'static str { + become passthrough(x); + //~^ ERROR lifetime may not live long enough +} + +fn passthrough(t: T) -> T { t } + +fn main() { + let x = String::from("hello, world"); + let s = link(&x); + drop(x); + println!("{s}"); +} diff --git a/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.stderr b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.stderr new file mode 100644 index 0000000000000..26a8e1f0122ad --- /dev/null +++ b/tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/ret-ty-borrowck-constraints.rs:5:5 + | +LL | fn link(x: &str) -> &'static str { + | - let's call the lifetime of this reference `'1` +LL | become passthrough(x); + | ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/generic-associated-types/type-param-defaults.rs b/tests/ui/generic-associated-types/type-param-defaults.rs index eea54c460734c..6e9a62b96c4bc 100644 --- a/tests/ui/generic-associated-types/type-param-defaults.rs +++ b/tests/ui/generic-associated-types/type-param-defaults.rs @@ -4,17 +4,17 @@ trait Trait { type Assoc; - //~^ ERROR defaults for type parameters are only allowed + //~^ ERROR defaults for generic parameters are not allowed here } impl Trait for () { type Assoc = u64; - //~^ ERROR defaults for type parameters are only allowed + //~^ ERROR defaults for generic parameters are not allowed here } impl Trait for u32 { type Assoc = T; - //~^ ERROR defaults for type parameters are only allowed + //~^ ERROR defaults for generic parameters are not allowed here } trait Other {} diff --git a/tests/ui/generic-associated-types/type-param-defaults.stderr b/tests/ui/generic-associated-types/type-param-defaults.stderr index 3c094d45fffcc..d9872dadbdb2e 100644 --- a/tests/ui/generic-associated-types/type-param-defaults.stderr +++ b/tests/ui/generic-associated-types/type-param-defaults.stderr @@ -1,16 +1,16 @@ -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/type-param-defaults.rs:6:16 | LL | type Assoc; | ^^^^^^^ -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/type-param-defaults.rs:11:16 | LL | type Assoc = u64; | ^^^^^^^ -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/type-param-defaults.rs:16:16 | LL | type Assoc = T; diff --git a/tests/ui/generic-const-items/parameter-defaults.rs b/tests/ui/generic-const-items/parameter-defaults.rs index c933db17fa209..b52cb0fd0028b 100644 --- a/tests/ui/generic-const-items/parameter-defaults.rs +++ b/tests/ui/generic-const-items/parameter-defaults.rs @@ -7,9 +7,17 @@ // FIXME(default_type_parameter_fallback): Consider reallowing them once they work properly. -const NONE: Option = None::; //~ ERROR defaults for type parameters are only allowed +const NONE: Option = None::; +//~^ ERROR defaults for generic parameters are not allowed here -fn main() { - let _ = NONE; - //~^ ERROR type annotations needed +impl Host { + const NADA: Option = None::; + //~^ ERROR defaults for generic parameters are not allowed here } + +enum Host {} + +fn body0() { let _ = NONE; } //~ ERROR type annotations needed +fn body1() { let _ = Host::NADA; } //~ ERROR type annotations needed + +fn main() {} diff --git a/tests/ui/generic-const-items/parameter-defaults.stderr b/tests/ui/generic-const-items/parameter-defaults.stderr index 13562c98f6d96..9bf1f6412f59b 100644 --- a/tests/ui/generic-const-items/parameter-defaults.stderr +++ b/tests/ui/generic-const-items/parameter-defaults.stderr @@ -1,20 +1,37 @@ -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/parameter-defaults.rs:10:12 | LL | const NONE: Option = None::; | ^^^^^^ +error: defaults for generic parameters are not allowed here + --> $DIR/parameter-defaults.rs:14:16 + | +LL | const NADA: Option = None::; + | ^^^^^^ + +error[E0282]: type annotations needed for `Option<_>` + --> $DIR/parameter-defaults.rs:20:18 + | +LL | fn body0() { let _ = NONE; } + | ^ ---- type must be known at this point + | +help: consider giving this pattern a type, where the type for type parameter `T` is specified + | +LL | fn body0() { let _: Option = NONE; } + | +++++++++++ + error[E0282]: type annotations needed for `Option<_>` - --> $DIR/parameter-defaults.rs:13:9 + --> $DIR/parameter-defaults.rs:21:18 | -LL | let _ = NONE; - | ^ ---- type must be known at this point +LL | fn body1() { let _ = Host::NADA; } + | ^ ---------- type must be known at this point | help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let _: Option = NONE; - | +++++++++++ +LL | fn body1() { let _: Option = Host::NADA; } + | +++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/generics/generic-extern.rs b/tests/ui/generics/generic-extern.rs index 36fa5eaafd672..b4f00fc118767 100644 --- a/tests/ui/generics/generic-extern.rs +++ b/tests/ui/generics/generic-extern.rs @@ -1,7 +1,15 @@ +// Ensure that we reject generic parameters on foreign items. + extern "C" { fn foo(); //~ ERROR foreign items may not have type parameters + + // Furthermore, check that type parameter defaults lead to a *hard* error, + // not just a lint error, for maximum forward compatibility. + #[allow(invalid_type_param_default)] // Should have no effect here. + fn bar(); //~ ERROR foreign items may not have type parameters + //~^ ERROR defaults for generic parameters are not allowed here } fn main() { - foo::(); //~ ERROR requires unsafe + unsafe { foo::() }; } diff --git a/tests/ui/generics/generic-extern.stderr b/tests/ui/generics/generic-extern.stderr index a3f2882531638..6e83715681264 100644 --- a/tests/ui/generics/generic-extern.stderr +++ b/tests/ui/generics/generic-extern.stderr @@ -1,20 +1,25 @@ error[E0044]: foreign items may not have type parameters - --> $DIR/generic-extern.rs:2:5 + --> $DIR/generic-extern.rs:4:5 | LL | fn foo(); | ^^^^^^^^^^^^ can't have type parameters | = help: replace the type parameters with concrete types like `u32` -error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block - --> $DIR/generic-extern.rs:6:5 +error: defaults for generic parameters are not allowed here + --> $DIR/generic-extern.rs:9:12 | -LL | foo::(); - | ^^^^^^^^^^^^ call to unsafe function +LL | fn bar(); + | ^^^^^^ + +error[E0044]: foreign items may not have type parameters + --> $DIR/generic-extern.rs:9:5 | - = note: consult the function's documentation for information on how to avoid undefined behavior +LL | fn bar(); + | ^^^^^^^^^^^^^^^^^ can't have type parameters + | + = help: replace the type parameters with concrete types like `u32` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0044, E0133. -For more information about an error, try `rustc --explain E0044`. +For more information about this error, try `rustc --explain E0044`. diff --git a/tests/ui/generics/invalid-type-param-default.rs b/tests/ui/generics/invalid-type-param-default.rs new file mode 100644 index 0000000000000..b47e142605c37 --- /dev/null +++ b/tests/ui/generics/invalid-type-param-default.rs @@ -0,0 +1,22 @@ +// Ensure that we emit the deny-by-default lint `invalid_type_param_default` in locations where +// type parameter defaults were accidentally allowed but don't have any effect whatsoever. +// +// Tracked in . +// FIXME(default_type_parameter_fallback): Consider reallowing them once they work properly. + +fn avg(_: T) {} +//~^ ERROR defaults for generic parameters are not allowed here [invalid_type_param_default] +//~| WARN this was previously accepted + +// issue: +fn mdn(_: T) {} +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared +//~| ERROR defaults for generic parameters are not allowed here [invalid_type_param_default] +//~| WARN this was previously accepted + +struct S(T); +impl S {} +//~^ ERROR defaults for generic parameters are not allowed here [invalid_type_param_default] +//~| WARN this was previously accepted + +fn main() {} diff --git a/tests/ui/generics/invalid-type-param-default.stderr b/tests/ui/generics/invalid-type-param-default.stderr new file mode 100644 index 0000000000000..1c8fdd8ab5ca8 --- /dev/null +++ b/tests/ui/generics/invalid-type-param-default.stderr @@ -0,0 +1,70 @@ +error[E0128]: generic parameter defaults cannot reference parameters before they are declared + --> $DIR/invalid-type-param-default.rs:12:12 + | +LL | fn mdn(_: T) {} + | ^^^^^^^ cannot reference `T` before it is declared + +error: defaults for generic parameters are not allowed here + --> $DIR/invalid-type-param-default.rs:7:8 + | +LL | fn avg(_: T) {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + = note: `#[deny(invalid_type_param_default)]` on by default + +error: defaults for generic parameters are not allowed here + --> $DIR/invalid-type-param-default.rs:12:8 + | +LL | fn mdn(_: T) {} + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + +error: defaults for generic parameters are not allowed here + --> $DIR/invalid-type-param-default.rs:18:6 + | +LL | impl S {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0128`. +Future incompatibility report: Future breakage diagnostic: +error: defaults for generic parameters are not allowed here + --> $DIR/invalid-type-param-default.rs:7:8 + | +LL | fn avg(_: T) {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + = note: `#[deny(invalid_type_param_default)]` on by default + +Future breakage diagnostic: +error: defaults for generic parameters are not allowed here + --> $DIR/invalid-type-param-default.rs:12:8 + | +LL | fn mdn(_: T) {} + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + = note: `#[deny(invalid_type_param_default)]` on by default + +Future breakage diagnostic: +error: defaults for generic parameters are not allowed here + --> $DIR/invalid-type-param-default.rs:18:6 + | +LL | impl S {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + = note: `#[deny(invalid_type_param_default)]` on by default + diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.rs b/tests/ui/generics/overlapping-errors-span-issue-123861.rs index e0a27f6874874..2549f4b371465 100644 --- a/tests/ui/generics/overlapping-errors-span-issue-123861.rs +++ b/tests/ui/generics/overlapping-errors-span-issue-123861.rs @@ -1,7 +1,7 @@ fn mainIterator<_ = _> {} //~^ ERROR expected identifier, found reserved identifier `_` //~| ERROR missing parameters for function definition -//~| ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions [invalid_type_param_default] +//~| ERROR defaults for generic parameters are not allowed here [invalid_type_param_default] //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! //~| ERROR the placeholder `_` is not allowed within types on item signatures for functions [E0121] diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.stderr b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr index 7d08d8fed9f92..44e8b4a01e7fd 100644 --- a/tests/ui/generics/overlapping-errors-span-issue-123861.stderr +++ b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr @@ -15,7 +15,7 @@ help: add a parameter list LL | fn mainIterator<_ = _>() {} | ++ -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/overlapping-errors-span-issue-123861.rs:1:17 | LL | fn mainIterator<_ = _> {} @@ -35,7 +35,7 @@ error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0121`. Future incompatibility report: Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/overlapping-errors-span-issue-123861.rs:1:17 | LL | fn mainIterator<_ = _> {} diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs index 1c3c66c537ff9..04a95f7f6f013 100644 --- a/tests/ui/impl-trait/where-allowed.rs +++ b/tests/ui/impl-trait/where-allowed.rs @@ -236,17 +236,15 @@ type InTypeAliasGenericParamDefault = T; //~^ ERROR `impl Trait` is not allowed in generic parameter defaults // Disallowed -impl T {} -//~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions -//~| WARNING this was previously accepted by the compiler but is being phased out -//~| ERROR `impl Trait` is not allowed in generic parameter defaults +#[expect(invalid_type_param_default)] +impl T {} +//~^ ERROR `impl Trait` is not allowed in generic parameter defaults //~| ERROR no nominal type found // Disallowed +#[expect(invalid_type_param_default)] fn in_method_generic_param_default(_: T) {} -//~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions -//~| WARNING this was previously accepted by the compiler but is being phased out -//~| ERROR `impl Trait` is not allowed in generic parameter defaults +//~^ ERROR `impl Trait` is not allowed in generic parameter defaults fn main() { let _in_local_variable: impl Fn() = || {}; diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 052ae5a99315c..08caff326c470 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -311,10 +311,10 @@ LL | type InTypeAliasGenericParamDefault = T; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:239:11 + --> $DIR/where-allowed.rs:240:10 | -LL | impl T {} - | ^^^^^^^^^^ +LL | impl T {} + | ^^^^^^^^^^ | = note: `impl Trait` is only allowed in arguments and return types of functions and methods @@ -327,7 +327,7 @@ LL | fn in_method_generic_param_default(_: T) {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/where-allowed.rs:252:29 + --> $DIR/where-allowed.rs:250:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ @@ -338,7 +338,7 @@ LL | let _in_local_variable: impl Fn() = || {}; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in closure return types - --> $DIR/where-allowed.rs:254:46 + --> $DIR/where-allowed.rs:252:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ @@ -368,25 +368,6 @@ LL - fn in_trait_impl_return() -> impl Debug { () } LL + fn in_trait_impl_return() -> <() as DummyTrait>::Out { () } | -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:246:36 - | -LL | fn in_method_generic_param_default(_: T) {} - | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default - -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:239:7 - | -LL | impl T {} - | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - error[E0283]: type annotations needed --> $DIR/where-allowed.rs:46:57 | @@ -408,10 +389,10 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:239:1 + --> $DIR/where-allowed.rs:240:1 | -LL | impl T {} - | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type +LL | impl T {} + | ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead @@ -431,29 +412,21 @@ LL | type InTypeAlias = impl Debug; | = note: `InTypeAlias` must be used in combination with a concrete type within the same crate -error: aborting due to 50 previous errors +error: aborting due to 48 previous errors Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666. For more information about an error, try `rustc --explain E0053`. Future incompatibility report: Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +warning: defaults for generic parameters are not allowed here --> $DIR/where-allowed.rs:246:36 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:239:7 - | -LL | impl T {} - | ^^^^^^^^^^^^^^ +warning: defaults for generic parameters are not allowed here + --> $DIR/where-allowed.rs:240:6 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default +LL | impl T {} + | ^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-26812.rs b/tests/ui/issues/issue-26812.rs deleted file mode 100644 index 8eb030a8ec94f..0000000000000 --- a/tests/ui/issues/issue-26812.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn avg(_: T) {} -//~^ ERROR generic parameter defaults cannot reference parameters before they are declared -//~| ERROR defaults for type parameters -//~| WARN previously accepted - -fn main() {} diff --git a/tests/ui/issues/issue-26812.stderr b/tests/ui/issues/issue-26812.stderr deleted file mode 100644 index bb60d67e2876e..0000000000000 --- a/tests/ui/issues/issue-26812.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0128]: generic parameter defaults cannot reference parameters before they are declared - --> $DIR/issue-26812.rs:1:10 - | -LL | fn avg(_: T) {} - | ^^^^^^^ cannot reference `T` before it is declared - -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/issue-26812.rs:1:8 - | -LL | fn avg(_: T) {} - | ^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0128`. -Future incompatibility report: Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/issue-26812.rs:1:8 - | -LL | fn avg(_: T) {} - | ^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default - diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs index 0e92b41ae1ee2..b3e9642332b09 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.rs +++ b/tests/ui/lifetimes/unusual-rib-combinations.rs @@ -14,7 +14,7 @@ fn b() {} // Paren generic args in AnonymousReportError fn c() {} //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait -//~| ERROR defaults for type parameters are only allowed in +//~| ERROR defaults for generic parameters are not allowed here //~| WARN this was previously accepted // Elided lifetime in path in ConstGeneric diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 7373ca8cf8434..bd68479c58c54 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -22,7 +22,7 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait LL | fn c() {} | ^^^^ only `Fn` traits may use parentheses -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/unusual-rib-combinations.rs:15:6 | LL | fn c() {} @@ -43,7 +43,7 @@ error: aborting due to 6 previous errors Some errors have detailed explanations: E0106, E0214, E0308, E0770. For more information about an error, try `rustc --explain E0106`. Future incompatibility report: Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/unusual-rib-combinations.rs:15:6 | LL | fn c() {} diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.rs b/tests/ui/missing/missing-items/missing-type-parameter2.rs index e9b32fb7198d4..772e60b1376c3 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.rs +++ b/tests/ui/missing/missing-items/missing-type-parameter2.rs @@ -5,7 +5,7 @@ impl X {} //~| ERROR unresolved item provided when a constant was expected impl X {} //~^ ERROR cannot find type `N` in this scope -//~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +//~| ERROR defaults for generic parameters are not allowed here //~| ERROR unresolved item provided when a constant was expected fn foo(_: T) where T: Send {} diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.stderr b/tests/ui/missing/missing-items/missing-type-parameter2.stderr index f6418de20b6a4..3c132e769eaef 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.stderr +++ b/tests/ui/missing/missing-items/missing-type-parameter2.stderr @@ -103,7 +103,7 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | impl X<{ N }> {} | + + -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/missing-type-parameter2.rs:6:9 | LL | impl X {} diff --git a/tests/ui/parser/attribute-on-empty.rs b/tests/ui/parser/attribute-on-empty.rs new file mode 100644 index 0000000000000..5932377f73eca --- /dev/null +++ b/tests/ui/parser/attribute-on-empty.rs @@ -0,0 +1,29 @@ +//! Regression test for: +//! + +struct Baz(i32); + +fn main() { + let _: Baz<#[cfg(any())]> = todo!(); + //~^ ERROR attributes cannot be applied here +} + +fn f(_param: #[attr]) {} +//~^ ERROR attributes cannot be applied to a function parameter's type +//~| ERROR expected type, found `)` + +fn g() -> #[attr] { 0 } +//~^ ERROR attributes cannot be applied here + +struct S { + field: #[attr], + //~^ ERROR attributes cannot be applied here + field1: (#[attr], i32), + //~^ ERROR attributes cannot be applied here +} + +type Tuple = (#[attr], String); +//~^ ERROR attributes cannot be applied here + +impl #[attr] {} +//~^ ERROR attributes cannot be applied here diff --git a/tests/ui/parser/attribute-on-empty.stderr b/tests/ui/parser/attribute-on-empty.stderr new file mode 100644 index 0000000000000..7c4806c8704aa --- /dev/null +++ b/tests/ui/parser/attribute-on-empty.stderr @@ -0,0 +1,52 @@ +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:7:16 + | +LL | let _: Baz<#[cfg(any())]> = todo!(); + | - ^^^^^^^^^^^^^ attributes are not allowed here + | | + | while parsing the type for `_` + +error: attributes cannot be applied to a function parameter's type + --> $DIR/attribute-on-empty.rs:11:14 + | +LL | fn f(_param: #[attr]) {} + | ^^^^^^^ attributes are not allowed here + +error: expected type, found `)` + --> $DIR/attribute-on-empty.rs:11:21 + | +LL | fn f(_param: #[attr]) {} + | ^ expected type + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:15:11 + | +LL | fn g() -> #[attr] { 0 } + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:19:12 + | +LL | field: #[attr], + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:21:14 + | +LL | field1: (#[attr], i32), + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:25:15 + | +LL | type Tuple = (#[attr], String); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied here + --> $DIR/attribute-on-empty.rs:28:6 + | +LL | impl #[attr] {} + | ^^^^^^^ attributes are not allowed here + +error: aborting due to 8 previous errors + diff --git a/tests/ui/parser/attribute-on-type.fixed b/tests/ui/parser/attribute-on-type.fixed new file mode 100644 index 0000000000000..5024bfdc2bce9 --- /dev/null +++ b/tests/ui/parser/attribute-on-type.fixed @@ -0,0 +1,58 @@ +//! Regression test for: +//! + +//@ run-rustfix + +#![allow(dead_code, unused_variables)] + +struct Foo(T); +struct Bar<'a>(&'a i32); +struct Baz(i32); + +fn main() { + let foo: Foo = Foo(2i32); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: &'static str = "123"; + //~^ ERROR attributes cannot be applied to types + + let _: Bar<'static> = Bar(&123); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Baz<42> = Baz(42); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Foo = Foo(String::new()); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Bar<'static> = Bar(&456); + //~^ ERROR attributes cannot be applied to generic arguments + + let _generic: Box = Box::new(1); + //~^ ERROR attributes cannot be applied to generic arguments + + let _assignment: i32 = *Box::new(1); + //~^ ERROR attributes cannot be applied to types + + let _complex: Vec = vec![]; + //~^ ERROR attributes cannot be applied to generic arguments + + let _nested: Box> = Box::new(vec![]); + //~^ ERROR attributes cannot be applied to generic arguments +} + +fn g() -> i32 { 0 } +//~^ ERROR attributes cannot be applied to types + +struct S { + field: i32, + //~^ ERROR attributes cannot be applied to types + field1: (i32, i32), + //~^ ERROR attributes cannot be applied to types +} + +type Tuple = (i32, String); +//~^ ERROR attributes cannot be applied to types + +impl S {} +//~^ ERROR attributes cannot be applied to types diff --git a/tests/ui/parser/attribute-on-type.rs b/tests/ui/parser/attribute-on-type.rs new file mode 100644 index 0000000000000..196d322bdf8f3 --- /dev/null +++ b/tests/ui/parser/attribute-on-type.rs @@ -0,0 +1,58 @@ +//! Regression test for: +//! + +//@ run-rustfix + +#![allow(dead_code, unused_variables)] + +struct Foo(T); +struct Bar<'a>(&'a i32); +struct Baz(i32); + +fn main() { + let foo: Foo<#[cfg(not(wrong))] i32> = Foo(2i32); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: #[attr] &'static str = "123"; + //~^ ERROR attributes cannot be applied to types + + let _: Bar<#[cfg(any())] 'static> = Bar(&123); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Baz<#[cfg(any())] 42> = Baz(42); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); + //~^ ERROR attributes cannot be applied to generic arguments + + let _: Bar<#[cfg(any())] 'static> = Bar(&456); + //~^ ERROR attributes cannot be applied to generic arguments + + let _generic: Box<#[attr] i32> = Box::new(1); + //~^ ERROR attributes cannot be applied to generic arguments + + let _assignment: #[attr] i32 = *Box::new(1); + //~^ ERROR attributes cannot be applied to types + + let _complex: Vec<#[derive(Debug)] String> = vec![]; + //~^ ERROR attributes cannot be applied to generic arguments + + let _nested: Box> = Box::new(vec![]); + //~^ ERROR attributes cannot be applied to generic arguments +} + +fn g() -> #[attr] i32 { 0 } +//~^ ERROR attributes cannot be applied to types + +struct S { + field: #[attr] i32, + //~^ ERROR attributes cannot be applied to types + field1: (#[attr] i32, i32), + //~^ ERROR attributes cannot be applied to types +} + +type Tuple = (#[attr] i32, String); +//~^ ERROR attributes cannot be applied to types + +impl #[attr] S {} +//~^ ERROR attributes cannot be applied to types diff --git a/tests/ui/parser/attribute-on-type.stderr b/tests/ui/parser/attribute-on-type.stderr new file mode 100644 index 0000000000000..603c7e2be51a0 --- /dev/null +++ b/tests/ui/parser/attribute-on-type.stderr @@ -0,0 +1,92 @@ +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:13:18 + | +LL | let foo: Foo<#[cfg(not(wrong))] i32> = Foo(2i32); + | ^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:16:12 + | +LL | let _: #[attr] &'static str = "123"; + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:19:16 + | +LL | let _: Bar<#[cfg(any())] 'static> = Bar(&123); + | ^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:22:16 + | +LL | let _: Baz<#[cfg(any())] 42> = Baz(42); + | ^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:25:16 + | +LL | let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); + | ^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:28:16 + | +LL | let _: Bar<#[cfg(any())] 'static> = Bar(&456); + | ^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:31:23 + | +LL | let _generic: Box<#[attr] i32> = Box::new(1); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:34:22 + | +LL | let _assignment: #[attr] i32 = *Box::new(1); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:37:23 + | +LL | let _complex: Vec<#[derive(Debug)] String> = vec![]; + | ^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to generic arguments + --> $DIR/attribute-on-type.rs:40:26 + | +LL | let _nested: Box> = Box::new(vec![]); + | ^^^^^^^^^^^^^^^^^^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:44:11 + | +LL | fn g() -> #[attr] i32 { 0 } + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:48:12 + | +LL | field: #[attr] i32, + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:50:14 + | +LL | field1: (#[attr] i32, i32), + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:54:15 + | +LL | type Tuple = (#[attr] i32, String); + | ^^^^^^^ attributes are not allowed here + +error: attributes cannot be applied to types + --> $DIR/attribute-on-type.rs:57:6 + | +LL | impl #[attr] S {} + | ^^^^^^^ attributes are not allowed here + +error: aborting due to 15 previous errors + diff --git a/tests/ui/parser/issues/issue-103143.rs b/tests/ui/parser/issues/issue-103143.rs index a584274c40514..90f10fc1a089c 100644 --- a/tests/ui/parser/issues/issue-103143.rs +++ b/tests/ui/parser/issues/issue-103143.rs @@ -1,5 +1,5 @@ fn main() { x::<#[a]y::> - //~^ ERROR invalid const generic expression + //~^ ERROR attributes cannot be applied to generic arguments //~| ERROR cannot find value `x` in this scope } diff --git a/tests/ui/parser/issues/issue-103143.stderr b/tests/ui/parser/issues/issue-103143.stderr index 4035c69afa712..168a2077396c7 100644 --- a/tests/ui/parser/issues/issue-103143.stderr +++ b/tests/ui/parser/issues/issue-103143.stderr @@ -1,13 +1,8 @@ -error: invalid const generic expression - --> $DIR/issue-103143.rs:2:13 +error: attributes cannot be applied to generic arguments + --> $DIR/issue-103143.rs:2:9 | LL | x::<#[a]y::> - | ^^^^^^ - | -help: expressions must be enclosed in braces to be used as const generic arguments - | -LL | x::<#[a]{ y:: }> - | + + + | ^^^^ attributes are not allowed here error[E0425]: cannot find value `x` in this scope --> $DIR/issue-103143.rs:2:5 diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed index a851300a9828e..40028307a8cb1 100644 --- a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.fixed @@ -1,7 +1,9 @@ // Regression test for issues #100790 and #106439. //@ run-rustfix -pub struct Example(#[allow(dead_code)] usize) +#![allow(dead_code)] + +pub struct Example(usize) where (): Sized; //~^^^ ERROR where clauses are not allowed before tuple struct bodies diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs index 10f435859f15a..d8dbb4238d206 100644 --- a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.rs @@ -1,10 +1,12 @@ // Regression test for issues #100790 and #106439. //@ run-rustfix +#![allow(dead_code)] + pub struct Example where (): Sized, -(#[allow(dead_code)] usize); +(usize); //~^^^ ERROR where clauses are not allowed before tuple struct bodies struct _Demo diff --git a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr index ddbf237e8662b..66dadd9fd4c24 100644 --- a/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr +++ b/tests/ui/parser/recover/recover-where-clause-before-tuple-struct-body-0.stderr @@ -1,23 +1,23 @@ error: where clauses are not allowed before tuple struct bodies - --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:5:1 + --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:7:1 | LL | pub struct Example | ------- while parsing this tuple struct LL | / where LL | | (): Sized, | |______________^ unexpected where clause -LL | (#[allow(dead_code)] usize); - | --------------------------- the struct body +LL | (usize); + | ------- the struct body | help: move the body before the where clause | -LL ~ pub struct Example(#[allow(dead_code)] usize) +LL ~ pub struct Example(usize) LL | where LL ~ (): Sized; | error: where clauses are not allowed before tuple struct bodies - --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:11:1 + --> $DIR/recover-where-clause-before-tuple-struct-body-0.rs:13:1 | LL | struct _Demo | ----- while parsing this tuple struct diff --git a/tests/ui/traits/const-traits/feature-gate.rs b/tests/ui/traits/const-traits/feature-gate.rs index 5ad56ddcd334e..c2918f0249b9e 100644 --- a/tests/ui/traits/const-traits/feature-gate.rs +++ b/tests/ui/traits/const-traits/feature-gate.rs @@ -13,6 +13,9 @@ impl const T for S {} const fn f() {} //[stock]~ ERROR const trait impls are experimental fn g() {} //[stock]~ ERROR const trait impls are experimental +const trait Trait {} //[stock]~ ERROR const trait impls are experimental +#[cfg(false)] const trait Trait {} //[stock]~ ERROR const trait impls are experimental + macro_rules! discard { ($ty:ty) => {} } discard! { impl [const] T } //[stock]~ ERROR const trait impls are experimental diff --git a/tests/ui/traits/const-traits/feature-gate.stock.stderr b/tests/ui/traits/const-traits/feature-gate.stock.stderr index f3ba3039a23aa..551c7ced7c1f4 100644 --- a/tests/ui/traits/const-traits/feature-gate.stock.stderr +++ b/tests/ui/traits/const-traits/feature-gate.stock.stderr @@ -29,7 +29,27 @@ LL | fn g() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:18:17 + --> $DIR/feature-gate.rs:16:1 + | +LL | const trait Trait {} + | ^^^^^ + | + = note: see issue #143874 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:17:15 + | +LL | #[cfg(false)] const trait Trait {} + | ^^^^^ + | + = note: see issue #143874 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: const trait impls are experimental + --> $DIR/feature-gate.rs:21:17 | LL | discard! { impl [const] T } | ^^^^^^^ @@ -39,7 +59,7 @@ LL | discard! { impl [const] T } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/feature-gate.rs:19:17 + --> $DIR/feature-gate.rs:22:17 | LL | discard! { impl const T } | ^^^^^ @@ -58,6 +78,6 @@ LL | #[const_trait] = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr b/tests/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr index bf8829c09257f..e8bbdaaacbf72 100644 --- a/tests/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr +++ b/tests/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr @@ -13,7 +13,7 @@ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0282`. Future incompatibility report: Future breakage diagnostic: -warning: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +warning: defaults for generic parameters are not allowed here --> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:3:11 | LL | fn foo() -> (T, U) { diff --git a/tests/ui/type/default_type_parameter_in_fn_or_impl.rs b/tests/ui/type/default_type_parameter_in_fn_or_impl.rs deleted file mode 100644 index 33038e24bc62b..0000000000000 --- a/tests/ui/type/default_type_parameter_in_fn_or_impl.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow(unused)] - -fn avg(_: T) {} -//~^ ERROR defaults for type parameters are only allowed -//~| WARN this was previously accepted - -struct S(T); -impl S {} -//~^ ERROR defaults for type parameters are only allowed -//~| WARN this was previously accepted - -fn main() {} diff --git a/tests/ui/type/default_type_parameter_in_fn_or_impl.stderr b/tests/ui/type/default_type_parameter_in_fn_or_impl.stderr deleted file mode 100644 index a3205cd3c29ca..0000000000000 --- a/tests/ui/type/default_type_parameter_in_fn_or_impl.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/default_type_parameter_in_fn_or_impl.rs:3:8 - | -LL | fn avg(_: T) {} - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default - -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/default_type_parameter_in_fn_or_impl.rs:8:6 - | -LL | impl S {} - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - -error: aborting due to 2 previous errors - -Future incompatibility report: Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/default_type_parameter_in_fn_or_impl.rs:3:8 - | -LL | fn avg(_: T) {} - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default - -Future breakage diagnostic: -error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/default_type_parameter_in_fn_or_impl.rs:8:6 - | -LL | impl S {} - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #36887 - = note: `#[deny(invalid_type_param_default)]` on by default - diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs index ad7d972879fff..072a699a6b5b9 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs @@ -4,7 +4,7 @@ trait Trait { fn fnc(&self) -> dyn Trait { //~^ ERROR the name `N` is already used for a generic parameter in this item's generic parameters //~| ERROR expected value, found builtin type `u32` - //~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + //~| ERROR defaults for generic parameters are not allowed here bar //~^ ERROR cannot find value `bar` in this scope } diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr index dc5a1cf3485ee..47f3e83fae21a 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr @@ -39,7 +39,7 @@ LL | trait Trait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +error: defaults for generic parameters are not allowed here --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:4:12 | LL | fn fnc(&self) -> dyn Trait {