Auto merge of #145020 - GuillaumeGomez:rollup-5prs9kw, r=GuillaumeGomez
Rollup of 15 pull requests Successful merges: - rust-lang/rust#144195 (Parser: Recover from attributes applied to types and generic args) - rust-lang/rust#144794 (Port `#[coroutine]` to the new attribute system) - rust-lang/rust#144835 (Anonymize binders in tail call sig) - rust-lang/rust#144861 (Stabilize `panic_payload_as_str` feature) - rust-lang/rust#144917 (Enforce tail call type is related to body return type in borrowck) - rust-lang/rust#144948 (we only merge candidates for trait and normalizes-to goals) - rust-lang/rust#144956 (Gate const trait syntax) - rust-lang/rust#144970 (rustdoc: fix caching of intra-doc links on reexports) - rust-lang/rust#144972 (add code example showing that file_prefix treats dotfiles as the name of a file, not an extension) - rust-lang/rust#144975 (`File::set_times`: Update documentation and example to support setting timestamps on directories) - rust-lang/rust#144977 (Fortify generic param default checks) - rust-lang/rust#144996 (simplifycfg: Mark as changed when start is modified in collapse goto chain) - rust-lang/rust#144998 (mir: Do not modify NonUse in `super_projection_elem`) - rust-lang/rust#145000 (Remove unneeded `stage` parameter when setting up stdlib Cargo) - rust-lang/rust#145008 (Fix rustdoc scrape examples crash) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6bcdcc73bd
83 changed files with 1054 additions and 502 deletions
|
|
@ -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;
|
||||
|
|
|
|||
15
compiler/rustc_attr_parsing/src/attributes/body.rs
Normal file
15
compiler/rustc_attr_parsing/src/attributes/body.rs
Normal file
|
|
@ -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<S: Stage> NoArgsAttributeParser<S> for CoroutineParser {
|
||||
const PATH: &[Symbol] = &[sym::coroutine];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(rustc_span::Span) -> AttributeKind = |span| AttributeKind::Coroutine(span);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<WithoutArgs<ConstContinueParser>>,
|
||||
Single<WithoutArgs<ConstStabilityIndirectParser>>,
|
||||
Single<WithoutArgs<ConstTraitParser>>,
|
||||
Single<WithoutArgs<CoroutineParser>>,
|
||||
Single<WithoutArgs<DenyExplicitImplParser>>,
|
||||
Single<WithoutArgs<DoNotImplementViaObjectParser>>,
|
||||
Single<WithoutArgs<ExportStableParser>>,
|
||||
|
|
|
|||
|
|
@ -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<BasicBlock>,
|
||||
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
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
} 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::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,6 +297,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[const_trait]`.
|
||||
ConstTrait(Span),
|
||||
|
||||
/// Represents `#[coroutine]`.
|
||||
Coroutine(Span),
|
||||
|
||||
/// Represents `#[coverage(..)]`.
|
||||
Coverage(Span, CoverageAttrKind),
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ impl AttributeKind {
|
|||
ConstStability { .. } => Yes,
|
||||
ConstStabilityIndirect => No,
|
||||
ConstTrait(..) => No,
|
||||
Coroutine(..) => No,
|
||||
Coverage(..) => No,
|
||||
DenyExplicitImpl(..) => No,
|
||||
Deprecation { .. } => Yes,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
// 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 (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),
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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::Const { has_default: default.is_some(), synthetic }
|
||||
}
|
||||
|
||||
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 },
|
||||
})
|
||||
}
|
||||
};
|
||||
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 <https://github.com/rust-lang/rust/issues/36887>.
|
||||
FutureCompatForbidden,
|
||||
Forbidden,
|
||||
}
|
||||
|
||||
fn param_default_policy(node: Node<'_>) -> Option<ParamDefaultPolicy> {
|
||||
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<Span> {
|
||||
struct LateBoundRegionsDetector<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:?}")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<I>],
|
||||
candidates: &[Candidate<I>],
|
||||
) -> Option<CanonicalResponse<I>> {
|
||||
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<I> = 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<I>]) -> CanonicalResponse<I> {
|
||||
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<I>]) -> CanonicalResponse<I> {
|
||||
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<I>]) -> QueryResult<I> {
|
||||
if responses.is_empty() {
|
||||
fn flounder(&mut self, candidates: &[Candidate<I>]) -> QueryResult<I> {
|
||||
if candidates.is_empty() {
|
||||
return Err(NoSolution);
|
||||
} else {
|
||||
Ok(self.bail_with_ambiguity(responses))
|
||||
Ok(self.bail_with_ambiguity(candidates))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1346,11 +1346,10 @@ where
|
|||
mut candidates: Vec<Candidate<I>>,
|
||||
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), 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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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<GenericArg>> {
|
||||
let mut attr_span: Option<Span> = 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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Ty>> {
|
||||
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(),
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()?);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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<RenderedLink> {
|
||||
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 }| {
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,11 +333,14 @@ pub(crate) fn run(
|
|||
pub(crate) fn load_call_locations(
|
||||
with_examples: Vec<String>,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
loaded_paths: &mut Vec<PathBuf>,
|
||||
) -> 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: <https://github.com/rust-lang/rust/pull/144600>.
|
||||
//
|
||||
// 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}")),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2024"
|
||||
|
||||
[[example]]
|
||||
name = "complex"
|
||||
doc-scrape-examples = true
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
let mut x = foo::X::new();
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
// This file MUST exist to trigger the original bug.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
pub struct X;
|
||||
|
||||
impl X {
|
||||
pub fn new() -> Self {
|
||||
X
|
||||
}
|
||||
}
|
||||
16
tests/run-make/rustdoc-scrape-examples-paths/rmake.rs
Normal file
16
tests/run-make/rustdoc-scrape-examples-paths/rmake.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//! Test to ensure that the rustdoc `scrape-examples` feature is not panicking.
|
||||
//! Regression test for <https://github.com/rust-lang/rust/issues/144752>.
|
||||
|
||||
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();
|
||||
}
|
||||
35
tests/rustdoc/intra-doc/macro-caching-144965.rs
Normal file
35
tests/rustdoc/intra-doc/macro-caching-144965.rs
Normal file
|
|
@ -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!();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
struct Foo<const N: usize>;
|
||||
|
||||
impl<const N: usize = 1> Foo<N> {}
|
||||
//~^ ERROR defaults for const parameters are only allowed
|
||||
//~^ ERROR defaults for generic parameters are not allowed here
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -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<const N: usize = 1> Foo<N> {}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
trait Trait<T> {
|
||||
fn fnc<const N: usize = "">(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
fn fnc<const N: usize = "">(&self) {} //~ERROR defaults for generic parameters are not allowed here
|
||||
//~^ ERROR: mismatched types
|
||||
fn foo<const N: usize = { std::mem::size_of::<T>() }>(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
fn foo<const N: usize = { std::mem::size_of::<T>() }>(&self) {} //~ERROR defaults for generic parameters are not allowed here
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -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<const N: usize = "">(&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<const N: usize = { std::mem::size_of::<T>() }>(&self) {}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
fn foo<const SIZE: usize = 5usize>() {}
|
||||
//~^ ERROR defaults for const parameters are
|
||||
//~^ ERROR defaults for generic parameters are not allowed here
|
||||
|
|
|
|||
|
|
@ -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<const SIZE: usize = 5usize>() {}
|
||||
|
|
|
|||
13
tests/ui/explicit-tail-calls/higher-ranked-arg.rs
Normal file
13
tests/ui/explicit-tail-calls/higher-ranked-arg.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Regression test for <https://github.com/rust-lang/rust/issues/144826>.
|
||||
//@ check-pass
|
||||
|
||||
#![feature(explicit_tail_calls)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn foo(x: fn(&i32)) {
|
||||
become bar(x);
|
||||
}
|
||||
|
||||
fn bar(_: fn(&i32)) {}
|
||||
|
||||
fn main() {}
|
||||
16
tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs
Normal file
16
tests/ui/explicit-tail-calls/ret-ty-borrowck-constraints.rs
Normal file
|
|
@ -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 { t }
|
||||
|
||||
fn main() {
|
||||
let x = String::from("hello, world");
|
||||
let s = link(&x);
|
||||
drop(x);
|
||||
println!("{s}");
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -4,17 +4,17 @@
|
|||
|
||||
trait Trait {
|
||||
type Assoc<T = u32>;
|
||||
//~^ ERROR defaults for type parameters are only allowed
|
||||
//~^ ERROR defaults for generic parameters are not allowed here
|
||||
}
|
||||
|
||||
impl Trait for () {
|
||||
type Assoc<T = u32> = 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 = u32> = T;
|
||||
//~^ ERROR defaults for type parameters are only allowed
|
||||
//~^ ERROR defaults for generic parameters are not allowed here
|
||||
}
|
||||
|
||||
trait Other {}
|
||||
|
|
|
|||
|
|
@ -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<T = u32>;
|
||||
| ^^^^^^^
|
||||
|
||||
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<T = u32> = 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 = u32> = T;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,17 @@
|
|||
|
||||
// FIXME(default_type_parameter_fallback): Consider reallowing them once they work properly.
|
||||
|
||||
const NONE<T = ()>: Option<T> = None::<T>; //~ ERROR defaults for type parameters are only allowed
|
||||
const NONE<T = ()>: Option<T> = None::<T>;
|
||||
//~^ ERROR defaults for generic parameters are not allowed here
|
||||
|
||||
fn main() {
|
||||
let _ = NONE;
|
||||
//~^ ERROR type annotations needed
|
||||
impl Host {
|
||||
const NADA<T = ()>: Option<T> = None::<T>;
|
||||
//~^ 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() {}
|
||||
|
|
|
|||
|
|
@ -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<T = ()>: Option<T> = None::<T>;
|
||||
| ^^^^^^
|
||||
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/parameter-defaults.rs:13:9
|
||||
error: defaults for generic parameters are not allowed here
|
||||
--> $DIR/parameter-defaults.rs:14:16
|
||||
|
|
||||
LL | let _ = NONE;
|
||||
| ^ ---- type must be known at this point
|
||||
LL | const NADA<T = ()>: Option<T> = None::<T>;
|
||||
| ^^^^^^
|
||||
|
||||
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 | let _: Option<T> = NONE;
|
||||
| +++++++++++
|
||||
LL | fn body0() { let _: Option<T> = NONE; }
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/parameter-defaults.rs:21:18
|
||||
|
|
||||
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 | fn body1() { let _: Option<T> = Host::NADA; }
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
// Ensure that we reject generic parameters on foreign items.
|
||||
|
||||
extern "C" {
|
||||
fn foo<T>(); //~ 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<T = ()>(); //~ ERROR foreign items may not have type parameters
|
||||
//~^ ERROR defaults for generic parameters are not allowed here
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::<i32>(); //~ ERROR requires unsafe
|
||||
unsafe { foo::<i32>() };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<T>();
|
||||
| ^^^^^^^^^^^^ 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::<i32>();
|
||||
| ^^^^^^^^^^^^ call to unsafe function
|
||||
LL | fn bar<T = ()>();
|
||||
| ^^^^^^
|
||||
|
||||
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<T = ()>();
|
||||
| ^^^^^^^^^^^^^^^^^ 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`.
|
||||
|
|
|
|||
22
tests/ui/generics/invalid-type-param-default.rs
Normal file
22
tests/ui/generics/invalid-type-param-default.rs
Normal file
|
|
@ -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 <https://github.com/rust-lang/rust/issues/36887>.
|
||||
// FIXME(default_type_parameter_fallback): Consider reallowing them once they work properly.
|
||||
|
||||
fn avg<T = i32>(_: T) {}
|
||||
//~^ ERROR defaults for generic parameters are not allowed here [invalid_type_param_default]
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
// issue: <https://github.com/rust-lang/rust/issues/26812>
|
||||
fn mdn<T = T::Item>(_: 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>(T);
|
||||
impl<T = i32> S<T> {}
|
||||
//~^ ERROR defaults for generic parameters are not allowed here [invalid_type_param_default]
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
fn main() {}
|
||||
70
tests/ui/generics/invalid-type-param-default.stderr
Normal file
70
tests/ui/generics/invalid-type-param-default.stderr
Normal file
|
|
@ -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 = T::Item>(_: 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 = i32>(_: 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 <https://github.com/rust-lang/rust/issues/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 = T::Item>(_: 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 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
error: defaults for generic parameters are not allowed here
|
||||
--> $DIR/invalid-type-param-default.rs:18:6
|
||||
|
|
||||
LL | impl<T = i32> S<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 <https://github.com/rust-lang/rust/issues/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 = i32>(_: 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 <https://github.com/rust-lang/rust/issues/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 = T::Item>(_: 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 <https://github.com/rust-lang/rust/issues/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<T = i32> S<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 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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<_ = _> {}
|
||||
|
|
|
|||
|
|
@ -236,17 +236,15 @@ type InTypeAliasGenericParamDefault<T = impl Debug> = T;
|
|||
//~^ ERROR `impl Trait` is not allowed in generic parameter defaults
|
||||
|
||||
// Disallowed
|
||||
impl <T = impl Debug> 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 = impl Debug> 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 = impl Debug>(_: 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() = || {};
|
||||
|
|
|
|||
|
|
@ -311,10 +311,10 @@ LL | type InTypeAliasGenericParamDefault<T = impl Debug> = 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 = impl Debug> T {}
|
||||
| ^^^^^^^^^^
|
||||
LL | impl<T = impl Debug> 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 = impl Debug>(_: 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 = impl Debug>(_: 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 <https://github.com/rust-lang/rust/issues/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 = impl Debug> 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 <https://github.com/rust-lang/rust/issues/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<Args>, 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 Debug> T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||
LL | impl<T = impl Debug> 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<R> = 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 = impl Debug>(_: 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 <https://github.com/rust-lang/rust/issues/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
|
||||
warning: defaults for generic parameters are not allowed here
|
||||
--> $DIR/where-allowed.rs:240:6
|
||||
|
|
||||
LL | impl <T = impl Debug> 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 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
LL | impl<T = impl Debug> T {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
fn avg<T=T::Item>(_: T) {}
|
||||
//~^ ERROR generic parameter defaults cannot reference parameters before they are declared
|
||||
//~| ERROR defaults for type parameters
|
||||
//~| WARN previously accepted
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -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=T::Item>(_: 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=T::Item>(_: 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 <https://github.com/rust-lang/rust/issues/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=T::Item>(_: 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 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ fn b<const C: u8()>() {}
|
|||
// Paren generic args in AnonymousReportError
|
||||
fn c<T = u8()>() {}
|
||||
//~^ 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
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
|
|||
LL | fn c<T = u8()>() {}
|
||||
| ^^^^ 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<T = u8()>() {}
|
||||
|
|
@ -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<T = u8()>() {}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ impl X<N> {}
|
|||
//~| ERROR unresolved item provided when a constant was expected
|
||||
impl<T, const A: u8 = 2> X<N> {}
|
||||
//~^ 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 {}
|
||||
|
|
|
|||
|
|
@ -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<T, const A: u8 = 2> X<N> {}
|
||||
|
|
|
|||
29
tests/ui/parser/attribute-on-empty.rs
Normal file
29
tests/ui/parser/attribute-on-empty.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! Regression test for: <https://github.com/rust-lang/rust/issues/144132>
|
||||
//! <https://github.com/rust-lang/rust/issues/135017>
|
||||
|
||||
struct Baz<const N: usize>(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
|
||||
52
tests/ui/parser/attribute-on-empty.stderr
Normal file
52
tests/ui/parser/attribute-on-empty.stderr
Normal file
|
|
@ -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
|
||||
|
||||
58
tests/ui/parser/attribute-on-type.fixed
Normal file
58
tests/ui/parser/attribute-on-type.fixed
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//! Regression test for: <https://github.com/rust-lang/rust/issues/144132>
|
||||
//! <https://github.com/rust-lang/rust/issues/135017>
|
||||
|
||||
//@ run-rustfix
|
||||
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
struct Foo<T>(T);
|
||||
struct Bar<'a>(&'a i32);
|
||||
struct Baz<const N: usize>(i32);
|
||||
|
||||
fn main() {
|
||||
let foo: Foo<i32> = 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<String> = 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<i32> = 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<String> = vec![];
|
||||
//~^ ERROR attributes cannot be applied to generic arguments
|
||||
|
||||
let _nested: Box<Vec<u64>> = 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
|
||||
58
tests/ui/parser/attribute-on-type.rs
Normal file
58
tests/ui/parser/attribute-on-type.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//! Regression test for: <https://github.com/rust-lang/rust/issues/144132>
|
||||
//! <https://github.com/rust-lang/rust/issues/135017>
|
||||
|
||||
//@ run-rustfix
|
||||
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
struct Foo<T>(T);
|
||||
struct Bar<'a>(&'a i32);
|
||||
struct Baz<const N: usize>(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<Vec<#[cfg(feature = "test")] u64>> = 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
|
||||
92
tests/ui/parser/attribute-on-type.stderr
Normal file
92
tests/ui/parser/attribute-on-type.stderr
Normal file
|
|
@ -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<Vec<#[cfg(feature = "test")] u64>> = 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
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fn main() {
|
||||
x::<#[a]y::<z>>
|
||||
//~^ ERROR invalid const generic expression
|
||||
//~^ ERROR attributes cannot be applied to generic arguments
|
||||
//~| ERROR cannot find value `x` in this scope
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<z>>
|
||||
| ^^^^^^
|
||||
|
|
||||
help: expressions must be enclosed in braces to be used as const generic arguments
|
||||
|
|
||||
LL | x::<#[a]{ y::<z> }>
|
||||
| + +
|
||||
| ^^^^ attributes are not allowed here
|
||||
|
||||
error[E0425]: cannot find value `x` in this scope
|
||||
--> $DIR/issue-103143.rs:2:5
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ impl const T for S {}
|
|||
const fn f<A: [const] T>() {} //[stock]~ ERROR const trait impls are experimental
|
||||
fn g<A: const T>() {} //[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
|
||||
|
|
|
|||
|
|
@ -29,7 +29,27 @@ LL | fn g<A: 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:18:17
|
||||
--> $DIR/feature-gate.rs:16:1
|
||||
|
|
||||
LL | const trait Trait {}
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
|
|
|||
|
|
@ -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 = u64>() -> (T, U) {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
#![allow(unused)]
|
||||
|
||||
fn avg<T=i32>(_: T) {}
|
||||
//~^ ERROR defaults for type parameters are only allowed
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
struct S<T>(T);
|
||||
impl<T=i32> S<T> {}
|
||||
//~^ ERROR defaults for type parameters are only allowed
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -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=i32>(_: 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 <https://github.com/rust-lang/rust/issues/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<T=i32> S<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 <https://github.com/rust-lang/rust/issues/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=i32>(_: 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 <https://github.com/rust-lang/rust/issues/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<T=i32> S<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 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
|
@ -4,7 +4,7 @@ trait Trait<const N: dyn Trait = bar> {
|
|||
fn fnc<const N: dyn Trait = u32>(&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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ LL | trait Trait<const N: dyn Trait = bar> {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= 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<const N: dyn Trait = u32>(&self) -> dyn Trait {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue