Address review comments

This commit is contained in:
Amanieu d'Antras 2021-02-25 00:09:33 +00:00
parent 00eca69bff
commit 2451f124c9
6 changed files with 78 additions and 90 deletions

View File

@ -44,7 +44,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
ExprKind::Call(ref f, ref args) => {
if let Some(legacy_args) = self.legacy_const_generic_args(f) {
if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args)
} else {
let f = self.lower_expr(f);
@ -298,39 +298,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
/// Checks if an expression refers to a function marked with
/// `#[rustc_legacy_const_generics]` and returns the argument index list
/// from the attribute.
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>> {
if let ExprKind::Path(None, path) = &expr.kind {
if path.segments.last().unwrap().args.is_some() {
return None;
}
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
if partial_res.unresolved_segments() != 0 {
return None;
}
if let Res::Def(hir::def::DefKind::Fn, def_id) = partial_res.base_res() {
let attrs = self.item_attrs(def_id);
let attr = attrs
.iter()
.find(|a| self.sess.check_name(a, sym::rustc_legacy_const_generics))?;
let mut ret = vec![];
for meta in attr.meta_item_list()? {
match meta.literal()?.kind {
LitKind::Int(a, _) => {
ret.push(a as usize);
}
_ => panic!("invalid arg index"),
}
}
return Some(ret);
}
}
}
None
}
fn lower_legacy_const_generics(
&mut self,
mut f: Expr,
@ -366,12 +333,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
// Add generic args to the last element of the path
path.segments.last_mut().unwrap().args =
Some(AstP(GenericArgs::AngleBracketed(AngleBracketedArgs {
span: DUMMY_SP,
args: generic_args,
})));
// Add generic args to the last element of the path.
let last_segment = path.segments.last_mut().unwrap();
assert!(last_segment.args.is_none());
last_segment.args = Some(AstP(GenericArgs::AngleBracketed(AngleBracketedArgs {
span: DUMMY_SP,
args: generic_args,
})));
// Now lower everything as normal.
let f = self.lower_expr(&f);

View File

@ -175,7 +175,7 @@ pub trait ResolverAstLowering {
fn item_generics_num_lifetimes(&self, def: DefId, sess: &Session) -> usize;
fn item_attrs(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute>;
fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
/// Obtains resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
@ -2828,16 +2828,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}
}
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> {
if let Some(_local_def_id) = def_id.as_local() {
// FIXME: This doesn't actually work, items doesn't include everything?
//self.items[&hir::ItemId { def_id: local_def_id }].attrs.into()
Vec::new()
} else {
self.resolver.item_attrs(def_id, self.sess)
}
}
}
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {

View File

@ -789,6 +789,23 @@ impl CheckAttrVisitor<'tcx> {
})) = item
{
let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
for param in generics.params {
match param.kind {
hir::GenericParamKind::Const { .. } => {}
_ => {
self.tcx
.sess
.struct_span_err(
meta.span(),
"#[rustc_legacy_const_generics] functions must \
only have const generics",
)
.span_label(param.span, "non-const generic parameter")
.emit();
break;
}
}
}
if *val >= arg_count {
let span = meta.span();
self.tcx

View File

@ -2326,8 +2326,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
ExprKind::Call(ref callee, ref arguments) => {
self.resolve_expr(callee, Some(expr));
let const_args = self.legacy_const_generic_args(callee).unwrap_or(Vec::new());
let const_args = self.r.legacy_const_generic_args(callee).unwrap_or(Vec::new());
for (idx, argument) in arguments.iter().enumerate() {
// 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,
@ -2418,42 +2420,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
Some((ident.name, ns)),
)
}
/// Checks if an expression refers to a function marked with
/// `#[rustc_legacy_const_generics]` and returns the argument index list
/// from the attribute.
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>> {
if let ExprKind::Path(None, path) = &expr.kind {
if path.segments.last().unwrap().args.is_some() {
return None;
}
if let Some(partial_res) = self.r.get_partial_res(expr.id) {
if partial_res.unresolved_segments() != 0 {
return None;
}
if let Res::Def(def::DefKind::Fn, def_id) = partial_res.base_res() {
if def_id.is_local() {
return None;
}
let attrs = self.r.cstore().item_attrs(def_id, self.r.session);
let attr = attrs
.iter()
.find(|a| self.r.session.check_name(a, sym::rustc_legacy_const_generics))?;
let mut ret = vec![];
for meta in attr.meta_item_list()? {
match meta.literal()?.kind {
LitKind::Int(a, _) => {
ret.push(a as usize);
}
_ => panic!("invalid arg index"),
}
}
return Some(ret);
}
}
}
None
}
}
impl<'a> Resolver<'a> {

View File

@ -29,6 +29,7 @@ use rustc_ast::unwrap_or;
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{self as ast, NodeId};
use rustc_ast::{Crate, CRATE_NODE_ID};
use rustc_ast::{Expr, ExprKind, LitKind};
use rustc_ast::{ItemKind, ModKind, Path};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_ast_pretty::pprust;
@ -1076,8 +1077,8 @@ impl ResolverAstLowering for Resolver<'_> {
self.cstore().item_generics_num_lifetimes(def_id, sess)
}
fn item_attrs(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
self.cstore().item_attrs(def_id, sess)
fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
self.legacy_const_generic_args(expr)
}
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
@ -3312,6 +3313,49 @@ impl<'a> Resolver<'a> {
pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
if let Some(def_id) = def_id.as_local() { Some(self.def_id_to_span[def_id]) } else { None }
}
/// Checks if an expression refers to a function marked with
/// `#[rustc_legacy_const_generics]` and returns the argument index list
/// from the attribute.
pub fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
if let ExprKind::Path(None, path) = &expr.kind {
// Don't perform legacy const generics rewriting if the path already
// has generic arguments.
if path.segments.last().unwrap().args.is_some() {
return None;
}
let partial_res = self.partial_res_map.get(&expr.id)?;
if partial_res.unresolved_segments() != 0 {
return None;
}
if let Res::Def(def::DefKind::Fn, def_id) = partial_res.base_res() {
// We only support cross-crate argument rewriting. Uses
// within the same crate should be updated to use the new
// const generics style.
if def_id.is_local() {
return None;
}
let attrs = self.cstore().item_attrs(def_id, self.session);
let attr = attrs
.iter()
.find(|a| self.session.check_name(a, sym::rustc_legacy_const_generics))?;
let mut ret = vec![];
for meta in attr.meta_item_list()? {
match meta.literal()?.kind {
LitKind::Int(a, _) => {
ret.push(a as usize);
}
_ => panic!("invalid arg index"),
}
}
return Some(ret);
}
}
None
}
}
fn names_to_string(names: &[Symbol]) -> String {

View File

@ -26,6 +26,9 @@ extern {
fn foo7(_: u8);
}
#[rustc_legacy_const_generics(0)] //~ ERROR #[rustc_legacy_const_generics] functions must only have
fn foo3<X>() {}
#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute
fn bar1() {}