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

Migrate rustc_ty_utils to SessionDiagnostic #100735

Merged
merged 1 commit into from
Aug 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4601,6 +4601,7 @@ dependencies = [
"rustc_hir",
"rustc_index",
"rustc_infer",
"rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
Expand Down
47 changes: 47 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/ty_utils.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop

ty_utils_generic_constant_too_complex = overly complex generic constant
.help = consider moving this anonymous constant into a `const` function
.maybe_supported = this operation may be supported in the future

ty_utils_borrow_not_supported = borrowing is not supported in generic constants

ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants

ty_utils_array_not_supported = array construction is not supported in generic constants

ty_utils_block_not_supported = blocks are not supported in generic constant

ty_utils_never_to_any_not_supported = converting nevers to any is not supported in generic constant

ty_utils_tuple_not_supported = tuple construction is not supported in generic constants

ty_utils_index_not_supported = indexing is not supported in generic constant

ty_utils_field_not_supported = field access is not supported in generic constant

ty_utils_const_block_not_supported = const blocks are not supported in generic constant

ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants

ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants

ty_utils_yield_not_supported = generator control flow is not allowed in generic constants

ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants

ty_utils_box_not_supported = allocations are not allowed in generic constants

ty_utils_binary_not_supported = unsupported binary operation in generic constants

ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow

ty_utils_assign_not_supported = assignment is not supported in generic constants

ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants

ty_utils_control_flow_not_supported = control flow is not supported in generic constants

ty_utils_inline_asm_not_supported = assembly is not supported in generic constants

ty_utils_operation_not_supported = unsupported operation in generic constant
1 change: 1 addition & 0 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fluent_messages! {
plugin_impl => "../locales/en-US/plugin_impl.ftl",
privacy => "../locales/en-US/privacy.ftl",
save_analysis => "../locales/en-US/save_analysis.ftl",
ty_utils => "../locales/en-US/ty_utils.ftl",
typeck => "../locales/en-US/typeck.ftl",
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ty_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
rustc_infer = { path = "../rustc_infer" }
rustc_macros = { path = "../rustc_macros" }
rustc_span = { path = "../rustc_span" }
rustc_session = { path = "../rustc_session" }
rustc_target = { path = "../rustc_target" }
Expand Down
173 changes: 83 additions & 90 deletions compiler/rustc_ty_utils/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use rustc_target::abi::VariantIdx;

use std::iter;

use crate::errors::{GenericConstantTooComplex, GenericConstantTooComplexSub};

/// Destructures array, ADT or tuple constants into the constants
/// of their fields.
pub(crate) fn destructure_const<'tcx>(
Expand Down Expand Up @@ -93,26 +95,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
self.body.exprs[self.body_id].span
}

fn error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> {
let reported = self
.tcx
.sess
.struct_span_err(self.root_span(), "overly complex generic constant")
.span_label(span, msg)
.help("consider moving this anonymous constant into a `const` function")
.emit();
fn error(&mut self, sub: GenericConstantTooComplexSub) -> Result<!, ErrorGuaranteed> {
let reported = self.tcx.sess.emit_err(GenericConstantTooComplex {
span: self.root_span(),
maybe_supported: None,
sub,
});

Err(reported)
}
fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> {
let reported = self
.tcx
.sess
.struct_span_err(self.root_span(), "overly complex generic constant")
.span_label(span, msg)
.help("consider moving this anonymous constant into a `const` function")
.note("this operation may be supported in the future")
.emit();

fn maybe_supported_error(
&mut self,
sub: GenericConstantTooComplexSub,
) -> Result<!, ErrorGuaranteed> {
let reported = self.tcx.sess.emit_err(GenericConstantTooComplex {
span: self.root_span(),
maybe_supported: Some(()),
sub,
});

Err(reported)
}
Expand Down Expand Up @@ -243,22 +244,23 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
&ExprKind::Scope { value, .. } => self.recurse_build(value)?,
&ExprKind::PlaceTypeAscription { source, .. }
| &ExprKind::ValueTypeAscription { source, .. } => self.recurse_build(source)?,
&ExprKind::Literal { lit, neg} => {
&ExprKind::Literal { lit, neg } => {
let sp = node.span;
let constant =
match self.tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) {
Ok(c) => c,
Err(LitToConstError::Reported) => {
self.tcx.const_error(node.ty)
}
Err(LitToConstError::TypeError) => {
bug!("encountered type error in lit_to_const")
}
};
let constant = match self.tcx.at(sp).lit_to_const(LitToConstInput {
lit: &lit.node,
ty: node.ty,
neg,
}) {
Ok(c) => c,
Err(LitToConstError::Reported) => self.tcx.const_error(node.ty),
Err(LitToConstError::TypeError) => {
bug!("encountered type error in lit_to_const")
}
};

self.nodes.push(Node::Leaf(constant))
}
&ExprKind::NonHirLiteral { lit , user_ty: _} => {
&ExprKind::NonHirLiteral { lit, user_ty: _ } => {
let val = ty::ValTree::from_scalar_int(lit);
self.nodes.push(Node::Leaf(ty::Const::from_value(self.tcx, val, node.ty)))
}
Expand All @@ -269,19 +271,17 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
&ExprKind::NamedConst { def_id, substs, user_ty: _ } => {
let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);

let constant = self.tcx.mk_const(ty::ConstS {
kind: ty::ConstKind::Unevaluated(uneval),
ty: node.ty,
});
let constant = self
.tcx
.mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty: node.ty });

self.nodes.push(Node::Leaf(constant))
}

ExprKind::ConstParam {param, ..} => {
let const_param = self.tcx.mk_const(ty::ConstS {
kind: ty::ConstKind::Param(*param),
ty: node.ty,
});
ExprKind::ConstParam { param, .. } => {
let const_param = self
.tcx
.mk_const(ty::ConstS { kind: ty::ConstKind::Param(*param), ty: node.ty });
self.nodes.push(Node::Leaf(const_param))
}

Expand Down Expand Up @@ -312,13 +312,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
// }
// ```
ExprKind::Block { block } => {
if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block] {
if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block]
{
self.recurse_build(*e)?
} else {
self.maybe_supported_error(
self.maybe_supported_error(GenericConstantTooComplexSub::BlockNotSupported(
node.span,
"blocks are not supported in generic constant",
)?
))?
}
}
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
Expand All @@ -332,7 +332,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
let arg = self.recurse_build(source)?;
self.nodes.push(Node::Cast(CastKind::As, arg, node.ty))
}
ExprKind::Borrow{ arg, ..} => {
ExprKind::Borrow { arg, .. } => {
let arg_node = &self.body.exprs[*arg];

// Skip reborrows for now until we allow Deref/Borrow/AddressOf
Expand All @@ -341,84 +341,77 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
if let ExprKind::Deref { arg } = arg_node.kind {
self.recurse_build(arg)?
} else {
self.maybe_supported_error(
self.maybe_supported_error(GenericConstantTooComplexSub::BorrowNotSupported(
node.span,
"borrowing is not supported in generic constants",
)?
))?
}
}
// FIXME(generic_const_exprs): We may want to support these.
ExprKind::AddressOf { .. } | ExprKind::Deref {..}=> self.maybe_supported_error(
node.span,
"dereferencing or taking the address is not supported in generic constants",
ExprKind::AddressOf { .. } | ExprKind::Deref { .. } => self.maybe_supported_error(
GenericConstantTooComplexSub::AddressAndDerefNotSupported(node.span),
)?,
ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error(
node.span,
"array construction is not supported in generic constants",
ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error(
GenericConstantTooComplexSub::ArrayNotSupported(node.span),
)?,
ExprKind::NeverToAny { .. } => self.maybe_supported_error(
node.span,
"converting nevers to any is not supported in generic constant",
GenericConstantTooComplexSub::NeverToAnyNotSupported(node.span),
)?,
ExprKind::Tuple { .. } => self.maybe_supported_error(
node.span,
"tuple construction is not supported in generic constants",
GenericConstantTooComplexSub::TupleNotSupported(node.span),
)?,
ExprKind::Index { .. } => self.maybe_supported_error(
node.span,
"indexing is not supported in generic constant",
GenericConstantTooComplexSub::IndexNotSupported(node.span),
)?,
ExprKind::Field { .. } => self.maybe_supported_error(
node.span,
"field access is not supported in generic constant",
GenericConstantTooComplexSub::FieldNotSupported(node.span),
)?,
ExprKind::ConstBlock { .. } => self.maybe_supported_error(
node.span,
"const blocks are not supported in generic constant",
)?,
ExprKind::Adt(_) => self.maybe_supported_error(
node.span,
"struct/enum construction is not supported in generic constants",
GenericConstantTooComplexSub::ConstBlockNotSupported(node.span),
)?,
ExprKind::Adt(_) => self
.maybe_supported_error(GenericConstantTooComplexSub::AdtNotSupported(node.span))?,
// dont know if this is correct
ExprKind::Pointer { .. } =>
self.error(node.span, "pointer casts are not allowed in generic constants")?,
ExprKind::Yield { .. } =>
self.error(node.span, "generator control flow is not allowed in generic constants")?,
ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => self
.error(
node.span,
"loops and loop control flow are not supported in generic constants",
)?,
ExprKind::Box { .. } =>
self.error(node.span, "allocations are not allowed in generic constants")?,
ExprKind::Pointer { .. } => {
self.error(GenericConstantTooComplexSub::PointerNotSupported(node.span))?
}
ExprKind::Yield { .. } => {
self.error(GenericConstantTooComplexSub::YieldNotSupported(node.span))?
}
ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => {
self.error(GenericConstantTooComplexSub::LoopNotSupported(node.span))?
}
ExprKind::Box { .. } => {
self.error(GenericConstantTooComplexSub::BoxNotSupported(node.span))?
}

ExprKind::Unary { .. } => unreachable!(),
// we handle valid unary/binary ops above
ExprKind::Binary { .. } =>
self.error(node.span, "unsupported binary operation in generic constants")?,
ExprKind::LogicalOp { .. } =>
self.error(node.span, "unsupported operation in generic constants, short-circuiting operations would imply control flow")?,
ExprKind::Binary { .. } => {
self.error(GenericConstantTooComplexSub::BinaryNotSupported(node.span))?
}
ExprKind::LogicalOp { .. } => {
self.error(GenericConstantTooComplexSub::LogicalOpNotSupported(node.span))?
}
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
self.error(node.span, "assignment is not supported in generic constants")?
self.error(GenericConstantTooComplexSub::AssignNotSupported(node.span))?
}
ExprKind::Closure { .. } | ExprKind::Return { .. } => {
self.error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))?
}
ExprKind::Closure { .. } | ExprKind::Return { .. } => self.error(
node.span,
"closures and function keywords are not supported in generic constants",
)?,
// let expressions imply control flow
ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } =>
self.error(node.span, "control flow is not supported in generic constants")?,
ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => {
self.error(GenericConstantTooComplexSub::ControlFlowNotSupported(node.span))?
}
ExprKind::InlineAsm { .. } => {
self.error(node.span, "assembly is not supported in generic constants")?
self.error(GenericConstantTooComplexSub::InlineAsmNotSupported(node.span))?
}

// we dont permit let stmts so `VarRef` and `UpvarRef` cant happen
ExprKind::VarRef { .. }
| ExprKind::UpvarRef { .. }
| ExprKind::StaticRef { .. }
| ExprKind::ThreadLocalRef(_) => {
self.error(node.span, "unsupported operation in generic constant")?
self.error(GenericConstantTooComplexSub::OperationNotSupported(node.span))?
}
})
}
Expand Down
Loading