diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 6566c6041b6e5..15efa7650293c 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -52,6 +52,7 @@ pub enum Def { AssociatedExistential(DefId), PrimTy(hir::PrimTy), TyParam(DefId), + ConstParam(DefId), SelfTy(Option /* trait */, Option /* impl */), ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]` @@ -265,7 +266,8 @@ impl Def { Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) | Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) | Def::TraitAlias(id) | - Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) | + Def::AssociatedTy(id) | Def::TyParam(id) | Def::ConstParam(id) | Def::Struct(id) | + Def::StructCtor(id, ..) | Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | Def::Macro(id, ..) | Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => { @@ -322,6 +324,7 @@ impl Def { Def::Const(..) => "constant", Def::AssociatedConst(..) => "associated constant", Def::TyParam(..) => "type parameter", + Def::ConstParam(..) => "const parameter", Def::PrimTy(..) => "builtin type", Def::Local(..) => "local variable", Def::Upvar(..) => "closure capture", diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d0fd5bd6844b0..3de41b1665d6d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1157,6 +1157,15 @@ impl<'a> LoweringContext<'a> { match arg { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)), + ast::GenericArg::Const(ct) => { + // FIXME(const_generics): const generics are not yet defined in the HIR. + self.sess.struct_span_err( + ct.value.span, + "const generics in any position are currently unsupported", + ).emit(); + self.sess.abort_if_errors(); + bug!(); + } } } @@ -2441,7 +2450,7 @@ impl<'a> LoweringContext<'a> { |this| this.lower_param_bounds(¶m.bounds, itctx.reborrow()), ); - match param.kind { + let (name, kind) = match param.kind { GenericParamKind::Lifetime => { let was_collecting_in_band = self.is_collecting_in_band_lifetimes; self.is_collecting_in_band_lifetimes = false; @@ -2457,22 +2466,14 @@ impl<'a> LoweringContext<'a> { | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()), hir::LifetimeName::Error => ParamName::Error, }; - let param = hir::GenericParam { - id: lt.id, - hir_id: lt.hir_id, - name: param_name, - span: lt.span, - pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"), - attrs: self.lower_attrs(¶m.attrs), - bounds, - kind: hir::GenericParamKind::Lifetime { - kind: hir::LifetimeParamKind::Explicit, - } + + let kind = hir::GenericParamKind::Lifetime { + kind: hir::LifetimeParamKind::Explicit }; self.is_collecting_in_band_lifetimes = was_collecting_in_band; - param + (param_name, kind) } GenericParamKind::Type { ref default, .. } => { // Don't expose `Self` (recovered "keyword used as ident" parse error). @@ -2491,27 +2492,41 @@ impl<'a> LoweringContext<'a> { .chain(params) .collect(); } - let LoweredNodeId { node_id, hir_id } = self.lower_node_id(param.id); - hir::GenericParam { - id: node_id, - hir_id, - name: hir::ParamName::Plain(ident), - pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"), - attrs: self.lower_attrs(¶m.attrs), - bounds, - span: ident.span, - kind: hir::GenericParamKind::Type { - default: default.as_ref().map(|x| { - self.lower_ty(x, ImplTraitContext::disallowed()) - }), - synthetic: param.attrs.iter() - .filter(|attr| attr.check_name("rustc_synthetic")) - .map(|_| hir::SyntheticTyParamKind::ImplTrait) - .next(), - } - } + let kind = hir::GenericParamKind::Type { + default: default.as_ref().map(|x| { + self.lower_ty(x, ImplTraitContext::disallowed()) + }), + synthetic: param.attrs.iter() + .filter(|attr| attr.check_name("rustc_synthetic")) + .map(|_| hir::SyntheticTyParamKind::ImplTrait) + .next(), + }; + + (hir::ParamName::Plain(ident), kind) } + GenericParamKind::Const { .. } => { + // FIXME(const_generics): const generics are not yet defined in the HIR. + self.sess.struct_span_err( + param.ident.span, + "const generics in any position are currently unsupported", + ).emit(); + self.sess.abort_if_errors(); + bug!(); + } + }; + + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(param.id); + + hir::GenericParam { + id: node_id, + hir_id, + name, + span: param.ident.span, + pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"), + attrs: self.lower_attrs(¶m.attrs), + bounds, + kind, } } diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 710170674f761..02fb503e752b5 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -218,6 +218,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { let def_path_data = match param.kind { GenericParamKind::Lifetime { .. } => DefPathData::LifetimeParam(name), GenericParamKind::Type { .. } => DefPathData::TypeParam(name), + GenericParamKind::Const { .. } => DefPathData::ConstParam(name), }; self.create_def(param.id, def_path_data, REGULAR_SPACE, param.ident.span); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index a8193e1d34837..84e9cde6df160 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -356,10 +356,12 @@ pub enum DefPathData { /// A closure expression ClosureExpr, // Subportions of items - /// A type parameter (generic parameter) + /// A type (generic) parameter TypeParam(InternedString), - /// A lifetime definition + /// A lifetime (generic) parameter LifetimeParam(InternedString), + /// A const (generic) parameter + ConstParam(InternedString), /// A variant of a enum EnumVariant(InternedString), /// A struct field @@ -641,6 +643,7 @@ impl DefPathData { MacroDef(name) | TypeParam(name) | LifetimeParam(name) | + ConstParam(name) | EnumVariant(name) | Field(name) | GlobalMetaData(name) => Some(name), @@ -669,6 +672,7 @@ impl DefPathData { MacroDef(name) | TypeParam(name) | LifetimeParam(name) | + ConstParam(name) | EnumVariant(name) | Field(name) | GlobalMetaData(name) => { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 2b359428b1fa1..712fd360fbb6f 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1046,6 +1046,7 @@ impl_stable_hash_for!(enum hir::def::Def { AssociatedExistential(def_id), PrimTy(prim_ty), TyParam(def_id), + ConstParam(def_id), SelfTy(trait_def_id, impl_def_id), ForeignTy(def_id), Fn(def_id), diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index f89e50d696945..8214c8bacc704 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -325,6 +325,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::Module(..) | data @ DefPathData::TypeParam(..) | data @ DefPathData::LifetimeParam(..) | + data @ DefPathData::ConstParam(..) | data @ DefPathData::EnumVariant(..) | data @ DefPathData::Field(..) | data @ DefPathData::AnonConst | diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2cd82d44af3aa..a12ec3471a91c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -426,6 +426,7 @@ impl PrintContext { DefPathData::ClosureExpr | DefPathData::TypeParam(_) | DefPathData::LifetimeParam(_) | + DefPathData::ConstParam(_) | DefPathData::Field(_) | DefPathData::StructCtor | DefPathData::AnonConst | diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 3deb2ff8d8a0b..a1c9d3ece2c0d 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -7,8 +7,10 @@ // or type checking or some other kind of complex analysis. use std::mem; +use syntax::print::pprust; use rustc::lint; use rustc::session::Session; +use rustc_data_structures::fx::FxHashMap; use syntax::ast::*; use syntax::attr; use syntax::source_map::Spanned; @@ -271,7 +273,74 @@ impl<'a> AstValidator<'a> { _ => None, } } +} +enum GenericPosition { + Param, + Arg, +} + +fn validate_generics_order<'a>( + handler: &errors::Handler, + generics: impl Iterator)>, + pos: GenericPosition, + span: Span, +) { + let mut max_param: Option = None; + let mut out_of_order = FxHashMap::default(); + let mut param_idents = vec![]; + + for (kind, span, ident) in generics { + if let Some(ident) = ident { + param_idents.push((kind, param_idents.len(), ident)); + } + let max_param = &mut max_param; + match max_param { + Some(max_param) if *max_param > kind => { + let entry = out_of_order.entry(kind).or_insert((*max_param, vec![])); + entry.1.push(span); + } + Some(_) | None => *max_param = Some(kind), + }; + } + + let mut ordered_params = "<".to_string(); + if !out_of_order.is_empty() { + param_idents.sort_by_key(|&(po, i, _)| (po, i)); + let mut first = true; + for (_, _, ident) in param_idents { + if !first { + ordered_params += ", "; + } + ordered_params += &ident; + first = false; + } + } + ordered_params += ">"; + + let pos_str = match pos { + GenericPosition::Param => "parameter", + GenericPosition::Arg => "argument", + }; + + for (param_ord, (max_param, spans)) in out_of_order { + let mut err = handler.struct_span_err(spans, + &format!( + "{} {pos}s must be declared prior to {} {pos}s", + param_ord, + max_param, + pos = pos_str, + )); + if let GenericPosition::Param = pos { + err.span_suggestion( + span, + &format!("reorder the {}s: lifetimes, then types, then consts", pos_str), + ordered_params.clone(), + Applicability::MachineApplicable, + ); + } + err.emit(); + } } impl<'a> Visitor<'a> for AstValidator<'a> { @@ -412,6 +481,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .note("only trait implementations may be annotated with default").emit(); } } + ItemKind::Fn(_, header, ref generics, _) => { + // We currently do not permit const generics in `const fn`, as + // this is tantamount to allowing compile-time dependent typing. + if header.constness.node == Constness::Const { + // Look for const generics and error if we find any. + for param in &generics.params { + match param.kind { + GenericParamKind::Const { .. } => { + self.err_handler() + .struct_span_err( + item.span, + "const parameters are not permitted in `const fn`", + ) + .emit(); + } + _ => {} + } + } + } + } ItemKind::ForeignMod(..) => { self.invalid_visibility( &item.vis, @@ -508,6 +597,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { match *generic_args { GenericArgs::AngleBracketed(ref data) => { walk_list!(self, visit_generic_arg, &data.args); + validate_generics_order(self.err_handler(), data.args.iter().map(|arg| { + (match arg { + GenericArg::Lifetime(..) => ParamKindOrd::Lifetime, + GenericArg::Type(..) => ParamKindOrd::Type, + GenericArg::Const(..) => ParamKindOrd::Const, + }, arg.span(), None) + }), GenericPosition::Arg, generic_args.span()); // Type bindings such as `Item=impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. self.with_impl_trait(None, |this| { @@ -526,27 +622,32 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_generics(&mut self, generics: &'a Generics) { - let mut seen_non_lifetime_param = false; - let mut seen_default = None; + let mut prev_ty_default = None; for param in &generics.params { - match (¶m.kind, seen_non_lifetime_param) { - (GenericParamKind::Lifetime { .. }, true) => { + if let GenericParamKind::Type { ref default, .. } = param.kind { + if default.is_some() { + prev_ty_default = Some(param.ident.span); + } else if let Some(span) = prev_ty_default { self.err_handler() - .span_err(param.ident.span, "lifetime parameters must be leading"); - }, - (GenericParamKind::Lifetime { .. }, false) => {} - (GenericParamKind::Type { ref default, .. }, _) => { - seen_non_lifetime_param = true; - if default.is_some() { - seen_default = Some(param.ident.span); - } else if let Some(span) = seen_default { - self.err_handler() - .span_err(span, "type parameters with a default must be trailing"); - break; - } + .span_err(span, "type parameters with a default must be trailing"); + break; } } } + + validate_generics_order(self.err_handler(), generics.params.iter().map(|param| { + let span = param.ident.span; + let ident = Some(param.ident.to_string()); + match ¶m.kind { + GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, span, ident), + GenericParamKind::Type { .. } => (ParamKindOrd::Type, span, ident), + GenericParamKind::Const { ref ty } => { + let ty = pprust::ty_to_string(ty); + (ParamKindOrd::Const, span, Some(format!("const {}: {}", param.ident, ty))) + } + } + }), GenericPosition::Param, generics.span); + for predicate in &generics.where_clause.predicates { if let WherePredicate::EqPredicate(ref predicate) = *predicate { self.err_handler() @@ -554,6 +655,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { supported in where clauses (see #20041)"); } } + visit::walk_generics(self, generics) } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 0db8689c0c17c..5c095994a1bbd 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -414,8 +414,8 @@ https://doc.rust-lang.org/reference.html#use-declarations "##, E0401: r##" -Inner items do not inherit type parameters from the functions they are embedded -in. +Inner items do not inherit type or const parameters from the functions +they are embedded in. Erroneous code example: diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b166b1be02f45..0d1f6328105b3 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -15,7 +15,7 @@ use rustc_errors as errors; pub use rustc::hir::def::{Namespace, PerNS}; -use TypeParameters::*; +use GenericParameters::*; use RibKind::*; use rustc::hir::map::{Definitions, DefCollector}; @@ -142,10 +142,11 @@ impl Ord for BindingError { } enum ResolutionError<'a> { - /// error E0401: can't use type parameters from outer function - TypeParametersFromOuterFunction(Def), - /// error E0403: the name is already used for a type parameter in this type parameter list - NameAlreadyUsedInTypeParameterList(Name, &'a Span), + /// error E0401: can't use type or const parameters from outer function + GenericParamsFromOuterFunction(Def), + /// error E0403: the name is already used for a type/const parameter in this list of + /// generic parameters + NameAlreadyUsedInParameterList(Name, &'a Span), /// error E0407: method is not a member of trait MethodNotMemberOfTrait(Name, &'a str), /// error E0437: type is not a member of trait @@ -177,7 +178,7 @@ enum ResolutionError<'a> { /// error E0530: X bindings cannot shadow Ys BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>), /// error E0128: type parameters with a default cannot use forward declared identifiers - ForwardDeclaredTyParam, + ForwardDeclaredTyParam, // FIXME(const_generics:defaults) } /// Combines an error with provided span and emits it @@ -195,12 +196,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, resolution_error: ResolutionError<'a>) -> DiagnosticBuilder<'sess> { match resolution_error { - ResolutionError::TypeParametersFromOuterFunction(outer_def) => { + ResolutionError::GenericParamsFromOuterFunction(outer_def) => { let mut err = struct_span_err!(resolver.session, - span, - E0401, - "can't use type parameters from outer function"); - err.span_label(span, "use of type variable from outer function"); + span, + E0401, + "can't use generic parameters from outer function", + ); + err.span_label(span, format!("use of generic parameter from outer function")); let cm = resolver.session.source_map(); match outer_def { @@ -224,20 +226,25 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, } return err; }, - Def::TyParam(typaram_defid) => { - if let Some(typaram_span) = resolver.definitions.opt_span(typaram_defid) { - err.span_label(typaram_span, "type variable from outer function"); + Def::TyParam(def_id) => { + if let Some(span) = resolver.definitions.opt_span(def_id) { + err.span_label(span, "type variable from outer function"); } - }, + } + Def::ConstParam(def_id) => { + if let Some(span) = resolver.definitions.opt_span(def_id) { + err.span_label(span, "const variable from outer function"); + } + } _ => { - bug!("TypeParametersFromOuterFunction should only be used with Def::SelfTy or \ - Def::TyParam") + bug!("GenericParamsFromOuterFunction should only be used with Def::SelfTy, \ + Def::TyParam"); } } // Try to retrieve the span of the function signature and generate a new message with - // a local type parameter - let sugg_msg = "try using a local type parameter instead"; + // a local type or const parameter. + let sugg_msg = &format!("try using a local generic parameter instead"); if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) { // Suggest the modification to the user err.span_suggestion( @@ -247,19 +254,20 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, Applicability::MachineApplicable, ); } else if let Some(sp) = cm.generate_fn_name_span(span) { - err.span_label(sp, "try adding a local type parameter in this method instead"); + err.span_label(sp, + format!("try adding a local generic parameter in this method instead")); } else { - err.help("try using a local type parameter instead"); + err.help(&format!("try using a local generic parameter instead")); } err } - ResolutionError::NameAlreadyUsedInTypeParameterList(name, first_use_span) => { + ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => { let mut err = struct_span_err!(resolver.session, span, E0403, - "the name `{}` is already used for a type parameter \ - in this type parameter list", + "the name `{}` is already used for a generic \ + parameter in this list of generic parameters", name); err.span_label(span, "already used"); err.span_label(first_use_span.clone(), format!("first use of `{}`", name)); @@ -546,8 +554,7 @@ impl<'a> PathSource<'a> { Def::Struct(..) | Def::Union(..) | Def::Enum(..) | Def::Trait(..) | Def::TraitAlias(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::PrimTy(..) | Def::TyParam(..) | - Def::SelfTy(..) | Def::Existential(..) | - Def::ForeignTy(..) => true, + Def::SelfTy(..) | Def::Existential(..) | Def::ForeignTy(..) => true, _ => false, }, PathSource::Trait(AliasPossibility::No) => match def { @@ -564,7 +571,7 @@ impl<'a> PathSource<'a> { Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Fn) | Def::Const(..) | Def::Static(..) | Def::Local(..) | Def::Upvar(..) | Def::Fn(..) | Def::Method(..) | Def::AssociatedConst(..) | - Def::SelfCtor(..) => true, + Def::SelfCtor(..) | Def::ConstParam(..) => true, _ => false, }, PathSource::Pat => match def { @@ -748,6 +755,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { self.resolve_block(block); } fn visit_anon_const(&mut self, constant: &'tcx ast::AnonConst) { + debug!("visit_anon_const {:?}", constant); self.with_constant_rib(|this| { visit::walk_anon_const(this, constant); }); @@ -781,15 +789,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { visit::walk_poly_trait_ref(self, tref, m); } fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) { - let type_parameters = match foreign_item.node { + let generic_params = match foreign_item.node { ForeignItemKind::Fn(_, ref generics) => { - HasTypeParameters(generics, ItemRibKind) + HasGenericParams(generics, ItemRibKind) } - ForeignItemKind::Static(..) => NoTypeParameters, - ForeignItemKind::Ty => NoTypeParameters, - ForeignItemKind::Macro(..) => NoTypeParameters, + ForeignItemKind::Static(..) => NoGenericParams, + ForeignItemKind::Ty => NoGenericParams, + ForeignItemKind::Macro(..) => NoGenericParams, }; - self.with_type_parameter_rib(type_parameters, |this| { + self.with_generic_param_rib(generic_params, |this| { visit::walk_foreign_item(this, foreign_item); }); } @@ -799,6 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { _: Span, node_id: NodeId) { + debug!("(resolving function) entering function"); let (rib_kind, asyncness) = match function_kind { FnKind::ItemFn(_, ref header, ..) => (ItemRibKind, header.asyncness), @@ -855,6 +864,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { self.label_ribs.pop(); self.ribs[ValueNS].pop(); } + fn visit_generics(&mut self, generics: &'tcx Generics) { // For type parameter defaults, we have to ban access // to following type parameters, as the Substs can only @@ -865,6 +875,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { let mut found_default = false; default_ban_rib.bindings.extend(generics.params.iter() .filter_map(|param| match param.kind { + GenericParamKind::Const { .. } | GenericParamKind::Lifetime { .. } => None, GenericParamKind::Type { ref default, .. } => { found_default |= default.is_some(); @@ -893,6 +904,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { // Allow all following defaults to refer to this type parameter. default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name)); } + GenericParamKind::Const { ref ty } => { + for bound in ¶m.bounds { + self.visit_param_bound(bound); + } + + self.visit_ty(ty); + } } } for p in &generics.where_clause.predicates { @@ -902,9 +920,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { } #[derive(Copy, Clone)] -enum TypeParameters<'a, 'b> { - NoTypeParameters, - HasTypeParameters(// Type parameters. +enum GenericParameters<'a, 'b> { + NoGenericParams, + HasGenericParams(// Type parameters. &'b Generics, // The kind of the rib used for type parameters. @@ -2040,6 +2058,7 @@ impl<'a> Resolver<'a> { let record_used = record_used_id.is_some(); let mut module = self.graph_root; for i in (0 .. self.ribs[ns].len()).rev() { + debug!("walk rib\n{:?}", self.ribs[ns][i].bindings); if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() { // The ident resolves to a type parameter or local variable. return Some(LexicalScopeBinding::Def( @@ -2361,8 +2380,9 @@ impl<'a> Resolver<'a> { } fn resolve_adt(&mut self, item: &Item, generics: &Generics) { + debug!("resolve_adt"); self.with_current_self_item(item, |this| { - this.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { + this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { let item_def_id = this.definitions.local_def_id(item.id); this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| { visit::walk_item(this, item); @@ -2415,13 +2435,13 @@ impl<'a> Resolver<'a> { fn resolve_item(&mut self, item: &Item) { let name = item.ident.name; - debug!("(resolving item) resolving {}", name); + debug!("(resolving item) resolving {} ({:?})", name, item.node); match item.node { ItemKind::Ty(_, ref generics) | ItemKind::Fn(_, _, ref generics, _) | ItemKind::Existential(_, ref generics) => { - self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| visit::walk_item(this, item)); } @@ -2440,16 +2460,16 @@ impl<'a> Resolver<'a> { ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => { // Create a new rib for the trait-wide type parameters. - self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { let local_def_id = this.definitions.local_def_id(item.id); this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds); for trait_item in trait_items { - let type_parameters = HasTypeParameters(&trait_item.generics, + let generic_params = HasGenericParams(&trait_item.generics, TraitOrImplItemRibKind); - this.with_type_parameter_rib(type_parameters, |this| { + this.with_generic_param_rib(generic_params, |this| { match trait_item.node { TraitItemKind::Const(ref ty, ref default) => { this.visit_ty(ty); @@ -2481,7 +2501,7 @@ impl<'a> Resolver<'a> { ItemKind::TraitAlias(ref generics, ref bounds) => { // Create a new rib for the trait-wide type parameters. - self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { let local_def_id = this.definitions.local_def_id(item.id); this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| { this.visit_generics(generics); @@ -2498,6 +2518,7 @@ impl<'a> Resolver<'a> { ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(ref ty, ref expr) => { + debug!("resolve_item ItemKind::Const"); self.with_item_rib(|this| { this.visit_ty(ty); this.with_constant_rib(|this| { @@ -2519,23 +2540,25 @@ impl<'a> Resolver<'a> { } } - fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F) + fn with_generic_param_rib<'b, F>(&'b mut self, generic_params: GenericParameters<'a, 'b>, f: F) where F: FnOnce(&mut Resolver<'_>) { - match type_parameters { - HasTypeParameters(generics, rib_kind) => { + debug!("with_generic_param_rib"); + match generic_params { + HasGenericParams(generics, rib_kind) => { let mut function_type_rib = Rib::new(rib_kind); + let mut function_value_rib = Rib::new(rib_kind); let mut seen_bindings = FxHashMap::default(); for param in &generics.params { match param.kind { GenericParamKind::Lifetime { .. } => {} GenericParamKind::Type { .. } => { let ident = param.ident.modern(); - debug!("with_type_parameter_rib: {}", param.id); + debug!("with_generic_param_rib: {}", param.id); if seen_bindings.contains_key(&ident) { let span = seen_bindings.get(&ident).unwrap(); - let err = ResolutionError::NameAlreadyUsedInTypeParameterList( + let err = ResolutionError::NameAlreadyUsedInParameterList( ident.name, span, ); @@ -2548,20 +2571,40 @@ impl<'a> Resolver<'a> { function_type_rib.bindings.insert(ident, def); self.record_def(param.id, PathResolution::new(def)); } + GenericParamKind::Const { .. } => { + let ident = param.ident.modern(); + debug!("with_generic_param_rib: {}", param.id); + + if seen_bindings.contains_key(&ident) { + let span = seen_bindings.get(&ident).unwrap(); + let err = ResolutionError::NameAlreadyUsedInParameterList( + ident.name, + span, + ); + resolve_error(self, param.ident.span, err); + } + seen_bindings.entry(ident).or_insert(param.ident.span); + + let def = Def::ConstParam(self.definitions.local_def_id(param.id)); + function_value_rib.bindings.insert(ident, def); + self.record_def(param.id, PathResolution::new(def)); + } } } + self.ribs[ValueNS].push(function_value_rib); self.ribs[TypeNS].push(function_type_rib); } - NoTypeParameters => { + NoGenericParams => { // Nothing to do. } } f(self); - if let HasTypeParameters(..) = type_parameters { + if let HasGenericParams(..) = generic_params { self.ribs[TypeNS].pop(); + self.ribs[ValueNS].pop(); } } @@ -2586,6 +2629,7 @@ impl<'a> Resolver<'a> { fn with_constant_rib(&mut self, f: F) where F: FnOnce(&mut Resolver<'_>) { + debug!("with_constant_rib"); self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind)); self.label_ribs.push(Rib::new(ConstantItemRibKind)); f(self); @@ -2679,8 +2723,9 @@ impl<'a> Resolver<'a> { self_type: &Ty, item_id: NodeId, impl_items: &[ImplItem]) { + debug!("resolve_implementation"); // If applicable, create a rib for the type parameters. - self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { // Dummy self type for better errors if `Self` is used in the trait path. this.with_self_rib(Def::SelfTy(None, None), |this| { // Resolve the trait reference, if necessary. @@ -2693,30 +2738,37 @@ impl<'a> Resolver<'a> { } // Resolve the self type. this.visit_ty(self_type); - // Resolve the type parameters. + // Resolve the generic parameters. this.visit_generics(generics); // Resolve the items within the impl. this.with_current_self_type(self_type, |this| { this.with_self_struct_ctor_rib(item_def_id, |this| { + debug!("resolve_implementation with_self_struct_ctor_rib"); for impl_item in impl_items { this.resolve_visibility(&impl_item.vis); // We also need a new scope for the impl item type parameters. - let type_parameters = HasTypeParameters(&impl_item.generics, - TraitOrImplItemRibKind); - this.with_type_parameter_rib(type_parameters, |this| { + let generic_params = HasGenericParams(&impl_item.generics, + TraitOrImplItemRibKind); + this.with_generic_param_rib(generic_params, |this| { use self::ResolutionError::*; match impl_item.node { ImplItemKind::Const(..) => { + debug!( + "resolve_implementation ImplItemKind::Const", + ); // If this is a trait impl, ensure the const // exists in trait - this.check_trait_item(impl_item.ident, - ValueNS, - impl_item.span, - |n, s| ConstNotMemberOfTrait(n, s)); - this.with_constant_rib(|this| - visit::walk_impl_item(this, impl_item) + this.check_trait_item( + impl_item.ident, + ValueNS, + impl_item.span, + |n, s| ConstNotMemberOfTrait(n, s), ); + + this.with_constant_rib(|this| { + visit::walk_impl_item(this, impl_item) + }); } ImplItemKind::Method(..) => { // If this is a trait impl, ensure the method @@ -4095,6 +4147,7 @@ impl<'a> Resolver<'a> { mut def: Def, record_used: bool, span: Span) -> Def { + debug!("adjust_local_def"); let ribs = &self.ribs[ns][rib_index + 1..]; // An invalid forward use of a type parameter from a previous default. @@ -4111,6 +4164,9 @@ impl<'a> Resolver<'a> { span_bug!(span, "unexpected {:?} in bindings", def) } Def::Local(node_id) => { + use ResolutionError::*; + let mut res_err = None; + for rib in ribs { match rib.kind { NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) | @@ -4146,21 +4202,26 @@ impl<'a> Resolver<'a> { // named function item. This is not allowed, so we // report an error. if record_used { - resolve_error(self, span, - ResolutionError::CannotCaptureDynamicEnvironmentInFnItem); + // We don't immediately trigger a resolve error, because + // we want certain other resolution errors (namely those + // emitted for `ConstantItemRibKind` below) to take + // precedence. + res_err = Some(CannotCaptureDynamicEnvironmentInFnItem); } - return Def::Err; } ConstantItemRibKind => { // Still doesn't deal with upvars if record_used { - resolve_error(self, span, - ResolutionError::AttemptToUseNonConstantValueInConstant); + resolve_error(self, span, AttemptToUseNonConstantValueInConstant); } return Def::Err; } } } + if let Some(res_err) = res_err { + resolve_error(self, span, res_err); + return Def::Err; + } } Def::TyParam(..) | Def::SelfTy(..) => { for rib in ribs { @@ -4171,17 +4232,38 @@ impl<'a> Resolver<'a> { // Nothing to do. Continue. } ItemRibKind => { - // This was an attempt to use a type parameter outside - // its scope. + // This was an attempt to use a type parameter outside its scope. if record_used { - resolve_error(self, span, - ResolutionError::TypeParametersFromOuterFunction(def)); + resolve_error( + self, + span, + ResolutionError::GenericParamsFromOuterFunction(def), + ); } return Def::Err; } } } } + Def::ConstParam(..) => { + // A const param is always declared in a signature, which is always followed by + // some kind of function rib kind (specifically, ItemRibKind in the case of a + // normal function), so we can skip the first rib as it will be guaranteed to + // (spuriously) conflict with the const param. + for rib in &ribs[1..] { + if let ItemRibKind = rib.kind { + // This was an attempt to use a const parameter outside its scope. + if record_used { + resolve_error( + self, + span, + ResolutionError::GenericParamsFromOuterFunction(def), + ); + } + return Def::Err; + } + } + } _ => {} } def diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 995df3802aabd..91e9c7745d280 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -364,6 +364,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ); } } + ast::GenericParamKind::Const { .. } => {} } } self.visit_generics(generics); @@ -1447,9 +1448,16 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc fn visit_generics(&mut self, generics: &'l ast::Generics) { for param in &generics.params { - if let ast::GenericParamKind::Type { ref default, .. } = param.kind { - self.process_bounds(¶m.bounds); - if let Some(ref ty) = default { + match param.kind { + ast::GenericParamKind::Lifetime { .. } => {} + ast::GenericParamKind::Type { ref default, .. } => { + self.process_bounds(¶m.bounds); + if let Some(ref ty) = default { + self.visit_ty(&ty); + } + } + ast::GenericParamKind::Const { ref ty } => { + self.process_bounds(¶m.bounds); self.visit_ty(&ty); } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 73eb5de5c76f0..4969d521b8039 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -762,6 +762,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ref_id: id_from_def_id(def_id), }) } + HirDef::ConstParam(def_id) => { + Some(Ref { + kind: RefKind::Variable, + span, + ref_id: id_from_def_id(def_id), + }) + } HirDef::StructCtor(def_id, _) => { // This is a reference to a tuple struct where the def_id points // to an invisible constructor function. That is not a very useful diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 7d4c0d0f9f56f..72615fc8a65ac 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -622,12 +622,20 @@ impl Sig for ast::Generics { let mut defs = Vec::with_capacity(self.params.len()); for param in &self.params { - let mut param_text = param.ident.to_string(); + let mut param_text = String::new(); + if let ast::GenericParamKind::Const { .. } = param.kind { + param_text.push_str("const "); + } + param_text.push_str(¶m.ident.as_str()); defs.push(SigElement { id: id_from_node_id(param.id, scx), start: offset + text.len(), - end: offset + text.len() + param_text.len(), + end: offset + text.len() + param_text.as_str().len(), }); + if let ast::GenericParamKind::Const { ref ty } = param.kind { + param_text.push_str(": "); + param_text.push_str(&pprust::ty_to_string(&ty)); + } if !param.bounds.is_empty() { param_text.push_str(": "); match param.kind { @@ -646,6 +654,9 @@ impl Sig for ast::Generics { param_text.push_str(&pprust::bounds_to_string(¶m.bounds)); // FIXME descend properly into bounds. } + ast::GenericParamKind::Const { .. } => { + // Const generics cannot contain bounds. + } } } text.push_str(¶m_text); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 3ed09dfe99239..e6533ac4b7559 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -348,13 +348,14 @@ fn main() { "##, E0044: r##" -You can't use type parameters on foreign items. Example of erroneous code: +You can't use type or const parameters on foreign items. +Example of erroneous code: ```compile_fail,E0044 extern { fn some_func(x: T); } ``` -To fix this, replace the type parameter with the specializations that you +To fix this, replace the generic parameter with the specializations that you need: ``` diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2cfe2cc896cb1..681d8eeaa0d73 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -167,6 +167,17 @@ impl GenericArgs { pub enum GenericArg { Lifetime(Lifetime), Type(P), + Const(AnonConst), +} + +impl GenericArg { + pub fn span(&self) -> Span { + match self { + GenericArg::Lifetime(lt) => lt.ident.span, + GenericArg::Type(ty) => ty.span, + GenericArg::Const(ct) => ct.value.span, + } + } } /// A path like `Foo<'a, T>` @@ -296,13 +307,32 @@ impl GenericBound { pub type GenericBounds = Vec; +/// Specifies the enforced ordering for generic parameters. In the future, +/// if we wanted to relax this order, we could override `PartialEq` and +/// `PartialOrd`, to allow the kinds to be unordered. +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] +pub enum ParamKindOrd { + Lifetime, + Type, + Const, +} + +impl fmt::Display for ParamKindOrd { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ParamKindOrd::Lifetime => "lifetime".fmt(f), + ParamKindOrd::Type => "type".fmt(f), + ParamKindOrd::Const => "const".fmt(f), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum GenericParamKind { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime, - Type { - default: Option>, - }, + Type { default: Option> }, + Const { ty: P }, } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 1e83f6c03ec30..6708e3c12a005 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -38,12 +38,14 @@ pub trait AstBuilder { bindings: Vec) -> (ast::QSelf, ast::Path); - // types + // types and consts fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy; fn ty(&self, span: Span, ty: ast::TyKind) -> P; fn ty_path(&self, path: ast::Path) -> P; fn ty_ident(&self, span: Span, idents: ast::Ident) -> P; + fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst; + fn const_ident(&self, span: Span, idents: ast::Ident) -> ast::AnonConst; fn ty_rptr(&self, span: Span, ty: P, @@ -394,6 +396,22 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.ty_path(self.path_ident(span, ident)) } + fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst { + ast::AnonConst { + id: ast::DUMMY_NODE_ID, + value: P(ast::Expr { + id: ast::DUMMY_NODE_ID, + node: expr, + span, + attrs: ThinVec::new(), + }) + } + } + + fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst { + self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident))) + } + fn ty_rptr(&self, span: Span, ty: P, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e7b9a884b5e0c..0853b4399d2c1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -15,7 +15,7 @@ use AttributeType::*; use AttributeGate::*; -use crate::ast::{self, NodeId, PatKind, RangeEnd}; +use crate::ast::{self, NodeId, GenericParam, GenericParamKind, PatKind, RangeEnd}; use crate::attr; use crate::early_buffered_lints::BufferedEarlyLintId; use crate::source_map::Spanned; @@ -462,6 +462,9 @@ declare_features! ( // Re-Rebalance coherence (active, re_rebalance_coherence, "1.32.0", Some(55437), None), + // Const generic types. + (active, const_generics, "1.34.0", Some(44580), None), + // #[optimize(X)] (active, optimize_attribute, "1.34.0", Some(54882), None), @@ -1899,6 +1902,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_fn(self, fn_kind, fn_decl, span); } + fn visit_generic_param(&mut self, param: &'a GenericParam) { + if let GenericParamKind::Const { .. } = param.kind { + gate_feature_post!(&self, const_generics, param.ident.span, + "const generics are unstable"); + } + visit::walk_generic_param(self, param); + } + fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) { match ti.node { ast::TraitItemKind::Method(ref sig, ref block) => { @@ -1984,7 +1995,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], // Some features are known to be incomplete and using them is likely to have // unanticipated results, such as compiler crashes. We warn the user about these // to alert them. - let incomplete_features = ["generic_associated_types"]; + let incomplete_features = ["generic_associated_types", "const_generics"]; let mut features = Features::new(); let mut edition_enabled_features = FxHashMap::default(); diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 0fd8bbf100fa2..1e5eb0992bd1b 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -480,6 +480,7 @@ pub fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) match arg { GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), GenericArg::Type(ty) => vis.visit_ty(ty), + GenericArg::Const(ct) => vis.visit_anon_const(ct), } } @@ -698,6 +699,9 @@ pub fn noop_visit_generic_param(param: &mut GenericParam, vis: &m GenericParamKind::Type { default } => { visit_opt(default, |default| vis.visit_ty(default)); } + GenericParamKind::Const { ty } => { + vis.visit_ty(ty); + } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cacdab980facd..d71145893c34a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -397,6 +397,7 @@ crate enum TokenType { Ident, Path, Type, + Const, } impl TokenType { @@ -409,6 +410,7 @@ impl TokenType { TokenType::Ident => "identifier".to_string(), TokenType::Path => "path".to_string(), TokenType::Type => "type".to_string(), + TokenType::Const => "const".to_string(), } } } @@ -946,6 +948,15 @@ impl<'a> Parser<'a> { } } + fn check_const_arg(&mut self) -> bool { + if self.token.can_begin_const_arg() { + true + } else { + self.expected_tokens.push(TokenType::Const); + false + } + } + /// Expect and consume a `+`. if `+=` is seen, replace it with a `=` /// and continue. If a `+` is not seen, return false. /// @@ -1031,7 +1042,8 @@ impl<'a> Parser<'a> { } /// Attempt to consume a `<`. If `<<` is seen, replace it with a single - /// `<` and continue. If a `<` is not seen, return false. + /// `<` and continue. If `<-` is seen, replace it with a single `<` + /// and continue. If a `<` is not seen, return false. /// /// This is meant to be used when parsing generics on a path to get the /// starting token. @@ -1047,6 +1059,11 @@ impl<'a> Parser<'a> { self.bump_with(token::Lt, span); true } + token::LArrow => { + let span = self.span.with_lo(self.span.lo() + BytePos(1)); + self.bump_with(token::BinOp(token::Minus), span); + true + } _ => false, }; @@ -5482,15 +5499,27 @@ impl<'a> Parser<'a> { Ok((ident, TraitItemKind::Type(bounds, default), generics)) } + fn parse_const_param(&mut self, preceding_attrs: Vec) -> PResult<'a, GenericParam> { + self.expect_keyword(keywords::Const)?; + let ident = self.parse_ident()?; + self.expect(&token::Colon)?; + let ty = self.parse_ty()?; + + Ok(GenericParam { + ident, + id: ast::DUMMY_NODE_ID, + attrs: preceding_attrs.into(), + bounds: Vec::new(), + kind: GenericParamKind::Const { + ty, + } + }) + } + /// Parses (possibly empty) list of lifetime and type parameters, possibly including /// trailing comma and erroneous trailing attributes. crate fn parse_generic_params(&mut self) -> PResult<'a, Vec> { - let mut lifetimes = Vec::new(); let mut params = Vec::new(); - let mut seen_ty_param: Option = None; - let mut last_comma_span = None; - let mut bad_lifetime_pos = vec![]; - let mut suggestions = vec![]; loop { let attrs = self.parse_outer_attributes()?; if self.check_lifetime() { @@ -5501,39 +5530,40 @@ impl<'a> Parser<'a> { } else { Vec::new() }; - lifetimes.push(ast::GenericParam { + params.push(ast::GenericParam { ident: lifetime.ident, id: lifetime.id, attrs: attrs.into(), bounds, kind: ast::GenericParamKind::Lifetime, }); - if let Some(sp) = seen_ty_param { - let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); - bad_lifetime_pos.push(self.prev_span); - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - suggestions.push((remove_sp, String::new())); - suggestions.push(( - sp.shrink_to_lo(), - format!("{}, ", snippet))); - } - } + } else if self.check_keyword(keywords::Const) { + // Parse const parameter. + params.push(self.parse_const_param(attrs)?); } else if self.check_ident() { // Parse type parameter. params.push(self.parse_ty_param(attrs)?); - if seen_ty_param.is_none() { - seen_ty_param = Some(self.prev_span); - } } else { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { - let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" }; - self.struct_span_err( - attrs[0].span, - &format!("trailing attribute after {} parameters", param_kind), - ) - .span_label(attrs[0].span, "attributes must go before parameters") - .emit(); + if !params.is_empty() { + self.struct_span_err( + attrs[0].span, + &format!("trailing attribute after generic parameter"), + ) + .span_label(attrs[0].span, "attributes must go before parameters") + .emit(); + } else { + self.struct_span_err( + attrs[0].span, + &format!("attribute without generic parameters"), + ) + .span_label( + attrs[0].span, + "attributes are only permitted when preceding parameters", + ) + .emit(); + } } break } @@ -5541,24 +5571,8 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break } - last_comma_span = Some(self.prev_span); } - if !bad_lifetime_pos.is_empty() { - let mut err = self.struct_span_err( - bad_lifetime_pos, - "lifetime parameters must be declared prior to type parameters", - ); - if !suggestions.is_empty() { - err.multipart_suggestion( - "move the lifetime parameter prior to the first type parameter", - suggestions, - Applicability::MachineApplicable, - ); - } - err.emit(); - } - lifetimes.extend(params); // ensure the correct order of lifetimes and type params - Ok(lifetimes) + Ok(params) } /// Parse a set of optional generic type parameter declarations. Where @@ -5740,35 +5754,16 @@ impl<'a> Parser<'a> { fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { let mut args = Vec::new(); let mut bindings = Vec::new(); + let mut misplaced_assoc_ty_bindings: Vec = Vec::new(); + let mut assoc_ty_bindings: Vec = Vec::new(); - let mut seen_type = false; - let mut seen_binding = false; - - let mut last_comma_span = None; - let mut first_type_or_binding_span: Option = None; - let mut first_binding_span: Option = None; + let args_lo = self.span; - let mut bad_lifetime_pos = vec![]; - let mut bad_type_pos = vec![]; - - let mut lifetime_suggestions = vec![]; - let mut type_suggestions = vec![]; loop { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. args.push(GenericArg::Lifetime(self.expect_lifetime())); - - if seen_type || seen_binding { - let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); - bad_lifetime_pos.push(self.prev_span); - - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - lifetime_suggestions.push((remove_sp, String::new())); - lifetime_suggestions.push(( - first_type_or_binding_span.unwrap().shrink_to_lo(), - format!("{}, ", snippet))); - } - } + misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { // Parse associated type binding. let lo = self.span; @@ -5782,131 +5777,64 @@ impl<'a> Parser<'a> { ty, span, }); - - seen_binding = true; - if first_type_or_binding_span.is_none() { - first_type_or_binding_span = Some(span); - } - if first_binding_span.is_none() { - first_binding_span = Some(span); - } + assoc_ty_bindings.push(span); + } else if self.check_const_arg() { + // FIXME(const_generics): to distinguish between idents for types and consts, + // we should introduce a GenericArg::Ident in the AST and distinguish when + // lowering to the HIR. For now, idents for const args are not permitted. + + // Parse const argument. + let expr = if let token::OpenDelim(token::Brace) = self.token { + self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())? + } else if self.token.is_ident() { + // FIXME(const_generics): to distinguish between idents for types and consts, + // we should introduce a GenericArg::Ident in the AST and distinguish when + // lowering to the HIR. For now, idents for const args are not permitted. + return Err( + self.fatal("identifiers may currently not be used for const generics") + ); + } else { + // FIXME(const_generics): this currently conflicts with emplacement syntax + // with negative integer literals. + self.parse_literal_maybe_minus()? + }; + let value = AnonConst { + id: ast::DUMMY_NODE_ID, + value: expr, + }; + args.push(GenericArg::Const(value)); + misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); } else if self.check_type() { // Parse type argument. - let ty_param = self.parse_ty()?; - if seen_binding { - let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span); - bad_type_pos.push(self.prev_span); - - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) { - type_suggestions.push((remove_sp, String::new())); - type_suggestions.push(( - first_binding_span.unwrap().shrink_to_lo(), - format!("{}, ", snippet))); - } - } - - if first_type_or_binding_span.is_none() { - first_type_or_binding_span = Some(ty_param.span); - } - args.push(GenericArg::Type(ty_param)); - seen_type = true; + args.push(GenericArg::Type(self.parse_ty()?)); + misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); } else { break } if !self.eat(&token::Comma) { break - } else { - last_comma_span = Some(self.prev_span); - } - } - - self.maybe_report_incorrect_generic_argument_order( - bad_lifetime_pos, bad_type_pos, lifetime_suggestions, type_suggestions - ); - - Ok((args, bindings)) - } - - /// Maybe report an error about incorrect generic argument order - "lifetime parameters - /// must be declared before type parameters", "type parameters must be declared before - /// associated type bindings" or both. - fn maybe_report_incorrect_generic_argument_order( - &self, - bad_lifetime_pos: Vec, - bad_type_pos: Vec, - lifetime_suggestions: Vec<(Span, String)>, - type_suggestions: Vec<(Span, String)>, - ) { - let mut err = if !bad_lifetime_pos.is_empty() && !bad_type_pos.is_empty() { - let mut positions = bad_lifetime_pos.clone(); - positions.extend_from_slice(&bad_type_pos); - - self.struct_span_err( - positions, - "generic arguments must declare lifetimes, types and associated type bindings in \ - that order", - ) - } else if !bad_lifetime_pos.is_empty() { - self.struct_span_err( - bad_lifetime_pos.clone(), - "lifetime parameters must be declared prior to type parameters" - ) - } else if !bad_type_pos.is_empty() { - self.struct_span_err( - bad_type_pos.clone(), - "type parameters must be declared prior to associated type bindings" - ) - } else { - return; - }; - - if !bad_lifetime_pos.is_empty() { - for sp in &bad_lifetime_pos { - err.span_label(*sp, "must be declared prior to type parameters"); } } - if !bad_type_pos.is_empty() { - for sp in &bad_type_pos { - err.span_label(*sp, "must be declared prior to associated type bindings"); - } - } - - if !lifetime_suggestions.is_empty() && !type_suggestions.is_empty() { - let mut suggestions = lifetime_suggestions; - suggestions.extend_from_slice(&type_suggestions); - - let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1; - err.multipart_suggestion( - &format!( - "move the parameter{}", - if plural { "s" } else { "" }, - ), - suggestions, - Applicability::MachineApplicable, - ); - } else if !lifetime_suggestions.is_empty() { - err.multipart_suggestion( - &format!( - "move the lifetime parameter{} prior to the first type parameter", - if bad_lifetime_pos.len() > 1 { "s" } else { "" }, - ), - lifetime_suggestions, - Applicability::MachineApplicable, - ); - } else if !type_suggestions.is_empty() { - err.multipart_suggestion( - &format!( - "move the type parameter{} prior to the first associated type binding", - if bad_type_pos.len() > 1 { "s" } else { "" }, - ), - type_suggestions, - Applicability::MachineApplicable, + // FIXME: we would like to report this in ast_validation instead, but we currently do not + // preserve ordering of generic parameters with respect to associated type binding, so we + // lose that information after parsing. + if misplaced_assoc_ty_bindings.len() > 0 { + let mut err = self.struct_span_err( + args_lo.to(self.prev_span), + "associated type bindings must be declared after generic parameters", ); + for span in misplaced_assoc_ty_bindings { + err.span_label( + span, + "this associated type binding should be moved after the generic parameters", + ); + } + err.emit(); } - err.emit(); + Ok((args, bindings)) } /// Parses an optional `where` clause and places it in `generics`. @@ -6526,6 +6454,7 @@ impl<'a> Parser<'a> { // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds // `<` (LIFETIME|IDENT) `=` - generic parameter with a default + // `<` const - generic const parameter // The only truly ambiguous case is // `<` IDENT `>` `::` IDENT ... // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) @@ -6535,7 +6464,8 @@ impl<'a> Parser<'a> { (self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) || self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) && self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma || - t == &token::Colon || t == &token::Eq)) + t == &token::Colon || t == &token::Eq) || + self.look_ahead(1, |t| t.is_keyword(keywords::Const))) } fn parse_impl_body(&mut self) -> PResult<'a, (Vec, Vec)> { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 3b1fa5ea01f54..d5856c67156c0 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -279,6 +279,20 @@ impl Token { } } + /// Returns `true` if the token can appear at the start of a const param. + pub fn can_begin_const_arg(&self) -> bool { + match self { + OpenDelim(Brace) => true, + Interpolated(ref nt) => match nt.0 { + NtExpr(..) => true, + NtBlock(..) => true, + NtLiteral(..) => true, + _ => false, + } + _ => self.can_begin_literal_or_bool(), + } + } + /// Returns `true` if the token can appear at the start of a generic bound. crate fn can_begin_bound(&self) -> bool { self.is_path_start() || self.is_lifetime() || self.is_keyword(keywords::For) || @@ -293,7 +307,7 @@ impl Token { } } - /// Returns `true` if the token is any literal, a minus (which can follow a literal, + /// Returns `true` if the token is any literal, a minus (which can prefix a literal, /// for example a '-42', or one of the boolean idents). crate fn can_begin_literal_or_bool(&self) -> bool { match *self { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c7c4c4f16205b..c670f47b597da 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1025,6 +1025,7 @@ impl<'a> State<'a> { match generic_arg { GenericArg::Lifetime(lt) => self.print_lifetime(*lt), GenericArg::Type(ty) => self.print_type(ty), + GenericArg::Const(ct) => self.print_expr(&ct.value), } } @@ -2929,7 +2930,7 @@ impl<'a> State<'a> { s.print_outer_attributes_inline(¶m.attrs)?; let lt = ast::Lifetime { id: param.id, ident: param.ident }; s.print_lifetime_bounds(lt, ¶m.bounds) - }, + } ast::GenericParamKind::Type { ref default } => { s.print_outer_attributes_inline(¶m.attrs)?; s.print_ident(param.ident)?; @@ -2943,6 +2944,15 @@ impl<'a> State<'a> { _ => Ok(()) } } + ast::GenericParamKind::Const { ref ty } => { + s.print_outer_attributes_inline(¶m.attrs)?; + s.word_space("const")?; + s.print_ident(param.ident)?; + s.s.space()?; + s.word_space(":")?; + s.print_type(ty)?; + s.print_type_bounds(":", ¶m.bounds) + } } })?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index acbb58a66b6b4..bb3b0ea7359a8 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -126,6 +126,7 @@ pub trait Visitor<'ast>: Sized { match generic_arg { GenericArg::Lifetime(lt) => self.visit_lifetime(lt), GenericArg::Type(ty) => self.visit_ty(ty), + GenericArg::Const(ct) => self.visit_anon_const(ct), } } fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { @@ -486,6 +487,7 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Generi match param.kind { GenericParamKind::Lifetime => {} GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default), + GenericParamKind::Const { ref ty, .. } => visitor.visit_ty(ty), } } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index e6fe125da9f98..4678c7520455a 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -560,6 +560,7 @@ impl<'a> TraitDef<'a> { cx.typaram(self.span, param.ident, vec![], bounds, None) } + GenericParamKind::Const { .. } => param.clone(), })); // and similarly for where clauses @@ -657,6 +658,9 @@ impl<'a> TraitDef<'a> { GenericParamKind::Type { .. } => { GenericArg::Type(cx.ty_ident(self.span, param.ident)) } + GenericParamKind::Const { .. } => { + GenericArg::Const(cx.const_ident(self.span, param.ident)) + } }).collect(); // Create the type of `self`. diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index ea6e07922b2b3..100ec0057ee02 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -94,7 +94,7 @@ impl<'a> Path<'a> { } } -/// A type. Supports pointers, Self, and literals +/// A type. Supports pointers, Self, and literals. #[derive(Clone)] pub enum Ty<'a> { Self_, @@ -107,6 +107,13 @@ pub enum Ty<'a> { Tuple(Vec>), } +/// A const expression. Supports literals and blocks. +#[derive(Clone, Eq, PartialEq)] +pub enum Const { + Literal, + Block, +} + pub fn borrowed_ptrty<'r>() -> PtrTy<'r> { Borrowed(None, ast::Mutability::Immutable) } @@ -180,6 +187,9 @@ impl<'a> Ty<'a> { GenericParamKind::Type { .. } => { GenericArg::Type(cx.ty_ident(span, param.ident)) } + GenericParamKind::Const { .. } => { + GenericArg::Const(cx.const_ident(span, param.ident)) + } }).collect(); cx.path_all(span, false, vec![self_ty], params, vec![]) diff --git a/src/test/ui/attribute-with-no-generics-in-parameter-list.rs b/src/test/ui/attribute-with-no-generics-in-parameter-list.rs new file mode 100644 index 0000000000000..c2cc91d8f7703 --- /dev/null +++ b/src/test/ui/attribute-with-no-generics-in-parameter-list.rs @@ -0,0 +1,3 @@ +fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters + +fn main() {} diff --git a/src/test/ui/attribute-with-no-generics-in-parameter-list.stderr b/src/test/ui/attribute-with-no-generics-in-parameter-list.stderr new file mode 100644 index 0000000000000..f08f107a62ffe --- /dev/null +++ b/src/test/ui/attribute-with-no-generics-in-parameter-list.stderr @@ -0,0 +1,8 @@ +error: attribute without generic parameters + --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8 + | +LL | fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters + | ^^^^^^^ attributes are only permitted when preceding parameters + +error: aborting due to previous error + diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs index d7feb03853077..ca5fdd9da859b 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.rs @@ -7,7 +7,7 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { - //~^ ERROR trailing attribute after lifetime parameters + //~^ ERROR trailing attribute after generic parameter } fn main() { diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr index c4c0cee5ccc31..55e7a9877846f 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr @@ -1,4 +1,4 @@ -error: trailing attribute after lifetime parameters +error: trailing attribute after generic parameter --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25 | LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs index f9db6a5f72af9..c795612acf08c 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.rs @@ -7,6 +7,6 @@ struct RefAny<'a, T>(&'a T); impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} -//~^ ERROR trailing attribute after type parameters +//~^ ERROR trailing attribute after generic parameter fn main() {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr index 9099d74ce1be9..acd0ae3678a7c 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr @@ -1,4 +1,4 @@ -error: trailing attribute after type parameters +error: trailing attribute after generic parameter --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35 | LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs index e9f908d479f64..3cfc70b41850a 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs @@ -6,7 +6,7 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); fn hof_lt(_: Q) where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 - //~^ ERROR trailing attribute after lifetime parameters + //~^ ERROR trailing attribute after generic parameter {} fn main() {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr index 452f0ea5e1753..b9ca00974677b 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr @@ -1,4 +1,4 @@ -error: trailing attribute after lifetime parameters +error: trailing attribute after generic parameter --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:44 | LL | where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 diff --git a/src/test/ui/bad/bad-type-env-capture.rs b/src/test/ui/bad/bad-type-env-capture.rs index d2e6dff125273..53dfb13139a54 100644 --- a/src/test/ui/bad/bad-type-env-capture.rs +++ b/src/test/ui/bad/bad-type-env-capture.rs @@ -1,4 +1,4 @@ fn foo() { - fn bar(b: T) { } //~ ERROR can't use type parameters from outer + fn bar(b: T) { } //~ ERROR can't use generic parameters from outer } fn main() { } diff --git a/src/test/ui/bad/bad-type-env-capture.stderr b/src/test/ui/bad/bad-type-env-capture.stderr index 5558a44006180..ce803e96801f9 100644 --- a/src/test/ui/bad/bad-type-env-capture.stderr +++ b/src/test/ui/bad/bad-type-env-capture.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/bad-type-env-capture.rs:2:15 | LL | fn foo() { | - type variable from outer function -LL | fn bar(b: T) { } //~ ERROR can't use type parameters from outer - | --- ^ use of type variable from outer function +LL | fn bar(b: T) { } //~ ERROR can't use generic parameters from outer + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-expression-parameter.rs b/src/test/ui/const-generics/const-expression-parameter.rs new file mode 100644 index 0000000000000..f4e9008dbd0f1 --- /dev/null +++ b/src/test/ui/const-generics/const-expression-parameter.rs @@ -0,0 +1,23 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn u32_identity() -> u32 { + //~^ ERROR const generics in any position are currently unsupported + 5 +} + +fn foo_a() { + u32_identity::<-1>(); //~ ERROR expected identifier, found `<-` +} + +fn foo_b() { + u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+` +} + +fn foo_c() { + u32_identity::< -1 >(); // ok +} + +fn main() { + u32_identity::<5>(); // ok +} diff --git a/src/test/ui/const-generics/const-expression-parameter.stderr b/src/test/ui/const-generics/const-expression-parameter.stderr new file mode 100644 index 0000000000000..1dd3a960316d9 --- /dev/null +++ b/src/test/ui/const-generics/const-expression-parameter.stderr @@ -0,0 +1,26 @@ +error: expected identifier, found `<-` + --> $DIR/const-expression-parameter.rs:10:19 + | +LL | u32_identity::<-1>(); //~ ERROR expected identifier, found `<-` + | ^^ expected identifier + +error: expected one of `,` or `>`, found `+` + --> $DIR/const-expression-parameter.rs:14:22 + | +LL | u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+` + | ^ expected one of `,` or `>` here + +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-expression-parameter.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error: const generics in any position are currently unsupported + --> $DIR/const-expression-parameter.rs:4:23 + | +LL | fn u32_identity() -> u32 { + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/const-generics/const-fn-with-const-param.rs b/src/test/ui/const-generics/const-fn-with-const-param.rs new file mode 100644 index 0000000000000..052d723d96edb --- /dev/null +++ b/src/test/ui/const-generics/const-fn-with-const-param.rs @@ -0,0 +1,12 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +const fn const_u32_identity() -> u32 { + //~^ ERROR const parameters are not permitted in `const fn` + //~^^ ERROR const generics in any position are currently unsupported + X +} + +fn main() { + println!("{:?}", const_u32_identity::<18>()); +} diff --git a/src/test/ui/const-generics/const-fn-with-const-param.stderr b/src/test/ui/const-generics/const-fn-with-const-param.stderr new file mode 100644 index 0000000000000..a08ebfb0d9766 --- /dev/null +++ b/src/test/ui/const-generics/const-fn-with-const-param.stderr @@ -0,0 +1,24 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-fn-with-const-param.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error: const parameters are not permitted in `const fn` + --> $DIR/const-fn-with-const-param.rs:4:1 + | +LL | / const fn const_u32_identity() -> u32 { +LL | | //~^ ERROR const parameters are not permitted in `const fn` +LL | | //~^^ ERROR const generics in any position are currently unsupported +LL | | X +LL | | } + | |_^ + +error: const generics in any position are currently unsupported + --> $DIR/const-fn-with-const-param.rs:4:35 + | +LL | const fn const_u32_identity() -> u32 { + | ^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs new file mode 100644 index 0000000000000..3f120cbc4d337 --- /dev/null +++ b/src/test/ui/const-generics/const-param-before-other-params.rs @@ -0,0 +1,13 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn foo(_: T) { + //~^ ERROR type parameters must be declared prior to const parameters + //~^^ ERROR const generics in any position are currently unsupported +} + +fn bar(_: &'a ()) { + //~^ ERROR lifetime parameters must be declared prior to const parameters +} + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr new file mode 100644 index 0000000000000..aedcaf52e2688 --- /dev/null +++ b/src/test/ui/const-generics/const-param-before-other-params.stderr @@ -0,0 +1,26 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-param-before-other-params.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error: type parameters must be declared prior to const parameters + --> $DIR/const-param-before-other-params.rs:4:21 + | +LL | fn foo(_: T) { + | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` + +error: lifetime parameters must be declared prior to const parameters + --> $DIR/const-param-before-other-params.rs:9:21 + | +LL | fn bar(_: &'a ()) { + | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` + +error: const generics in any position are currently unsupported + --> $DIR/const-param-before-other-params.rs:4:14 + | +LL | fn foo(_: T) { + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.rs b/src/test/ui/const-generics/const-param-from-outer-fn.rs new file mode 100644 index 0000000000000..5a8dd92086f85 --- /dev/null +++ b/src/test/ui/const-generics/const-param-from-outer-fn.rs @@ -0,0 +1,11 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn foo() { + //~^ ERROR const generics in any position are currently unsupported + fn bar() -> u32 { + X //~ ERROR can't use generic parameters from outer function + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.stderr b/src/test/ui/const-generics/const-param-from-outer-fn.stderr new file mode 100644 index 0000000000000..b238b3a2aa453 --- /dev/null +++ b/src/test/ui/const-generics/const-param-from-outer-fn.stderr @@ -0,0 +1,26 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-param-from-outer-fn.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error[E0401]: can't use generic parameters from outer function + --> $DIR/const-param-from-outer-fn.rs:7:9 + | +LL | fn foo() { + | - const variable from outer function +LL | //~^ ERROR const generics in any position are currently unsupported +LL | fn bar() -> u32 { + | --- try adding a local generic parameter in this method instead +LL | X //~ ERROR can't use generic parameters from outer function + | ^ use of generic parameter from outer function + +error: const generics in any position are currently unsupported + --> $DIR/const-param-from-outer-fn.rs:4:14 + | +LL | fn foo() { + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/duplicate/duplicate-type-parameter.stderr b/src/test/ui/duplicate/duplicate-type-parameter.stderr index 41750d4bb3625..17d48edc35c91 100644 --- a/src/test/ui/duplicate/duplicate-type-parameter.stderr +++ b/src/test/ui/duplicate/duplicate-type-parameter.stderr @@ -1,4 +1,4 @@ -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:1:12 | LL | type Foo = Option; @@ -6,7 +6,7 @@ LL | type Foo = Option; | | | first use of `T` -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:4:14 | LL | struct Bar(T); @@ -14,7 +14,7 @@ LL | struct Bar(T); | | | first use of `T` -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:7:14 | LL | struct Baz { @@ -22,7 +22,7 @@ LL | struct Baz { | | | first use of `T` -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:12:12 | LL | enum Boo { @@ -30,7 +30,7 @@ LL | enum Boo { | | | first use of `T` -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:18:11 | LL | fn quux(x: T) {} @@ -38,7 +38,7 @@ LL | fn quux(x: T) {} | | | first use of `T` -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:21:13 | LL | trait Qux {} @@ -46,7 +46,7 @@ LL | trait Qux {} | | | first use of `T` -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/duplicate-type-parameter.rs:24:8 | LL | impl Qux for Option {} diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index c94fa497678e0..27f281ee43786 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -1,26 +1,26 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/E0401.rs:4:39 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bfnr, W: Fn()>(y: T) { //~ ERROR E0401 - | --------------------------- ^ use of type variable from outer function + | --------------------------- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bfnr, W: Fn(), T>` + | help: try using a local generic parameter instead: `bfnr, W: Fn(), T>` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/E0401.rs:9:16 | LL | fn foo(x: T) { | - type variable from outer function ... LL | fn baz $DIR/E0401.rs:22:25 | LL | impl Iterator for A { @@ -29,7 +29,7 @@ LL | impl Iterator for A { LL | fn helper(sel: &Self) -> u8 { //~ ERROR E0401 | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | use a type here instead error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0403.stderr b/src/test/ui/error-codes/E0403.stderr index 919a82dbe1a72..b924647502965 100644 --- a/src/test/ui/error-codes/E0403.stderr +++ b/src/test/ui/error-codes/E0403.stderr @@ -1,4 +1,4 @@ -error[E0403]: the name `T` is already used for a type parameter in this type parameter list +error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters --> $DIR/E0403.rs:1:11 | LL | fn foo(s: T, u: T) {} //~ ERROR E0403 diff --git a/src/test/ui/feature-gates/feature-gate-const_generics.rs b/src/test/ui/feature-gates/feature-gate-const_generics.rs new file mode 100644 index 0000000000000..a8a4ed5772299 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-const_generics.rs @@ -0,0 +1,6 @@ +fn foo() {} //~ ERROR const generics are unstable +//~^ const generics in any position are currently unsupported + +struct Foo([(); X]); //~ ERROR const generics are unstable + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-const_generics.stderr b/src/test/ui/feature-gates/feature-gate-const_generics.stderr new file mode 100644 index 0000000000000..905cc07b6a175 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-const_generics.stderr @@ -0,0 +1,25 @@ +error[E0658]: const generics are unstable (see issue #44580) + --> $DIR/feature-gate-const_generics.rs:1:14 + | +LL | fn foo() {} //~ ERROR const generics are unstable + | ^ + | + = help: add #![feature(const_generics)] to the crate attributes to enable + +error[E0658]: const generics are unstable (see issue #44580) + --> $DIR/feature-gate-const_generics.rs:4:18 + | +LL | struct Foo([(); X]); //~ ERROR const generics are unstable + | ^ + | + = help: add #![feature(const_generics)] to the crate attributes to enable + +error: const generics in any position are currently unsupported + --> $DIR/feature-gate-const_generics.rs:1:14 + | +LL | fn foo() {} //~ ERROR const generics are unstable + | ^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/impl-trait/bindings.rs b/src/test/ui/impl-trait/bindings.rs index 899303646d671..91d092634a901 100644 --- a/src/test/ui/impl-trait/bindings.rs +++ b/src/test/ui/impl-trait/bindings.rs @@ -2,27 +2,27 @@ fn a(x: T) { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant } fn b(x: T) { let _ = move || { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant }; } trait Foo { fn a(x: T) { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant } } impl Foo for i32 { fn a(x: T) { const foo: impl Clone = x; -//~^ ERROR can't capture dynamic environment in a fn item + //~^ ERROR attempt to use a non-constant value in a constant } } diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index 2a9be7a270a73..a5bf583afeaf6 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -1,35 +1,27 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:4:29 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:10:33 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:17:33 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:24:33 | LL | const foo: impl Clone = x; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/inner-static-type-parameter.rs b/src/test/ui/inner-static-type-parameter.rs index 60b4c5b8131b3..c08ccd29d8011 100644 --- a/src/test/ui/inner-static-type-parameter.rs +++ b/src/test/ui/inner-static-type-parameter.rs @@ -4,7 +4,7 @@ enum Bar { What } //~ ERROR parameter `T` is never used fn foo() { static a: Bar = Bar::What; -//~^ ERROR can't use type parameters from outer function +//~^ ERROR can't use generic parameters from outer function } fn main() { diff --git a/src/test/ui/inner-static-type-parameter.stderr b/src/test/ui/inner-static-type-parameter.stderr index 2f2856edb0ca9..87fb364954d96 100644 --- a/src/test/ui/inner-static-type-parameter.stderr +++ b/src/test/ui/inner-static-type-parameter.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/inner-static-type-parameter.rs:6:19 | LL | fn foo() { | --- - type variable from outer function | | - | try adding a local type parameter in this method instead + | try adding a local generic parameter in this method instead LL | static a: Bar = Bar::What; - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function error[E0392]: parameter `T` is never used --> $DIR/inner-static-type-parameter.rs:3:10 diff --git a/src/test/ui/issues/issue-12796.rs b/src/test/ui/issues/issue-12796.rs index acd4584c73700..942d6b9a5686e 100644 --- a/src/test/ui/issues/issue-12796.rs +++ b/src/test/ui/issues/issue-12796.rs @@ -1,7 +1,7 @@ trait Trait { fn outer(&self) { fn inner(_: &Self) { - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } } diff --git a/src/test/ui/issues/issue-12796.stderr b/src/test/ui/issues/issue-12796.stderr index 4bc29fd37dc4a..a01fd2d65420b 100644 --- a/src/test/ui/issues/issue-12796.stderr +++ b/src/test/ui/issues/issue-12796.stderr @@ -1,10 +1,10 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-12796.rs:3:22 | LL | fn inner(_: &Self) { | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | can't use `Self` here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-3.rs b/src/test/ui/issues/issue-20616-3.rs index e84506ee249d2..9bfd5bf231302 100644 --- a/src/test/ui/issues/issue-20616-3.rs +++ b/src/test/ui/issues/issue-20616-3.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -12,7 +10,8 @@ type Type_1_<'a, T> = &'a T; //type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` -type Type_3 = Box; //~ error: expected one of `>`, identifier, lifetime, or type, found `,` +type Type_3 = Box; +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` //type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` diff --git a/src/test/ui/issues/issue-20616-3.stderr b/src/test/ui/issues/issue-20616-3.stderr index 5247298b7cc26..f51fb949c740c 100644 --- a/src/test/ui/issues/issue-20616-3.stderr +++ b/src/test/ui/issues/issue-20616-3.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-3.rs:15:24 +error: expected one of `>`, const, identifier, lifetime, or type, found `,` + --> $DIR/issue-20616-3.rs:13:24 | -LL | type Type_3 = Box; //~ error: expected one of `>`, identifier, lifetime, or type, found `,` - | ^ expected one of `>`, identifier, lifetime, or type here +LL | type Type_3 = Box; + | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-4.rs b/src/test/ui/issues/issue-20616-4.rs index 785a6fa7d9a2f..e9a34a04667b0 100644 --- a/src/test/ui/issues/issue-20616-4.rs +++ b/src/test/ui/issues/issue-20616-4.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -16,7 +14,7 @@ type Type_1_<'a, T> = &'a T; type Type_4 = Type_1_<'static,, T>; -//~^ error: expected one of `>`, identifier, lifetime, or type, found `,` +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` type Type_5_<'a> = Type_1_<'a, ()>; diff --git a/src/test/ui/issues/issue-20616-4.stderr b/src/test/ui/issues/issue-20616-4.stderr index 74c38d9e97d60..22a655465e83c 100644 --- a/src/test/ui/issues/issue-20616-4.stderr +++ b/src/test/ui/issues/issue-20616-4.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-4.rs:18:34 +error: expected one of `>`, const, identifier, lifetime, or type, found `,` + --> $DIR/issue-20616-4.rs:16:34 | LL | type Type_4 = Type_1_<'static,, T>; - | ^ expected one of `>`, identifier, lifetime, or type here + | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-5.rs b/src/test/ui/issues/issue-20616-5.rs index 71dcc1f3a024f..23862516d2cbf 100644 --- a/src/test/ui/issues/issue-20616-5.rs +++ b/src/test/ui/issues/issue-20616-5.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -22,7 +20,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; type Type_5<'a> = Type_1_<'a, (),,>; -//~^ error: expected one of `>`, identifier, lifetime, or type, found `,` +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` diff --git a/src/test/ui/issues/issue-20616-5.stderr b/src/test/ui/issues/issue-20616-5.stderr index 38457beadc448..d83fc41f43ec0 100644 --- a/src/test/ui/issues/issue-20616-5.stderr +++ b/src/test/ui/issues/issue-20616-5.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-5.rs:24:34 +error: expected one of `>`, const, identifier, lifetime, or type, found `,` + --> $DIR/issue-20616-5.rs:22:34 | LL | type Type_5<'a> = Type_1_<'a, (),,>; - | ^ expected one of `>`, identifier, lifetime, or type here + | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-6.rs b/src/test/ui/issues/issue-20616-6.rs index da32da4885242..dc327f3f78824 100644 --- a/src/test/ui/issues/issue-20616-6.rs +++ b/src/test/ui/issues/issue-20616-6.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -25,7 +23,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; type Type_6 = Type_5_<'a,,>; -//~^ error: expected one of `>`, identifier, lifetime, or type, found `,` +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` //type Type_7 = Box<(),,>; // error: expected type, found `,` diff --git a/src/test/ui/issues/issue-20616-6.stderr b/src/test/ui/issues/issue-20616-6.stderr index 55b1d031a3915..0740df595234a 100644 --- a/src/test/ui/issues/issue-20616-6.stderr +++ b/src/test/ui/issues/issue-20616-6.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-6.rs:27:26 +error: expected one of `>`, const, identifier, lifetime, or type, found `,` + --> $DIR/issue-20616-6.rs:25:26 | LL | type Type_6 = Type_5_<'a,,>; - | ^ expected one of `>`, identifier, lifetime, or type here + | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-7.rs b/src/test/ui/issues/issue-20616-7.rs index feaaff2c89025..ffd1620c1d306 100644 --- a/src/test/ui/issues/issue-20616-7.rs +++ b/src/test/ui/issues/issue-20616-7.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -27,7 +25,8 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` -type Type_7 = Box<(),,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,` +type Type_7 = Box<(),,>; +//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,` //type Type_8<'a,,> = &'a (); // error: expected ident, found `,` diff --git a/src/test/ui/issues/issue-20616-7.stderr b/src/test/ui/issues/issue-20616-7.stderr index 8b5f67c703f64..c0e108375be29 100644 --- a/src/test/ui/issues/issue-20616-7.stderr +++ b/src/test/ui/issues/issue-20616-7.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, lifetime, or type, found `,` - --> $DIR/issue-20616-7.rs:30:22 +error: expected one of `>`, const, identifier, lifetime, or type, found `,` + --> $DIR/issue-20616-7.rs:28:22 | -LL | type Type_7 = Box<(),,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,` - | ^ expected one of `>`, identifier, lifetime, or type here +LL | type Type_7 = Box<(),,>; + | ^ expected one of `>`, const, identifier, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-8.rs b/src/test/ui/issues/issue-20616-8.rs index 2fc7243559a31..c9e8b61e50b52 100644 --- a/src/test/ui/issues/issue-20616-8.rs +++ b/src/test/ui/issues/issue-20616-8.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -30,7 +28,8 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_7 = Box<(),,>; // error: expected type, found `,` -type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, identifier, or lifetime, found `,` +type Type_8<'a,,> = &'a (); +//~^ error: expected one of `>`, `const`, identifier, or lifetime, found `,` //type Type_9 = Box; // error: expected identifier, found `,` diff --git a/src/test/ui/issues/issue-20616-8.stderr b/src/test/ui/issues/issue-20616-8.stderr index cdeb544f07c4c..0ef9192f1e73a 100644 --- a/src/test/ui/issues/issue-20616-8.stderr +++ b/src/test/ui/issues/issue-20616-8.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, or lifetime, found `,` - --> $DIR/issue-20616-8.rs:33:16 +error: expected one of `>`, `const`, identifier, or lifetime, found `,` + --> $DIR/issue-20616-8.rs:31:16 | -LL | type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, identifier, or lifetime, found `,` - | ^ expected one of `>`, identifier, or lifetime here +LL | type Type_8<'a,,> = &'a (); + | ^ expected one of `>`, `const`, identifier, or lifetime here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20616-9.rs b/src/test/ui/issues/issue-20616-9.rs index b14a5b0ff36da..1c509f26fd63a 100644 --- a/src/test/ui/issues/issue-20616-9.rs +++ b/src/test/ui/issues/issue-20616-9.rs @@ -1,8 +1,6 @@ // We need all these 9 issue-20616-N.rs files // because we can only catch one parsing error at a time - - type Type_1_<'a, T> = &'a T; @@ -33,4 +31,5 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_8<'a,,> = &'a (); // error: expected identifier, found `,` -type Type_9 = Box; //~ error: expected one of `>`, identifier, or lifetime, found `,` +type Type_9 = Box; +//~^ error: expected one of `>`, `const`, identifier, or lifetime, found `,` diff --git a/src/test/ui/issues/issue-20616-9.stderr b/src/test/ui/issues/issue-20616-9.stderr index dfe705c6f12ed..5fd1400a2e8ca 100644 --- a/src/test/ui/issues/issue-20616-9.stderr +++ b/src/test/ui/issues/issue-20616-9.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, or lifetime, found `,` - --> $DIR/issue-20616-9.rs:36:15 +error: expected one of `>`, `const`, identifier, or lifetime, found `,` + --> $DIR/issue-20616-9.rs:34:15 | -LL | type Type_9 = Box; //~ error: expected one of `>`, identifier, or lifetime, found `,` - | ^ expected one of `>`, identifier, or lifetime here +LL | type Type_9 = Box; + | ^ expected one of `>`, `const`, identifier, or lifetime here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-27433.rs b/src/test/ui/issues/issue-27433.rs index 2cc7d05e7c691..156ae68efe2c5 100644 --- a/src/test/ui/issues/issue-27433.rs +++ b/src/test/ui/issues/issue-27433.rs @@ -1,5 +1,5 @@ fn main() { let foo = 42u32; const FOO : u32 = foo; - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant } diff --git a/src/test/ui/issues/issue-27433.stderr b/src/test/ui/issues/issue-27433.stderr index 78a193dd99a7f..e232d17e6d7a6 100644 --- a/src/test/ui/issues/issue-27433.stderr +++ b/src/test/ui/issues/issue-27433.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-27433.rs:3:23 | LL | const FOO : u32 = foo; - | ^^^ - | - = help: use the `|| { ... }` closure form instead + | ^^^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-3021-c.rs b/src/test/ui/issues/issue-3021-c.rs index 491336206ca94..94ed1fdf78191 100644 --- a/src/test/ui/issues/issue-3021-c.rs +++ b/src/test/ui/issues/issue-3021-c.rs @@ -1,8 +1,8 @@ fn siphash() { trait U { - fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function - //~^ ERROR can't use type parameters from outer function + fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } diff --git a/src/test/ui/issues/issue-3021-c.stderr b/src/test/ui/issues/issue-3021-c.stderr index 323ce4fa30613..5eadf7837c7d0 100644 --- a/src/test/ui/issues/issue-3021-c.stderr +++ b/src/test/ui/issues/issue-3021-c.stderr @@ -1,24 +1,24 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3021-c.rs:4:24 | LL | fn siphash() { | - type variable from outer function ... -LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function - | - ^ use of type variable from outer function +LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function + | - ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `g` + | help: try using a local generic parameter instead: `g` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3021-c.rs:4:30 | LL | fn siphash() { | - type variable from outer function ... -LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function - | - ^ use of type variable from outer function +LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function + | - ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `g` + | help: try using a local generic parameter instead: `g` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-3214.rs b/src/test/ui/issues/issue-3214.rs index 85eae2686e6a9..9a727aa305797 100644 --- a/src/test/ui/issues/issue-3214.rs +++ b/src/test/ui/issues/issue-3214.rs @@ -1,6 +1,6 @@ fn foo() { struct Foo { - x: T, //~ ERROR can't use type parameters from outer function + x: T, //~ ERROR can't use generic parameters from outer function } impl Drop for Foo { diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr index 4ecea4f98006e..e6526bad3e0d3 100644 --- a/src/test/ui/issues/issue-3214.stderr +++ b/src/test/ui/issues/issue-3214.stderr @@ -1,13 +1,13 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-3214.rs:3:12 | LL | fn foo() { | --- - type variable from outer function | | - | try adding a local type parameter in this method instead + | try adding a local generic parameter in this method instead LL | struct Foo { -LL | x: T, //~ ERROR can't use type parameters from outer function - | ^ use of type variable from outer function +LL | x: T, //~ ERROR can't use generic parameters from outer function + | ^ use of generic parameter from outer function error[E0107]: wrong number of type arguments: expected 0, found 1 --> $DIR/issue-3214.rs:6:26 diff --git a/src/test/ui/issues/issue-3521-2.rs b/src/test/ui/issues/issue-3521-2.rs index 39f7fcb833756..871394f9eaeb9 100644 --- a/src/test/ui/issues/issue-3521-2.rs +++ b/src/test/ui/issues/issue-3521-2.rs @@ -2,7 +2,7 @@ fn main() { let foo = 100; static y: isize = foo + 1; - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant println!("{}", y); } diff --git a/src/test/ui/issues/issue-3521-2.stderr b/src/test/ui/issues/issue-3521-2.stderr index 1464fd74bba69..d54bbbcdc3325 100644 --- a/src/test/ui/issues/issue-3521-2.stderr +++ b/src/test/ui/issues/issue-3521-2.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3521-2.rs:4:23 | LL | static y: isize = foo + 1; - | ^^^ - | - = help: use the `|| { ... }` closure form instead + | ^^^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-3668-2.rs b/src/test/ui/issues/issue-3668-2.rs index 265a884ded7aa..525f6f5684e70 100644 --- a/src/test/ui/issues/issue-3668-2.rs +++ b/src/test/ui/issues/issue-3668-2.rs @@ -1,6 +1,6 @@ fn f(x:isize) { static child: isize = x + 1; - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant } fn main() {} diff --git a/src/test/ui/issues/issue-3668-2.stderr b/src/test/ui/issues/issue-3668-2.stderr index 8dd6f49d8de5a..d6a6e8379602d 100644 --- a/src/test/ui/issues/issue-3668-2.stderr +++ b/src/test/ui/issues/issue-3668-2.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3668-2.rs:2:27 | LL | static child: isize = x + 1; - | ^ - | - = help: use the `|| { ... }` closure form instead + | ^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-3668.rs b/src/test/ui/issues/issue-3668.rs index 3f61b1b02e779..0e1f19a75baeb 100644 --- a/src/test/ui/issues/issue-3668.rs +++ b/src/test/ui/issues/issue-3668.rs @@ -6,7 +6,7 @@ trait PTrait { impl PTrait for P { fn getChildOption(&self) -> Option> { static childVal: Box

= self.child.get(); - //~^ ERROR can't capture dynamic environment + //~^ ERROR attempt to use a non-constant value in a constant panic!(); } } diff --git a/src/test/ui/issues/issue-3668.stderr b/src/test/ui/issues/issue-3668.stderr index 7f974de9da8ea..98cd3631a5365 100644 --- a/src/test/ui/issues/issue-3668.stderr +++ b/src/test/ui/issues/issue-3668.stderr @@ -1,11 +1,9 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3668.rs:8:34 | LL | static childVal: Box

= self.child.get(); - | ^^^^ - | - = help: use the `|| { ... }` closure form instead + | ^^^^ non-constant value error: aborting due to previous error -For more information about this error, try `rustc --explain E0434`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/issues/issue-5997-enum.rs b/src/test/ui/issues/issue-5997-enum.rs index 0987117ecd402..3ff4e036c60be 100644 --- a/src/test/ui/issues/issue-5997-enum.rs +++ b/src/test/ui/issues/issue-5997-enum.rs @@ -1,6 +1,6 @@ fn f() -> bool { enum E { V(Z) } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function true } diff --git a/src/test/ui/issues/issue-5997-enum.stderr b/src/test/ui/issues/issue-5997-enum.stderr index 5c26dc92c8584..5c778143e13dd 100644 --- a/src/test/ui/issues/issue-5997-enum.stderr +++ b/src/test/ui/issues/issue-5997-enum.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-5997-enum.rs:2:16 | LL | fn f() -> bool { | - - type variable from outer function | | - | try adding a local type parameter in this method instead + | try adding a local generic parameter in this method instead LL | enum E { V(Z) } - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function error: aborting due to previous error diff --git a/src/test/ui/issues/issue-5997-struct.rs b/src/test/ui/issues/issue-5997-struct.rs index 04ac489a55c50..6cf510b0a9d75 100644 --- a/src/test/ui/issues/issue-5997-struct.rs +++ b/src/test/ui/issues/issue-5997-struct.rs @@ -1,5 +1,5 @@ fn f() -> bool { - struct S(T); //~ ERROR can't use type parameters from outer function + struct S(T); //~ ERROR can't use generic parameters from outer function true } diff --git a/src/test/ui/issues/issue-5997-struct.stderr b/src/test/ui/issues/issue-5997-struct.stderr index 1d05d13242e8e..a60987b3f98ba 100644 --- a/src/test/ui/issues/issue-5997-struct.stderr +++ b/src/test/ui/issues/issue-5997-struct.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/issue-5997-struct.rs:2:14 | LL | fn f() -> bool { | - - type variable from outer function | | - | try adding a local type parameter in this method instead -LL | struct S(T); //~ ERROR can't use type parameters from outer function - | ^ use of type variable from outer function + | try adding a local generic parameter in this method instead +LL | struct S(T); //~ ERROR can't use generic parameters from outer function + | ^ use of generic parameter from outer function error: aborting due to previous error diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr index 7ac8dffdfbe0c..3cef5db66c66f 100644 --- a/src/test/ui/lifetime-before-type-params.stderr +++ b/src/test/ui/lifetime-before-type-params.stderr @@ -2,41 +2,25 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/lifetime-before-type-params.rs:2:13 | LL | fn first() {} - | ^^ ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | fn first<'a, 'b, T>() {} - | ^^^ ^^^ -- + | ----^^--^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: lifetime parameters must be declared prior to type parameters --> $DIR/lifetime-before-type-params.rs:4:18 | LL | fn second<'a, T, 'b>() {} - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | fn second<'a, 'b, T>() {} - | ^^^ -- + | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: lifetime parameters must be declared prior to type parameters --> $DIR/lifetime-before-type-params.rs:6:16 | LL | fn third() {} - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | fn third<'a, T, U>() {} - | ^^^ -- + | -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>` error: lifetime parameters must be declared prior to type parameters --> $DIR/lifetime-before-type-params.rs:8:18 | LL | fn fourth<'a, T, 'b, U, 'c, V>() {} - | ^^ ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | fn fourth<'a, 'b, 'c, T, U, V>() {} - | ^^^ ^^^ -- -- + | --------^^-----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>` error[E0601]: `main` function not found in crate `lifetime_before_type_params` | diff --git a/src/test/ui/nested-ty-params.rs b/src/test/ui/nested-ty-params.rs index 102f8d02ee416..85413acdb1491 100644 --- a/src/test/ui/nested-ty-params.rs +++ b/src/test/ui/nested-ty-params.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use type parameters from outer function +// error-pattern:can't use generic parameters from outer function fn hd(v: Vec ) -> U { fn hd1(w: [U]) -> U { return w[0]; } diff --git a/src/test/ui/nested-ty-params.stderr b/src/test/ui/nested-ty-params.stderr index 617eddf6525df..37adeffb9b07a 100644 --- a/src/test/ui/nested-ty-params.stderr +++ b/src/test/ui/nested-ty-params.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/nested-ty-params.rs:3:16 | LL | fn hd(v: Vec ) -> U { | - type variable from outer function LL | fn hd1(w: [U]) -> U { return w[0]; } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `hd1` + | help: try using a local generic parameter instead: `hd1` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/nested-ty-params.rs:3:23 | LL | fn hd(v: Vec ) -> U { | - type variable from outer function LL | fn hd1(w: [U]) -> U { return w[0]; } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `hd1` + | help: try using a local generic parameter instead: `hd1` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/bounds-lifetime.rs b/src/test/ui/parser/bounds-lifetime.rs index 89a969bb2e2a9..9225cfce94eb8 100644 --- a/src/test/ui/parser/bounds-lifetime.rs +++ b/src/test/ui/parser/bounds-lifetime.rs @@ -6,6 +6,6 @@ type A = for<'a: 'b + 'c> fn(); // OK (rejected later by ast_validation) type A = for<'a: 'b,> fn(); // OK(rejected later by ast_validation) type A = for<'a: 'b +> fn(); // OK (rejected later by ast_validation) type A = for<'a, T> fn(); // OK (rejected later by ast_validation) -type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,` +type A = for<,> fn(); //~ ERROR expected one of `>`, `const`, identifier, or lifetime, found `,` fn main() {} diff --git a/src/test/ui/parser/bounds-lifetime.stderr b/src/test/ui/parser/bounds-lifetime.stderr index f39e5beb6ac90..191ea3ebd070a 100644 --- a/src/test/ui/parser/bounds-lifetime.stderr +++ b/src/test/ui/parser/bounds-lifetime.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, or lifetime, found `,` +error: expected one of `>`, `const`, identifier, or lifetime, found `,` --> $DIR/bounds-lifetime.rs:9:14 | -LL | type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,` - | ^ expected one of `>`, identifier, or lifetime here +LL | type A = for<,> fn(); //~ ERROR expected one of `>`, `const`, identifier, or lifetime, found `,` + | ^ expected one of `>`, `const`, identifier, or lifetime here error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-enum.stderr b/src/test/ui/parser/issue-14303-enum.stderr index a31429e7228c5..bcecd75b1abba 100644 --- a/src/test/ui/parser/issue-14303-enum.stderr +++ b/src/test/ui/parser/issue-14303-enum.stderr @@ -2,11 +2,7 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/issue-14303-enum.rs:1:15 | LL | enum X<'a, T, 'b> { - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | enum X<'a, 'b, T> { - | ^^^ -- + | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-fn-def.stderr b/src/test/ui/parser/issue-14303-fn-def.stderr index 4582aeef428d3..082c37e0be795 100644 --- a/src/test/ui/parser/issue-14303-fn-def.stderr +++ b/src/test/ui/parser/issue-14303-fn-def.stderr @@ -2,11 +2,7 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/issue-14303-fn-def.rs:1:15 | LL | fn foo<'a, T, 'b>(x: &'a T) {} - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | fn foo<'a, 'b, T>(x: &'a T) {} - | ^^^ -- + | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs index 17b9b766b2181..39694198cdb4d 100644 --- a/src/test/ui/parser/issue-14303-fncall.rs +++ b/src/test/ui/parser/issue-14303-fncall.rs @@ -11,7 +11,7 @@ fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { let _x = (*start..*end) .map(|x| S { a: start, b: end }) .collect::>>(); - //~^ ERROR lifetime parameters must be declared prior to type parameters + //~^ ERROR lifetime arguments must be declared prior to type arguments } fn main() {} diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.stderr index 2a7364915949e..8ef9f1a1a6c79 100644 --- a/src/test/ui/parser/issue-14303-fncall.stderr +++ b/src/test/ui/parser/issue-14303-fncall.stderr @@ -1,12 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters +error: lifetime arguments must be declared prior to type arguments --> $DIR/issue-14303-fncall.rs:13:29 | LL | .collect::>>(); - | ^^ must be declared prior to type parameters -help: move the lifetime parameter prior to the first type parameter - | -LL | .collect::>>(); - | ^^^ -- + | ^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-impl.stderr b/src/test/ui/parser/issue-14303-impl.stderr index a1953396153e0..3b5615d2a9eca 100644 --- a/src/test/ui/parser/issue-14303-impl.stderr +++ b/src/test/ui/parser/issue-14303-impl.stderr @@ -2,11 +2,7 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/issue-14303-impl.rs:3:13 | LL | impl<'a, T, 'b> X {} - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | impl<'a, 'b, T> X {} - | ^^^ -- + | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-path.rs b/src/test/ui/parser/issue-14303-path.rs index a08c89f3437b4..386d19859e4a8 100644 --- a/src/test/ui/parser/issue-14303-path.rs +++ b/src/test/ui/parser/issue-14303-path.rs @@ -8,6 +8,6 @@ mod foo { } fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} -//~^ ERROR lifetime parameters must be declared prior to type parameters +//~^ ERROR lifetime arguments must be declared prior to type arguments fn main() {} diff --git a/src/test/ui/parser/issue-14303-path.stderr b/src/test/ui/parser/issue-14303-path.stderr index fb4fb32e11e50..19f2995ebee53 100644 --- a/src/test/ui/parser/issue-14303-path.stderr +++ b/src/test/ui/parser/issue-14303-path.stderr @@ -1,14 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters +error: lifetime arguments must be declared prior to type arguments --> $DIR/issue-14303-path.rs:10:40 | LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} - | ^^ ^^ must be declared prior to type parameters - | | - | must be declared prior to type parameters -help: move the lifetime parameters prior to the first type parameter - | -LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, 'b, 'c, T>) {} - | ^^^ ^^^ -- + | ^^ ^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-struct.stderr b/src/test/ui/parser/issue-14303-struct.stderr index 668b8d1de6899..dbd0b987dd190 100644 --- a/src/test/ui/parser/issue-14303-struct.stderr +++ b/src/test/ui/parser/issue-14303-struct.stderr @@ -2,11 +2,7 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/issue-14303-struct.rs:1:17 | LL | struct X<'a, T, 'b> { - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | struct X<'a, 'b, T> { - | ^^^ -- + | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-trait.stderr b/src/test/ui/parser/issue-14303-trait.stderr index 11ce0c44351ad..7dfa62d823fd8 100644 --- a/src/test/ui/parser/issue-14303-trait.stderr +++ b/src/test/ui/parser/issue-14303-trait.stderr @@ -2,11 +2,7 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/issue-14303-trait.rs:1:18 | LL | trait Foo<'a, T, 'b> {} - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | trait Foo<'a, 'b, T> {} - | ^^^ -- + | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-32214.rs b/src/test/ui/parser/issue-32214.rs index 7e55bc038e766..7191a3234c083 100644 --- a/src/test/ui/parser/issue-32214.rs +++ b/src/test/ui/parser/issue-32214.rs @@ -3,6 +3,6 @@ trait Trait { type Item; } pub fn test >() {} -//~^ ERROR type parameters must be declared prior to associated type bindings +//~^ ERROR associated type bindings must be declared after generic parameters fn main() { } diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr index 660e517c85a13..7022019a22f26 100644 --- a/src/test/ui/parser/issue-32214.stderr +++ b/src/test/ui/parser/issue-32214.stderr @@ -1,12 +1,10 @@ -error: type parameters must be declared prior to associated type bindings - --> $DIR/issue-32214.rs:5:34 +error: associated type bindings must be declared after generic parameters + --> $DIR/issue-32214.rs:5:25 | LL | pub fn test >() {} - | ^ must be declared prior to associated type bindings -help: move the type parameter prior to the first associated type binding - | -LL | pub fn test >() {} - | ^^ -- + | -------^^^ + | | + | this associated type binding should be moved after the generic parameters error: aborting due to previous error diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs b/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs index 12de76d9d6d9f..79d51f5595d26 100644 --- a/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs +++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs @@ -1 +1 @@ -type mut_box = Box; //~ ERROR expected one of `>`, lifetime, or type, found `mut` +type mut_box = Box; //~ ERROR expected one of `>`, const, lifetime, or type, found `mut` diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr index 0177b19d74e7e..b2759778d0313 100644 --- a/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr +++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, lifetime, or type, found `mut` +error: expected one of `>`, const, lifetime, or type, found `mut` --> $DIR/removed-syntax-uniq-mut-ty.rs:1:20 | -LL | type mut_box = Box; //~ ERROR expected one of `>`, lifetime, or type, found `mut` - | ^^^ expected one of `>`, lifetime, or type here +LL | type mut_box = Box; //~ ERROR expected one of `>`, const, lifetime, or type, found `mut` + | ^^^ expected one of `>`, const, lifetime, or type here error: aborting due to previous error diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs index 112427a3fceae..c77a66524f73f 100644 --- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs +++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.rs @@ -6,7 +6,7 @@ trait TraitA { fn outer(&self) { enum Foo { Variance(A) - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } } @@ -14,21 +14,21 @@ trait TraitA { trait TraitB { fn outer(&self) { struct Foo(A); - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } trait TraitC { fn outer(&self) { struct Foo { a: A } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } trait TraitD { fn outer(&self) { fn foo(a: A) { } - //~^ ERROR can't use type parameters from outer function + //~^ ERROR can't use generic parameters from outer function } } diff --git a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 8eca720d88e8c..f6b8abf4057e5 100644 --- a/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/src/test/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -1,44 +1,44 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:8:22 | LL | trait TraitA { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | enum Foo { LL | Variance(A) - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 | LL | trait TraitB { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | struct Foo(A); - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 | LL | trait TraitC { | - type variable from outer function LL | fn outer(&self) { - | ----- try adding a local type parameter in this method instead + | ----- try adding a local generic parameter in this method instead LL | struct Foo { a: A } - | ^ use of type variable from outer function + | ^ use of generic parameter from outer function -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 | LL | trait TraitD { | - type variable from outer function LL | fn outer(&self) { LL | fn foo(a: A) { } - | ------ ^ use of type variable from outer function + | ------ ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `foo` + | help: try using a local generic parameter instead: `foo` error: aborting due to 4 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/empty_generics.rs b/src/test/ui/rfc1598-generic-associated-types/empty_generics.rs index 158ebc7d3888a..afc27701920dc 100644 --- a/src/test/ui/rfc1598-generic-associated-types/empty_generics.rs +++ b/src/test/ui/rfc1598-generic-associated-types/empty_generics.rs @@ -3,7 +3,7 @@ trait Foo { type Bar<,>; - //~^ ERROR expected one of `>`, identifier, or lifetime, found `,` + //~^ ERROR expected one of `>`, `const`, identifier, or lifetime, found `,` } fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr index 2a01b2a3f0fa5..5b98302924e3c 100644 --- a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr @@ -1,8 +1,8 @@ -error: expected one of `>`, identifier, or lifetime, found `,` +error: expected one of `>`, `const`, identifier, or lifetime, found `,` --> $DIR/empty_generics.rs:5:14 | LL | type Bar<,>; - | ^ expected one of `>`, identifier, or lifetime here + | ^ expected one of `>`, `const`, identifier, or lifetime here warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash --> $DIR/empty_generics.rs:1:12 diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index b36e927b5c0c6..2d6dee0621662 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -2,41 +2,25 @@ error: lifetime parameters must be declared prior to type parameters --> $DIR/suggest-move-lifetimes.rs:1:13 | LL | struct A { //~ ERROR lifetime parameters must be declared - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | struct A<'a, T> { //~ ERROR lifetime parameters must be declared - | ^^^ -- + | ----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T>` error: lifetime parameters must be declared prior to type parameters --> $DIR/suggest-move-lifetimes.rs:5:13 | LL | struct B { //~ ERROR lifetime parameters must be declared - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared - | ^^^ -- + | ----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>` error: lifetime parameters must be declared prior to type parameters --> $DIR/suggest-move-lifetimes.rs:10:16 | LL | struct C { //~ ERROR lifetime parameters must be declared - | ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | struct C<'a, T, U> { //~ ERROR lifetime parameters must be declared - | ^^^ -- + | -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>` error: lifetime parameters must be declared prior to type parameters --> $DIR/suggest-move-lifetimes.rs:15:16 | LL | struct D { //~ ERROR lifetime parameters must be declared - | ^^ ^^ ^^ -help: move the lifetime parameter prior to the first type parameter - | -LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared - | ^^^ ^^^ ^^^ -- -- + | -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>` error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/suggest-move-types.rs b/src/test/ui/suggestions/suggest-move-types.rs index fd10ba4350c4a..890950ea08c5d 100644 --- a/src/test/ui/suggestions/suggest-move-types.rs +++ b/src/test/ui/suggestions/suggest-move-types.rs @@ -25,19 +25,20 @@ trait ThreeWithLifetime<'a, 'b, 'c, T, U, V> { type C; } -struct A> { //~ ERROR type parameters must be declared +struct A> { //~ ERROR associated type bindings must be declared after generic parameters m: M, t: T, } struct Al<'a, T, M: OneWithLifetime> { -//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order +//~^ ERROR associated type bindings must be declared after generic parameters +//~^^ ERROR lifetime arguments must be declared prior to type arguments m: M, t: &'a T, } -struct B> { //~ ERROR type parameters must be declared +struct B> { //~ ERROR associated type bindings must be declared after generic parameters m: M, t: T, u: U, @@ -45,14 +46,15 @@ struct B> { //~ ERROR type paramete } struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { -//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order +//~^ ERROR associated type bindings must be declared after generic parameters +//~^^ ERROR lifetime arguments must be declared prior to type arguments m: M, t: &'a T, u: &'b U, v: &'c V, } -struct C> { //~ ERROR type parameters must be declared +struct C> { //~ ERROR associated type bindings must be declared after generic parameters m: M, t: T, u: U, @@ -60,14 +62,15 @@ struct C> { //~ ERROR type paramete } struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { -//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order +//~^ ERROR associated type bindings must be declared after generic parameters +//~^^ ERROR lifetime arguments must be declared prior to type arguments m: M, t: &'a T, u: &'b U, v: &'c V, } -struct D> { //~ ERROR type parameters must be declared +struct D> { //~ ERROR associated type bindings must be declared after generic parameters m: M, t: T, u: U, @@ -75,7 +78,8 @@ struct D> { //~ ERROR type paramete } struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { -//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order +//~^ ERROR associated type bindings must be declared after generic parameters +//~^^ ERROR lifetime arguments must be declared prior to type arguments m: M, t: &'a T, u: &'b U, diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr index 3643d9a912455..0901b71911d43 100644 --- a/src/test/ui/suggestions/suggest-move-types.stderr +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -1,107 +1,102 @@ -error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:28:26 +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:28:20 | -LL | struct A> { //~ ERROR type parameters must be declared - | ^ must be declared prior to associated type bindings -help: move the type parameter prior to the first associated type binding - | -LL | struct A> { //~ ERROR type parameters must be declared - | ^^ -- +LL | struct A> { //~ ERROR associated type bindings must be declared after generic parameters + | ----^^^ + | | + | this associated type binding should be moved after the generic parameters -error: generic arguments must declare lifetimes, types and associated type bindings in that order - --> $DIR/suggest-move-types.rs:34:46 +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:34:37 | LL | struct Al<'a, T, M: OneWithLifetime> { - | ^ ^^ must be declared prior to type parameters - | | - | must be declared prior to associated type bindings -help: move the parameters - | -LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A=()>> { - | ^^^ ^^ -- + | ----^^^^^^^ + | | + | this associated type binding should be moved after the generic parameters -error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:40:46 - | -LL | struct B> { //~ ERROR type parameters must be declared - | ^ ^ ^ must be declared prior to associated type bindings - | | | - | | must be declared prior to associated type bindings - | must be declared prior to associated type bindings -help: move the type parameters prior to the first associated type binding - | -LL | struct B> { //~ ERROR type parameters must be declared - | ^^ ^^ ^^ -- +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:41:28 + | +LL | struct B> { //~ ERROR associated type bindings must be declared after generic parameters + | ----^^----^^----^^^^^^^^^ + | | | | + | | | this associated type binding should be moved after the generic parameters + | | this associated type binding should be moved after the generic parameters + | this associated type binding should be moved after the generic parameters -error: generic arguments must declare lifetimes, types and associated type bindings in that order - --> $DIR/suggest-move-types.rs:47:80 +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:48:53 | LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^ ^ ^ ^^ ^^ ^^ must be declared prior to type parameters - | | | | | | - | | | | | must be declared prior to type parameters - | | | | must be declared prior to type parameters - | | | must be declared prior to associated type bindings - | | must be declared prior to associated type bindings - | must be declared prior to associated type bindings -help: move the parameters - | -LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> { - | ^^^ ^^^ ^^^ ^^ ^^ ^^ -- + | ----^^----^^----^^^^^^^^^^^^^^^^^^^^^ + | | | | + | | | this associated type binding should be moved after the generic parameters + | | this associated type binding should be moved after the generic parameters + | this associated type binding should be moved after the generic parameters -error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:55:49 - | -LL | struct C> { //~ ERROR type parameters must be declared - | ^ ^ must be declared prior to associated type bindings - | | - | must be declared prior to associated type bindings -help: move the type parameters prior to the first associated type binding - | -LL | struct C> { //~ ERROR type parameters must be declared - | ^^ ^^ -- +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:57:28 + | +LL | struct C> { //~ ERROR associated type bindings must be declared after generic parameters + | ^^^----^^----^^----^^^^^^ + | | | | + | | | this associated type binding should be moved after the generic parameters + | | this associated type binding should be moved after the generic parameters + | this associated type binding should be moved after the generic parameters -error: generic arguments must declare lifetimes, types and associated type bindings in that order - --> $DIR/suggest-move-types.rs:62:56 +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:64:53 | LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^ ^^ ^ ^^ must be declared prior to type parameters - | | | | | - | | | | must be declared prior to associated type bindings - | | | must be declared prior to type parameters - | | must be declared prior to associated type bindings - | must be declared prior to type parameters -help: move the parameters + | ^^^^^^^----^^----^^----^^^^^^^^^^^^^^ + | | | | + | | | this associated type binding should be moved after the generic parameters + | | this associated type binding should be moved after the generic parameters + | this associated type binding should be moved after the generic parameters + +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:73:28 + | +LL | struct D> { //~ ERROR associated type bindings must be declared after generic parameters + | ^^^----^^----^^^^^----^^^ + | | | | + | | | this associated type binding should be moved after the generic parameters + | | this associated type binding should be moved after the generic parameters + | this associated type binding should be moved after the generic parameters + +error: associated type bindings must be declared after generic parameters + --> $DIR/suggest-move-types.rs:80:53 | -LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> { - | ^^^ ^^^ ^^^ -- ^^ ^^ -- +LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^^^^^^^----^^----^^^^^^^^^----^^^^^^^ + | | | | + | | | this associated type binding should be moved after the generic parameters + | | this associated type binding should be moved after the generic parameters + | this associated type binding should be moved after the generic parameters -error: type parameters must be declared prior to associated type bindings - --> $DIR/suggest-move-types.rs:70:43 +error: lifetime arguments must be declared prior to type arguments + --> $DIR/suggest-move-types.rs:34:46 | -LL | struct D> { //~ ERROR type parameters must be declared - | ^ ^ must be declared prior to associated type bindings - | | - | must be declared prior to associated type bindings -help: move the type parameters prior to the first associated type binding +LL | struct Al<'a, T, M: OneWithLifetime> { + | ^^ + +error: lifetime arguments must be declared prior to type arguments + --> $DIR/suggest-move-types.rs:48:80 | -LL | struct D> { //~ ERROR type parameters must be declared - | ^^ ^^ -- -- +LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^^ ^^ ^^ -error: generic arguments must declare lifetimes, types and associated type bindings in that order - --> $DIR/suggest-move-types.rs:77:56 +error: lifetime arguments must be declared prior to type arguments + --> $DIR/suggest-move-types.rs:64:56 | -LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^ ^^ ^ ^^ must be declared prior to type parameters - | | | | | - | | | | must be declared prior to associated type bindings - | | | must be declared prior to type parameters - | | must be declared prior to associated type bindings - | must be declared prior to type parameters -help: move the parameters +LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^^ ^^ ^^ + +error: lifetime arguments must be declared prior to type arguments + --> $DIR/suggest-move-types.rs:80:56 | -LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> { - | ^^^ ^^^ ^^^ -- ^^ ^^ -- -- +LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { + | ^^ ^^ ^^ -error: aborting due to 8 previous errors +error: aborting due to 12 previous errors diff --git a/src/test/ui/traits/trait-object-vs-lifetime.rs b/src/test/ui/traits/trait-object-vs-lifetime.rs index a12429c868ed0..36dec21be0520 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.rs +++ b/src/test/ui/traits/trait-object-vs-lifetime.rs @@ -12,6 +12,6 @@ fn main() { //~^ ERROR wrong number of lifetime arguments: expected 1, found 2 //~| ERROR wrong number of type arguments: expected 1, found 0 let _: S<'static +, 'static>; - //~^ ERROR lifetime parameters must be declared prior to type parameters + //~^ ERROR lifetime arguments must be declared prior to type arguments //~| ERROR at least one non-builtin trait is required for an object type } diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr index 4cc96bae5cd17..e0c52a72a0931 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr @@ -1,12 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters +error: lifetime arguments must be declared prior to type arguments --> $DIR/trait-object-vs-lifetime.rs:14:25 | LL | let _: S<'static +, 'static>; - | ^^^^^^^ must be declared prior to type parameters -help: move the lifetime parameter prior to the first type parameter - | -LL | let _: S<'static, 'static +>; - | ^^^^^^^^ -- + | ^^^^^^^ error[E0224]: at least one non-builtin trait is required for an object type --> $DIR/trait-object-vs-lifetime.rs:9:23 diff --git a/src/test/ui/type/type-arg-out-of-scope.rs b/src/test/ui/type/type-arg-out-of-scope.rs index b96c9bf6a0e41..d5b815f6a95e9 100644 --- a/src/test/ui/type/type-arg-out-of-scope.rs +++ b/src/test/ui/type/type-arg-out-of-scope.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use type parameters from outer function +// error-pattern:can't use generic parameters from outer function fn foo(x: T) { fn bar(f: Box T>) { } } diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr index 62b6a86662d04..645cbb33abec1 100644 --- a/src/test/ui/type/type-arg-out-of-scope.stderr +++ b/src/test/ui/type/type-arg-out-of-scope.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:25 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bar(f: Box T>) { } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/type-arg-out-of-scope.rs:3:31 | LL | fn foo(x: T) { | - type variable from outer function LL | fn bar(f: Box T>) { } - | --- ^ use of type variable from outer function + | --- ^ use of generic parameter from outer function | | - | help: try using a local type parameter instead: `bar` + | help: try using a local generic parameter instead: `bar` error: aborting due to 2 previous errors diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index 4c366a863637c..51bd116fbd61c 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -1,6 +1,6 @@ fn main() { let v = vec![0]; - const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item + const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 8783959f45f5f..0af777fdcf907 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -1,10 +1,8 @@ -error[E0434]: can't capture dynamic environment in a fn item +error[E0435]: attempt to use a non-constant value in a constant --> $DIR/type-dependent-def-issue-49241.rs:3:22 | -LL | const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item - | ^ - | - = help: use the `|| { ... }` closure form instead +LL | const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant + | ^ non-constant value error[E0080]: evaluation of constant value failed --> $DIR/type-dependent-def-issue-49241.rs:4:18 @@ -14,5 +12,5 @@ LL | let s: [u32; l] = v.into_iter().collect(); error: aborting due to 2 previous errors -Some errors occurred: E0080, E0434. +Some errors occurred: E0080, E0435. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/use-self-in-inner-fn.rs b/src/test/ui/use-self-in-inner-fn.rs index cde96dc778bbe..eccb315feb1e2 100644 --- a/src/test/ui/use-self-in-inner-fn.rs +++ b/src/test/ui/use-self-in-inner-fn.rs @@ -4,8 +4,8 @@ impl A { //~^ NOTE `Self` type implicitly declared here, by this `impl` fn banana(&mut self) { fn peach(this: &Self) { - //~^ ERROR can't use type parameters from outer function - //~| NOTE use of type variable from outer function + //~^ ERROR can't use generic parameters from outer function + //~| NOTE use of generic parameter from outer function //~| NOTE use a type here instead } } diff --git a/src/test/ui/use-self-in-inner-fn.stderr b/src/test/ui/use-self-in-inner-fn.stderr index a613804b8038b..966093499241d 100644 --- a/src/test/ui/use-self-in-inner-fn.stderr +++ b/src/test/ui/use-self-in-inner-fn.stderr @@ -1,4 +1,4 @@ -error[E0401]: can't use type parameters from outer function +error[E0401]: can't use generic parameters from outer function --> $DIR/use-self-in-inner-fn.rs:6:25 | LL | impl A { @@ -7,7 +7,7 @@ LL | impl A { LL | fn peach(this: &Self) { | ^^^^ | | - | use of type variable from outer function + | use of generic parameter from outer function | use a type here instead error: aborting due to previous error