Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
improve diagnostics and bless tests
  • Loading branch information
BoxyUwU committed May 5, 2023
commit 73b3ce26ecf580aec44e45308e952753f5218e07
29 changes: 27 additions & 2 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}`
Expand Down Expand Up @@ -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
19 changes: 10 additions & 9 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,25 +864,26 @@ 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
.is_nightly_build()
.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 })
}
Expand Down
47 changes: 41 additions & 6 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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>,
}
Expand All @@ -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)]
Expand Down Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, can this be merged with ParamInNonTrivialAnonConst?

#[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,
}
70 changes: 51 additions & 19 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -1206,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);
}

Expand All @@ -1229,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;
Expand Down Expand Up @@ -1262,14 +1282,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
RibKind::ConstantItem(trivial, _) => {
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;
Expand All @@ -1283,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;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
match rib.kind {
LifetimeRibKind::Item => break,
LifetimeRibKind::ConstParamTy => {
self.emit_non_static_lt_in_const_generic_error(lifetime);
self.emit_non_static_lt_in_const_param_ty_error(lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
Expand All @@ -1538,7 +1538,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
return;
}
LifetimeRibKind::ConcreteAnonConst(cause) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every lifetime you write that isnt '_ or 'static gets resolved to an error without an error actually having been emitted, this goes for when you do actually have a lifetime in scope (i.e. fn foo<'a>() -> [(); { let _: &'a (); 10 }] {}) or when you are writing lifetimes that haven't been declared (i.e. fn foo() -> [(); { let _: &'a (); 10 }] {}).

The bug is here. We need the feature check for generic_const_exprs be done on this whole block, instead of only doing it in emit_forbidden_non_static_lifetime_error. This way, lifetime resolution will continue walking ribs, instead of returning a LifetimeRes::Error straight.

Copy link
Member Author

@BoxyUwU BoxyUwU May 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this PR accomplishes that by just not adding the ConcreteAnonConst rib if generic_const_exprs is enabled, so the only time we encounter LifetimeRibKind::ConcreteAnonConst should be when we need to error. Super subtle 😅

self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
Expand Down
70 changes: 45 additions & 25 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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();
}
}
}

Expand Down
Loading