don't require FnCtxt
to check global asm
This commit is contained in:
parent
4b56fd9341
commit
b955fa7dd0
@ -1,3 +1,5 @@
|
|||||||
|
use crate::check::intrinsicck::InlineAsmCtxt;
|
||||||
|
|
||||||
use super::coercion::CoerceMany;
|
use super::coercion::CoerceMany;
|
||||||
use super::compare_method::check_type_bounds;
|
use super::compare_method::check_type_bounds;
|
||||||
use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
|
use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
|
||||||
@ -936,11 +938,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
|
|||||||
DefKind::GlobalAsm => {
|
DefKind::GlobalAsm => {
|
||||||
let it = tcx.hir().item(id);
|
let it = tcx.hir().item(id);
|
||||||
let hir::ItemKind::GlobalAsm(asm) = it.kind else { span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) };
|
let hir::ItemKind::GlobalAsm(asm) = it.kind else { span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) };
|
||||||
Inherited::build(tcx, it.def_id).enter(|inh| {
|
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.hir_id());
|
||||||
let fcx = FnCtxt::new(&inh, tcx.param_env(it.def_id), id.hir_id());
|
|
||||||
fcx.check_asm(asm, it.hir_id());
|
|
||||||
fcx.select_all_obligations_or_error();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use crate::check::fn_ctxt::arg_matrix::{
|
|||||||
ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx,
|
ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx,
|
||||||
};
|
};
|
||||||
use crate::check::gather_locals::Declaration;
|
use crate::check::gather_locals::Declaration;
|
||||||
|
use crate::check::intrinsicck::InlineAsmCtxt;
|
||||||
use crate::check::method::MethodCallee;
|
use crate::check::method::MethodCallee;
|
||||||
use crate::check::Expectation::*;
|
use crate::check::Expectation::*;
|
||||||
use crate::check::TupleArgumentsFlag::*;
|
use crate::check::TupleArgumentsFlag::*;
|
||||||
@ -59,7 +60,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
|
debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
|
||||||
for (asm, hir_id) in deferred_asm_checks.drain(..) {
|
for (asm, hir_id) in deferred_asm_checks.drain(..) {
|
||||||
let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
|
let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
|
||||||
self.check_asm(asm, enclosing_id);
|
InlineAsmCtxt::new_in_fn(self).check_asm(asm, enclosing_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ impl<'tcx> InheritedBuilder<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Inherited<'a, 'tcx> {
|
impl<'a, 'tcx> Inherited<'a, 'tcx> {
|
||||||
pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
|
fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
let body_id = tcx.hir().maybe_body_owned_by(item_id);
|
let body_id = tcx.hir().maybe_body_owned_by(item_id);
|
||||||
|
@ -111,6 +111,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InlineAsmCtxt<'a, 'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
fcx: Option<&'a FnCtxt<'a, 'tcx>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
|
pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
|
||||||
|
InlineAsmCtxt { tcx, fcx: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_in_fn(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
|
||||||
|
InlineAsmCtxt { tcx: fcx.tcx, fcx: Some(fcx) }
|
||||||
|
}
|
||||||
|
|
||||||
fn check_asm_operand_type(
|
fn check_asm_operand_type(
|
||||||
&self,
|
&self,
|
||||||
@ -122,9 +137,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
|
tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
|
||||||
target_features: &FxHashSet<Symbol>,
|
target_features: &FxHashSet<Symbol>,
|
||||||
) -> Option<InlineAsmType> {
|
) -> Option<InlineAsmType> {
|
||||||
|
let fcx = self.fcx.unwrap_or_else(|| span_bug!(expr.span, "asm operand for global asm"));
|
||||||
// Check the type against the allowed types for inline asm.
|
// Check the type against the allowed types for inline asm.
|
||||||
let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
|
let ty = fcx.typeck_results.borrow().expr_ty_adjusted(expr);
|
||||||
let ty = self.resolve_vars_if_possible(ty);
|
let ty = fcx.resolve_vars_if_possible(ty);
|
||||||
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
|
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
|
||||||
16 => InlineAsmType::I16,
|
16 => InlineAsmType::I16,
|
||||||
32 => InlineAsmType::I32,
|
32 => InlineAsmType::I32,
|
||||||
@ -134,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Expect types to be fully resolved, no const or type variables.
|
// Expect types to be fully resolved, no const or type variables.
|
||||||
if ty.has_infer_types_or_consts() {
|
if ty.has_infer_types_or_consts() {
|
||||||
assert!(self.is_tainted_by_errors());
|
assert!(fcx.is_tainted_by_errors());
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
|
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
|
||||||
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
|
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
|
||||||
ty::FnPtr(_) => Some(asm_ty_isize),
|
ty::FnPtr(_) => Some(asm_ty_isize),
|
||||||
ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
|
ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if fcx.is_thin_ptr_ty(ty) => {
|
||||||
Some(asm_ty_isize)
|
Some(asm_ty_isize)
|
||||||
}
|
}
|
||||||
ty::Adt(adt, substs) if adt.repr().simd() => {
|
ty::Adt(adt, substs) if adt.repr().simd() => {
|
||||||
@ -203,7 +219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Check that the type implements Copy. The only case where this can
|
// Check that the type implements Copy. The only case where this can
|
||||||
// possibly fail is for SIMD types which don't #[derive(Copy)].
|
// possibly fail is for SIMD types which don't #[derive(Copy)].
|
||||||
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, DUMMY_SP) {
|
if !fcx.infcx.type_is_copy_modulo_regions(fcx.param_env, ty, DUMMY_SP) {
|
||||||
let msg = "arguments for inline assembly must be copyable";
|
let msg = "arguments for inline assembly must be copyable";
|
||||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||||
err.note(&format!("`{ty}` does not implement the Copy trait"));
|
err.note(&format!("`{ty}` does not implement the Copy trait"));
|
||||||
@ -224,8 +240,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let msg = "incompatible types for asm inout argument";
|
let msg = "incompatible types for asm inout argument";
|
||||||
let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
|
let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
|
||||||
|
|
||||||
let in_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(in_expr);
|
let in_expr_ty = fcx.typeck_results.borrow().expr_ty_adjusted(in_expr);
|
||||||
let in_expr_ty = self.resolve_vars_if_possible(in_expr_ty);
|
let in_expr_ty = fcx.resolve_vars_if_possible(in_expr_ty);
|
||||||
err.span_label(in_expr.span, &format!("type `{in_expr_ty}`"));
|
err.span_label(in_expr.span, &format!("type `{in_expr_ty}`"));
|
||||||
err.span_label(expr.span, &format!("type `{ty}`"));
|
err.span_label(expr.span, &format!("type `{ty}`"));
|
||||||
err.note(
|
err.note(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user