diff options
| author | Amanieu d'Antras <amanieu@gmail.com> | 2021-02-24 06:46:30 +0000 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2021-02-24 06:46:30 +0000 |
| commit | 00eca69bffcb4ef95ba1dd6013b840bf12a85804 (patch) | |
| tree | a0f9e23cfc467a9b8859909622450a5fb2a413db /compiler/rustc_resolve | |
| parent | 69cde44390de43748904bceb808e2e1b097e62a8 (diff) | |
Properly reject non-const arguments
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 701d48a982d..877633820be 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2326,8 +2326,20 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::Call(ref callee, ref arguments) => { self.resolve_expr(callee, Some(expr)); - for argument in arguments { - self.resolve_expr(argument, None); + let const_args = self.legacy_const_generic_args(callee).unwrap_or(Vec::new()); + for (idx, argument) in arguments.iter().enumerate() { + if const_args.contains(&idx) { + self.with_constant_rib( + IsRepeatExpr::No, + argument.is_potential_trivial_const_param(), + None, + |this| { + this.resolve_expr(argument, None); + }, + ); + } else { + self.resolve_expr(argument, None); + } } } ExprKind::Type(ref type_expr, ref ty) => { @@ -2406,6 +2418,42 @@ 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> { |
