mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Auto merge of #111402 - matthiaskrgr:rollup-28cqfz5, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #97320 (Stabilize const_ptr_read) - #110770 (Limit lifetime of format_args!() with inlined args.) - #111021 (Move some tests) - #111215 (Various changes to name resolution of anon consts) - #111242 (support set `rpath` option for each target independently) - #111282 (Remove some `assume`s from slice iterators that don't do anything) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2f6bc5d259
@ -120,6 +120,12 @@ impl Path {
|
||||
pub fn is_global(&self) -> bool {
|
||||
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
|
||||
}
|
||||
|
||||
/// If this path is a single identifier with no arguments, does not ensure
|
||||
/// that the path resolves to a const param, the caller should check this.
|
||||
pub fn is_potential_trivial_const_arg(&self) -> bool {
|
||||
self.segments.len() == 1 && self.segments[0].args.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
|
||||
@ -1154,7 +1160,9 @@ impl Expr {
|
||||
///
|
||||
/// If this is not the case, name resolution does not resolve `N` when using
|
||||
/// `min_const_generics` as more complex expressions are not supported.
|
||||
pub fn is_potential_trivial_const_param(&self) -> bool {
|
||||
///
|
||||
/// Does not ensure that the path resolves to a const param, the caller should check this.
|
||||
pub fn is_potential_trivial_const_arg(&self) -> bool {
|
||||
let this = if let ExprKind::Block(block, None) = &self.kind
|
||||
&& block.stmts.len() == 1
|
||||
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
|
||||
@ -1165,8 +1173,7 @@ impl Expr {
|
||||
};
|
||||
|
||||
if let ExprKind::Path(None, path) = &this.kind
|
||||
&& path.segments.len() == 1
|
||||
&& path.segments[0].args.is_none()
|
||||
&& path.is_potential_trivial_const_arg()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
|
@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized {
|
||||
fn visit_variant(&mut self, v: &'ast Variant) {
|
||||
walk_variant(self, v)
|
||||
}
|
||||
fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
|
||||
self.visit_anon_const(discr);
|
||||
}
|
||||
fn visit_label(&mut self, label: &'ast Label) {
|
||||
walk_label(self, label)
|
||||
}
|
||||
@ -380,7 +383,7 @@ where
|
||||
visitor.visit_ident(variant.ident);
|
||||
visitor.visit_vis(&variant.vis);
|
||||
visitor.visit_variant_data(&variant.data);
|
||||
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
|
||||
walk_list!(visitor, visit_variant_discr, &variant.disr_expr);
|
||||
walk_list!(visitor, visit_attribute, &variant.attrs);
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,30 @@ fn expand_format_args<'hir>(
|
||||
&& argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
|
||||
&& arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr));
|
||||
|
||||
let args = if use_simple_array {
|
||||
let args = if arguments.is_empty() {
|
||||
// Generate:
|
||||
// &<core::fmt::Argument>::none()
|
||||
//
|
||||
// Note:
|
||||
// `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime.
|
||||
//
|
||||
// This makes sure that this still fails to compile, even when the argument is inlined:
|
||||
//
|
||||
// ```
|
||||
// let f = format_args!("{}", "a");
|
||||
// println!("{f}"); // error E0716
|
||||
// ```
|
||||
//
|
||||
// Cases where keeping the object around is allowed, such as `format_args!("a")`,
|
||||
// are handled above by the `allow_const` case.
|
||||
let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
|
||||
macsp,
|
||||
hir::LangItem::FormatArgument,
|
||||
sym::none,
|
||||
));
|
||||
let none = ctx.expr_call(macsp, none_fn, &[]);
|
||||
ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none))
|
||||
} else if use_simple_array {
|
||||
// Generate:
|
||||
// &[
|
||||
// <core::fmt::Argument>::new_display(&arg0),
|
||||
|
@ -1190,13 +1190,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// parsing. We try to resolve that ambiguity by attempting resolution in both the
|
||||
// type and value namespaces. If we resolved the path in the value namespace, we
|
||||
// transform it into a generic const argument.
|
||||
TyKind::Path(qself, path) => {
|
||||
TyKind::Path(None, path) => {
|
||||
if let Some(res) = self
|
||||
.resolver
|
||||
.get_partial_res(ty.id)
|
||||
.and_then(|partial_res| partial_res.full_res())
|
||||
{
|
||||
if !res.matches_ns(Namespace::TypeNS) {
|
||||
if !res.matches_ns(Namespace::TypeNS)
|
||||
&& path.is_potential_trivial_const_arg()
|
||||
{
|
||||
debug!(
|
||||
"lower_generic_arg: Lowering type argument as const argument: {:?}",
|
||||
ty,
|
||||
@ -1218,7 +1220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
let path_expr = Expr {
|
||||
id: ty.id,
|
||||
kind: ExprKind::Path(qself.clone(), path.clone()),
|
||||
kind: ExprKind::Path(None, path.clone()),
|
||||
span,
|
||||
attrs: AttrVec::new(),
|
||||
tokens: None,
|
||||
|
@ -1,9 +1,11 @@
|
||||
#### Note: this error code is no longer emitted by the compiler
|
||||
|
||||
A non-`'static` lifetime was used in a const generic. This is currently not
|
||||
allowed.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0771
|
||||
```compile_fail,E0770
|
||||
#![feature(adt_const_params)]
|
||||
|
||||
fn function_with_str<'a, const STRING: &'a str>() {} // error!
|
||||
|
@ -51,7 +51,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
// of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
|
||||
None
|
||||
} else if tcx.lazy_normalization() {
|
||||
if let Some(param_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id) {
|
||||
let parent_node = tcx.hir().get_parent(hir_id);
|
||||
if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node
|
||||
&& constant.hir_id == hir_id
|
||||
{
|
||||
// enum variant discriminants are not allowed to use any kind of generics
|
||||
None
|
||||
} else if let Some(param_id) =
|
||||
tcx.hir().opt_const_param_default_param_def_id(hir_id)
|
||||
{
|
||||
// If the def_id we are calling generics_of on is an anon ct default i.e:
|
||||
//
|
||||
// struct Foo<const N: usize = { .. }>;
|
||||
@ -94,15 +102,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
has_self: generics.has_self,
|
||||
has_late_bound_regions: generics.has_late_bound_regions,
|
||||
};
|
||||
} else {
|
||||
// HACK(eddyb) this provides the correct generics when
|
||||
// `feature(generic_const_expressions)` is enabled, so that const expressions
|
||||
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
||||
//
|
||||
// Note that we do not supply the parent generics when using
|
||||
// `min_const_generics`.
|
||||
Some(parent_def_id.to_def_id())
|
||||
}
|
||||
|
||||
// HACK(eddyb) this provides the correct generics when
|
||||
// `feature(generic_const_expressions)` is enabled, so that const expressions
|
||||
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
||||
//
|
||||
// Note that we do not supply the parent generics when using
|
||||
// `min_const_generics`.
|
||||
Some(parent_def_id.to_def_id())
|
||||
} else {
|
||||
let parent_node = tcx.hir().get_parent(hir_id);
|
||||
match parent_node {
|
||||
@ -115,11 +123,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
{
|
||||
Some(parent_def_id.to_def_id())
|
||||
}
|
||||
Node::Variant(Variant { disr_expr: Some(constant), .. })
|
||||
if constant.hir_id == hir_id =>
|
||||
{
|
||||
Some(parent_def_id.to_def_id())
|
||||
}
|
||||
Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
|
||||
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
|
||||
}
|
||||
|
@ -145,6 +145,15 @@ resolve_param_in_ty_of_const_param =
|
||||
the type of const parameters must not depend on other generic parameters
|
||||
.label = the type must not depend on the parameter `{$name}`
|
||||
|
||||
resolve_type_param_in_ty_of_const_param =
|
||||
type parameters may not be used in the type of const parameters
|
||||
|
||||
resolve_const_param_in_ty_of_const_param =
|
||||
const parameters may not be used in the type of const parameters
|
||||
|
||||
resolve_lifetime_param_in_ty_of_const_param =
|
||||
lifetime parameters may not be used in the type of const parameters
|
||||
|
||||
resolve_self_in_generic_param_default =
|
||||
generic parameters cannot use `Self` in their defaults
|
||||
.label = `Self` in generic parameter default
|
||||
@ -156,12 +165,15 @@ resolve_param_in_non_trivial_anon_const =
|
||||
resolve_param_in_non_trivial_anon_const_help =
|
||||
use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
resolve_param_in_non_trivial_anon_const_sub_type =
|
||||
resolve_type_param_in_non_trivial_anon_const =
|
||||
type parameters may not be used in const expressions
|
||||
|
||||
resolve_param_in_non_trivial_anon_const_sub_non_type =
|
||||
resolve_const_param_in_non_trivial_anon_const =
|
||||
const parameters may only be used as standalone arguments, i.e. `{$name}`
|
||||
|
||||
resolve_lifetime_param_in_non_trivial_anon_const =
|
||||
lifetime parameters may not be used in const expressions
|
||||
|
||||
resolve_unreachable_label =
|
||||
use of unreachable label `{$name}`
|
||||
.label = unreachable label `{$name}`
|
||||
@ -233,3 +245,16 @@ resolve_macro_use_extern_crate_self = `#[macro_use]` is not supported on `extern
|
||||
|
||||
resolve_accessible_unsure = not sure whether the path is accessible or not
|
||||
.note = the type may have associated items, but we are currently not checking them
|
||||
|
||||
resolve_param_in_enum_discriminant =
|
||||
generic parameters may not be used in enum discriminant values
|
||||
.label = cannot perform const operation using `{$name}`
|
||||
|
||||
resolve_type_param_in_enum_discriminant =
|
||||
type parameters may not be used in enum discriminant values
|
||||
|
||||
resolve_const_param_in_enum_discriminant =
|
||||
const parameters may not be used in enum discriminant values
|
||||
|
||||
resolve_lifetime_param_in_enum_discriminant =
|
||||
lifetime parameters may not be used in enum discriminant values
|
||||
|
@ -864,18 +864,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
ResolutionError::ForwardDeclaredGenericParam => {
|
||||
self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span })
|
||||
}
|
||||
ResolutionError::ParamInTyOfConstParam(name) => {
|
||||
self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name })
|
||||
}
|
||||
ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
|
||||
ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
|
||||
.tcx
|
||||
.sess
|
||||
.create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
|
||||
ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
|
||||
self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst {
|
||||
span,
|
||||
name,
|
||||
sub_is_type: if is_type {
|
||||
errs::ParamInNonTrivialAnonConstIsType::AType
|
||||
} else {
|
||||
errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
|
||||
},
|
||||
param_kind: is_type,
|
||||
help: self
|
||||
.tcx
|
||||
.sess
|
||||
@ -883,6 +880,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
.then_some(errs::ParamInNonTrivialAnonConstHelp),
|
||||
})
|
||||
}
|
||||
ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
|
||||
.tcx
|
||||
.sess
|
||||
.create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
|
||||
ResolutionError::SelfInGenericParamDefault => {
|
||||
self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span })
|
||||
}
|
||||
|
@ -326,6 +326,18 @@ pub(crate) struct ParamInTyOfConstParam {
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum ParamKindInTyOfConstParam {
|
||||
#[note(resolve_type_param_in_ty_of_const_param)]
|
||||
Type,
|
||||
#[note(resolve_const_param_in_ty_of_const_param)]
|
||||
Const,
|
||||
#[note(resolve_lifetime_param_in_ty_of_const_param)]
|
||||
Lifetime,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
@ -344,7 +356,7 @@ pub(crate) struct ParamInNonTrivialAnonConst {
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
|
||||
pub(crate) param_kind: ParamKindInNonTrivialAnonConst,
|
||||
#[subdiagnostic]
|
||||
pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
|
||||
}
|
||||
@ -354,11 +366,13 @@ pub(crate) struct ParamInNonTrivialAnonConst {
|
||||
pub(crate) struct ParamInNonTrivialAnonConstHelp;
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum ParamInNonTrivialAnonConstIsType {
|
||||
#[note(resolve_param_in_non_trivial_anon_const_sub_type)]
|
||||
AType,
|
||||
#[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
|
||||
NotAType { name: Symbol },
|
||||
pub(crate) enum ParamKindInNonTrivialAnonConst {
|
||||
#[note(resolve_type_param_in_non_trivial_anon_const)]
|
||||
Type,
|
||||
#[help(resolve_const_param_in_non_trivial_anon_const)]
|
||||
Const { name: Symbol },
|
||||
#[note(resolve_lifetime_param_in_non_trivial_anon_const)]
|
||||
Lifetime,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
@ -539,3 +553,24 @@ pub(crate) struct CfgAccessibleUnsure {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_param_in_enum_discriminant)]
|
||||
pub(crate) struct ParamInEnumDiscriminant {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub(crate) param_kind: ParamKindInEnumDiscriminant,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum ParamKindInEnumDiscriminant {
|
||||
#[note(resolve_type_param_in_enum_discriminant)]
|
||||
Type,
|
||||
#[note(resolve_const_param_in_enum_discriminant)]
|
||||
Const,
|
||||
#[note(resolve_lifetime_param_in_enum_discriminant)]
|
||||
Lifetime,
|
||||
}
|
||||
|
@ -13,8 +13,10 @@ use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
|
||||
use crate::late::{
|
||||
ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
|
||||
ConstantHasGenerics, ConstantItemKind, HasGenericParams, NoConstantGenericsReason, PathSource,
|
||||
Rib, RibKind,
|
||||
};
|
||||
use crate::macros::{sub_namespace_match, MacroRulesScope};
|
||||
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
|
||||
@ -1153,7 +1155,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
RibKind::ConstParamTy => {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
|
||||
self.report_error(
|
||||
span,
|
||||
ParamInTyOfConstParam {
|
||||
name: rib_ident.name,
|
||||
param_kind: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
@ -1188,11 +1196,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
RibKind::ConstantItem(trivial, _) => {
|
||||
let features = self.tcx.sess.features_untracked();
|
||||
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
|
||||
if !(trivial == ConstantHasGenerics::Yes
|
||||
|| features.generic_const_exprs)
|
||||
{
|
||||
if let ConstantHasGenerics::No(cause) = trivial {
|
||||
// HACK(min_const_generics): If we encounter `Self` in an anonymous
|
||||
// constant we can't easily tell if it's generic at this stage, so
|
||||
// we instead remember this and then enforce the self type to be
|
||||
@ -1210,13 +1214,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInNonTrivialAnonConst {
|
||||
name: rib_ident.name,
|
||||
is_type: true,
|
||||
},
|
||||
);
|
||||
let error = match cause {
|
||||
NoConstantGenericsReason::IsEnumDiscriminant => {
|
||||
ResolutionError::ParamInEnumDiscriminant {
|
||||
name: rib_ident.name,
|
||||
param_kind: ParamKindInEnumDiscriminant::Type,
|
||||
}
|
||||
}
|
||||
NoConstantGenericsReason::NonTrivialConstArg => {
|
||||
ResolutionError::ParamInNonTrivialAnonConst {
|
||||
name: rib_ident.name,
|
||||
param_kind:
|
||||
ParamKindInNonTrivialAnonConst::Type,
|
||||
}
|
||||
}
|
||||
};
|
||||
self.report_error(span, error);
|
||||
self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
|
||||
}
|
||||
|
||||
@ -1233,7 +1246,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInTyOfConstParam(rib_ident.name),
|
||||
ResolutionError::ParamInTyOfConstParam {
|
||||
name: rib_ident.name,
|
||||
param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
|
||||
},
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
@ -1264,20 +1280,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
| RibKind::ForwardGenericParamBan => continue,
|
||||
|
||||
RibKind::ConstantItem(trivial, _) => {
|
||||
let features = self.tcx.sess.features_untracked();
|
||||
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
|
||||
if !(trivial == ConstantHasGenerics::Yes
|
||||
|| features.generic_const_exprs)
|
||||
{
|
||||
if let ConstantHasGenerics::No(cause) = trivial {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInNonTrivialAnonConst {
|
||||
name: rib_ident.name,
|
||||
is_type: false,
|
||||
},
|
||||
);
|
||||
self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
|
||||
let error = match cause {
|
||||
NoConstantGenericsReason::IsEnumDiscriminant => {
|
||||
ResolutionError::ParamInEnumDiscriminant {
|
||||
name: rib_ident.name,
|
||||
param_kind: ParamKindInEnumDiscriminant::Const,
|
||||
}
|
||||
}
|
||||
NoConstantGenericsReason::NonTrivialConstArg => {
|
||||
ResolutionError::ParamInNonTrivialAnonConst {
|
||||
name: rib_ident.name,
|
||||
param_kind: ParamKindInNonTrivialAnonConst::Const {
|
||||
name: rib_ident.name,
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
self.report_error(span, error);
|
||||
}
|
||||
|
||||
return Res::Err;
|
||||
@ -1291,7 +1312,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if let Some(span) = finalize {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInTyOfConstParam(rib_ident.name),
|
||||
ResolutionError::ParamInTyOfConstParam {
|
||||
name: rib_ident.name,
|
||||
param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
|
||||
},
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
|
@ -66,6 +66,15 @@ enum IsRepeatExpr {
|
||||
Yes,
|
||||
}
|
||||
|
||||
/// Describes whether an `AnonConst` is a type level const arg or
|
||||
/// some other form of anon const (i.e. inline consts or enum discriminants)
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum AnonConstKind {
|
||||
EnumDiscriminant,
|
||||
InlineConst,
|
||||
ConstArg(IsRepeatExpr),
|
||||
}
|
||||
|
||||
impl PatternSource {
|
||||
fn descr(self) -> &'static str {
|
||||
match self {
|
||||
@ -105,7 +114,7 @@ pub(crate) enum HasGenericParams {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum ConstantHasGenerics {
|
||||
Yes,
|
||||
No,
|
||||
No(NoConstantGenericsReason),
|
||||
}
|
||||
|
||||
impl ConstantHasGenerics {
|
||||
@ -114,6 +123,27 @@ impl ConstantHasGenerics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reason for why an anon const is not allowed to reference generic parameters
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum NoConstantGenericsReason {
|
||||
/// Const arguments are only allowed to use generic parameters when:
|
||||
/// - `feature(generic_const_exprs)` is enabled
|
||||
/// or
|
||||
/// - the const argument is a sole const generic paramater, i.e. `foo::<{ N }>()`
|
||||
///
|
||||
/// If neither of the above are true then this is used as the cause.
|
||||
NonTrivialConstArg,
|
||||
/// Enum discriminants are not allowed to reference generic parameters ever, this
|
||||
/// is used when an anon const is in the following position:
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// enum Foo<const N: isize> {
|
||||
/// Variant = { N }, // this anon const is not allowed to use generics
|
||||
/// }
|
||||
/// ```
|
||||
IsEnumDiscriminant,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum ConstantItemKind {
|
||||
Const,
|
||||
@ -273,15 +303,18 @@ enum LifetimeRibKind {
|
||||
/// Signal we cannot find which should be the anonymous lifetime.
|
||||
ElisionFailure,
|
||||
|
||||
/// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
|
||||
/// generics. We are disallowing this until we can decide on how we want to handle non-'static
|
||||
/// lifetimes in const generics. See issue #74052 for discussion.
|
||||
ConstGeneric,
|
||||
/// This rib forbids usage of generic parameters inside of const parameter types.
|
||||
///
|
||||
/// While this is desirable to support eventually, it is difficult to do and so is
|
||||
/// currently forbidden. See rust-lang/project-const-generics#28 for more info.
|
||||
ConstParamTy,
|
||||
|
||||
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
|
||||
/// This function will emit an error if `generic_const_exprs` is not enabled, the body
|
||||
/// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static.
|
||||
AnonConst,
|
||||
/// Usage of generic parameters is forbidden in various positions for anon consts:
|
||||
/// - const arguments when `generic_const_exprs` is not enabled
|
||||
/// - enum discriminant values
|
||||
///
|
||||
/// This rib emits an error when a lifetime would resolve to a lifetime parameter.
|
||||
ConcreteAnonConst(NoConstantGenericsReason),
|
||||
|
||||
/// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
|
||||
Item,
|
||||
@ -648,13 +681,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
self.resolve_block(block);
|
||||
self.parent_scope.macro_rules = old_macro_rules;
|
||||
}
|
||||
fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
|
||||
// We deal with repeat expressions explicitly in `resolve_expr`.
|
||||
self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||
this.resolve_anon_const(constant, IsRepeatExpr::No);
|
||||
})
|
||||
})
|
||||
fn visit_anon_const(&mut self, _constant: &'ast AnonConst) {
|
||||
bug!("encountered anon const without a manual call to `resolve_anon_const`");
|
||||
}
|
||||
fn visit_expr(&mut self, expr: &'ast Expr) {
|
||||
self.resolve_expr(expr, None);
|
||||
@ -676,7 +704,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
let prev = self.diagnostic_metadata.current_trait_object;
|
||||
let prev_ty = self.diagnostic_metadata.current_type_path;
|
||||
match ty.kind {
|
||||
match &ty.kind {
|
||||
TyKind::Ref(None, _) => {
|
||||
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
|
||||
// NodeId `ty.id`.
|
||||
@ -685,7 +713,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
self.resolve_elided_lifetime(ty.id, span);
|
||||
visit::walk_ty(self, ty);
|
||||
}
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
TyKind::Path(qself, path) => {
|
||||
self.diagnostic_metadata.current_type_path = Some(ty);
|
||||
self.smart_resolve_path(ty.id, &qself, path, PathSource::Type);
|
||||
|
||||
@ -730,11 +758,11 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
visit::walk_ty(self, ty);
|
||||
self.lifetime_elision_candidates = candidates;
|
||||
}
|
||||
TyKind::TraitObject(ref bounds, ..) => {
|
||||
TyKind::TraitObject(bounds, ..) => {
|
||||
self.diagnostic_metadata.current_trait_object = Some(&bounds[..]);
|
||||
visit::walk_ty(self, ty)
|
||||
}
|
||||
TyKind::BareFn(ref bare_fn) => {
|
||||
TyKind::BareFn(bare_fn) => {
|
||||
let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo());
|
||||
self.with_generic_param_rib(
|
||||
&bare_fn.generic_params,
|
||||
@ -769,6 +797,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
},
|
||||
)
|
||||
}
|
||||
TyKind::Array(element_ty, length) => {
|
||||
self.visit_ty(element_ty);
|
||||
self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
||||
}
|
||||
TyKind::Typeof(ct) => {
|
||||
self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
|
||||
}
|
||||
_ => visit::walk_ty(self, ty),
|
||||
}
|
||||
self.diagnostic_metadata.current_trait_object = prev;
|
||||
@ -994,36 +1029,25 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
// namespace first, and if that fails we try again in the value namespace. If
|
||||
// resolution in the value namespace succeeds, we have an generic const argument on
|
||||
// our hands.
|
||||
if let TyKind::Path(ref qself, ref path) = ty.kind {
|
||||
if let TyKind::Path(None, ref path) = ty.kind {
|
||||
// We cannot disambiguate multi-segment paths right now as that requires type
|
||||
// checking.
|
||||
if path.segments.len() == 1 && path.segments[0].args.is_none() {
|
||||
if path.is_potential_trivial_const_arg() {
|
||||
let mut check_ns = |ns| {
|
||||
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
|
||||
.is_some()
|
||||
};
|
||||
if !check_ns(TypeNS) && check_ns(ValueNS) {
|
||||
// This must be equivalent to `visit_anon_const`, but we cannot call it
|
||||
// directly due to visitor lifetimes so we have to copy-paste some code.
|
||||
//
|
||||
// Note that we might not be inside of an repeat expression here,
|
||||
// but considering that `IsRepeatExpr` is only relevant for
|
||||
// non-trivial constants this is doesn't matter.
|
||||
self.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
ConstantHasGenerics::Yes,
|
||||
None,
|
||||
self.resolve_anon_const_manual(
|
||||
true,
|
||||
AnonConstKind::ConstArg(IsRepeatExpr::No),
|
||||
|this| {
|
||||
this.smart_resolve_path(
|
||||
ty.id,
|
||||
qself,
|
||||
&None,
|
||||
path,
|
||||
PathSource::Expr(None),
|
||||
);
|
||||
|
||||
if let Some(ref qself) = *qself {
|
||||
this.visit_ty(&qself.ty);
|
||||
}
|
||||
this.visit_path(path, ty.id);
|
||||
},
|
||||
);
|
||||
@ -1037,7 +1061,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
self.visit_ty(ty);
|
||||
}
|
||||
GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),
|
||||
GenericArg::Const(ct) => self.visit_anon_const(ct),
|
||||
GenericArg::Const(ct) => {
|
||||
self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
|
||||
}
|
||||
}
|
||||
self.diagnostic_metadata.currently_processing_generics = prev;
|
||||
}
|
||||
@ -1053,7 +1079,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
match constraint.kind {
|
||||
AssocConstraintKind::Equality { ref term } => match term {
|
||||
Term::Ty(ty) => self.visit_ty(ty),
|
||||
Term::Const(c) => self.visit_anon_const(c),
|
||||
Term::Const(c) => {
|
||||
self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
|
||||
}
|
||||
},
|
||||
AssocConstraintKind::Bound { ref bounds } => {
|
||||
walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
|
||||
@ -1102,8 +1130,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
| LifetimeRibKind::AnonymousReportError
|
||||
| LifetimeRibKind::Elided(_)
|
||||
| LifetimeRibKind::ElisionFailure
|
||||
| LifetimeRibKind::AnonConst
|
||||
| LifetimeRibKind::ConstGeneric => {}
|
||||
| LifetimeRibKind::ConcreteAnonConst(_)
|
||||
| LifetimeRibKind::ConstParamTy => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1164,7 +1192,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
InlineAsmOperand::Const { anon_const, .. } => {
|
||||
// Although this is `DefKind::AnonConst`, it is allowed to reference outer
|
||||
// generic parameters like an inline const.
|
||||
self.resolve_inline_const(anon_const);
|
||||
self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);
|
||||
}
|
||||
InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
|
||||
}
|
||||
@ -1188,6 +1216,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||
visit::walk_variant(self, v)
|
||||
}
|
||||
|
||||
fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
|
||||
self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);
|
||||
}
|
||||
|
||||
fn visit_field_def(&mut self, f: &'ast FieldDef) {
|
||||
self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));
|
||||
visit::walk_field_def(self, f)
|
||||
@ -1386,7 +1418,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
|
||||
this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
|
||||
this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
|
||||
this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
|
||||
this.visit_ty(ty)
|
||||
});
|
||||
this.ribs[TypeNS].pop().unwrap();
|
||||
@ -1395,9 +1427,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
if let Some(ref expr) = default {
|
||||
this.ribs[TypeNS].push(forward_ty_ban_rib);
|
||||
this.ribs[ValueNS].push(forward_const_ban_rib);
|
||||
this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
|
||||
this.resolve_anon_const(expr, IsRepeatExpr::No)
|
||||
});
|
||||
this.resolve_anon_const(
|
||||
expr,
|
||||
AnonConstKind::ConstArg(IsRepeatExpr::No),
|
||||
);
|
||||
forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
|
||||
forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
|
||||
}
|
||||
@ -1475,8 +1508,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
LifetimeUseSet::Many
|
||||
}),
|
||||
LifetimeRibKind::Generics { .. }
|
||||
| LifetimeRibKind::ConstGeneric => None,
|
||||
LifetimeRibKind::AnonConst => {
|
||||
| LifetimeRibKind::ConstParamTy => None,
|
||||
LifetimeRibKind::ConcreteAnonConst(_) => {
|
||||
span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
|
||||
}
|
||||
})
|
||||
@ -1495,8 +1528,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
|
||||
match rib.kind {
|
||||
LifetimeRibKind::Item => break,
|
||||
LifetimeRibKind::ConstGeneric => {
|
||||
self.emit_non_static_lt_in_const_generic_error(lifetime);
|
||||
LifetimeRibKind::ConstParamTy => {
|
||||
self.emit_non_static_lt_in_const_param_ty_error(lifetime);
|
||||
self.record_lifetime_res(
|
||||
lifetime.id,
|
||||
LifetimeRes::Error,
|
||||
@ -1504,8 +1537,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
);
|
||||
return;
|
||||
}
|
||||
LifetimeRibKind::AnonConst => {
|
||||
self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
|
||||
LifetimeRibKind::ConcreteAnonConst(cause) => {
|
||||
self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
|
||||
self.record_lifetime_res(
|
||||
lifetime.id,
|
||||
LifetimeRes::Error,
|
||||
@ -1604,9 +1637,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
return;
|
||||
}
|
||||
LifetimeRibKind::Item => break,
|
||||
LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
|
||||
LifetimeRibKind::AnonConst => {
|
||||
// There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
|
||||
LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
|
||||
LifetimeRibKind::ConcreteAnonConst(_) => {
|
||||
// There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
|
||||
span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind)
|
||||
}
|
||||
}
|
||||
@ -1826,9 +1859,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
|
||||
break;
|
||||
}
|
||||
LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
|
||||
LifetimeRibKind::AnonConst => {
|
||||
// There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
|
||||
LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
|
||||
LifetimeRibKind::ConcreteAnonConst(_) => {
|
||||
// There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
|
||||
span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind)
|
||||
}
|
||||
}
|
||||
@ -2560,7 +2593,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
|
||||
}
|
||||
|
||||
// HACK(min_const_generics,const_evaluatable_unchecked): We
|
||||
// HACK(min_const_generics, generic_const_exprs): We
|
||||
// want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
|
||||
// with a future compat lint for now. We do this by adding an
|
||||
// additional special case for repeat expressions.
|
||||
@ -2576,18 +2609,26 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
item: Option<(Ident, ConstantItemKind)>,
|
||||
f: impl FnOnce(&mut Self),
|
||||
) {
|
||||
self.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
|
||||
this.with_rib(
|
||||
TypeNS,
|
||||
RibKind::ConstantItem(
|
||||
may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
|
||||
item,
|
||||
),
|
||||
|this| {
|
||||
this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
|
||||
},
|
||||
)
|
||||
});
|
||||
let f = |this: &mut Self| {
|
||||
this.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
|
||||
this.with_rib(
|
||||
TypeNS,
|
||||
RibKind::ConstantItem(
|
||||
may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
|
||||
item,
|
||||
),
|
||||
|this| {
|
||||
this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
|
||||
},
|
||||
)
|
||||
})
|
||||
};
|
||||
|
||||
if let ConstantHasGenerics::No(cause) = may_use_generics {
|
||||
self.with_lifetime_rib(LifetimeRibKind::ConcreteAnonConst(cause), f)
|
||||
} else {
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
@ -3924,24 +3965,54 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
debug!("(resolving block) leaving block");
|
||||
}
|
||||
|
||||
fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) {
|
||||
debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
|
||||
self.with_constant_rib(
|
||||
is_repeat,
|
||||
if constant.value.is_potential_trivial_const_param() {
|
||||
ConstantHasGenerics::Yes
|
||||
} else {
|
||||
ConstantHasGenerics::No
|
||||
},
|
||||
None,
|
||||
|this| visit::walk_anon_const(this, constant),
|
||||
fn resolve_anon_const(&mut self, constant: &'ast AnonConst, anon_const_kind: AnonConstKind) {
|
||||
debug!(
|
||||
"resolve_anon_const(constant: {:?}, anon_const_kind: {:?})",
|
||||
constant, anon_const_kind
|
||||
);
|
||||
|
||||
self.resolve_anon_const_manual(
|
||||
constant.value.is_potential_trivial_const_arg(),
|
||||
anon_const_kind,
|
||||
|this| this.resolve_expr(&constant.value, None),
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
|
||||
debug!("resolve_anon_const {constant:?}");
|
||||
self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| {
|
||||
visit::walk_anon_const(this, constant)
|
||||
/// There are a few places that we need to resolve an anon const but we did not parse an
|
||||
/// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced
|
||||
/// const arguments that were parsed as type arguments, and `legact_const_generics` which
|
||||
/// parse as normal function argument expressions. To avoid duplicating the code for resolving
|
||||
/// an anon const we have this function which lets the caller manually call `resolve_expr` or
|
||||
/// `smart_resolve_path`.
|
||||
fn resolve_anon_const_manual(
|
||||
&mut self,
|
||||
is_trivial_const_arg: bool,
|
||||
anon_const_kind: AnonConstKind,
|
||||
resolve_expr: impl FnOnce(&mut Self),
|
||||
) {
|
||||
let is_repeat_expr = match anon_const_kind {
|
||||
AnonConstKind::ConstArg(is_repeat_expr) => is_repeat_expr,
|
||||
_ => IsRepeatExpr::No,
|
||||
};
|
||||
|
||||
let may_use_generics = match anon_const_kind {
|
||||
AnonConstKind::EnumDiscriminant => {
|
||||
ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
|
||||
}
|
||||
AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
|
||||
AnonConstKind::ConstArg(_) => {
|
||||
if self.r.tcx.features().generic_const_exprs || is_trivial_const_arg {
|
||||
ConstantHasGenerics::Yes
|
||||
} else {
|
||||
ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||
resolve_expr(this);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -4046,17 +4117,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
// Constant arguments need to be treated as AnonConst since
|
||||
// that is how they will be later lowered to HIR.
|
||||
if const_args.contains(&idx) {
|
||||
self.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
if argument.is_potential_trivial_const_param() {
|
||||
ConstantHasGenerics::Yes
|
||||
} else {
|
||||
ConstantHasGenerics::No
|
||||
},
|
||||
None,
|
||||
|this| {
|
||||
this.resolve_expr(argument, None);
|
||||
},
|
||||
self.resolve_anon_const_manual(
|
||||
argument.is_potential_trivial_const_arg(),
|
||||
AnonConstKind::ConstArg(IsRepeatExpr::No),
|
||||
|this| this.resolve_expr(argument, None),
|
||||
);
|
||||
} else {
|
||||
self.resolve_expr(argument, None);
|
||||
@ -4115,14 +4179,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
}
|
||||
ExprKind::Repeat(ref elem, ref ct) => {
|
||||
self.visit_expr(elem);
|
||||
self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
|
||||
this.resolve_anon_const(ct, IsRepeatExpr::Yes)
|
||||
})
|
||||
});
|
||||
self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
|
||||
}
|
||||
ExprKind::ConstBlock(ref ct) => {
|
||||
self.resolve_inline_const(ct);
|
||||
self.resolve_anon_const(ct, AnonConstKind::InlineConst);
|
||||
}
|
||||
ExprKind::Index(ref elem, ref idx) => {
|
||||
self.resolve_expr(elem, Some(expr));
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
|
||||
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
|
||||
use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
|
||||
use crate::path_names_to_string;
|
||||
use crate::{errors, path_names_to_string};
|
||||
use crate::{Module, ModuleKind, ModuleOrUniformRoot};
|
||||
use crate::{PathResult, PathSource, Segment};
|
||||
|
||||
@ -22,7 +22,6 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||
use rustc_hir::PrimTy;
|
||||
use rustc_session::lint;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::edit_distance::find_best_match_for_name;
|
||||
use rustc_span::edition::Edition;
|
||||
@ -35,6 +34,8 @@ use std::ops::Deref;
|
||||
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use super::NoConstantGenericsReason;
|
||||
|
||||
type Res = def::Res<ast::NodeId>;
|
||||
|
||||
/// A field or associated item from self type suggested in case of resolution failure.
|
||||
@ -2316,37 +2317,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
|
||||
struct_span_err!(
|
||||
self.r.tcx.sess,
|
||||
lifetime_ref.ident.span,
|
||||
E0771,
|
||||
"use of non-static lifetime `{}` in const generic",
|
||||
lifetime_ref.ident
|
||||
)
|
||||
.note(
|
||||
"for more information, see issue #74052 \
|
||||
<https://github.com/rust-lang/rust/issues/74052>",
|
||||
)
|
||||
.emit();
|
||||
pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
|
||||
self.r
|
||||
.tcx
|
||||
.sess
|
||||
.create_err(errors::ParamInTyOfConstParam {
|
||||
span: lifetime_ref.ident.span,
|
||||
name: lifetime_ref.ident.name,
|
||||
param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
|
||||
})
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
|
||||
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
|
||||
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
|
||||
pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
|
||||
pub(crate) fn emit_forbidden_non_static_lifetime_error(
|
||||
&self,
|
||||
cause: NoConstantGenericsReason,
|
||||
lifetime_ref: &ast::Lifetime,
|
||||
) {
|
||||
let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
|
||||
if !feature_active {
|
||||
feature_err(
|
||||
&self.r.tcx.sess.parse_sess,
|
||||
sym::generic_const_exprs,
|
||||
lifetime_ref.ident.span,
|
||||
"a non-static lifetime is not allowed in a `const`",
|
||||
)
|
||||
.emit();
|
||||
match cause {
|
||||
NoConstantGenericsReason::IsEnumDiscriminant => {
|
||||
self.r
|
||||
.tcx
|
||||
.sess
|
||||
.create_err(errors::ParamInEnumDiscriminant {
|
||||
span: lifetime_ref.ident.span,
|
||||
name: lifetime_ref.ident.name,
|
||||
param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
|
||||
})
|
||||
.emit();
|
||||
}
|
||||
NoConstantGenericsReason::NonTrivialConstArg => {
|
||||
assert!(!self.r.tcx.features().generic_const_exprs);
|
||||
self.r
|
||||
.tcx
|
||||
.sess
|
||||
.create_err(errors::ParamInNonTrivialAnonConst {
|
||||
span: lifetime_ref.ident.span,
|
||||
name: lifetime_ref.ident.name,
|
||||
param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
|
||||
help: self
|
||||
.r
|
||||
.tcx
|
||||
.sess
|
||||
.is_nightly_build()
|
||||
.then_some(errors::ParamInNonTrivialAnonConstHelp),
|
||||
})
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
use errors::{
|
||||
ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
|
||||
};
|
||||
use rustc_arena::{DroplessArena, TypedArena};
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID};
|
||||
@ -223,11 +226,15 @@ enum ResolutionError<'a> {
|
||||
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
|
||||
ForwardDeclaredGenericParam,
|
||||
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
|
||||
ParamInTyOfConstParam(Symbol),
|
||||
ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
|
||||
/// generic parameters must not be used inside const evaluations.
|
||||
///
|
||||
/// This error is only emitted when using `min_const_generics`.
|
||||
ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
|
||||
ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
|
||||
/// generic parameters must not be used inside enum discriminants.
|
||||
///
|
||||
/// This error is emitted even with `generic_const_exprs`.
|
||||
ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
|
||||
/// Error E0735: generic parameters with a default cannot use `Self`
|
||||
SelfInGenericParamDefault,
|
||||
/// Error E0767: use of unreachable label
|
||||
|
@ -1033,6 +1033,7 @@ symbols! {
|
||||
non_exhaustive_omitted_patterns_lint,
|
||||
non_lifetime_binders,
|
||||
non_modrs_mods,
|
||||
none,
|
||||
nontemporal_store,
|
||||
noop_method_borrow,
|
||||
noop_method_clone,
|
||||
|
@ -750,6 +750,10 @@ changelog-seen = 2
|
||||
# This option will override the same option under [build] section.
|
||||
#profiler = build.profiler (bool)
|
||||
|
||||
# This option supports enable `rpath` in each target independently,
|
||||
# and will override the same option under [rust] section. It only works on Unix platforms
|
||||
#rpath = rust.rpath (bool)
|
||||
|
||||
# Force static or dynamic linkage of the standard library for this target. If
|
||||
# this target is a host for rustc, this will also affect the linkage of the
|
||||
# compiler itself. This is useful for building rustc on targets that normally
|
||||
|
@ -113,7 +113,6 @@
|
||||
#![feature(const_maybe_uninit_write)]
|
||||
#![feature(const_maybe_uninit_zeroed)]
|
||||
#![feature(const_pin)]
|
||||
#![feature(const_ptr_read)]
|
||||
#![feature(const_refs_to_cell)]
|
||||
#![feature(const_size_of_val)]
|
||||
#![feature(const_waker)]
|
||||
|
@ -152,6 +152,21 @@ impl<'a> Argument<'a> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by `format_args` when all arguments are gone after inlining,
|
||||
/// when using `&[]` would incorrectly allow for a bigger lifetime.
|
||||
///
|
||||
/// This fails without format argument inlining, and that shouldn't be different
|
||||
/// when the argument is inlined:
|
||||
///
|
||||
/// ```compile_fail,E0716
|
||||
/// let f = format_args!("{}", "a");
|
||||
/// println!("{f}");
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn none() -> [Self; 0] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct represents the unsafety of constructing an `Arguments`.
|
||||
|
@ -2260,7 +2260,7 @@ extern "rust-intrinsic" {
|
||||
/// This intrinsic can *only* be called where the pointer is a local without
|
||||
/// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
|
||||
/// trivially obeys runtime-MIR rules about derefs in operands.
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_nounwind]
|
||||
pub fn read_via_copy<T>(ptr: *const T) -> T;
|
||||
|
||||
|
@ -140,7 +140,6 @@
|
||||
#![feature(const_pointer_is_aligned)]
|
||||
#![feature(const_ptr_as_ref)]
|
||||
#![feature(const_ptr_is_null)]
|
||||
#![feature(const_ptr_read)]
|
||||
#![feature(const_ptr_sub_ptr)]
|
||||
#![feature(const_ptr_write)]
|
||||
#![feature(const_raw_ptr_comparison)]
|
||||
|
@ -1195,7 +1195,7 @@ impl<T: ?Sized> *const T {
|
||||
///
|
||||
/// [`ptr::read`]: crate::ptr::read()
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn read(self) -> T
|
||||
@ -1236,7 +1236,7 @@ impl<T: ?Sized> *const T {
|
||||
///
|
||||
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn read_unaligned(self) -> T
|
||||
|
@ -1133,7 +1133,8 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
|
||||
/// [valid]: self#safety
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn read<T>(src: *const T) -> T {
|
||||
// It would be semantically correct to implement this via `copy_nonoverlapping`
|
||||
@ -1249,7 +1250,8 @@ pub const unsafe fn read<T>(src: *const T) -> T {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||
let mut tmp = MaybeUninit::<T>::uninit();
|
||||
|
@ -1305,7 +1305,7 @@ impl<T: ?Sized> *mut T {
|
||||
///
|
||||
/// [`ptr::read`]: crate::ptr::read()
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn read(self) -> T
|
||||
@ -1346,7 +1346,7 @@ impl<T: ?Sized> *mut T {
|
||||
///
|
||||
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||
#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn read_unaligned(self) -> T
|
||||
|
@ -124,12 +124,10 @@ macro_rules! iterator {
|
||||
fn next(&mut self) -> Option<$elem> {
|
||||
// could be implemented with slices, but this avoids bounds checks
|
||||
|
||||
// SAFETY: `assume` calls are safe since a slice's start pointer
|
||||
// must be non-null, and slices over non-ZSTs must also have a
|
||||
// non-null end pointer. The call to `next_unchecked!` is safe
|
||||
// since we check if the iterator is empty first.
|
||||
// SAFETY: `assume` call is safe because slices over non-ZSTs must
|
||||
// have a non-null end pointer. The call to `next_unchecked!` is
|
||||
// safe since we check if the iterator is empty first.
|
||||
unsafe {
|
||||
assume(!self.ptr.as_ptr().is_null());
|
||||
if !<T>::IS_ZST {
|
||||
assume(!self.end.is_null());
|
||||
}
|
||||
@ -339,12 +337,10 @@ macro_rules! iterator {
|
||||
fn next_back(&mut self) -> Option<$elem> {
|
||||
// could be implemented with slices, but this avoids bounds checks
|
||||
|
||||
// SAFETY: `assume` calls are safe since a slice's start pointer must be non-null,
|
||||
// and slices over non-ZSTs must also have a non-null end pointer.
|
||||
// The call to `next_back_unchecked!` is safe since we check if the iterator is
|
||||
// empty first.
|
||||
// SAFETY: `assume` call is safe because slices over non-ZSTs must
|
||||
// have a non-null end pointer. The call to `next_back_unchecked!`
|
||||
// is safe since we check if the iterator is empty first.
|
||||
unsafe {
|
||||
assume(!self.ptr.as_ptr().is_null());
|
||||
if !<T>::IS_ZST {
|
||||
assume(!self.end.is_null());
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#![feature(const_pointer_byte_offsets)]
|
||||
#![feature(const_pointer_is_aligned)]
|
||||
#![feature(const_ptr_as_ref)]
|
||||
#![feature(const_ptr_read)]
|
||||
#![feature(const_ptr_write)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_likely)]
|
||||
|
@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513)
|
||||
- Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false.
|
||||
- Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false.
|
||||
- Add `rpath` option in `target` section to support set rpath option for each target independently. [#111242](https://github.com/rust-lang/rust/pull/111242)
|
||||
|
||||
|
||||
## [Version 2] - 2020-09-25
|
||||
|
@ -1623,7 +1623,7 @@ impl<'a> Builder<'a> {
|
||||
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
|
||||
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
|
||||
// to change a flag in a binary?
|
||||
if self.config.rust_rpath && util::use_host_linker(target) {
|
||||
if self.config.rpath_enabled(target) && util::use_host_linker(target) {
|
||||
let rpath = if target.contains("apple") {
|
||||
// Note that we need to take one extra step on macOS to also pass
|
||||
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
|
||||
|
@ -467,6 +467,7 @@ pub struct Target {
|
||||
pub ndk: Option<PathBuf>,
|
||||
pub sanitizers: Option<bool>,
|
||||
pub profiler: Option<bool>,
|
||||
pub rpath: Option<bool>,
|
||||
pub crt_static: Option<bool>,
|
||||
pub musl_root: Option<PathBuf>,
|
||||
pub musl_libdir: Option<PathBuf>,
|
||||
@ -812,6 +813,7 @@ define_config! {
|
||||
android_ndk: Option<String> = "android-ndk",
|
||||
sanitizers: Option<bool> = "sanitizers",
|
||||
profiler: Option<bool> = "profiler",
|
||||
rpath: Option<bool> = "rpath",
|
||||
crt_static: Option<bool> = "crt-static",
|
||||
musl_root: Option<String> = "musl-root",
|
||||
musl_libdir: Option<String> = "musl-libdir",
|
||||
@ -1318,6 +1320,7 @@ impl Config {
|
||||
target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from);
|
||||
target.sanitizers = cfg.sanitizers;
|
||||
target.profiler = cfg.profiler;
|
||||
target.rpath = cfg.rpath;
|
||||
|
||||
config.target_config.insert(TargetSelection::from_user(&triple), target);
|
||||
}
|
||||
@ -1649,6 +1652,10 @@ impl Config {
|
||||
self.target_config.values().any(|t| t.profiler == Some(true)) || self.profiler
|
||||
}
|
||||
|
||||
pub fn rpath_enabled(&self, target: TargetSelection) -> bool {
|
||||
self.target_config.get(&target).map(|t| t.rpath).flatten().unwrap_or(self.rust_rpath)
|
||||
}
|
||||
|
||||
pub fn llvm_enabled(&self) -> bool {
|
||||
self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(const_ptr_read)]
|
||||
|
||||
const UNALIGNED_READ: () = unsafe {
|
||||
let x = &[0u8; 4];
|
||||
|
@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1953;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1920;
|
||||
const ROOT_ENTRY_LIMIT: usize = 895;
|
||||
|
||||
fn check_entries(tests_path: &Path, bad: &mut bool) {
|
||||
|
42
tests/codegen/slice-iter-nonnull.rs
Normal file
42
tests/codegen/slice-iter-nonnull.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// no-system-llvm
|
||||
// compile-flags: -O
|
||||
// ignore-debug (these add extra checks that make it hard to verify)
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// The slice iterator used to `assume` that the `start` pointer was non-null.
|
||||
// That ought to be unneeded, though, since the type is `NonNull`, so this test
|
||||
// confirms that the appropriate metadata is included to denote that.
|
||||
|
||||
// CHECK-LABEL: @slice_iter_next(
|
||||
#[no_mangle]
|
||||
pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> {
|
||||
// CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1
|
||||
// CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
|
||||
// CHECK-SAME: !nonnull
|
||||
// CHECK-SAME: !noundef
|
||||
// CHECK: %[[START:.+]] = load ptr, ptr %it,
|
||||
// CHECK-SAME: !nonnull
|
||||
// CHECK-SAME: !noundef
|
||||
// CHECK: icmp eq ptr %[[START]], %[[END]]
|
||||
|
||||
// CHECK: store ptr{{.+}}, ptr %it,
|
||||
|
||||
it.next()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @slice_iter_next_back(
|
||||
#[no_mangle]
|
||||
pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> {
|
||||
// CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1
|
||||
// CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
|
||||
// CHECK-SAME: !nonnull
|
||||
// CHECK-SAME: !noundef
|
||||
// CHECK: %[[START:.+]] = load ptr, ptr %it,
|
||||
// CHECK-SAME: !nonnull
|
||||
// CHECK-SAME: !noundef
|
||||
// CHECK: icmp eq ptr %[[START]], %[[END]]
|
||||
|
||||
// CHECK: store ptr{{.+}}, ptr %[[ENDP]],
|
||||
|
||||
it.next_back()
|
||||
}
|
13
tests/ui/const-generics/assoc_const_as_type_argument.rs
Normal file
13
tests/ui/const-generics/assoc_const_as_type_argument.rs
Normal file
@ -0,0 +1,13 @@
|
||||
trait Trait {
|
||||
const ASSOC: usize;
|
||||
}
|
||||
|
||||
fn bar<const N: usize>() {}
|
||||
|
||||
fn foo<T: Trait>() {
|
||||
bar::<<T as Trait>::ASSOC>();
|
||||
//~^ ERROR: expected associated type, found associated constant `Trait::ASSOC`
|
||||
//~| ERROR: unresolved item provided when a constant was expected
|
||||
}
|
||||
|
||||
fn main() {}
|
21
tests/ui/const-generics/assoc_const_as_type_argument.stderr
Normal file
21
tests/ui/const-generics/assoc_const_as_type_argument.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0575]: expected associated type, found associated constant `Trait::ASSOC`
|
||||
--> $DIR/assoc_const_as_type_argument.rs:8:11
|
||||
|
|
||||
LL | bar::<<T as Trait>::ASSOC>();
|
||||
| ^^^^^^^^^^^^^^^^^^^ not a associated type
|
||||
|
||||
error[E0747]: unresolved item provided when a constant was expected
|
||||
--> $DIR/assoc_const_as_type_argument.rs:8:11
|
||||
|
|
||||
LL | bar::<<T as Trait>::ASSOC>();
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||
|
|
||||
LL | bar::<{ <T as Trait>::ASSOC }>();
|
||||
| + +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0575, E0747.
|
||||
For more information about an error, try `rustc --explain E0575`.
|
@ -1,163 +0,0 @@
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:18:23
|
||||
|
|
||||
LL | let _: [u8; faz::<'a>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:21:23
|
||||
|
|
||||
LL | let _: [u8; faz::<'b>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:41:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'a>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:44:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'b>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:13:12
|
||||
|
|
||||
LL | let _: [u8; foo::<T>()];
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); foo::<T>()]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:15:12
|
||||
|
|
||||
LL | let _: [u8; bar::<N>()];
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:36:12
|
||||
|
|
||||
LL | let _: Foo<{ foo::<T>() }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { foo::<T>() }]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:38:12
|
||||
|
|
||||
LL | let _: Foo<{ bar::<N>() }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:25:17
|
||||
|
|
||||
LL | let _ = [0; foo::<T>()];
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); foo::<T>()]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:27:17
|
||||
|
|
||||
LL | let _ = [0; bar::<N>()];
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:`
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:30:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'a>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:33:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'b>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:47:19
|
||||
|
|
||||
LL | let _ = Foo::<{ foo::<T>() }>;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { foo::<T>() }]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/const-arg-in-const-arg.rs:49:19
|
||||
|
|
||||
LL | let _ = Foo::<{ bar::<N>() }>;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:`
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:52:27
|
||||
|
|
||||
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:55:27
|
||||
|
|
||||
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0794`.
|
@ -1,5 +1,5 @@
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:13:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:15:23
|
||||
|
|
||||
LL | let _: [u8; foo::<T>()];
|
||||
| ^ cannot perform const operation using `T`
|
||||
@ -8,7 +8,7 @@ LL | let _: [u8; foo::<T>()];
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:15:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:16:23
|
||||
|
|
||||
LL | let _: [u8; bar::<N>()];
|
||||
| ^ cannot perform const operation using `N`
|
||||
@ -16,44 +16,44 @@ LL | let _: [u8; bar::<N>()];
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:18:23
|
||||
|
|
||||
LL | let _: [u8; faz::<'a>(&())];
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:20:23
|
||||
|
|
||||
LL | let _: [u8; baz::<'a>(&())];
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:21:23
|
||||
|
|
||||
LL | let _: [u8; faz::<'b>(&())];
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:23:23
|
||||
|
|
||||
LL | let _: [u8; baz::<'b>(&())];
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:27:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:26:23
|
||||
|
|
||||
LL | let _ = [0; bar::<N>()];
|
||||
| ^ cannot perform const operation using `N`
|
||||
@ -61,44 +61,44 @@ LL | let _ = [0; bar::<N>()];
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:30:23
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:28:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'a>(&())];
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:32:23
|
||||
|
|
||||
LL | let _ = [0; baz::<'a>(&())];
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:33:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'b>(&())];
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:35:23
|
||||
|
|
||||
LL | let _ = [0; baz::<'b>(&())];
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:36:24
|
||||
--> $DIR/const-arg-in-const-arg.rs:30:23
|
||||
|
|
||||
LL | let _ = [0; baz::<'a>(&())];
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:31:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'b>(&())];
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:33:23
|
||||
|
|
||||
LL | let _ = [0; baz::<'b>(&())];
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:34:24
|
||||
|
|
||||
LL | let _: Foo<{ foo::<T>() }>;
|
||||
| ^ cannot perform const operation using `T`
|
||||
@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::<T>() }>;
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:38:24
|
||||
--> $DIR/const-arg-in-const-arg.rs:35:24
|
||||
|
|
||||
LL | let _: Foo<{ bar::<N>() }>;
|
||||
| ^ cannot perform const operation using `N`
|
||||
@ -115,44 +115,44 @@ LL | let _: Foo<{ bar::<N>() }>;
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:41:24
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:37:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'a>(&()) }>;
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:43:24
|
||||
|
|
||||
LL | let _: Foo<{ baz::<'a>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:44:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'b>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:46:24
|
||||
|
|
||||
LL | let _: Foo<{ baz::<'b>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:47:27
|
||||
--> $DIR/const-arg-in-const-arg.rs:39:24
|
||||
|
|
||||
LL | let _: Foo<{ baz::<'a>(&()) }>;
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:40:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'b>(&()) }>;
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:42:24
|
||||
|
|
||||
LL | let _: Foo<{ baz::<'b>(&()) }>;
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:43:27
|
||||
|
|
||||
LL | let _ = Foo::<{ foo::<T>() }>;
|
||||
| ^ cannot perform const operation using `T`
|
||||
@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::<T>() }>;
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:49:27
|
||||
--> $DIR/const-arg-in-const-arg.rs:44:27
|
||||
|
|
||||
LL | let _ = Foo::<{ bar::<N>() }>;
|
||||
| ^ cannot perform const operation using `N`
|
||||
@ -169,44 +169,44 @@ LL | let _ = Foo::<{ bar::<N>() }>;
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:52:27
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:46:27
|
||||
|
|
||||
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:54:27
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:48:27
|
||||
|
|
||||
LL | let _ = Foo::<{ baz::<'a>(&()) }>;
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:55:27
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:49:27
|
||||
|
|
||||
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
--> $DIR/const-arg-in-const-arg.rs:57:27
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-arg-in-const-arg.rs:51:27
|
||||
|
|
||||
LL | let _ = Foo::<{ baz::<'b>(&()) }>;
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'b`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0747]: unresolved item provided when a constant was expected
|
||||
--> $DIR/const-arg-in-const-arg.rs:15:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:16:23
|
||||
|
|
||||
LL | let _: [u8; bar::<N>()];
|
||||
| ^
|
||||
@ -223,7 +223,7 @@ LL | let _: [u8; faz::<'a>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
@ -235,13 +235,13 @@ LL | let _: [u8; faz::<'b>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0747]: unresolved item provided when a constant was expected
|
||||
--> $DIR/const-arg-in-const-arg.rs:38:24
|
||||
--> $DIR/const-arg-in-const-arg.rs:35:24
|
||||
|
|
||||
LL | let _: Foo<{ bar::<N>() }>;
|
||||
| ^
|
||||
@ -252,25 +252,25 @@ LL | let _: Foo<{ bar::<{ N }>() }>;
|
||||
| + +
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:41:24
|
||||
--> $DIR/const-arg-in-const-arg.rs:37:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'a>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:44:24
|
||||
--> $DIR/const-arg-in-const-arg.rs:40:24
|
||||
|
|
||||
LL | let _: Foo<{ faz::<'b>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
@ -284,7 +284,7 @@ LL | let _ = [0; foo::<T>()];
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
|
||||
error[E0747]: unresolved item provided when a constant was expected
|
||||
--> $DIR/const-arg-in-const-arg.rs:27:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:26:23
|
||||
|
|
||||
LL | let _ = [0; bar::<N>()];
|
||||
| ^
|
||||
@ -295,31 +295,31 @@ LL | let _ = [0; bar::<{ N }>()];
|
||||
| + +
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:30:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:28:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'a>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:33:23
|
||||
--> $DIR/const-arg-in-const-arg.rs:31:23
|
||||
|
|
||||
LL | let _ = [0; faz::<'b>(&())];
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0747]: unresolved item provided when a constant was expected
|
||||
--> $DIR/const-arg-in-const-arg.rs:49:27
|
||||
--> $DIR/const-arg-in-const-arg.rs:44:27
|
||||
|
|
||||
LL | let _ = Foo::<{ bar::<N>() }>;
|
||||
| ^
|
||||
@ -330,30 +330,30 @@ LL | let _ = Foo::<{ bar::<{ N }>() }>;
|
||||
| + +
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:52:27
|
||||
--> $DIR/const-arg-in-const-arg.rs:46:27
|
||||
|
|
||||
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/const-arg-in-const-arg.rs:55:27
|
||||
--> $DIR/const-arg-in-const-arg.rs:49:27
|
||||
|
|
||||
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
|
||||
| ^^
|
||||
|
|
||||
note: the late bound lifetime parameter is introduced here
|
||||
--> $DIR/const-arg-in-const-arg.rs:8:14
|
||||
--> $DIR/const-arg-in-const-arg.rs:10:14
|
||||
|
|
||||
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
|
||||
| ^^
|
||||
|
||||
error: aborting due to 36 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0658, E0747, E0794.
|
||||
For more information about an error, try `rustc --explain E0658`.
|
||||
Some errors have detailed explanations: E0747, E0794.
|
||||
For more information about an error, try `rustc --explain E0747`.
|
||||
|
@ -1,4 +1,6 @@
|
||||
// revisions: full min
|
||||
// revisions: min
|
||||
// we use a single revision because t his shoudl have a `full` revision
|
||||
// but right now that ICEs and I(@BoxyUwU) could not get stderr normalization to work
|
||||
|
||||
#![cfg_attr(full, feature(generic_const_exprs))]
|
||||
#![cfg_attr(full, allow(incomplete_features))]
|
||||
@ -11,50 +13,42 @@ const fn baz<'a>(_: &'a ()) -> usize where &'a (): Sized { 13 }
|
||||
struct Foo<const N: usize>;
|
||||
fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
|
||||
let _: [u8; foo::<T>()]; //[min]~ ERROR generic parameters may not
|
||||
//[full]~^ ERROR unconstrained generic constant
|
||||
let _: [u8; bar::<N>()]; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR unresolved item provided when a constant was expected
|
||||
//[full]~^^ ERROR unconstrained generic constant
|
||||
let _: [u8; faz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _: [u8; baz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
let _: [u8; faz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _: [u8; baz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not
|
||||
let _: [u8; faz::<'b>(&())]; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _: [u8; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not
|
||||
|
||||
let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter
|
||||
//[full]~^ ERROR unconstrained generic constant
|
||||
let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR unresolved item provided when a constant was expected
|
||||
//[full]~^^ ERROR unconstrained generic constant
|
||||
let _ = [0; faz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _ = [0; baz::<'a>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
let _ = [0; faz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _ = [0; baz::<'b>(&())]; //[min]~ ERROR a non-static lifetime
|
||||
let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not
|
||||
let _ = [0; faz::<'b>(&())]; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _ = [0; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not
|
||||
let _: Foo<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not
|
||||
//[full]~^ ERROR unconstrained generic constant
|
||||
let _: Foo<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR unresolved item provided when a constant was expected
|
||||
//[full]~^^ ERROR unconstrained generic constant
|
||||
let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
let _: Foo<{ faz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
let _: Foo<{ faz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
let _ = Foo::<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not
|
||||
//[full]~^ ERROR unconstrained generic constant
|
||||
let _ = Foo::<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR unresolved item provided when a constant was expected
|
||||
//[full]~^^ ERROR unconstrained generic constant
|
||||
let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
let _ = Foo::<{ faz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
//~^ ERROR cannot specify lifetime arguments
|
||||
let _ = Foo::<{ baz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime
|
||||
let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
let _ = Foo::<{ faz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
//[min]~^ ERROR cannot specify lifetime arguments
|
||||
let _ = Foo::<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,12 +1,11 @@
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/const-argument-non-static-lifetime.rs:14:17
|
||||
|
|
||||
LL | let _: &'a ();
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -11,7 +11,7 @@ fn test<const N: usize>() {}
|
||||
|
||||
fn wow<'a>() -> &'a () {
|
||||
test::<{
|
||||
let _: &'a (); //[min]~ ERROR a non-static lifetime
|
||||
let _: &'a (); //[min]~ ERROR generic parameters may not be used in const operations
|
||||
3
|
||||
}>();
|
||||
&()
|
||||
|
@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
||||
|
|
||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
||||
|
|
||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error: `[u8; N]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:11:47
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub struct Dependent<T, const X: T>([(); X]);
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0392]: parameter `T` is never used
|
||||
--> $DIR/const-param-type-depends-on-type-param.rs:11:22
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub struct Dependent<T, const X: T>([(); X]);
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0392]: parameter `T` is never used
|
||||
--> $DIR/const-param-type-depends-on-type-param.rs:11:22
|
||||
|
@ -1,7 +1,7 @@
|
||||
fn bug<'a>()
|
||||
where
|
||||
[(); { //~ ERROR mismatched types
|
||||
let _: &'a (); //~ ERROR a non-static lifetime is not allowed in a `const`
|
||||
let _: &'a (); //~ ERROR generic parameters may not be used in const operations
|
||||
}]:
|
||||
{}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/issue-74713.rs:4:17
|
||||
|
|
||||
LL | let _: &'a ();
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-74713.rs:3:10
|
||||
@ -18,5 +18,4 @@ LL | | }]:
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -0,0 +1,12 @@
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn foo() -> [(); {
|
||||
let a: &'a ();
|
||||
//~^ ERROR: use of undeclared lifetime name `'a`
|
||||
10_usize
|
||||
}] {
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,11 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/unresolved_lifetimes_error.rs:5:13
|
||||
|
|
||||
LL | fn foo() -> [(); {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | let a: &'a ();
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
@ -2,7 +2,7 @@
|
||||
|
||||
struct Foo<'a> //~ ERROR parameter `'a` is never used [E0392]
|
||||
{
|
||||
_a: [u8; std::mem::size_of::<&'a mut u8>()] //~ ERROR a non-static lifetime is not allowed in a `const`
|
||||
_a: [u8; std::mem::size_of::<&'a mut u8>()] //~ ERROR generic parameters may not be used in const operations
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/issue-46511.rs:5:35
|
||||
|
|
||||
LL | _a: [u8; std::mem::size_of::<&'a mut u8>()]
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0392]: parameter `'a` is never used
|
||||
--> $DIR/issue-46511.rs:3:12
|
||||
@ -17,5 +17,4 @@ LL | struct Foo<'a>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0392, E0658.
|
||||
For more information about an error, try `rustc --explain E0392`.
|
||||
For more information about this error, try `rustc --explain E0392`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// check-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(adt_const_params, const_ptr_read, generic_const_exprs)]
|
||||
#![feature(adt_const_params, generic_const_exprs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
const fn catone<const M: usize>(_a: &[u8; M]) -> [u8; M + 1]
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0771]: use of non-static lifetime `'a` in const generic
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-56445-1.rs:9:26
|
||||
|
|
||||
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
| ^^
|
||||
| ^^ the type must not depend on the parameter `'a`
|
||||
|
|
||||
= note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
|
||||
= note: lifetime parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0771`.
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0771]: use of non-static lifetime `'a` in const generic
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-56445-1.rs:9:26
|
||||
|
|
||||
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
| ^^
|
||||
| ^^ the type must not depend on the parameter `'a`
|
||||
|
|
||||
= note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
|
||||
= note: lifetime parameters may not be used in the type of const parameters
|
||||
|
||||
error: `&str` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-56445-1.rs:9:25
|
||||
@ -17,4 +17,4 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0771`.
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
@ -7,7 +7,7 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
//~^ ERROR: use of non-static lifetime `'a` in const generic
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//[min]~| ERROR: `&str` is forbidden as the type of a const generic parameter
|
||||
|
||||
impl Bug<'_, ""> {}
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | fn foo<const N: usize, const A: [u8; N]>() {}
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | fn foo<const N: usize, const A: [u8; N]>() {}
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error: `[u8; N]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-62878.rs:5:33
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
|
||||
| ^^^ the type must not depend on the parameter `LEN`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
|
||||
| ^^^ the type must not depend on the parameter `LEN`
|
||||
|
|
||||
= note: const parameters may not be used in the type of const parameters
|
||||
|
||||
error: `[u8; LEN]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-71169.rs:5:38
|
||||
|
@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71381.rs:23:40
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0741]: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:14:61
|
||||
|
@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71381.rs:23:40
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:14:61
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
||||
| ^ the type must not depend on the parameter `A`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0741]: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71611.rs:5:21
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
||||
| ^ the type must not depend on the parameter `A`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71611.rs:5:21
|
||||
|
@ -1,11 +0,0 @@
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait MyTrait<T> {}
|
||||
|
||||
fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
|
||||
//~^ ERROR overly complex generic constant
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,11 +0,0 @@
|
||||
error: overly complex generic constant
|
||||
--> $DIR/issue-77357.rs:6:46
|
||||
|
|
||||
LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constants
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
= note: this operation may be supported in the future
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,14 +0,0 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn bug<'a>()
|
||||
where
|
||||
for<'b> [(); {
|
||||
let x: &'b ();
|
||||
0
|
||||
}]:
|
||||
{}
|
||||
|
||||
fn main() {}
|
@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-88997.rs:8:54
|
||||
|
|
||||
LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
|
|
||||
LL | pub struct Foo<T, const H: T>(T)
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,4 +1,22 @@
|
||||
// run-pass
|
||||
// failure-status: 101
|
||||
// known-bug: unknown
|
||||
// error-pattern:internal compiler error
|
||||
// normalize-stderr-test "internal compiler error.*" -> ""
|
||||
// normalize-stderr-test "DefId\([^)]*\)" -> "..."
|
||||
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
|
||||
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
|
||||
// normalize-stderr-test "thread.*panicked.*\n" -> ""
|
||||
// normalize-stderr-test "stack backtrace:\n" -> ""
|
||||
// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
|
||||
// normalize-stderr-test "\s at .*\n" -> ""
|
||||
// normalize-stderr-test ".*note: Some details.*\n" -> ""
|
||||
// normalize-stderr-test "\n\n[ ]*\n" -> ""
|
||||
// normalize-stderr-test "compiler/.*: projection" -> "projection"
|
||||
// this should run-pass
|
||||
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
13
tests/ui/const-generics/late-bound-vars/in_closure.stderr
Normal file
13
tests/ui/const-generics/late-bound-vars/in_closure.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error: query stack during panic:
|
||||
#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}`
|
||||
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}`
|
||||
#2 [mir_for_ctfe] caching mir of `test::{closure#0}::{constant#1}` for CTFE
|
||||
#3 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}`
|
||||
#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}`
|
||||
#5 [eval_to_valtree] evaluating type-level constant
|
||||
#6 [typeck] type-checking `test`
|
||||
#7 [used_trait_imports] finding used_trait_imports `test`
|
||||
#8 [analysis] running analysis passes on this crate
|
||||
end of query stack
|
||||
error: aborting due to previous error
|
||||
|
@ -1,4 +1,21 @@
|
||||
// run-pass
|
||||
// failure-status: 101
|
||||
// known-bug: unknown
|
||||
// error-pattern:internal compiler error
|
||||
// normalize-stderr-test "internal compiler error.*" -> ""
|
||||
// normalize-stderr-test "DefId\([^)]*\)" -> "..."
|
||||
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
|
||||
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
|
||||
// normalize-stderr-test "thread.*panicked.*\n" -> ""
|
||||
// normalize-stderr-test "stack backtrace:\n" -> ""
|
||||
// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
|
||||
// normalize-stderr-test "\s at .*\n" -> ""
|
||||
// normalize-stderr-test ".*note: Some details.*\n" -> ""
|
||||
// normalize-stderr-test "\n\n[ ]*\n" -> ""
|
||||
// normalize-stderr-test "compiler/.*: projection" -> "projection"
|
||||
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
13
tests/ui/const-generics/late-bound-vars/simple.stderr
Normal file
13
tests/ui/const-generics/late-bound-vars/simple.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error: query stack during panic:
|
||||
#0 [mir_borrowck] borrow-checking `test::{constant#1}`
|
||||
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{constant#1}`
|
||||
#2 [mir_for_ctfe] caching mir of `test::{constant#1}` for CTFE
|
||||
#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}`
|
||||
#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}`
|
||||
#5 [eval_to_valtree] evaluating type-level constant
|
||||
#6 [typeck] type-checking `test`
|
||||
#7 [used_trait_imports] finding used_trait_imports `test`
|
||||
#8 [analysis] running analysis passes on this crate
|
||||
end of query stack
|
||||
error: aborting due to previous error
|
||||
|
@ -5,7 +5,7 @@ fn test<const N: usize>() {}
|
||||
|
||||
fn issue_75323_and_74447_1<'a>() -> &'a () {
|
||||
test::<{ let _: &'a (); 3 },>();
|
||||
//~^ ERROR a non-static lifetime is not allowed in a `const`
|
||||
//~^ ERROR generic parameters may not be used in const operations
|
||||
&()
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ fn issue_75323_and_74447_3() {
|
||||
|
||||
fn issue_73375<'a>() {
|
||||
[(); (|_: &'a u8| (), 0).1];
|
||||
//~^ ERROR a non-static lifetime is not allowed in a `const`
|
||||
//~^ ERROR generic parameters may not be used in const operations
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,21 +1,20 @@
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/forbid-non-static-lifetimes.rs:7:22
|
||||
|
|
||||
LL | test::<{ let _: &'a (); 3 },>();
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: a non-static lifetime is not allowed in a `const`
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/forbid-non-static-lifetimes.rs:21:16
|
||||
|
|
||||
LL | [(); (|_: &'a u8| (), 0).1];
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -2,7 +2,7 @@ struct Foo<
|
||||
'a,
|
||||
const N: usize = {
|
||||
let x: &'a ();
|
||||
//~^ ERROR use of non-static lifetime `'a` in const generic
|
||||
//~^ ERROR generic parameters may not be used in const operations
|
||||
3
|
||||
},
|
||||
>(&'a ());
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0771]: use of non-static lifetime `'a` in const generic
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/outer-lifetime-in-const-generic-default.rs:4:17
|
||||
|
|
||||
LL | let x: &'a ();
|
||||
| ^^
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
|
||||
= note: lifetime parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0771`.
|
||||
|
@ -0,0 +1,34 @@
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:7:15
|
||||
|
|
||||
LL | Variant = N,
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= note: const parameters may not be used in enum discriminant values
|
||||
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:12:17
|
||||
|
|
||||
LL | Variant = { N + 1 },
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= note: const parameters may not be used in enum discriminant values
|
||||
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:18:37
|
||||
|
|
||||
LL | Variant = { std::mem::size_of::<T>() as isize },
|
||||
| ^ cannot perform const operation using `T`
|
||||
|
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:25:17
|
||||
|
|
||||
LL | let a: &'a ();
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: lifetime parameters may not be used in enum discriminant values
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
@ -0,0 +1,34 @@
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:7:15
|
||||
|
|
||||
LL | Variant = N,
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= note: const parameters may not be used in enum discriminant values
|
||||
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:12:17
|
||||
|
|
||||
LL | Variant = { N + 1 },
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= note: const parameters may not be used in enum discriminant values
|
||||
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:18:37
|
||||
|
|
||||
LL | Variant = { std::mem::size_of::<T>() as isize },
|
||||
| ^ cannot perform const operation using `T`
|
||||
|
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/variant-discrimiant-no-generics.rs:25:17
|
||||
|
|
||||
LL | let a: &'a ();
|
||||
| ^^ cannot perform const operation using `'a`
|
||||
|
|
||||
= note: lifetime parameters may not be used in enum discriminant values
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
32
tests/ui/const-generics/variant-discrimiant-no-generics.rs
Normal file
32
tests/ui/const-generics/variant-discrimiant-no-generics.rs
Normal file
@ -0,0 +1,32 @@
|
||||
// revisions: full min
|
||||
|
||||
#![cfg_attr(full, feature(generic_const_exprs))]
|
||||
#![cfg_attr(full, allow(incomplete_features))]
|
||||
|
||||
enum Foo<const N: isize> {
|
||||
Variant = N,
|
||||
//~^ ERROR: generic parameters may not be used in enum discriminant values
|
||||
}
|
||||
|
||||
enum Owo<const N: isize> {
|
||||
Variant = { N + 1 },
|
||||
//~^ ERROR: generic parameters may not be used in enum discriminant values
|
||||
}
|
||||
|
||||
#[repr(isize)]
|
||||
enum Bar<T> {
|
||||
Variant = { std::mem::size_of::<T>() as isize },
|
||||
Other(T), //~^ ERROR: generic parameters may not be used in enum discriminant values
|
||||
}
|
||||
|
||||
#[repr(isize)]
|
||||
enum UwU<'a> {
|
||||
Variant = {
|
||||
let a: &'a ();
|
||||
//~^ ERROR: generic parameters may not be used in enum discriminant values
|
||||
10_isize
|
||||
},
|
||||
Other(&'a ()),
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,7 +1,5 @@
|
||||
// error-pattern: evaluation of constant value failed
|
||||
|
||||
#![feature(const_ptr_read)]
|
||||
|
||||
fn main() {
|
||||
use std::ptr;
|
||||
|
||||
|
@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed
|
||||
note: inside `std::ptr::read::<u32>`
|
||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||
note: inside `_READ`
|
||||
--> $DIR/out_of_bounds_read.rs:12:33
|
||||
--> $DIR/out_of_bounds_read.rs:10:33
|
||||
|
|
||||
LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -21,7 +21,7 @@ note: inside `std::ptr::read::<u32>`
|
||||
note: inside `ptr::const_ptr::<impl *const u32>::read`
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
note: inside `_CONST_READ`
|
||||
--> $DIR/out_of_bounds_read.rs:13:39
|
||||
--> $DIR/out_of_bounds_read.rs:11:39
|
||||
|
|
||||
LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
@ -36,7 +36,7 @@ note: inside `std::ptr::read::<u32>`
|
||||
note: inside `ptr::mut_ptr::<impl *mut u32>::read`
|
||||
--> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
||||
note: inside `_MUT_READ`
|
||||
--> $DIR/out_of_bounds_read.rs:14:37
|
||||
--> $DIR/out_of_bounds_read.rs:12:37
|
||||
|
|
||||
LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -3,7 +3,6 @@
|
||||
// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
|
||||
// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
|
||||
#![allow(invalid_value)]
|
||||
#![feature(const_ptr_read)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:16:1
|
||||
--> $DIR/ub-ref-ptr.rs:15:1
|
||||
|
|
||||
LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
|
||||
@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:20:1
|
||||
--> $DIR/ub-ref-ptr.rs:19:1
|
||||
|
|
||||
LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
|
||||
@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:24:1
|
||||
--> $DIR/ub-ref-ptr.rs:23:1
|
||||
|
|
||||
LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
|
||||
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference
|
||||
@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:27:1
|
||||
--> $DIR/ub-ref-ptr.rs:26:1
|
||||
|
|
||||
LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box
|
||||
@ -43,7 +43,7 @@ LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
|
||||
}
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:34:1
|
||||
--> $DIR/ub-ref-ptr.rs:33:1
|
||||
|
|
||||
LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:37:39
|
||||
--> $DIR/ub-ref-ptr.rs:36:39
|
||||
|
|
||||
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
note: erroneous constant used
|
||||
--> $DIR/ub-ref-ptr.rs:37:38
|
||||
--> $DIR/ub-ref-ptr.rs:36:38
|
||||
|
|
||||
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:40:86
|
||||
--> $DIR/ub-ref-ptr.rs:39:86
|
||||
|
|
||||
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
note: erroneous constant used
|
||||
--> $DIR/ub-ref-ptr.rs:40:85
|
||||
--> $DIR/ub-ref-ptr.rs:39:85
|
||||
|
|
||||
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:43:1
|
||||
--> $DIR/ub-ref-ptr.rs:42:1
|
||||
|
|
||||
LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance)
|
||||
@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:46:1
|
||||
--> $DIR/ub-ref-ptr.rs:45:1
|
||||
|
|
||||
LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance)
|
||||
@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
|
||||
}
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:49:41
|
||||
--> $DIR/ub-ref-ptr.rs:48:41
|
||||
|
|
||||
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:53:1
|
||||
--> $DIR/ub-ref-ptr.rs:52:1
|
||||
|
|
||||
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
|
||||
@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
|
||||
}
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ub-ref-ptr.rs:55:38
|
||||
--> $DIR/ub-ref-ptr.rs:54:38
|
||||
|
|
||||
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:58:1
|
||||
--> $DIR/ub-ref-ptr.rs:57:1
|
||||
|
|
||||
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
|
||||
@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref-ptr.rs:60:1
|
||||
--> $DIR/ub-ref-ptr.rs:59:1
|
||||
|
|
||||
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
|
||||
@ -158,7 +158,7 @@ note: inside `std::ptr::read::<u32>`
|
||||
note: inside `ptr::const_ptr::<impl *const u32>::read`
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
note: inside `UNALIGNED_READ`
|
||||
--> $DIR/ub-ref-ptr.rs:67:5
|
||||
--> $DIR/ub-ref-ptr.rs:66:5
|
||||
|
|
||||
LL | ptr.read();
|
||||
| ^^^^^^^^^^
|
||||
|
@ -1,7 +1,6 @@
|
||||
// revisions: no_flag with_flag
|
||||
// [no_flag] check-pass
|
||||
// [with_flag] compile-flags: -Zextra-const-ub-checks
|
||||
#![feature(const_ptr_read)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:9:20
|
||||
--> $DIR/detect-extra-ub.rs:8:20
|
||||
|
|
||||
LL | let _x: bool = transmute(3u8);
|
||||
| ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:15:21
|
||||
--> $DIR/detect-extra-ub.rs:14:21
|
||||
|
|
||||
LL | let _x: usize = transmute(&3u8);
|
||||
| ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8);
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:21:30
|
||||
--> $DIR/detect-extra-ub.rs:20:30
|
||||
|
|
||||
LL | let _x: (usize, usize) = transmute(x);
|
||||
| ^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
@ -23,7 +23,7 @@ LL | let _x: (usize, usize) = transmute(x);
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:26:20
|
||||
--> $DIR/detect-extra-ub.rs:25:20
|
||||
|
|
||||
LL | let _x: &u32 = transmute(&[0u8; 4]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
|
||||
|
@ -1,6 +1,5 @@
|
||||
// error-pattern unable to turn pointer into raw bytes
|
||||
// normalize-stderr-test: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC"
|
||||
#![feature(const_ptr_read)]
|
||||
|
||||
const C: () = unsafe {
|
||||
let foo = Some(&42 as *const i32);
|
||||
|
@ -10,7 +10,7 @@ note: inside `std::ptr::read::<u8>`
|
||||
note: inside `ptr::const_ptr::<impl *const u8>::read`
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
note: inside `C`
|
||||
--> $DIR/issue-miri-1910.rs:8:5
|
||||
--> $DIR/issue-miri-1910.rs:7:5
|
||||
|
|
||||
LL | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -7,7 +7,7 @@ use core::intrinsics::discriminant_value;
|
||||
enum MyWeirdOption<T> {
|
||||
None = 0,
|
||||
Some(T) = std::mem::size_of::<T>(),
|
||||
//~^ ERROR generic parameters may not be used in const operations
|
||||
//~^ ERROR generic parameters may not be used in enum discriminant values
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,11 +1,10 @@
|
||||
error: generic parameters may not be used in const operations
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:35
|
||||
|
|
||||
LL | Some(T) = std::mem::size_of::<T>(),
|
||||
| ^ cannot perform const operation using `T`
|
||||
|
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,7 +8,7 @@ enum MyWeirdOption<T> {
|
||||
//~^ ERROR parameter `T` is never used
|
||||
None = 0,
|
||||
Some = std::mem::size_of::<T>(),
|
||||
//~^ ERROR generic parameters may not be used in const operations
|
||||
//~^ ERROR generic parameters may not be used in enum discriminant values
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,11 +1,10 @@
|
||||
error: generic parameters may not be used in const operations
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/issue-70453-generics-in-discr-ice.rs:10:32
|
||||
|
|
||||
LL | Some = std::mem::size_of::<T>(),
|
||||
| ^ cannot perform const operation using `T`
|
||||
|
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error[E0392]: parameter `T` is never used
|
||||
--> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
|
||||
|
@ -1,11 +1,10 @@
|
||||
error: generic parameters may not be used in const operations
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/issue-70453-polymorphic-ctfe.rs:9:41
|
||||
|
|
||||
LL | Some(T) = core::mem::size_of::<*mut T>(),
|
||||
| ^ cannot perform const operation using `T`
|
||||
|
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
error: generic parameters may not be used in const operations
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/issue-67945-1.rs:3:16
|
||||
|
|
||||
LL | let x: S = 0;
|
||||
| ^ cannot perform const operation using `S`
|
||||
|
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error[E0392]: parameter `S` is never used
|
||||
--> $DIR/issue-67945-1.rs:1:10
|
||||
|
@ -1,11 +1,10 @@
|
||||
error: generic parameters may not be used in const operations
|
||||
error: generic parameters may not be used in enum discriminant values
|
||||
--> $DIR/issue-67945-2.rs:4:28
|
||||
|
|
||||
LL | Var = type_ascribe!(0, S),
|
||||
| ^ cannot perform const operation using `S`
|
||||
|
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
= note: type parameters may not be used in enum discriminant values
|
||||
|
||||
error[E0392]: parameter `S` is never used
|
||||
--> $DIR/issue-67945-2.rs:3:10
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![feature(adt_const_params)]
|
||||
//~^ WARN the feature `adt_const_params` is incomplete
|
||||
|
||||
fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0771
|
||||
fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0770
|
||||
|
||||
fn main() {
|
||||
function_with_str::<"Hello, world!">()
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0771]: use of non-static lifetime `'a` in const generic
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/E0771.rs:4:41
|
||||
|
|
||||
LL | fn function_with_str<'a, const STRING: &'a str>() {}
|
||||
| ^^
|
||||
| ^^ the type must not depend on the parameter `'a`
|
||||
|
|
||||
= note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
|
||||
= note: lifetime parameters may not be used in the type of const parameters
|
||||
|
||||
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/E0771.rs:1:12
|
||||
@ -17,4 +17,4 @@ LL | #![feature(adt_const_params)]
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0771`.
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user