Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #118044

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d6337e6
Add Seek::seek_relative
fintelia Oct 14, 2023
bc058b6
Add tracking issue
fintelia Oct 30, 2023
d9f7c9d
Improve documentation
fintelia Nov 4, 2023
3fdd84a
Allow trailing commas in static suggestions
Zalathar Nov 16, 2023
925111c
Support multiple globs in static suggestions
Zalathar Nov 16, 2023
0532216
Add test suggestions for `mir-opt` and `coverage`
Zalathar Nov 16, 2023
dfa7539
Suggest field typo through derefs
estebank Oct 24, 2023
8bd8f3b
Suggest `unwrap()` on field not found for `Result`/`Option`
estebank Oct 24, 2023
4f7dddd
recover primary span label
estebank Nov 9, 2023
6a2d9b4
address review comment
estebank Nov 15, 2023
1ee37bf
let-chain fmt
estebank Nov 16, 2023
19848d5
Fix links for std::process::Child{Stdin, Stdout, Stderr}
Lireer Nov 17, 2023
b408efe
Remove mir::Const::from_anon_const
compiler-errors Oct 5, 2023
4c0a9ef
make sure we still eagerly emit errors
compiler-errors Oct 5, 2023
6de5ea5
Review comment
compiler-errors Nov 17, 2023
289ce57
tweak logic of "unknown field" label
estebank Nov 18, 2023
c653bb9
jsondocck: bump jsonpath to 0.3, dropping few dup dependencies
klensy Nov 18, 2023
f21f28c
Rollup merge of #116446 - compiler-errors:yeet-mir-from_anon_const, r…
TaKO8Ki Nov 18, 2023
ad71725
Rollup merge of #116750 - fintelia:seek_seek_relative, r=Mark-Simulacrum
TaKO8Ki Nov 18, 2023
b7bc073
Rollup merge of #117110 - estebank:deref-field-suggestion, r=b-naber
TaKO8Ki Nov 18, 2023
1a02061
Rollup merge of #117961 - Zalathar:suggest, r=Mark-Simulacrum
TaKO8Ki Nov 18, 2023
eb89441
Rollup merge of #118020 - Lireer:patch-1, r=Mark-Simulacrum
TaKO8Ki Nov 18, 2023
d323f1e
Rollup merge of #118034 - klensy:dep-up-18-11-23, r=Mark-Simulacrum
TaKO8Ki Nov 18, 2023
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
113 changes: 14 additions & 99 deletions compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use std::fmt::{self, Debug, Display, Formatter};

use rustc_hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir};
use rustc_hir::def_id::DefId;
use rustc_session::RemapFileNameExt;
use rustc_span::Span;
use rustc_target::abi::{HasDataLayout, Size};

use crate::mir::interpret::{alloc_range, AllocId, ConstAllocation, ErrorHandled, Scalar};
use crate::mir::{pretty_print_const_value, Promoted};
use crate::ty::GenericArgsRef;
use crate::ty::ScalarInt;
use crate::ty::{self, print::pretty_print_const, List, Ty, TyCtxt};
use crate::ty::{GenericArgs, GenericArgsRef};
use crate::ty::{self, print::pretty_print_const, Ty, TyCtxt};

///////////////////////////////////////////////////////////////////////////
/// Evaluated Constants
Expand Down Expand Up @@ -220,6 +219,17 @@ pub enum Const<'tcx> {
}

impl<'tcx> Const<'tcx> {
pub fn identity_unevaluated(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::EarlyBinder<Const<'tcx>> {
ty::EarlyBinder::bind(Const::Unevaluated(
UnevaluatedConst {
def: def_id,
args: ty::GenericArgs::identity_for_item(tcx, def_id),
promoted: None,
},
tcx.type_of(def_id).skip_binder(),
))
}

#[inline(always)]
pub fn ty(&self) -> Ty<'tcx> {
match self {
Expand Down Expand Up @@ -399,101 +409,6 @@ impl<'tcx> Const<'tcx> {
Self::Val(val, ty)
}

/// Literals are converted to `Const::Val`, const generic parameters are eagerly
/// converted to a constant, everything else becomes `Unevaluated`.
#[instrument(skip(tcx), level = "debug", ret)]
pub fn from_anon_const(
tcx: TyCtxt<'tcx>,
def: LocalDefId,
param_env: ty::ParamEnv<'tcx>,
) -> Self {
let body_id = match tcx.hir().get_by_def_id(def) {
hir::Node::AnonConst(ac) => ac.body,
_ => {
span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants")
}
};

let expr = &tcx.hir().body(body_id).value;
debug!(?expr);

// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = match &expr.kind {
hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
block.expr.as_ref().unwrap()
}
_ => expr,
};
debug!("expr.kind: {:?}", expr.kind);

let ty = tcx.type_of(def).instantiate_identity();
debug!(?ty);

// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
// does not provide the parents generics to anonymous constants. We still allow generic const
// parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
// ever try to substitute the generic parameters in their bodies.
//
// While this doesn't happen as these constants are always used as `ty::ConstKind::Param`, it does
// cause issues if we were to remove that special-case and try to evaluate the constant instead.
use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
match expr.kind {
ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
// Find the name and index of the const parameter by indexing the generics of
// the parent item and construct a `ParamConst`.
let item_def_id = tcx.parent(def_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.item_name(def_id);
let ty_const = ty::Const::new_param(tcx, ty::ParamConst::new(index, name), ty);
debug!(?ty_const);

return Self::Ty(ty_const);
}
_ => {}
}

let hir_id = tcx.hir().local_def_id_to_hir_id(def);
let parent_args = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id)
&& let Some(parent_did) = parent_hir_id.as_owner()
{
GenericArgs::identity_for_item(tcx, parent_did)
} else {
List::empty()
};
debug!(?parent_args);

let did = def.to_def_id();
let child_args = GenericArgs::identity_for_item(tcx, did);
let args = tcx.mk_args_from_iter(parent_args.into_iter().chain(child_args.into_iter()));
debug!(?args);

let span = tcx.def_span(def);
let uneval = UnevaluatedConst::new(did, args);
debug!(?span, ?param_env);

match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
Ok(val) => {
debug!("evaluated const value");
Self::Val(val, ty)
}
Err(_) => {
debug!("error encountered during evaluation");
// Error was handled in `const_eval_resolve`. Here we just create a
// new unevaluated const and error hard later in codegen
Self::Unevaluated(
UnevaluatedConst {
def: did,
args: GenericArgs::identity_for_item(tcx, did),
promoted: None,
},
ty,
)
}
}
}

pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
match c.kind() {
ty::ConstKind::Value(valtree) => {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ impl<'tcx> Const<'tcx> {
}
}

// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
// does not provide the parents generics to anonymous constants. We still allow generic const
// parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
// ever try to substitute the generic parameters in their bodies.
match expr.kind {
hir::ExprKind::Path(hir::QPath::Resolved(
_,
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,15 +645,23 @@ impl<'tcx> Cx<'tcx> {
out_expr: out_expr.map(|expr| self.mirror_expr(expr)),
},
hir::InlineAsmOperand::Const { ref anon_const } => {
let value =
mir::Const::from_anon_const(tcx, anon_const.def_id, self.param_env);
let value = mir::Const::identity_unevaluated(
tcx,
anon_const.def_id.to_def_id(),
)
.instantiate_identity()
.normalize(tcx, self.param_env);
let span = tcx.def_span(anon_const.def_id);

InlineAsmOperand::Const { value, span }
}
hir::InlineAsmOperand::SymFn { ref anon_const } => {
let value =
mir::Const::from_anon_const(tcx, anon_const.def_id, self.param_env);
let value = mir::Const::identity_unevaluated(
tcx,
anon_const.def_id.to_def_id(),
)
.instantiate_identity()
.normalize(tcx, self.param_env);
let span = tcx.def_span(anon_const.def_id);

InlineAsmOperand::SymFn { value, span }
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/asm/const-error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(asm_const)]

// Test to make sure that we emit const errors eagerly for inline asm

use std::arch::asm;

fn test<T>() {
unsafe { asm!("/* {} */", const 1 / 0); }
//~^ ERROR evaluation of
}

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/asm/const-error.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0080]: evaluation of `test::<T>::{constant#0}` failed
--> $DIR/const-error.rs:8:37
|
LL | unsafe { asm!("/* {} */", const 1 / 0); }
| ^^^^^ attempt to divide `1_i32` by zero

error: aborting due to previous error

For more information about this error, try `rustc --explain E0080`.