1
Fork 0

Auto merge of #96800 - nbdd0121:const, r=nagisa

Permit `asm_const` and `asm_sym` to reference generic params

Related #96557

These constructs will be allowed:
```rust
fn foofoo<const N: usize>() {}

unsafe fn foo<const N: usize>() {
    asm!("/* {0} */", const N);
    asm!("/* {0} */", const N + 1);
    asm!("/* {0} */", sym foofoo::<N>);
}

fn barbar<T>() {}

unsafe fn bar<T>() {
    asm!("/* {0} */", const std::mem::size_of::<T>());
    asm!("/* {0} */", const std::mem::size_of::<(T, T)>());
    asm!("/* {0} */", sym barbar::<T>);
    asm!("/* {0} */", sym barbar::<(T, T)>);
}
```

`@Amanieu,` I didn't switch inline asms to use `DefKind::InlineAsm`, as I see little value doing that; given that no type inference is needed, it will only make typecking slower and more complex but will have no real gains. I did switch them to follow the same code path as inline asm during symbol resolution, though.
The `error: unconstrained generic constant` you mentioned in #76001 is due to the fact that `to_const` will actually add a wfness obligation to the constant, which we don't need for `asm_const`, so I have that removed.

`@rustbot` label: +A-inline-assembly +F-asm
This commit is contained in:
bors 2022-05-18 15:07:47 +00:00
commit 10d9ecda48
12 changed files with 117 additions and 59 deletions

View file

@ -1171,6 +1171,7 @@ impl<'a> Resolver<'a> {
| AssocItemRibKind
| ModuleRibKind(..)
| MacroDefinition(..)
| InlineAsmSymRibKind
| ForwardGenericParamBanRibKind => {
// Nothing to do. Continue.
continue;
@ -1216,22 +1217,6 @@ impl<'a> Resolver<'a> {
}
return Res::Err;
}
InlineAsmSymRibKind => {
let features = self.session.features_untracked();
if !features.generic_const_exprs {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
is_type: true,
},
);
}
return Res::Err;
}
continue;
}
};
if let Some(span) = finalize {
@ -1262,6 +1247,7 @@ impl<'a> Resolver<'a> {
| AssocItemRibKind
| ModuleRibKind(..)
| MacroDefinition(..)
| InlineAsmSymRibKind
| ForwardGenericParamBanRibKind => continue,
ConstantItemRibKind(trivial, _) => {
@ -1296,22 +1282,6 @@ impl<'a> Resolver<'a> {
}
return Res::Err;
}
InlineAsmSymRibKind => {
let features = self.session.features_untracked();
if !features.generic_const_exprs {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
is_type: false,
},
);
}
return Res::Err;
}
continue;
}
};
// This was an attempt to use a const parameter outside its scope.

View file

@ -918,6 +918,29 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
self.diagnostic_metadata.current_where_predicate = previous_value;
}
fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {
for (op, _) in &asm.operands {
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::Out { expr: Some(expr), .. }
| InlineAsmOperand::InOut { expr, .. } => self.visit_expr(expr),
InlineAsmOperand::Out { expr: None, .. } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
self.visit_expr(in_expr);
if let Some(out_expr) = out_expr {
self.visit_expr(out_expr);
}
}
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);
}
InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
}
}
}
fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
// This is similar to the code for AnonConst.
self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {