mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-11 06:24:24 +00:00
Auto merge of #125976 - compiler-errors:rollup-xt3le7w, r=compiler-errors
Rollup of 8 pull requests Successful merges: - #125667 (Silence follow-up errors directly based on error types and regions) - #125717 (Refactor `#[diagnostic::do_not_recommend]` support) - #125795 (Improve renaming suggestion for names with leading underscores) - #125865 (Fix ICE caused by ignoring EffectVars in type inference) - #125953 (Streamline `nested` calls.) - #125959 (Reduce `pub` exposure in `rustc_mir_build`) - #125967 (Split smir `Const` into `TyConst` and `MirConst`) - #125968 (Store the types of `ty::Expr` arguments in the `ty::Expr`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
30ea1a2693
@ -125,8 +125,8 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
placeholder_indices,
|
||||
placeholder_index_to_region: _,
|
||||
liveness_constraints,
|
||||
outlives_constraints,
|
||||
member_constraints,
|
||||
mut outlives_constraints,
|
||||
mut member_constraints,
|
||||
universe_causes,
|
||||
type_tests,
|
||||
} = constraints;
|
||||
@ -144,6 +144,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
&universal_region_relations,
|
||||
);
|
||||
|
||||
if let Some(guar) = universal_regions.tainted_by_errors() {
|
||||
// Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
|
||||
// outlives bounds that we may end up checking.
|
||||
outlives_constraints = Default::default();
|
||||
member_constraints = Default::default();
|
||||
|
||||
// Also taint the entire scope.
|
||||
infcx.set_tainted_by_errors(guar);
|
||||
}
|
||||
|
||||
let mut regioncx = RegionInferenceContext::new(
|
||||
infcx,
|
||||
var_origins,
|
||||
|
@ -29,7 +29,8 @@ use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, T
|
||||
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::{ErrorGuaranteed, Symbol};
|
||||
use std::cell::Cell;
|
||||
use std::iter;
|
||||
|
||||
use crate::renumber::RegionCtxt;
|
||||
@ -186,6 +187,10 @@ struct UniversalRegionIndices<'tcx> {
|
||||
|
||||
/// The vid assigned to `'static`. Used only for diagnostics.
|
||||
pub fr_static: RegionVid,
|
||||
|
||||
/// Whether we've encountered an error region. If we have, cancel all
|
||||
/// outlives errors, as they are likely bogus.
|
||||
pub tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -408,6 +413,10 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
self.indices.tainted_by_errors.get()
|
||||
}
|
||||
}
|
||||
|
||||
struct UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
@ -663,7 +672,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
|
||||
let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
|
||||
|
||||
UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
|
||||
UniversalRegionIndices {
|
||||
indices: global_mapping.chain(arg_mapping).collect(),
|
||||
fr_static,
|
||||
tainted_by_errors: Cell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_inputs_and_output(
|
||||
@ -868,7 +881,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
||||
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
||||
if let ty::ReVar(..) = *r {
|
||||
r.as_var()
|
||||
} else if r.is_error() {
|
||||
} else if let ty::ReError(guar) = *r {
|
||||
self.tainted_by_errors.set(Some(guar));
|
||||
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
|
||||
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
|
||||
// errors are being emitted and 2) it leaves the happy path unaffected.
|
||||
|
@ -3,7 +3,6 @@
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust as pprust_ast;
|
||||
use rustc_errors::FatalError;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir_pretty as pprust_hir;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
|
||||
@ -70,11 +69,7 @@ struct HirIdentifiedAnn<'tcx> {
|
||||
|
||||
impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> {
|
||||
fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) {
|
||||
pprust_hir::PpAnn::nested(
|
||||
&(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>),
|
||||
state,
|
||||
nested,
|
||||
)
|
||||
self.tcx.nested(state, nested)
|
||||
}
|
||||
|
||||
fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
|
||||
@ -152,8 +147,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> {
|
||||
if let pprust_hir::Nested::Body(id) = nested {
|
||||
self.maybe_typeck_results.set(Some(self.tcx.typeck_body(id)));
|
||||
}
|
||||
let pp_ann = &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>);
|
||||
pprust_hir::PpAnn::nested(pp_ann, state, nested);
|
||||
self.tcx.nested(state, nested);
|
||||
self.maybe_typeck_results.set(old_maybe_typeck_results);
|
||||
}
|
||||
|
||||
|
@ -502,7 +502,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
||||
bug!("unexpected sort of node in type_of(): {:?}", x);
|
||||
}
|
||||
};
|
||||
if let Err(e) = icx.check_tainted_by_errors() {
|
||||
if let Err(e) = icx.check_tainted_by_errors()
|
||||
&& !output.references_error()
|
||||
{
|
||||
ty::EarlyBinder::bind(Ty::new_error(tcx, e))
|
||||
} else {
|
||||
ty::EarlyBinder::bind(output)
|
||||
|
@ -587,6 +587,7 @@ pub enum FixupError {
|
||||
UnresolvedFloatTy(FloatVid),
|
||||
UnresolvedTy(TyVid),
|
||||
UnresolvedConst(ConstVid),
|
||||
UnresolvedEffect(EffectVid),
|
||||
}
|
||||
|
||||
/// See the `region_obligations` field for more information.
|
||||
@ -614,6 +615,7 @@ impl fmt::Display for FixupError {
|
||||
),
|
||||
UnresolvedTy(_) => write!(f, "unconstrained type"),
|
||||
UnresolvedConst(_) => write!(f, "unconstrained const value"),
|
||||
UnresolvedEffect(_) => write!(f, "unconstrained effect value"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,9 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
|
||||
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
|
||||
bug!("Unexpected const in full const resolver: {:?}", c);
|
||||
}
|
||||
ty::ConstKind::Infer(InferConst::EffectVar(evid)) => {
|
||||
return Err(FixupError::UnresolvedEffect(evid));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
c.try_super_fold_with(self)
|
||||
|
@ -24,7 +24,7 @@ pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
|
||||
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
|
||||
rustc_data_structures::static_assert_size!(ConstKind<'_>, 24);
|
||||
|
||||
/// Use this rather than `ConstData`, whenever possible.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
|
||||
@ -58,7 +58,7 @@ pub struct ConstData<'tcx> {
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(ConstData<'_>, 40);
|
||||
rustc_data_structures::static_assert_size!(ConstData<'_>, 32);
|
||||
|
||||
impl<'tcx> Const<'tcx> {
|
||||
#[inline]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::Const;
|
||||
use crate::mir;
|
||||
use crate::ty::abstract_const::CastKind;
|
||||
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
|
||||
use crate::ty::{self, visit::TypeVisitableExt as _, Ty, TyCtxt};
|
||||
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
||||
|
||||
#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)]
|
||||
@ -40,14 +40,125 @@ impl<'tcx> ty::UnevaluatedConst<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
||||
pub enum ExprKind {
|
||||
Binop(mir::BinOp),
|
||||
UnOp(mir::UnOp),
|
||||
FunctionCall,
|
||||
Cast(CastKind),
|
||||
}
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
||||
pub enum Expr<'tcx> {
|
||||
Binop(mir::BinOp, Const<'tcx>, Const<'tcx>),
|
||||
UnOp(mir::UnOp, Const<'tcx>),
|
||||
FunctionCall(Const<'tcx>, &'tcx List<Const<'tcx>>),
|
||||
Cast(CastKind, Const<'tcx>, Ty<'tcx>),
|
||||
pub struct Expr<'tcx> {
|
||||
pub kind: ExprKind,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
}
|
||||
impl<'tcx> Expr<'tcx> {
|
||||
pub fn new_binop(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
binop: mir::BinOp,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
rhs_ty: Ty<'tcx>,
|
||||
lhs_ct: Const<'tcx>,
|
||||
rhs_ct: Const<'tcx>,
|
||||
) -> Self {
|
||||
let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
|
||||
[lhs_ty.into(), rhs_ty.into(), lhs_ct.into(), rhs_ct.into()].into_iter(),
|
||||
);
|
||||
|
||||
Self { kind: ExprKind::Binop(binop), args }
|
||||
}
|
||||
|
||||
pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) {
|
||||
assert!(matches!(self.kind, ExprKind::Binop(_)));
|
||||
|
||||
match self.args().as_slice() {
|
||||
[lhs_ty, rhs_ty, lhs_ct, rhs_ct] => (
|
||||
lhs_ty.expect_ty(),
|
||||
rhs_ty.expect_ty(),
|
||||
lhs_ct.expect_const(),
|
||||
rhs_ct.expect_const(),
|
||||
),
|
||||
_ => bug!("Invalid args for `Binop` expr {self:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_unop(tcx: TyCtxt<'tcx>, unop: mir::UnOp, ty: Ty<'tcx>, ct: Const<'tcx>) -> Self {
|
||||
let args =
|
||||
tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>([ty.into(), ct.into()].into_iter());
|
||||
|
||||
Self { kind: ExprKind::UnOp(unop), args }
|
||||
}
|
||||
|
||||
pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) {
|
||||
assert!(matches!(self.kind, ExprKind::UnOp(_)));
|
||||
|
||||
match self.args().as_slice() {
|
||||
[ty, ct] => (ty.expect_ty(), ct.expect_const()),
|
||||
_ => bug!("Invalid args for `UnOp` expr {self:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_call(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
func_ty: Ty<'tcx>,
|
||||
func_expr: Const<'tcx>,
|
||||
arguments: impl Iterator<Item = Const<'tcx>>,
|
||||
) -> Self {
|
||||
let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
|
||||
[func_ty.into(), func_expr.into()].into_iter().chain(arguments.map(|ct| ct.into())),
|
||||
);
|
||||
|
||||
Self { kind: ExprKind::FunctionCall, args }
|
||||
}
|
||||
|
||||
pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) {
|
||||
assert!(matches!(self.kind, ExprKind::FunctionCall));
|
||||
|
||||
match self.args().as_slice() {
|
||||
[func_ty, func, rest @ ..] => (
|
||||
func_ty.expect_ty(),
|
||||
func.expect_const(),
|
||||
rest.iter().map(|arg| arg.expect_const()),
|
||||
),
|
||||
_ => bug!("Invalid args for `Call` expr {self:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_cast(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cast: CastKind,
|
||||
value_ty: Ty<'tcx>,
|
||||
value: Const<'tcx>,
|
||||
to_ty: Ty<'tcx>,
|
||||
) -> Self {
|
||||
let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
|
||||
[value_ty.into(), value.into(), to_ty.into()].into_iter(),
|
||||
);
|
||||
|
||||
Self { kind: ExprKind::Cast(cast), args }
|
||||
}
|
||||
|
||||
pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) {
|
||||
assert!(matches!(self.kind, ExprKind::Cast(_)));
|
||||
|
||||
match self.args().as_slice() {
|
||||
[value_ty, value, to_ty] => {
|
||||
(value_ty.expect_ty(), value.expect_const(), to_ty.expect_ty())
|
||||
}
|
||||
_ => bug!("Invalid args for `Cast` expr {self:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(kind: ExprKind, args: ty::GenericArgsRef<'tcx>) -> Self {
|
||||
Self { kind, args }
|
||||
}
|
||||
|
||||
pub fn args(&self) -> ty::GenericArgsRef<'tcx> {
|
||||
self.args
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(Expr<'_>, 24);
|
||||
rustc_data_structures::static_assert_size!(Expr<'_>, 16);
|
||||
|
@ -374,26 +374,7 @@ impl FlagComputation {
|
||||
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
|
||||
}
|
||||
ty::ConstKind::Value(_) => {}
|
||||
ty::ConstKind::Expr(e) => {
|
||||
use ty::Expr;
|
||||
match e {
|
||||
Expr::Binop(_, l, r) => {
|
||||
self.add_const(l);
|
||||
self.add_const(r);
|
||||
}
|
||||
Expr::UnOp(_, v) => self.add_const(v),
|
||||
Expr::FunctionCall(f, args) => {
|
||||
self.add_const(f);
|
||||
for arg in args {
|
||||
self.add_const(arg);
|
||||
}
|
||||
}
|
||||
Expr::Cast(_, c, t) => {
|
||||
self.add_ty(t);
|
||||
self.add_const(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ConstKind::Expr(e) => self.add_args(e.args()),
|
||||
ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ pub use self::closure::{
|
||||
CAPTURE_STRUCT_LOCAL,
|
||||
};
|
||||
pub use self::consts::{
|
||||
Const, ConstData, ConstInt, ConstKind, Expr, ScalarInt, UnevaluatedConst, ValTree,
|
||||
Const, ConstData, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree,
|
||||
};
|
||||
pub use self::context::{
|
||||
tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift,
|
||||
|
@ -1533,8 +1533,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
print_ty: bool,
|
||||
) -> Result<(), PrintError> {
|
||||
define_scoped_cx!(self);
|
||||
match expr {
|
||||
Expr::Binop(op, c1, c2) => {
|
||||
match expr.kind {
|
||||
ty::ExprKind::Binop(op) => {
|
||||
let (_, _, c1, c2) = expr.binop_args();
|
||||
|
||||
let precedence = |binop: rustc_middle::mir::BinOp| {
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence()
|
||||
@ -1543,22 +1545,26 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
let formatted_op = op.to_hir_binop().as_str();
|
||||
let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) {
|
||||
(
|
||||
ty::ConstKind::Expr(Expr::Binop(lhs_op, _, _)),
|
||||
ty::ConstKind::Expr(Expr::Binop(rhs_op, _, _)),
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }),
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }),
|
||||
) => (precedence(lhs_op) < op_precedence, precedence(rhs_op) < op_precedence),
|
||||
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), ty::ConstKind::Expr(_)) => {
|
||||
(precedence(lhs_op) < op_precedence, true)
|
||||
}
|
||||
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
|
||||
(true, precedence(rhs_op) < op_precedence)
|
||||
}
|
||||
(
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }),
|
||||
ty::ConstKind::Expr(_),
|
||||
) => (precedence(lhs_op) < op_precedence, true),
|
||||
(
|
||||
ty::ConstKind::Expr(_),
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }),
|
||||
) => (true, precedence(rhs_op) < op_precedence),
|
||||
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(_)) => (true, true),
|
||||
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), _) => {
|
||||
(precedence(lhs_op) < op_precedence, false)
|
||||
}
|
||||
(_, ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
|
||||
(false, precedence(rhs_op) < op_precedence)
|
||||
}
|
||||
(
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }),
|
||||
_,
|
||||
) => (precedence(lhs_op) < op_precedence, false),
|
||||
(
|
||||
_,
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }),
|
||||
) => (false, precedence(rhs_op) < op_precedence),
|
||||
(ty::ConstKind::Expr(_), _) => (true, false),
|
||||
(_, ty::ConstKind::Expr(_)) => (false, true),
|
||||
_ => (false, false),
|
||||
@ -1574,7 +1580,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
rhs_parenthesized,
|
||||
)?;
|
||||
}
|
||||
Expr::UnOp(op, ct) => {
|
||||
ty::ExprKind::UnOp(op) => {
|
||||
let (_, ct) = expr.unop_args();
|
||||
|
||||
use rustc_middle::mir::UnOp;
|
||||
let formatted_op = match op {
|
||||
UnOp::Not => "!",
|
||||
@ -1583,7 +1591,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
};
|
||||
let parenthesized = match ct.kind() {
|
||||
_ if op == UnOp::PtrMetadata => true,
|
||||
ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op,
|
||||
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::UnOp(c_op), .. }) => {
|
||||
c_op != op
|
||||
}
|
||||
ty::ConstKind::Expr(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
@ -1593,61 +1603,37 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
parenthesized,
|
||||
)?
|
||||
}
|
||||
Expr::FunctionCall(fn_def, fn_args) => {
|
||||
use ty::TyKind;
|
||||
match fn_def.ty().kind() {
|
||||
TyKind::FnDef(def_id, gen_args) => {
|
||||
p!(print_value_path(*def_id, gen_args), "(");
|
||||
if print_ty {
|
||||
let tcx = self.tcx();
|
||||
let sig = tcx.fn_sig(def_id).instantiate(tcx, gen_args).skip_binder();
|
||||
ty::ExprKind::FunctionCall => {
|
||||
let (_, fn_def, fn_args) = expr.call_args();
|
||||
|
||||
let mut args_with_ty = fn_args.iter().map(|ct| (ct, ct.ty()));
|
||||
let output_ty = sig.output();
|
||||
|
||||
if let Some((ct, ty)) = args_with_ty.next() {
|
||||
self.typed_value(
|
||||
|this| this.pretty_print_const(ct, print_ty),
|
||||
|this| this.pretty_print_type(ty),
|
||||
": ",
|
||||
)?;
|
||||
for (ct, ty) in args_with_ty {
|
||||
p!(", ");
|
||||
self.typed_value(
|
||||
|this| this.pretty_print_const(ct, print_ty),
|
||||
|this| this.pretty_print_type(ty),
|
||||
": ",
|
||||
)?;
|
||||
}
|
||||
}
|
||||
p!(write(") -> {output_ty}"));
|
||||
} else {
|
||||
p!(comma_sep(fn_args.iter()), ")");
|
||||
}
|
||||
}
|
||||
_ => bug!("unexpected type of fn def"),
|
||||
}
|
||||
write!(self, "(")?;
|
||||
self.pretty_print_const(fn_def, print_ty)?;
|
||||
p!(")(", comma_sep(fn_args), ")");
|
||||
}
|
||||
Expr::Cast(kind, ct, ty) => {
|
||||
ty::ExprKind::Cast(kind) => {
|
||||
let (_, value, to_ty) = expr.cast_args();
|
||||
|
||||
use ty::abstract_const::CastKind;
|
||||
if kind == CastKind::As || (kind == CastKind::Use && self.should_print_verbose()) {
|
||||
let parenthesized = match ct.kind() {
|
||||
ty::ConstKind::Expr(Expr::Cast(_, _, _)) => false,
|
||||
let parenthesized = match value.kind() {
|
||||
ty::ConstKind::Expr(ty::Expr {
|
||||
kind: ty::ExprKind::Cast { .. }, ..
|
||||
}) => false,
|
||||
ty::ConstKind::Expr(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
self.maybe_parenthesized(
|
||||
|this| {
|
||||
this.typed_value(
|
||||
|this| this.pretty_print_const(ct, print_ty),
|
||||
|this| this.pretty_print_type(ty),
|
||||
|this| this.pretty_print_const(value, print_ty),
|
||||
|this| this.pretty_print_type(to_ty),
|
||||
" as ",
|
||||
)
|
||||
},
|
||||
parenthesized,
|
||||
)?;
|
||||
} else {
|
||||
self.pretty_print_const(ct, print_ty)?
|
||||
self.pretty_print_const(value, print_ty)?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
use crate::ty::error::{ExpectedFound, TypeError};
|
||||
use crate::ty::{
|
||||
self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg,
|
||||
GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable,
|
||||
self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, GenericArg, GenericArgKind,
|
||||
GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -665,46 +665,18 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
||||
a.ty(),
|
||||
));
|
||||
}
|
||||
// Before calling relate on exprs, it is necessary to ensure that the nested consts
|
||||
// have identical types.
|
||||
(ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => {
|
||||
let r = relation;
|
||||
|
||||
// FIXME(generic_const_exprs): is it possible to relate two consts which are not identical
|
||||
// exprs? Should we care about that?
|
||||
// FIXME(generic_const_exprs): relating the `ty()`s is a little weird since it is supposed to
|
||||
// ICE If they mismatch. Unfortunately `ConstKind::Expr` is a little special and can be thought
|
||||
// of as being generic over the argument types, however this is implicit so these types don't get
|
||||
// related when we relate the args of the item this const arg is for.
|
||||
let expr = match (ae, be) {
|
||||
(Expr::Binop(a_op, al, ar), Expr::Binop(b_op, bl, br)) if a_op == b_op => {
|
||||
r.relate(al.ty(), bl.ty())?;
|
||||
r.relate(ar.ty(), br.ty())?;
|
||||
Expr::Binop(a_op, r.consts(al, bl)?, r.consts(ar, br)?)
|
||||
}
|
||||
(Expr::UnOp(a_op, av), Expr::UnOp(b_op, bv)) if a_op == b_op => {
|
||||
r.relate(av.ty(), bv.ty())?;
|
||||
Expr::UnOp(a_op, r.consts(av, bv)?)
|
||||
}
|
||||
(Expr::Cast(ak, av, at), Expr::Cast(bk, bv, bt)) if ak == bk => {
|
||||
r.relate(av.ty(), bv.ty())?;
|
||||
Expr::Cast(ak, r.consts(av, bv)?, r.tys(at, bt)?)
|
||||
}
|
||||
(Expr::FunctionCall(af, aa), Expr::FunctionCall(bf, ba))
|
||||
if aa.len() == ba.len() =>
|
||||
{
|
||||
r.relate(af.ty(), bf.ty())?;
|
||||
let func = r.consts(af, bf)?;
|
||||
let mut related_args = Vec::with_capacity(aa.len());
|
||||
for (a_arg, b_arg) in aa.iter().zip(ba.iter()) {
|
||||
related_args.push(r.consts(a_arg, b_arg)?);
|
||||
}
|
||||
let related_args = tcx.mk_const_list(&related_args);
|
||||
Expr::FunctionCall(func, related_args)
|
||||
}
|
||||
match (ae.kind, be.kind) {
|
||||
(ty::ExprKind::Binop(a_binop), ty::ExprKind::Binop(b_binop))
|
||||
if a_binop == b_binop => {}
|
||||
(ty::ExprKind::UnOp(a_unop), ty::ExprKind::UnOp(b_unop)) if a_unop == b_unop => {}
|
||||
(ty::ExprKind::FunctionCall, ty::ExprKind::FunctionCall) => {}
|
||||
(ty::ExprKind::Cast(a_kind), ty::ExprKind::Cast(b_kind)) if a_kind == b_kind => {}
|
||||
_ => return Err(TypeError::ConstMismatch(expected_found(a, b))),
|
||||
};
|
||||
return Ok(ty::Const::new_expr(tcx, expr, a.ty()));
|
||||
}
|
||||
|
||||
let args = relation.relate(ae.args(), be.args())?;
|
||||
return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args), a.ty()));
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
@ -147,14 +147,27 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::consts::Expr<'tcx> {
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
match this.data {
|
||||
ty::Expr::Binop(op, lhs, rhs) => {
|
||||
write!(f, "({op:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs))
|
||||
match this.data.kind {
|
||||
ty::ExprKind::Binop(op) => {
|
||||
let (lhs_ty, rhs_ty, lhs, rhs) = this.data.binop_args();
|
||||
write!(
|
||||
f,
|
||||
"({op:?}: ({:?}: {:?}), ({:?}: {:?}))",
|
||||
&this.wrap(lhs),
|
||||
&this.wrap(lhs_ty),
|
||||
&this.wrap(rhs),
|
||||
&this.wrap(rhs_ty),
|
||||
)
|
||||
}
|
||||
ty::Expr::UnOp(op, rhs) => write!(f, "({op:?}: {:?})", &this.wrap(rhs)),
|
||||
ty::Expr::FunctionCall(func, args) => {
|
||||
write!(f, "{:?}(", &this.wrap(func))?;
|
||||
for arg in args.as_slice().iter().rev().skip(1).rev() {
|
||||
ty::ExprKind::UnOp(op) => {
|
||||
let (rhs_ty, rhs) = this.data.unop_args();
|
||||
write!(f, "({op:?}: ({:?}: {:?}))", &this.wrap(rhs), &this.wrap(rhs_ty))
|
||||
}
|
||||
ty::ExprKind::FunctionCall => {
|
||||
let (func_ty, func, args) = this.data.call_args();
|
||||
let args = args.collect::<Vec<_>>();
|
||||
write!(f, "({:?}: {:?})(", &this.wrap(func), &this.wrap(func_ty))?;
|
||||
for arg in args.iter().rev().skip(1).rev() {
|
||||
write!(f, "{:?}, ", &this.wrap(arg))?;
|
||||
}
|
||||
if let Some(arg) = args.last() {
|
||||
@ -163,8 +176,15 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::consts::Expr<'tcx> {
|
||||
|
||||
write!(f, ")")
|
||||
}
|
||||
ty::Expr::Cast(cast_kind, lhs, rhs) => {
|
||||
write!(f, "({cast_kind:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs))
|
||||
ty::ExprKind::Cast(kind) => {
|
||||
let (value_ty, value, to_ty) = this.data.cast_args();
|
||||
write!(
|
||||
f,
|
||||
"({kind:?}: ({:?}: {:?}), {:?})",
|
||||
&this.wrap(value),
|
||||
&this.wrap(value_ty),
|
||||
&this.wrap(to_ty)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,24 +222,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||
| ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Error(_) => {}
|
||||
|
||||
ty::ConstKind::Expr(expr) => match expr {
|
||||
ty::Expr::UnOp(_, v) => push_inner(stack, v.into()),
|
||||
ty::Expr::Binop(_, l, r) => {
|
||||
push_inner(stack, r.into());
|
||||
push_inner(stack, l.into())
|
||||
}
|
||||
ty::Expr::FunctionCall(func, args) => {
|
||||
for a in args.iter().rev() {
|
||||
push_inner(stack, a.into());
|
||||
}
|
||||
push_inner(stack, func.into());
|
||||
}
|
||||
ty::Expr::Cast(_, c, t) => {
|
||||
push_inner(stack, t.into());
|
||||
push_inner(stack, c.into());
|
||||
}
|
||||
},
|
||||
|
||||
ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
|
||||
ty::ConstKind::Unevaluated(ct) => {
|
||||
stack.extend(ct.args.iter().rev());
|
||||
}
|
||||
|
@ -179,18 +179,18 @@ impl MCDCState {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MCDCInfoBuilder {
|
||||
pub(crate) struct MCDCInfoBuilder {
|
||||
branch_spans: Vec<MCDCBranchSpan>,
|
||||
decision_spans: Vec<MCDCDecisionSpan>,
|
||||
state: MCDCState,
|
||||
}
|
||||
|
||||
impl MCDCInfoBuilder {
|
||||
pub fn new() -> Self {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() }
|
||||
}
|
||||
|
||||
pub fn visit_evaluated_condition(
|
||||
pub(crate) fn visit_evaluated_condition(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
source_info: SourceInfo,
|
||||
@ -243,7 +243,7 @@ impl MCDCInfoBuilder {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn into_done(self) -> (Vec<MCDCDecisionSpan>, Vec<MCDCBranchSpan>) {
|
||||
pub(crate) fn into_done(self) -> (Vec<MCDCDecisionSpan>, Vec<MCDCBranchSpan>) {
|
||||
(self.decision_spans, self.branch_spans)
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_args(&mut self, params: &IndexSlice<ParamId, Param<'tcx>>) -> PResult<()> {
|
||||
pub(crate) fn parse_args(&mut self, params: &IndexSlice<ParamId, Param<'tcx>>) -> PResult<()> {
|
||||
for param in params.iter() {
|
||||
let (var, span) = {
|
||||
let pat = param.pat.as_ref().unwrap();
|
||||
@ -149,7 +149,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
///
|
||||
/// This allows us to easily parse the basic blocks declarations, local declarations, and
|
||||
/// basic block definitions in order.
|
||||
pub fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> {
|
||||
pub(crate) fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> {
|
||||
let body = parse_by_kind!(self, expr_id, _, "whole body",
|
||||
ExprKind::Block { block } => self.thir[*block].expr.unwrap(),
|
||||
);
|
||||
|
@ -12,7 +12,7 @@ use crate::build::expr::as_constant::as_constant_inner;
|
||||
use super::{parse_by_kind, PResult, ParseCtxt};
|
||||
|
||||
impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
pub fn parse_statement(&self, expr_id: ExprId) -> PResult<StatementKind<'tcx>> {
|
||||
pub(crate) fn parse_statement(&self, expr_id: ExprId) -> PResult<StatementKind<'tcx>> {
|
||||
parse_by_kind!(self, expr_id, _, "statement",
|
||||
@call(mir_storage_live, args) => {
|
||||
Ok(StatementKind::StorageLive(self.parse_local(args[0])?))
|
||||
@ -46,7 +46,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_terminator(&self, expr_id: ExprId) -> PResult<TerminatorKind<'tcx>> {
|
||||
pub(crate) fn parse_terminator(&self, expr_id: ExprId) -> PResult<TerminatorKind<'tcx>> {
|
||||
parse_by_kind!(self, expr_id, expr, "terminator",
|
||||
@call(mir_return, _args) => {
|
||||
Ok(TerminatorKind::Return)
|
||||
@ -261,7 +261,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
|
||||
pub(crate) fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
|
||||
parse_by_kind!(self, expr_id, expr, "operand",
|
||||
@call(mir_move, args) => self.parse_place(args[0]).map(Operand::Move),
|
||||
@call(mir_static, args) => self.parse_static(args[0]),
|
||||
|
@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_constant_inner<'tcx>(
|
||||
pub(crate) fn as_constant_inner<'tcx>(
|
||||
expr: &Expr<'tcx>,
|
||||
push_cuta: impl FnMut(&Box<CanonicalUserType<'tcx>>) -> Option<UserTypeAnnotationIndex>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -62,9 +62,9 @@
|
||||
|
||||
pub(crate) mod as_constant;
|
||||
mod as_operand;
|
||||
pub mod as_place;
|
||||
pub(crate) mod as_place;
|
||||
mod as_rvalue;
|
||||
mod as_temp;
|
||||
pub mod category;
|
||||
pub(crate) mod category;
|
||||
mod into;
|
||||
mod stmt;
|
||||
|
@ -456,7 +456,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind {
|
||||
pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind {
|
||||
match ref_mutability {
|
||||
Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
|
||||
Mutability::Not => BorrowKind::Shared,
|
||||
|
@ -97,7 +97,7 @@ use rustc_span::{Span, DUMMY_SP};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Scopes<'tcx> {
|
||||
pub(crate) struct Scopes<'tcx> {
|
||||
scopes: Vec<Scope>,
|
||||
|
||||
/// The current set of breakable scopes. See module comment for more details.
|
||||
|
@ -597,7 +597,7 @@ enum UnsafeOpKind {
|
||||
use UnsafeOpKind::*;
|
||||
|
||||
impl UnsafeOpKind {
|
||||
pub fn emit_unsafe_op_in_unsafe_fn_lint(
|
||||
fn emit_unsafe_op_in_unsafe_fn_lint(
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
hir_id: HirId,
|
||||
@ -737,7 +737,7 @@ impl UnsafeOpKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emit_requires_unsafe_err(
|
||||
fn emit_requires_unsafe_err(
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
span: Span,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,4 @@
|
||||
//! Construction of MIR from HIR.
|
||||
//!
|
||||
//! This crate also contains the match exhaustiveness and usefulness checking.
|
||||
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
|
@ -1562,6 +1562,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
Some(suggestion) if suggestion.candidate == kw::Underscore => return false,
|
||||
Some(suggestion) => suggestion,
|
||||
};
|
||||
|
||||
let mut did_label_def_span = false;
|
||||
|
||||
if let Some(def_span) = suggestion.res.opt_def_id().map(|def_id| self.def_span(def_id)) {
|
||||
if span.overlaps(def_span) {
|
||||
// Don't suggest typo suggestion for itself like in the following:
|
||||
@ -1595,31 +1598,38 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
errors::DefinedHere::SingleItem { span, candidate_descr, candidate }
|
||||
}
|
||||
};
|
||||
did_label_def_span = true;
|
||||
err.subdiagnostic(self.tcx.dcx(), label);
|
||||
}
|
||||
|
||||
let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target
|
||||
let (span, msg, sugg) = if let SuggestionTarget::SimilarlyNamed = suggestion.target
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& let Some(span) = suggestion.span
|
||||
&& let Some(candidate) = suggestion.candidate.as_str().strip_prefix('_')
|
||||
&& snippet == candidate
|
||||
{
|
||||
let candidate = suggestion.candidate;
|
||||
// When the suggested binding change would be from `x` to `_x`, suggest changing the
|
||||
// original binding definition instead. (#60164)
|
||||
let post = format!(", consider renaming `{}` into `{snippet}`", suggestion.candidate);
|
||||
(span, snippet, post)
|
||||
} else {
|
||||
(span, suggestion.candidate.to_ident_string(), String::new())
|
||||
};
|
||||
let msg = match suggestion.target {
|
||||
SuggestionTarget::SimilarlyNamed => format!(
|
||||
"{} {} with a similar name exists{post}",
|
||||
suggestion.res.article(),
|
||||
suggestion.res.descr()
|
||||
),
|
||||
SuggestionTarget::SingleItem => {
|
||||
format!("maybe you meant this {}", suggestion.res.descr())
|
||||
let msg = format!(
|
||||
"the leading underscore in `{candidate}` marks it as unused, consider renaming it to `{snippet}`"
|
||||
);
|
||||
if !did_label_def_span {
|
||||
err.span_label(span, format!("`{candidate}` defined here"));
|
||||
}
|
||||
(span, msg, snippet)
|
||||
} else {
|
||||
let msg = match suggestion.target {
|
||||
SuggestionTarget::SimilarlyNamed => format!(
|
||||
"{} {} with a similar name exists",
|
||||
suggestion.res.article(),
|
||||
suggestion.res.descr()
|
||||
),
|
||||
SuggestionTarget::SingleItem => {
|
||||
format!("maybe you meant this {}", suggestion.res.descr())
|
||||
}
|
||||
};
|
||||
(span, msg, suggestion.candidate.to_ident_string())
|
||||
};
|
||||
err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
|
||||
true
|
||||
|
@ -5,17 +5,17 @@
|
||||
|
||||
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
|
||||
use crate::rustc_smir::Tables;
|
||||
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy, TyCtxt};
|
||||
use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt};
|
||||
use rustc_span::Symbol;
|
||||
use stable_mir::abi::Layout;
|
||||
use stable_mir::mir::alloc::AllocId;
|
||||
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
|
||||
use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, Safety, UnOp};
|
||||
use stable_mir::ty::{
|
||||
Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
|
||||
DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
|
||||
GenericArgKind, GenericArgs, IndexedVal, IntTy, Movability, Pattern, Region, RigidTy, Span,
|
||||
TermKind, TraitRef, Ty, UintTy, VariantDef, VariantIdx,
|
||||
Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind,
|
||||
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
|
||||
GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy,
|
||||
Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
|
||||
};
|
||||
use stable_mir::{CrateItem, CrateNum, DefId};
|
||||
|
||||
@ -55,7 +55,7 @@ impl RustcInternal for GenericArgKind {
|
||||
let arg: rustc_ty::GenericArg<'tcx> = match self {
|
||||
GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(),
|
||||
GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(),
|
||||
GenericArgKind::Const(cnst) => ty_const(cnst, tables, tcx).into(),
|
||||
GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(),
|
||||
};
|
||||
tcx.lift(arg).unwrap()
|
||||
}
|
||||
@ -76,13 +76,20 @@ impl RustcInternal for Ty {
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for TyConst {
|
||||
type T<'tcx> = InternalConst<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tcx.lift(tables.ty_consts[self.id]).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for Pattern {
|
||||
type T<'tcx> = rustc_ty::Pattern<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tcx.mk_pat(match self {
|
||||
Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
|
||||
start: start.as_ref().map(|c| ty_const(c, tables, tcx)),
|
||||
end: end.as_ref().map(|c| ty_const(c, tables, tcx)),
|
||||
start: start.as_ref().map(|c| c.internal(tables, tcx)),
|
||||
end: end.as_ref().map(|c| c.internal(tables, tcx)),
|
||||
include_end: *include_end,
|
||||
},
|
||||
})
|
||||
@ -101,7 +108,7 @@ impl RustcInternal for RigidTy {
|
||||
RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)),
|
||||
RigidTy::Never => rustc_ty::TyKind::Never,
|
||||
RigidTy::Array(ty, cnst) => {
|
||||
rustc_ty::TyKind::Array(ty.internal(tables, tcx), ty_const(cnst, tables, tcx))
|
||||
rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx))
|
||||
}
|
||||
RigidTy::Pat(ty, pat) => {
|
||||
rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx))
|
||||
@ -239,23 +246,10 @@ impl RustcInternal for VariantDef {
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_const<'tcx>(
|
||||
constant: &Const,
|
||||
tables: &mut Tables<'_>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> rustc_ty::Const<'tcx> {
|
||||
match constant.internal(tables, tcx) {
|
||||
rustc_middle::mir::Const::Ty(c) => c,
|
||||
cnst => {
|
||||
panic!("Trying to convert constant `{constant:?}` to type constant, but found {cnst:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RustcInternal for Const {
|
||||
impl RustcInternal for MirConst {
|
||||
type T<'tcx> = rustc_middle::mir::Const<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
let constant = tables.constants[self.id];
|
||||
let constant = tables.mir_consts[self.id];
|
||||
match constant {
|
||||
rustc_middle::mir::Const::Ty(ty) => rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap()),
|
||||
rustc_middle::mir::Const::Unevaluated(uneval, ty) => {
|
||||
@ -392,7 +386,7 @@ impl RustcInternal for TermKind {
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
match self {
|
||||
TermKind::Type(ty) => ty.internal(tables, tcx).into(),
|
||||
TermKind::Const(const_) => ty_const(const_, tables, tcx).into(),
|
||||
TermKind::Const(cnst) => cnst.internal(tables, tcx).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,8 @@ where
|
||||
spans: IndexMap::default(),
|
||||
types: IndexMap::default(),
|
||||
instances: IndexMap::default(),
|
||||
constants: IndexMap::default(),
|
||||
ty_consts: IndexMap::default(),
|
||||
mir_consts: IndexMap::default(),
|
||||
layouts: IndexMap::default(),
|
||||
}));
|
||||
stable_mir::compiler_interface::run(&tables, || init(&tables, f))
|
||||
|
@ -6,7 +6,6 @@
|
||||
#![allow(rustc::usage_of_qualified_ty)]
|
||||
|
||||
use rustc_abi::HasDataLayout;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers,
|
||||
};
|
||||
@ -14,6 +13,7 @@ use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
|
||||
use rustc_middle::ty::{
|
||||
GenericPredicates, Instance, List, ParamEnv, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
|
||||
};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use stable_mir::abi::{FnAbi, Layout, LayoutShape};
|
||||
use stable_mir::compiler_interface::Context;
|
||||
@ -22,9 +22,9 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef};
|
||||
use stable_mir::mir::{BinOp, Body, Place, UnOp};
|
||||
use stable_mir::target::{MachineInfo, MachineSize};
|
||||
use stable_mir::ty::{
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
|
||||
ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind,
|
||||
UintTy, VariantDef,
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
|
||||
ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, Ty,
|
||||
TyConst, TyKind, UintTy, VariantDef,
|
||||
};
|
||||
use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol};
|
||||
use std::cell::RefCell;
|
||||
@ -360,7 +360,15 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect()
|
||||
}
|
||||
|
||||
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error> {
|
||||
fn eval_target_usize(&self, cnst: &MirConst) -> Result<u64, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let mir_const = cnst.internal(&mut *tables, tcx);
|
||||
mir_const
|
||||
.try_eval_target_usize(tables.tcx, ParamEnv::empty())
|
||||
.ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
|
||||
}
|
||||
fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result<u64, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let mir_const = cnst.internal(&mut *tables, tcx);
|
||||
@ -369,7 +377,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
.ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
|
||||
}
|
||||
|
||||
fn try_new_const_zst(&self, ty: Ty) -> Result<Const, Error> {
|
||||
fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let ty_internal = ty.internal(&mut *tables, tcx);
|
||||
@ -390,25 +398,45 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(ty::Const::zero_sized(tables.tcx, ty_internal).stable(&mut *tables))
|
||||
Ok(mir::Const::Ty(ty::Const::zero_sized(tables.tcx, ty_internal)).stable(&mut *tables))
|
||||
}
|
||||
|
||||
fn new_const_str(&self, value: &str) -> Const {
|
||||
fn new_const_str(&self, value: &str) -> MirConst {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let ty = ty::Ty::new_static_str(tcx);
|
||||
let bytes = value.as_bytes();
|
||||
let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes);
|
||||
|
||||
ty::Const::new_value(tcx, val_tree, ty).stable(&mut *tables)
|
||||
let ct = ty::Const::new_value(tcx, val_tree, ty);
|
||||
super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)
|
||||
}
|
||||
|
||||
fn new_const_bool(&self, value: bool) -> Const {
|
||||
fn new_const_bool(&self, value: bool) -> MirConst {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
ty::Const::from_bool(tables.tcx, value).stable(&mut *tables)
|
||||
let ct = ty::Const::from_bool(tables.tcx, value);
|
||||
let ty = tables.tcx.types.bool;
|
||||
super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)
|
||||
}
|
||||
|
||||
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<Const, Error> {
|
||||
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx));
|
||||
let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size;
|
||||
|
||||
// We don't use Const::from_bits since it doesn't have any error checking.
|
||||
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
|
||||
Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
|
||||
})?;
|
||||
let ct = ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty);
|
||||
Ok(super::convert::mir_const_from_ty_const(&mut *tables, ct, ty))
|
||||
}
|
||||
fn try_new_ty_const_uint(
|
||||
&self,
|
||||
value: u128,
|
||||
uint_ty: UintTy,
|
||||
) -> Result<stable_mir::ty::TyConst, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx));
|
||||
@ -453,7 +481,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
.stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn const_pretty(&self, cnst: &stable_mir::ty::Const) -> String {
|
||||
fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
cnst.internal(&mut *tables, tcx).to_string()
|
||||
@ -474,6 +502,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
tables.types[ty].kind().stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String {
|
||||
let tables = self.0.borrow_mut();
|
||||
tables.ty_consts[ct].to_string()
|
||||
}
|
||||
|
||||
fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
|
@ -6,7 +6,7 @@ use rustc_middle::mir::interpret::alloc_range;
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment};
|
||||
use stable_mir::ty::{Allocation, Const, ConstantKind};
|
||||
use stable_mir::ty::{Allocation, ConstantKind, MirConst};
|
||||
use stable_mir::{opaque, Error};
|
||||
|
||||
use crate::rustc_smir::{alloc, Stable, Tables};
|
||||
@ -724,11 +724,16 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
||||
type T = stable_mir::ty::Const;
|
||||
type T = stable_mir::ty::MirConst;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap());
|
||||
match *self {
|
||||
mir::Const::Ty(c) => c.stable(tables),
|
||||
mir::Const::Ty(c) => MirConst::new(
|
||||
stable_mir::ty::ConstantKind::Ty(c.stable(tables)),
|
||||
c.ty().stable(tables),
|
||||
id,
|
||||
),
|
||||
mir::Const::Unevaluated(unev_const, ty) => {
|
||||
let kind =
|
||||
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
|
||||
@ -737,21 +742,18 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
||||
promoted: unev_const.promoted.map(|u| u.as_u32()),
|
||||
});
|
||||
let ty = ty.stable(tables);
|
||||
let id = tables.intern_const(tables.tcx.lift(*self).unwrap());
|
||||
Const::new(kind, ty, id)
|
||||
MirConst::new(kind, ty, id)
|
||||
}
|
||||
mir::Const::Val(mir::ConstValue::ZeroSized, ty) => {
|
||||
let ty = ty.stable(tables);
|
||||
let id = tables.intern_const(tables.tcx.lift(*self).unwrap());
|
||||
Const::new(ConstantKind::ZeroSized, ty, id)
|
||||
MirConst::new(ConstantKind::ZeroSized, ty, id)
|
||||
}
|
||||
mir::Const::Val(val, ty) => {
|
||||
let ty = tables.tcx.lift(ty).unwrap();
|
||||
let val = tables.tcx.lift(val).unwrap();
|
||||
let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
|
||||
let ty = ty.stable(tables);
|
||||
let id = tables.intern_const(tables.tcx.lift(*self).unwrap());
|
||||
Const::new(kind, ty, id)
|
||||
MirConst::new(kind, ty, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ mod error;
|
||||
mod mir;
|
||||
mod ty;
|
||||
|
||||
pub use ty::mir_const_from_ty_const;
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
||||
type T = stable_mir::mir::Safety;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
|
@ -3,8 +3,7 @@
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::{mir, ty};
|
||||
use stable_mir::ty::{
|
||||
AdtKind, Const, ConstantKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy,
|
||||
TyKind, UintTy,
|
||||
AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy,
|
||||
};
|
||||
|
||||
use crate::rustc_smir::{alloc, Stable, Tables};
|
||||
@ -410,8 +409,50 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mir_const_from_ty_const<'tcx>(
|
||||
tables: &mut Tables<'tcx>,
|
||||
ty_const: ty::Const<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> stable_mir::ty::MirConst {
|
||||
let kind = match ty_const.kind() {
|
||||
ty::Value(val) => {
|
||||
let val = match val {
|
||||
ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
|
||||
ty::ValTree::Branch(branch) => {
|
||||
ty::ValTree::Branch(tables.tcx.lift(branch).unwrap())
|
||||
}
|
||||
};
|
||||
let ty = tables.tcx.lift(ty).unwrap();
|
||||
let const_val = tables.tcx.valtree_to_const_val((ty, val));
|
||||
if matches!(const_val, mir::ConstValue::ZeroSized) {
|
||||
stable_mir::ty::ConstantKind::ZeroSized
|
||||
} else {
|
||||
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
|
||||
ty, const_val, tables,
|
||||
))
|
||||
}
|
||||
}
|
||||
ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
|
||||
ty::ErrorCt(_) => unreachable!(),
|
||||
ty::InferCt(_) => unreachable!(),
|
||||
ty::BoundCt(_, _) => unimplemented!(),
|
||||
ty::PlaceholderCt(_) => unimplemented!(),
|
||||
ty::Unevaluated(uv) => {
|
||||
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
|
||||
def: tables.const_def(uv.def),
|
||||
args: uv.args.stable(tables),
|
||||
promoted: None,
|
||||
})
|
||||
}
|
||||
ty::ExprCt(_) => unimplemented!(),
|
||||
};
|
||||
let stable_ty = tables.intern_ty(ty);
|
||||
let id = tables.intern_mir_const(mir::Const::Ty(ty_const));
|
||||
stable_mir::ty::MirConst::new(kind, stable_ty, id)
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
||||
type T = stable_mir::ty::Const;
|
||||
type T = stable_mir::ty::TyConst;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
let kind = match self.kind() {
|
||||
@ -425,30 +466,27 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
||||
let ty = tables.tcx.lift(self.ty()).unwrap();
|
||||
let const_val = tables.tcx.valtree_to_const_val((ty, val));
|
||||
if matches!(const_val, mir::ConstValue::ZeroSized) {
|
||||
ConstantKind::ZeroSized
|
||||
stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables))
|
||||
} else {
|
||||
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
|
||||
ty, const_val, tables,
|
||||
))
|
||||
stable_mir::ty::TyConstKind::Value(
|
||||
ty.stable(tables),
|
||||
alloc::new_allocation(ty, const_val, tables),
|
||||
)
|
||||
}
|
||||
}
|
||||
ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
|
||||
ty::ParamCt(param) => stable_mir::ty::TyConstKind::Param(param.stable(tables)),
|
||||
ty::Unevaluated(uv) => stable_mir::ty::TyConstKind::Unevaluated(
|
||||
tables.const_def(uv.def),
|
||||
uv.args.stable(tables),
|
||||
),
|
||||
ty::ErrorCt(_) => unreachable!(),
|
||||
ty::InferCt(_) => unreachable!(),
|
||||
ty::BoundCt(_, _) => unimplemented!(),
|
||||
ty::PlaceholderCt(_) => unimplemented!(),
|
||||
ty::Unevaluated(uv) => {
|
||||
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
|
||||
def: tables.const_def(uv.def),
|
||||
args: uv.args.stable(tables),
|
||||
promoted: None,
|
||||
})
|
||||
}
|
||||
ty::ExprCt(_) => unimplemented!(),
|
||||
};
|
||||
let ty = self.ty().stable(tables);
|
||||
let id = tables.intern_const(mir::Const::Ty(tables.tcx.lift(*self).unwrap()));
|
||||
Const::new(kind, ty, id)
|
||||
let id = tables.intern_ty_const(tables.tcx.lift(*self).unwrap());
|
||||
stable_mir::ty::TyConst::new(kind, id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use stable_mir::abi::Layout;
|
||||
use stable_mir::mir::mono::InstanceDef;
|
||||
use stable_mir::ty::{ConstId, Span};
|
||||
use stable_mir::ty::{MirConstId, Span, TyConstId};
|
||||
use stable_mir::{CtorKind, ItemKind};
|
||||
use std::ops::RangeInclusive;
|
||||
use tracing::debug;
|
||||
@ -33,7 +33,8 @@ pub struct Tables<'tcx> {
|
||||
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
|
||||
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
|
||||
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
||||
pub(crate) constants: IndexMap<mir::Const<'tcx>, ConstId>,
|
||||
pub(crate) ty_consts: IndexMap<ty::Const<'tcx>, TyConstId>,
|
||||
pub(crate) mir_consts: IndexMap<mir::Const<'tcx>, MirConstId>,
|
||||
pub(crate) layouts: IndexMap<rustc_target::abi::Layout<'tcx>, Layout>,
|
||||
}
|
||||
|
||||
@ -42,8 +43,12 @@ impl<'tcx> Tables<'tcx> {
|
||||
self.types.create_or_fetch(ty)
|
||||
}
|
||||
|
||||
pub(crate) fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
|
||||
self.constants.create_or_fetch(constant)
|
||||
pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId {
|
||||
self.ty_consts.create_or_fetch(ct)
|
||||
}
|
||||
|
||||
pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId {
|
||||
self.mir_consts.create_or_fetch(constant)
|
||||
}
|
||||
|
||||
pub(crate) fn has_body(&self, instance: Instance<'tcx>) -> bool {
|
||||
|
@ -414,7 +414,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
||||
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
||||
let trait_predicate = self.apply_do_not_recommend(trait_predicate, &mut obligation);
|
||||
|
||||
// Let's use the root obligation as the main message, when we care about the
|
||||
// most general case ("X doesn't implement Pattern<'_>") over the case that
|
||||
@ -996,12 +995,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn apply_do_not_recommend(
|
||||
&self,
|
||||
mut trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
|
||||
obligation: &'_ mut PredicateObligation<'tcx>,
|
||||
) -> ty::Binder<'tcx, ty::TraitPredicate<'tcx>> {
|
||||
fn apply_do_not_recommend(&self, obligation: &mut PredicateObligation<'tcx>) -> bool {
|
||||
let mut base_cause = obligation.cause.code().clone();
|
||||
let mut applied_do_not_recommend = false;
|
||||
loop {
|
||||
if let ObligationCauseCode::ImplDerived(ref c) = base_cause {
|
||||
if self.tcx.has_attrs_with_path(
|
||||
@ -1011,7 +1007,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
let code = (*c.derived.parent_code).clone();
|
||||
obligation.cause.map_code(|_| code);
|
||||
obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx);
|
||||
trait_predicate = c.derived.parent_trait_pred.clone();
|
||||
applied_do_not_recommend = true;
|
||||
}
|
||||
}
|
||||
if let Some((parent_cause, _parent_pred)) = base_cause.parent() {
|
||||
@ -1021,7 +1017,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
trait_predicate
|
||||
applied_do_not_recommend
|
||||
}
|
||||
|
||||
fn emit_specialized_closure_kind_error(
|
||||
@ -1521,6 +1517,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed {
|
||||
let mut error = FulfillmentError {
|
||||
obligation: error.obligation.clone(),
|
||||
code: error.code.clone(),
|
||||
root_obligation: error.root_obligation.clone(),
|
||||
};
|
||||
if matches!(
|
||||
error.code,
|
||||
FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented)
|
||||
| FulfillmentErrorCode::Project(_)
|
||||
) && self.apply_do_not_recommend(&mut error.obligation)
|
||||
{
|
||||
error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented);
|
||||
}
|
||||
|
||||
match error.code {
|
||||
FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error(
|
||||
error.obligation.clone(),
|
||||
|
@ -148,17 +148,24 @@ fn recurse_build<'tcx>(
|
||||
for &id in args.iter() {
|
||||
new_args.push(recurse_build(tcx, body, id, root_span)?);
|
||||
}
|
||||
let new_args = tcx.mk_const_list(&new_args);
|
||||
ty::Const::new_expr(tcx, Expr::FunctionCall(fun, new_args), node.ty)
|
||||
ty::Const::new_expr(
|
||||
tcx,
|
||||
Expr::new_call(tcx, fun.ty(), fun, new_args.into_iter()),
|
||||
node.ty,
|
||||
)
|
||||
}
|
||||
&ExprKind::Binary { op, lhs, rhs } if check_binop(op) => {
|
||||
let lhs = recurse_build(tcx, body, lhs, root_span)?;
|
||||
let rhs = recurse_build(tcx, body, rhs, root_span)?;
|
||||
ty::Const::new_expr(tcx, Expr::Binop(op, lhs, rhs), node.ty)
|
||||
ty::Const::new_expr(
|
||||
tcx,
|
||||
Expr::new_binop(tcx, op, lhs.ty(), rhs.ty(), lhs, rhs),
|
||||
node.ty,
|
||||
)
|
||||
}
|
||||
&ExprKind::Unary { op, arg } if check_unop(op) => {
|
||||
let arg = recurse_build(tcx, body, arg, root_span)?;
|
||||
ty::Const::new_expr(tcx, Expr::UnOp(op, arg), node.ty)
|
||||
ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg.ty(), arg), node.ty)
|
||||
}
|
||||
// This is necessary so that the following compiles:
|
||||
//
|
||||
@ -178,12 +185,22 @@ fn recurse_build<'tcx>(
|
||||
// "coercion cast" i.e. using a coercion or is a no-op.
|
||||
// This is important so that `N as usize as usize` doesn't unify with `N as usize`. (untested)
|
||||
&ExprKind::Use { source } => {
|
||||
let arg = recurse_build(tcx, body, source, root_span)?;
|
||||
ty::Const::new_expr(tcx, Expr::Cast(CastKind::Use, arg, node.ty), node.ty)
|
||||
let value_ty = body.exprs[source].ty;
|
||||
let value = recurse_build(tcx, body, source, root_span)?;
|
||||
ty::Const::new_expr(
|
||||
tcx,
|
||||
Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty),
|
||||
node.ty,
|
||||
)
|
||||
}
|
||||
&ExprKind::Cast { source } => {
|
||||
let arg = recurse_build(tcx, body, source, root_span)?;
|
||||
ty::Const::new_expr(tcx, Expr::Cast(CastKind::As, arg, node.ty), node.ty)
|
||||
let value_ty = body.exprs[source].ty;
|
||||
let value = recurse_build(tcx, body, source, root_span)?;
|
||||
ty::Const::new_expr(
|
||||
tcx,
|
||||
Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty),
|
||||
node.ty,
|
||||
)
|
||||
}
|
||||
ExprKind::Borrow { arg, .. } => {
|
||||
let arg_node = &body.exprs[*arg];
|
||||
|
@ -11,10 +11,10 @@ use crate::mir::mono::{Instance, InstanceDef, StaticDef};
|
||||
use crate::mir::{BinOp, Body, Place, UnOp};
|
||||
use crate::target::MachineInfo;
|
||||
use crate::ty::{
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
|
||||
ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
|
||||
ImplDef, ImplTrait, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty,
|
||||
TyKind, UintTy, VariantDef,
|
||||
ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
|
||||
TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
|
||||
};
|
||||
use crate::{
|
||||
mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
|
||||
@ -109,19 +109,21 @@ pub trait Context {
|
||||
fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef>;
|
||||
|
||||
/// Evaluate constant as a target usize.
|
||||
fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error>;
|
||||
fn eval_target_usize(&self, cnst: &MirConst) -> Result<u64, Error>;
|
||||
fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result<u64, Error>;
|
||||
|
||||
/// Create a new zero-sized constant.
|
||||
fn try_new_const_zst(&self, ty: Ty) -> Result<Const, Error>;
|
||||
fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error>;
|
||||
|
||||
/// Create a new constant that represents the given string value.
|
||||
fn new_const_str(&self, value: &str) -> Const;
|
||||
fn new_const_str(&self, value: &str) -> MirConst;
|
||||
|
||||
/// Create a new constant that represents the given boolean value.
|
||||
fn new_const_bool(&self, value: bool) -> Const;
|
||||
fn new_const_bool(&self, value: bool) -> MirConst;
|
||||
|
||||
/// Create a new constant that represents the given value.
|
||||
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<Const, Error>;
|
||||
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error>;
|
||||
fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<TyConst, Error>;
|
||||
|
||||
/// Create a new type from the given kind.
|
||||
fn new_rigid_ty(&self, kind: RigidTy) -> Ty;
|
||||
@ -136,11 +138,13 @@ pub trait Context {
|
||||
fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty;
|
||||
|
||||
/// Returns literal value of a const as a string.
|
||||
fn const_pretty(&self, cnst: &Const) -> String;
|
||||
fn mir_const_pretty(&self, cnst: &MirConst) -> String;
|
||||
|
||||
/// `Span` of an item
|
||||
fn span_of_an_item(&self, def_id: DefId) -> Span;
|
||||
|
||||
fn ty_const_pretty(&self, ct: TyConstId) -> String;
|
||||
|
||||
/// Obtain the representation of a type.
|
||||
fn ty_pretty(&self, ty: Ty) -> String;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::compiler_interface::with;
|
||||
use crate::mir::pretty::function_body;
|
||||
use crate::ty::{
|
||||
AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
|
||||
VariantIdx,
|
||||
AdtDef, ClosureDef, CoroutineDef, GenericArgs, MirConst, Movability, Region, RigidTy, Ty,
|
||||
TyConst, TyKind, VariantIdx,
|
||||
};
|
||||
use crate::{Error, Opaque, Span, Symbol};
|
||||
use std::io;
|
||||
@ -524,7 +524,7 @@ pub enum Rvalue {
|
||||
/// Corresponds to source code like `[x; 32]`.
|
||||
///
|
||||
/// [#74836]: https://github.com/rust-lang/rust/issues/74836
|
||||
Repeat(Operand, Const),
|
||||
Repeat(Operand, TyConst),
|
||||
|
||||
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
|
||||
///
|
||||
@ -718,7 +718,7 @@ pub enum VarDebugInfoContents {
|
||||
pub struct ConstOperand {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
pub const_: Const,
|
||||
pub const_: MirConst,
|
||||
}
|
||||
|
||||
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
|
||||
@ -833,7 +833,7 @@ type UserTypeAnnotationIndex = usize;
|
||||
pub struct Constant {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
pub literal: Const,
|
||||
pub literal: MirConst,
|
||||
}
|
||||
|
||||
/// The possible branch sites of a [TerminatorKind::SwitchInt].
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents};
|
||||
use crate::ty::{Const, IndexedVal, Ty};
|
||||
use crate::ty::{IndexedVal, MirConst, Ty, TyConst};
|
||||
use crate::{with, Body, Mutability};
|
||||
use fmt::{Display, Formatter};
|
||||
use std::fmt::Debug;
|
||||
@ -46,7 +46,7 @@ pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -
|
||||
VarDebugInfoContents::Place(place) => {
|
||||
format!("{place:?}")
|
||||
}
|
||||
VarDebugInfoContents::Const(constant) => pretty_const(&constant.const_),
|
||||
VarDebugInfoContents::Const(constant) => pretty_mir_const(&constant.const_),
|
||||
};
|
||||
writeln!(writer, " debug {} => {};", info.name, content)
|
||||
})?;
|
||||
@ -310,12 +310,16 @@ fn pretty_operand(operand: &Operand) -> String {
|
||||
Operand::Move(mv) => {
|
||||
format!("move {:?}", mv)
|
||||
}
|
||||
Operand::Constant(cnst) => pretty_const(&cnst.literal),
|
||||
Operand::Constant(cnst) => pretty_mir_const(&cnst.literal),
|
||||
}
|
||||
}
|
||||
|
||||
fn pretty_const(literal: &Const) -> String {
|
||||
with(|cx| cx.const_pretty(literal))
|
||||
fn pretty_mir_const(literal: &MirConst) -> String {
|
||||
with(|cx| cx.mir_const_pretty(literal))
|
||||
}
|
||||
|
||||
fn pretty_ty_const(ct: &TyConst) -> String {
|
||||
with(|cx| cx.ty_const_pretty(ct.id))
|
||||
}
|
||||
|
||||
fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
|
||||
@ -359,7 +363,7 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
|
||||
write!(writer, "{kind}{:?}", place)
|
||||
}
|
||||
Rvalue::Repeat(op, cnst) => {
|
||||
write!(writer, "{} \" \" {}", &pretty_operand(op), cnst.ty())
|
||||
write!(writer, "{} \" \" {}", &pretty_operand(op), &pretty_ty_const(cnst))
|
||||
}
|
||||
Rvalue::ShallowInitBox(_, _) => Ok(()),
|
||||
Rvalue::ThreadLocalRef(item) => {
|
||||
|
@ -36,7 +36,7 @@
|
||||
//! variant argument) that does not require visiting.
|
||||
|
||||
use crate::mir::*;
|
||||
use crate::ty::{Const, GenericArgs, Region, Ty};
|
||||
use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
|
||||
use crate::{Error, Opaque, Span};
|
||||
|
||||
pub trait MirVisitor {
|
||||
@ -112,8 +112,13 @@ pub trait MirVisitor {
|
||||
self.super_constant(constant, location)
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, constant: &Const, location: Location) {
|
||||
self.super_const(constant, location)
|
||||
fn visit_mir_const(&mut self, constant: &MirConst, location: Location) {
|
||||
self.super_mir_const(constant, location)
|
||||
}
|
||||
|
||||
fn visit_ty_const(&mut self, constant: &TyConst, location: Location) {
|
||||
let _ = location;
|
||||
self.super_ty_const(constant)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, region: &Region, location: Location) {
|
||||
@ -339,7 +344,7 @@ pub trait MirVisitor {
|
||||
}
|
||||
Rvalue::Repeat(op, constant) => {
|
||||
self.visit_operand(op, location);
|
||||
self.visit_const(constant, location);
|
||||
self.visit_ty_const(constant, location);
|
||||
}
|
||||
Rvalue::ShallowInitBox(op, ty) => {
|
||||
self.visit_ty(ty, location);
|
||||
@ -378,14 +383,18 @@ pub trait MirVisitor {
|
||||
fn super_constant(&mut self, constant: &Constant, location: Location) {
|
||||
let Constant { span, user_ty: _, literal } = constant;
|
||||
self.visit_span(span);
|
||||
self.visit_const(literal, location);
|
||||
self.visit_mir_const(literal, location);
|
||||
}
|
||||
|
||||
fn super_const(&mut self, constant: &Const, location: Location) {
|
||||
let Const { kind: _, ty, id: _ } = constant;
|
||||
fn super_mir_const(&mut self, constant: &MirConst, location: Location) {
|
||||
let MirConst { kind: _, ty, id: _ } = constant;
|
||||
self.visit_ty(ty, location);
|
||||
}
|
||||
|
||||
fn super_ty_const(&mut self, constant: &TyConst) {
|
||||
let _ = constant;
|
||||
}
|
||||
|
||||
fn super_region(&mut self, region: &Region) {
|
||||
let _ = region;
|
||||
}
|
||||
@ -407,7 +416,7 @@ pub trait MirVisitor {
|
||||
self.visit_place(place, PlaceContext::NON_USE, location);
|
||||
}
|
||||
VarDebugInfoContents::Const(constant) => {
|
||||
self.visit_const(&constant.const_, location);
|
||||
self.visit_mir_const(&constant.const_, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,11 @@ impl Ty {
|
||||
|
||||
/// Create a new array type.
|
||||
pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
|
||||
Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::try_from_target_usize(size)?)))
|
||||
Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?)))
|
||||
}
|
||||
|
||||
/// Create a new array type from Const length.
|
||||
pub fn new_array_with_const_len(elem_ty: Ty, len: Const) -> Ty {
|
||||
pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
|
||||
}
|
||||
|
||||
@ -101,24 +101,66 @@ impl Ty {
|
||||
/// Represents a pattern in the type system
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Pattern {
|
||||
Range { start: Option<Const>, end: Option<Const>, include_end: bool },
|
||||
Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
|
||||
}
|
||||
|
||||
/// Represents a constant in MIR or from the Type system.
|
||||
/// Represents a constant in the type system
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Const {
|
||||
pub struct TyConst {
|
||||
pub(crate) kind: TyConstKind,
|
||||
pub id: TyConstId,
|
||||
}
|
||||
|
||||
impl TyConst {
|
||||
pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst {
|
||||
Self { kind, id }
|
||||
}
|
||||
|
||||
/// Retrieve the constant kind.
|
||||
pub fn kind(&self) -> &TyConstKind {
|
||||
&self.kind
|
||||
}
|
||||
|
||||
/// Creates an interned usize constant.
|
||||
fn try_from_target_usize(val: u64) -> Result<Self, Error> {
|
||||
with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize))
|
||||
}
|
||||
|
||||
/// Try to evaluate to a target `usize`.
|
||||
pub fn eval_target_usize(&self) -> Result<u64, Error> {
|
||||
with(|cx| cx.eval_target_usize_ty(self))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum TyConstKind {
|
||||
Param(ParamConst),
|
||||
Bound(DebruijnIndex, BoundVar),
|
||||
Unevaluated(ConstDef, GenericArgs),
|
||||
|
||||
// FIXME: These should be a valtree
|
||||
Value(Ty, Allocation),
|
||||
ZSTValue(Ty),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct TyConstId(usize);
|
||||
|
||||
/// Represents a constant in MIR
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct MirConst {
|
||||
/// The constant kind.
|
||||
pub(crate) kind: ConstantKind,
|
||||
/// The constant type.
|
||||
pub(crate) ty: Ty,
|
||||
/// Used for internal tracking of the internal constant.
|
||||
pub id: ConstId,
|
||||
pub id: MirConstId,
|
||||
}
|
||||
|
||||
impl Const {
|
||||
impl MirConst {
|
||||
/// Build a constant. Note that this should only be used by the compiler.
|
||||
pub fn new(kind: ConstantKind, ty: Ty, id: ConstId) -> Const {
|
||||
Const { kind, ty, id }
|
||||
pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst {
|
||||
MirConst { kind, ty, id }
|
||||
}
|
||||
|
||||
/// Retrieve the constant kind.
|
||||
@ -131,11 +173,6 @@ impl Const {
|
||||
self.ty
|
||||
}
|
||||
|
||||
/// Creates an interned usize constant.
|
||||
fn try_from_target_usize(val: u64) -> Result<Self, Error> {
|
||||
with(|cx| cx.try_new_const_uint(val.into(), UintTy::Usize))
|
||||
}
|
||||
|
||||
/// Try to evaluate to a target `usize`.
|
||||
pub fn eval_target_usize(&self) -> Result<u64, Error> {
|
||||
with(|cx| cx.eval_target_usize(self))
|
||||
@ -143,7 +180,7 @@ impl Const {
|
||||
|
||||
/// Create a constant that represents a new zero-sized constant of type T.
|
||||
/// Fails if the type is not a ZST or if it doesn't have a known size.
|
||||
pub fn try_new_zero_sized(ty: Ty) -> Result<Const, Error> {
|
||||
pub fn try_new_zero_sized(ty: Ty) -> Result<MirConst, Error> {
|
||||
with(|cx| cx.try_new_const_zst(ty))
|
||||
}
|
||||
|
||||
@ -152,23 +189,23 @@ impl Const {
|
||||
/// Note that there is no guarantee today about duplication of the same constant.
|
||||
/// I.e.: Calling this function multiple times with the same argument may or may not return
|
||||
/// the same allocation.
|
||||
pub fn from_str(value: &str) -> Const {
|
||||
pub fn from_str(value: &str) -> MirConst {
|
||||
with(|cx| cx.new_const_str(value))
|
||||
}
|
||||
|
||||
/// Build a new constant that represents the given boolean value.
|
||||
pub fn from_bool(value: bool) -> Const {
|
||||
pub fn from_bool(value: bool) -> MirConst {
|
||||
with(|cx| cx.new_const_bool(value))
|
||||
}
|
||||
|
||||
/// Build a new constant that represents the given unsigned integer.
|
||||
pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<Const, Error> {
|
||||
pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
|
||||
with(|cx| cx.try_new_const_uint(value, uint_ty))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct ConstId(usize);
|
||||
pub struct MirConstId(usize);
|
||||
|
||||
type Ident = Opaque;
|
||||
|
||||
@ -484,7 +521,7 @@ pub enum RigidTy {
|
||||
Adt(AdtDef, GenericArgs),
|
||||
Foreign(ForeignDef),
|
||||
Str,
|
||||
Array(Ty, Const),
|
||||
Array(Ty, TyConst),
|
||||
Pat(Ty, Pattern),
|
||||
Slice(Ty),
|
||||
RawPtr(Ty, Mutability),
|
||||
@ -866,7 +903,7 @@ impl std::ops::Index<ParamTy> for GenericArgs {
|
||||
}
|
||||
|
||||
impl std::ops::Index<ParamConst> for GenericArgs {
|
||||
type Output = Const;
|
||||
type Output = TyConst;
|
||||
|
||||
fn index(&self, index: ParamConst) -> &Self::Output {
|
||||
self.0[index.index as usize].expect_const()
|
||||
@ -877,7 +914,7 @@ impl std::ops::Index<ParamConst> for GenericArgs {
|
||||
pub enum GenericArgKind {
|
||||
Lifetime(Region),
|
||||
Type(Ty),
|
||||
Const(Const),
|
||||
Const(TyConst),
|
||||
}
|
||||
|
||||
impl GenericArgKind {
|
||||
@ -894,7 +931,7 @@ impl GenericArgKind {
|
||||
/// Panic if this generic argument is not a const, otherwise
|
||||
/// return the const.
|
||||
#[track_caller]
|
||||
pub fn expect_const(&self) -> &Const {
|
||||
pub fn expect_const(&self) -> &TyConst {
|
||||
match self {
|
||||
GenericArgKind::Const(c) => c,
|
||||
_ => panic!("{self:?}"),
|
||||
@ -913,7 +950,7 @@ impl GenericArgKind {
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum TermKind {
|
||||
Type(Ty),
|
||||
Const(Const),
|
||||
Const(TyConst),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@ -1202,6 +1239,7 @@ impl Allocation {
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum ConstantKind {
|
||||
Ty(TyConst),
|
||||
Allocated(Allocation),
|
||||
Unevaluated(UnevaluatedConst),
|
||||
Param(ParamConst),
|
||||
@ -1335,7 +1373,7 @@ pub enum PredicateKind {
|
||||
ObjectSafe(TraitDef),
|
||||
SubType(SubtypePredicate),
|
||||
Coerce(CoercePredicate),
|
||||
ConstEquate(Const, Const),
|
||||
ConstEquate(TyConst, TyConst),
|
||||
Ambiguous,
|
||||
AliasRelate(TermKind, TermKind, AliasRelationDirection),
|
||||
}
|
||||
@ -1346,9 +1384,9 @@ pub enum ClauseKind {
|
||||
RegionOutlives(RegionOutlivesPredicate),
|
||||
TypeOutlives(TypeOutlivesPredicate),
|
||||
Projection(ProjectionPredicate),
|
||||
ConstArgHasType(Const, Ty),
|
||||
ConstArgHasType(TyConst, Ty),
|
||||
WellFormed(GenericArgKind),
|
||||
ConstEvaluatable(Const),
|
||||
ConstEvaluatable(TyConst),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@ -1426,7 +1464,8 @@ macro_rules! index_impl {
|
||||
};
|
||||
}
|
||||
|
||||
index_impl!(ConstId);
|
||||
index_impl!(TyConstId);
|
||||
index_impl!(MirConstId);
|
||||
index_impl!(Ty);
|
||||
index_impl!(Span);
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::Opaque;
|
||||
use crate::{ty::TyConst, Opaque};
|
||||
|
||||
use super::ty::{
|
||||
Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
|
||||
Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
|
||||
Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
|
||||
MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
|
||||
};
|
||||
|
||||
pub trait Visitor: Sized {
|
||||
@ -12,7 +12,7 @@ pub trait Visitor: Sized {
|
||||
fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
|
||||
ty.super_visit(self)
|
||||
}
|
||||
fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
|
||||
fn visit_const(&mut self, c: &TyConst) -> ControlFlow<Self::Break> {
|
||||
c.super_visit(self)
|
||||
}
|
||||
fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
|
||||
@ -42,12 +42,32 @@ impl Visitable for Ty {
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitable for Const {
|
||||
impl Visitable for TyConst {
|
||||
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||
visitor.visit_const(self)
|
||||
}
|
||||
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||
match &self.kind {
|
||||
crate::ty::TyConstKind::Param(_) => {}
|
||||
crate::ty::TyConstKind::Bound(_, _) => {}
|
||||
crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
|
||||
crate::ty::TyConstKind::Value(ty, alloc) => {
|
||||
alloc.visit(visitor)?;
|
||||
ty.visit(visitor)?;
|
||||
}
|
||||
crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitable for MirConst {
|
||||
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||
self.super_visit(visitor)
|
||||
}
|
||||
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||
match &self.kind() {
|
||||
super::ty::ConstantKind::Ty(ct) => ct.visit(visitor)?,
|
||||
super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
|
||||
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
|
||||
super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {}
|
||||
|
@ -1,11 +0,0 @@
|
||||
//@ known-bug: #119830
|
||||
#![feature(effects)]
|
||||
#![feature(min_specialization)]
|
||||
|
||||
trait Specialize {}
|
||||
|
||||
trait Foo {}
|
||||
|
||||
impl<T> const Foo for T {}
|
||||
|
||||
impl<T> const Foo for T where T: const Specialize {}
|
@ -1,13 +1,16 @@
|
||||
// This test ensures that it's not crashing rustdoc.
|
||||
|
||||
pub struct Foo<'a, 'b, T> {
|
||||
field1: dyn Bar<'a, 'b,>,
|
||||
field1: dyn Bar<'a, 'b>,
|
||||
//~^ ERROR
|
||||
//~| ERROR
|
||||
//~| ERROR
|
||||
}
|
||||
|
||||
pub trait Bar<'x, 's, U>
|
||||
where U: 'x,
|
||||
Self:'x,
|
||||
Self:'s
|
||||
{}
|
||||
where
|
||||
U: 'x,
|
||||
Self: 'x,
|
||||
Self: 's,
|
||||
{
|
||||
}
|
||||
|
@ -1,26 +1,43 @@
|
||||
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/unable-fulfill-trait.rs:4:17
|
||||
|
|
||||
LL | field1: dyn Bar<'a, 'b,>,
|
||||
LL | field1: dyn Bar<'a, 'b>,
|
||||
| ^^^ expected 1 generic argument
|
||||
|
|
||||
note: trait defined here, with 1 generic parameter: `U`
|
||||
--> $DIR/unable-fulfill-trait.rs:9:11
|
||||
--> $DIR/unable-fulfill-trait.rs:10:11
|
||||
|
|
||||
LL | pub trait Bar<'x, 's, U>
|
||||
| ^^^ -
|
||||
help: add missing generic argument
|
||||
|
|
||||
LL | field1: dyn Bar<'a, 'b, U,>,
|
||||
LL | field1: dyn Bar<'a, 'b, U>,
|
||||
| +++
|
||||
|
||||
error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
|
||||
--> $DIR/unable-fulfill-trait.rs:4:13
|
||||
|
|
||||
LL | field1: dyn Bar<'a, 'b,>,
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | field1: dyn Bar<'a, 'b>,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0478]: lifetime bound not satisfied
|
||||
--> $DIR/unable-fulfill-trait.rs:4:13
|
||||
|
|
||||
LL | field1: dyn Bar<'a, 'b>,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lifetime parameter instantiated with the lifetime `'b` as defined here
|
||||
--> $DIR/unable-fulfill-trait.rs:3:20
|
||||
|
|
||||
LL | pub struct Foo<'a, 'b, T> {
|
||||
| ^^
|
||||
note: but lifetime parameter must outlive the lifetime `'a` as defined here
|
||||
--> $DIR/unable-fulfill-trait.rs:3:16
|
||||
|
|
||||
LL | pub struct Foo<'a, 'b, T> {
|
||||
| ^^
|
||||
|
||||
Some errors have detailed explanations: E0107, E0227.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0227, E0478.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
@ -22,7 +22,7 @@ use rustc_smir::rustc_internal;
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
use stable_mir::mir::mono::Instance;
|
||||
use stable_mir::mir::{Body, Constant, Operand, Rvalue, StatementKind, TerminatorKind};
|
||||
use stable_mir::ty::{Const, ConstantKind};
|
||||
use stable_mir::ty::{ConstantKind, MirConst};
|
||||
use stable_mir::{CrateDef, CrateItems, ItemKind};
|
||||
use std::convert::TryFrom;
|
||||
use std::io::Write;
|
||||
@ -77,7 +77,7 @@ fn check_msg(body: &Body, expected: &str) {
|
||||
};
|
||||
assert_eq!(alloc.provenance.ptrs.len(), 1);
|
||||
|
||||
let alloc_prov_id = alloc.provenance.ptrs[0].1 .0;
|
||||
let alloc_prov_id = alloc.provenance.ptrs[0].1.0;
|
||||
let GlobalAlloc::Memory(val) = GlobalAlloc::from(alloc_prov_id) else {
|
||||
unreachable!()
|
||||
};
|
||||
@ -95,7 +95,7 @@ fn change_panic_msg(mut body: Body, new_msg: &str) -> Body {
|
||||
for bb in &mut body.blocks {
|
||||
match &mut bb.terminator.kind {
|
||||
TerminatorKind::Call { args, .. } => {
|
||||
let new_const = Const::from_str(new_msg);
|
||||
let new_const = MirConst::from_str(new_msg);
|
||||
args[0] = Operand::Constant(Constant {
|
||||
literal: new_const,
|
||||
span: bb.terminator.span,
|
||||
|
@ -13,7 +13,7 @@ impl<T> Windows { //~ ERROR: missing generics for struct `Windows`
|
||||
|
||||
impl<T> Windows<T> {
|
||||
fn T() -> Option<Self::Item> {}
|
||||
//~^ ERROR: ambiguous associated type
|
||||
//[no_gate]~^ ERROR: ambiguous associated type
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -20,20 +20,7 @@ help: add missing generic argument
|
||||
LL | impl<T> Windows<T> {
|
||||
| +++
|
||||
|
||||
error[E0223]: ambiguous associated type
|
||||
--> $DIR/issue-109071.rs:15:22
|
||||
|
|
||||
LL | fn T() -> Option<Self::Item> {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: use fully-qualified syntax
|
||||
|
|
||||
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0223, E0637.
|
||||
Some errors have detailed explanations: E0107, E0637.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
@ -8,6 +8,5 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d`
|
||||
}
|
||||
|
||||
fn test(_: Lexer::Cursor) {}
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
|
||||
fn main() {}
|
||||
|
@ -6,15 +6,6 @@ LL | impl Lexer<'d> {
|
||||
| |
|
||||
| help: consider introducing lifetime `'d` here: `<'d>`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-109299.rs:10:1
|
||||
|
|
||||
LL | fn test(_: Lexer::Cursor) {}
|
||||
| ^^^^^^^^-^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | has type `Lexer<'1>::Cursor`
|
||||
| requires that `'1` must outlive `'static`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
@ -5,7 +5,6 @@ struct DataWrapper<'static> {
|
||||
//~^ ERROR invalid lifetime parameter name: `'static`
|
||||
data: &'a [u8; Self::SIZE],
|
||||
//~^ ERROR use of undeclared lifetime name `'a`
|
||||
//~^^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
impl DataWrapper<'a> {
|
||||
|
@ -14,7 +14,7 @@ LL | data: &'a [u8; Self::SIZE],
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/generic_const_early_param.rs:11:18
|
||||
--> $DIR/generic_const_early_param.rs:10:18
|
||||
|
|
||||
LL | impl DataWrapper<'a> {
|
||||
| - ^^ undeclared lifetime
|
||||
@ -30,13 +30,7 @@ LL | #![feature(generic_const_exprs)]
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/generic_const_early_param.rs:6:20
|
||||
|
|
||||
LL | data: &'a [u8; Self::SIZE],
|
||||
| ^^^^^^^^^^ requires that `'_` must outlive `'static`
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0261, E0262.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
|
@ -15,6 +15,7 @@ where
|
||||
{
|
||||
type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
//~^ ERROR private type
|
||||
//~| ERROR private type
|
||||
fn assoc_fn() -> Self::AssocTy {
|
||||
Const
|
||||
}
|
||||
|
@ -7,6 +7,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
||||
--> $DIR/eval-privacy.rs:16:5
|
||||
|
|
||||
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
| ^^^^^^^^^^^^ can't leak private type
|
||||
...
|
||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0446`.
|
||||
|
@ -7,7 +7,7 @@ LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71381.rs:22:40
|
||||
--> $DIR/issue-71381.rs:23:40
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
@ -7,13 +7,29 @@ LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71381.rs:22:40
|
||||
--> $DIR/issue-71381.rs:23:40
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:14:61
|
||||
|
|
||||
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:23:19
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
@ -13,6 +13,7 @@ unsafe extern "C" fn pass(args: PassArg) {
|
||||
impl Test {
|
||||
pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//[min]~^^ ERROR: using function pointers as const generic parameters is forbidden
|
||||
self.0 = Self::trampiline::<Args, IDX, FN> as _
|
||||
}
|
||||
|
||||
@ -21,6 +22,7 @@ impl Test {
|
||||
const IDX: usize,
|
||||
const FN: unsafe extern "C" fn(Args),
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//[min]~^^ ERROR: using function pointers as const generic parameters is forbidden
|
||||
>(
|
||||
args: Args,
|
||||
) {
|
||||
|
@ -6,6 +6,14 @@ LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
||||
|
|
||||
= note: type parameters may not be used in the type of const parameters
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71611.rs:5:21
|
||||
|
|
||||
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
fn func<A, const F: fn(inner: A)>(outer: A) {
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//[min]~| ERROR: using function pointers as const generic parameters is forbidden
|
||||
F(outer);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ impl Opcode2 {
|
||||
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
|
||||
move |i| match msg_type {
|
||||
Opcode2::OP2 => unimplemented!(),
|
||||
//~^ ERROR: could not evaluate constant pattern
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,13 @@ help: you might be missing a type parameter
|
||||
LL | pub struct Opcode2<S>(&'a S);
|
||||
| +++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
|
||||
|
|
||||
LL | Opcode2::OP2 => unimplemented!(),
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0412.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
|
@ -0,0 +1,15 @@
|
||||
error[E0277]: Very important message!
|
||||
--> $DIR/type_mismatch.rs:25:14
|
||||
|
|
||||
LL | verify::<u8>();
|
||||
| ^^ the trait `TheImportantOne` is not implemented for `u8`
|
||||
|
|
||||
note: required by a bound in `verify`
|
||||
--> $DIR/type_mismatch.rs:22:14
|
||||
|
|
||||
LL | fn verify<T: TheImportantOne>() {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `verify`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,15 @@
|
||||
error[E0277]: Very important message!
|
||||
--> $DIR/type_mismatch.rs:25:14
|
||||
|
|
||||
LL | verify::<u8>();
|
||||
| ^^ the trait `TheImportantOne` is not implemented for `u8`
|
||||
|
|
||||
note: required by a bound in `verify`
|
||||
--> $DIR/type_mismatch.rs:22:14
|
||||
|
|
||||
LL | fn verify<T: TheImportantOne>() {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `verify`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,27 @@
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(do_not_recommend)]
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Very important message!")]
|
||||
trait TheImportantOne {}
|
||||
|
||||
trait ImplementationDetail {
|
||||
type Restriction;
|
||||
}
|
||||
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T: ImplementationDetail<Restriction = ()>> TheImportantOne for T {}
|
||||
|
||||
// Comment out this `impl` to show the expected error message.
|
||||
impl ImplementationDetail for u8 {
|
||||
type Restriction = u8;
|
||||
}
|
||||
|
||||
fn verify<T: TheImportantOne>() {}
|
||||
|
||||
pub fn main() {
|
||||
verify::<u8>();
|
||||
//~^ERROR: Very important message! [E0277]
|
||||
}
|
@ -9,7 +9,6 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
|
||||
//~^ ERROR missing generics for associated type
|
||||
//~^^ ERROR missing generics for associated type
|
||||
//~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
//~| ERROR may not live long enough
|
||||
t
|
||||
}
|
||||
}
|
||||
|
@ -51,16 +51,7 @@ help: add missing lifetime argument
|
||||
LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
|
||||
| ++++
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/gat-trait-path-missing-lifetime.rs:8:3
|
||||
|
|
||||
LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
|
||||
| ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | lifetime `'a` defined here
|
||||
| requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0049, E0107.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
|
@ -52,5 +52,4 @@ fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
|
||||
pub fn main() {
|
||||
let doc = create_doc();
|
||||
let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
|
||||
//~^ ERROR: `doc` does not live long enough
|
||||
}
|
||||
|
@ -27,21 +27,7 @@ LL | type Cursor<'a>: DocCursor<'a>;
|
||||
= note: this bound is currently required to ensure that impls have maximum flexibility
|
||||
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
|
||||
|
||||
error[E0597]: `doc` does not live long enough
|
||||
--> $DIR/issue-70304.rs:54:59
|
||||
|
|
||||
LL | let doc = create_doc();
|
||||
| --- binding `doc` declared here
|
||||
LL | let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
|
||||
| ------------^^^^-
|
||||
| | |
|
||||
| | borrowed value does not live long enough
|
||||
| argument requires that `doc` is borrowed for `'static`
|
||||
LL |
|
||||
LL | }
|
||||
| - `doc` dropped here while still borrowed
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0597, E0637.
|
||||
Some errors have detailed explanations: E0106, E0637.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
||||
|
@ -9,6 +9,9 @@ impl Provider for () {
|
||||
struct Holder<B> {
|
||||
inner: Box<dyn Provider<A = B>>,
|
||||
//~^ ERROR: missing generics for associated type
|
||||
//~| ERROR: missing generics for associated type
|
||||
//~| ERROR: missing generics for associated type
|
||||
//~| ERROR: the trait `Provider` cannot be made into an object
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -14,6 +14,57 @@ help: add missing lifetime argument
|
||||
LL | inner: Box<dyn Provider<A<'a> = B>>,
|
||||
| ++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0107]: missing generics for associated type `Provider::A`
|
||||
--> $DIR/issue-71176.rs:10:27
|
||||
|
|
||||
LL | inner: Box<dyn Provider<A = B>>,
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/issue-71176.rs:2:10
|
||||
|
|
||||
LL | type A<'a>;
|
||||
| ^ --
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: add missing lifetime argument
|
||||
|
|
||||
LL | inner: Box<dyn Provider<A<'a> = B>>,
|
||||
| ++++
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
||||
error[E0107]: missing generics for associated type `Provider::A`
|
||||
--> $DIR/issue-71176.rs:10:27
|
||||
|
|
||||
LL | inner: Box<dyn Provider<A = B>>,
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/issue-71176.rs:2:10
|
||||
|
|
||||
LL | type A<'a>;
|
||||
| ^ --
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: add missing lifetime argument
|
||||
|
|
||||
LL | inner: Box<dyn Provider<A<'a> = B>>,
|
||||
| ++++
|
||||
|
||||
error[E0038]: the trait `Provider` cannot be made into an object
|
||||
--> $DIR/issue-71176.rs:10:14
|
||||
|
|
||||
LL | inner: Box<dyn Provider<A = B>>,
|
||||
| ^^^^^^^^^^^^^^^^^^^ `Provider` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/issue-71176.rs:2:10
|
||||
|
|
||||
LL | trait Provider {
|
||||
| -------- this trait cannot be made into an object...
|
||||
LL | type A<'a>;
|
||||
| ^ ...because it contains the generic associated type `A`
|
||||
= help: consider moving `A` to another trait
|
||||
= help: only type `()` implements the trait, consider using it directly instead
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0038, E0107.
|
||||
For more information about an error, try `rustc --explain E0038`.
|
||||
|
@ -22,8 +22,7 @@ fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
|
||||
//~^ ERROR missing generics for associated type
|
||||
{
|
||||
for n in 0i16..100 {
|
||||
*dst.test_mut() = n.into(); //~ ERROR: cannot borrow
|
||||
//~^ ERROR: borrowed data escapes outside of function
|
||||
*dst.test_mut() = n.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,30 +25,6 @@ help: add missing lifetime argument
|
||||
LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output<'a> = &'a mut f32>)
|
||||
| ++++
|
||||
|
||||
error[E0499]: cannot borrow `*dst` as mutable more than once at a time
|
||||
--> $DIR/issue-80433.rs:25:10
|
||||
|
|
||||
LL | *dst.test_mut() = n.into();
|
||||
| ^^^-----------
|
||||
| |
|
||||
| `*dst` was mutably borrowed here in the previous iteration of the loop
|
||||
| argument requires that `*dst` is borrowed for `'static`
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error[E0521]: borrowed data escapes outside of function
|
||||
--> $DIR/issue-80433.rs:25:10
|
||||
|
|
||||
LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
|
||||
| -- --- `dst` is a reference that is only valid in the function body
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | *dst.test_mut() = n.into();
|
||||
| ^^^^^^^^^^^^^^
|
||||
| |
|
||||
| `dst` escapes the function body here
|
||||
| argument requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0499, E0521.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
For more information about this error, try `rustc --explain E0107`.
|
||||
|
@ -1,11 +1,9 @@
|
||||
// issue: 114146
|
||||
|
||||
|
||||
trait Foo {
|
||||
fn bar<'other: 'a>() -> impl Sized + 'a {}
|
||||
//~^ ERROR use of undeclared lifetime name `'a`
|
||||
//~| ERROR use of undeclared lifetime name `'a`
|
||||
//~| ERROR expected generic lifetime parameter, found `'static`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:20
|
||||
--> $DIR/bad-item-bound-within-rpitit-2.rs:4:20
|
||||
|
|
||||
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
|
||||
| ^^ undeclared lifetime
|
||||
@ -14,7 +14,7 @@ LL | trait Foo<'a> {
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:42
|
||||
--> $DIR/bad-item-bound-within-rpitit-2.rs:4:42
|
||||
|
|
||||
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
|
||||
| ^^ undeclared lifetime
|
||||
@ -28,15 +28,6 @@ help: consider introducing lifetime `'a` here
|
||||
LL | trait Foo<'a> {
|
||||
| ++++
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'static`
|
||||
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:45
|
||||
|
|
||||
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
|
||||
| ------ ^^
|
||||
| |
|
||||
| cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0792.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
@ -7,7 +7,7 @@ struct Wrap<F>(F);
|
||||
|
||||
impl<A, B, F> MyFn<A> for Wrap<F>
|
||||
where
|
||||
F: Fn(A) -> B
|
||||
F: Fn(A) -> B,
|
||||
{
|
||||
type Output = B;
|
||||
|
||||
@ -16,13 +16,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct A;
|
||||
fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||
fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> {
|
||||
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
Wrap(|a| Some(a).into_iter())
|
||||
//~^ ERROR implementation of `FnOnce` is not general enough
|
||||
//~| ERROR implementation of `FnOnce` is not general enough
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,34 +1,15 @@
|
||||
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
--> $DIR/issue-67830.rs:21:62
|
||||
--> $DIR/issue-67830.rs:20:64
|
||||
|
|
||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||
| ^^
|
||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> {
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-67830.rs:21:23
|
||||
--> $DIR/issue-67830.rs:20:23
|
||||
|
|
||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> {
|
||||
| ^^
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-67830.rs:23:5
|
||||
|
|
||||
LL | Wrap(|a| Some(a).into_iter())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-67830.rs:23:5
|
||||
|
|
||||
LL | Wrap(|a| Some(a).into_iter())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0657`.
|
||||
|
@ -18,16 +18,11 @@ fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
&()
|
||||
//~^ ERROR implementation of `Hrtb` is not general enough
|
||||
//~| ERROR implementation of `Hrtb` is not general enough
|
||||
}
|
||||
|
||||
fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
x
|
||||
//~^ ERROR implementation of `Hrtb` is not general enough
|
||||
//~| ERROR implementation of `Hrtb` is not general enough
|
||||
//~| ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -22,72 +22,18 @@ note: lifetime declared here
|
||||
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:20:5
|
||||
|
|
||||
LL | &()
|
||||
| ^^^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:20:5
|
||||
|
|
||||
LL | &()
|
||||
| ^^^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'a>` would have to be implemented for the type `&()`
|
||||
= note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0`
|
||||
|
||||
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
--> $DIR/issue-88236-2.rs:25:78
|
||||
--> $DIR/issue-88236-2.rs:23:78
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-88236-2.rs:25:45
|
||||
--> $DIR/issue-88236-2.rs:23:45
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-88236-2.rs:27:5
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| -- lifetime `'b` defined here
|
||||
LL |
|
||||
LL | x
|
||||
| ^ returning this value requires that `'b` must outlive `'static`
|
||||
|
|
||||
help: to declare that `impl for<'a> Hrtb<'a, Assoc = impl Send + '_>` captures data from argument `x`, you can add an explicit `'b` lifetime bound
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b {
|
||||
| ++++
|
||||
help: to declare that `impl Send + 'a` captures data from argument `x`, you can add an explicit `'b` lifetime bound
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> {
|
||||
| ++++
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:27:5
|
||||
|
|
||||
LL | x
|
||||
| ^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:27:5
|
||||
|
|
||||
LL | x
|
||||
| ^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'a>` would have to be implemented for the type `&()`
|
||||
= note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0657`.
|
||||
|
@ -31,7 +31,6 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||
|
||||
fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
//~| ERROR implementation of `Bar` is not general enough
|
||||
|
||||
fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
@ -64,6 +63,5 @@ fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<
|
||||
// `'b` is not in scope for the outlives bound.
|
||||
fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
|
||||
//~| ERROR implementation of `Bar` is not general enough
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/nested-rpit-hrtb.rs:57:77
|
||||
--> $DIR/nested-rpit-hrtb.rs:56:77
|
||||
|
|
||||
LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ^^ undeclared lifetime
|
||||
@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/nested-rpit-hrtb.rs:65:82
|
||||
--> $DIR/nested-rpit-hrtb.rs:64:82
|
||||
|
|
||||
LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ^^ undeclared lifetime
|
||||
@ -65,29 +65,20 @@ note: lifetime declared here
|
||||
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||
| ^^
|
||||
|
||||
error: implementation of `Bar` is not general enough
|
||||
--> $DIR/nested-rpit-hrtb.rs:32:78
|
||||
|
|
||||
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||
| ^^ implementation of `Bar` is not general enough
|
||||
|
|
||||
= note: `()` must implement `Bar<'a>`
|
||||
= note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
|
||||
|
||||
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||
--> $DIR/nested-rpit-hrtb.rs:36:73
|
||||
--> $DIR/nested-rpit-hrtb.rs:35:73
|
||||
|
|
||||
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/nested-rpit-hrtb.rs:36:44
|
||||
--> $DIR/nested-rpit-hrtb.rs:35:44
|
||||
|
|
||||
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
||||
error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied
|
||||
--> $DIR/nested-rpit-hrtb.rs:46:79
|
||||
--> $DIR/nested-rpit-hrtb.rs:45:79
|
||||
|
|
||||
LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
|
||||
| ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()`
|
||||
@ -96,7 +87,7 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc
|
||||
= help: for that trait implementation, expected `()`, found `&'a ()`
|
||||
|
||||
error: implementation of `Bar` is not general enough
|
||||
--> $DIR/nested-rpit-hrtb.rs:50:93
|
||||
--> $DIR/nested-rpit-hrtb.rs:49:93
|
||||
|
|
||||
LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
|
||||
| ^^ implementation of `Bar` is not general enough
|
||||
@ -105,7 +96,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc =
|
||||
= note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
|
||||
|
||||
error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied
|
||||
--> $DIR/nested-rpit-hrtb.rs:61:64
|
||||
--> $DIR/nested-rpit-hrtb.rs:60:64
|
||||
|
|
||||
LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()`
|
||||
@ -113,16 +104,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b>
|
||||
= help: the trait `Qux<'_>` is implemented for `()`
|
||||
= help: for that trait implementation, expected `()`, found `&'a ()`
|
||||
|
||||
error: implementation of `Bar` is not general enough
|
||||
--> $DIR/nested-rpit-hrtb.rs:65:86
|
||||
|
|
||||
LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ^^ implementation of `Bar` is not general enough
|
||||
|
|
||||
= note: `()` must implement `Bar<'a>`
|
||||
= note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0277, E0657.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
|
@ -8,6 +8,9 @@ static FOO: (dyn AsRef<OsStr>, u8) = ("hello", 42);
|
||||
|
||||
const BAR: (&Path, [u8], usize) = ("hello", [], 42);
|
||||
//~^ ERROR cannot find type `Path` in this scope
|
||||
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
//~| ERROR mismatched types
|
||||
|
||||
static BAZ: ([u8], usize) = ([], 0);
|
||||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
|
@ -21,7 +21,35 @@ LL + use std::path::Path;
|
||||
|
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/issue-84108.rs:12:13
|
||||
--> $DIR/issue-84108.rs:9:12
|
||||
|
|
||||
LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/issue-84108.rs:9:12
|
||||
|
|
||||
LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-84108.rs:9:45
|
||||
|
|
||||
LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
|
||||
| ^^ expected `[u8]`, found `[_; 0]`
|
||||
|
|
||||
= note: expected slice `[u8]`
|
||||
found array `[_; 0]`
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/issue-84108.rs:15:13
|
||||
|
|
||||
LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
@ -30,7 +58,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/issue-84108.rs:12:13
|
||||
--> $DIR/issue-84108.rs:15:13
|
||||
|
|
||||
LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
@ -40,7 +68,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-84108.rs:12:30
|
||||
--> $DIR/issue-84108.rs:15:30
|
||||
|
|
||||
LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
| ^^ expected `[u8]`, found `[_; 0]`
|
||||
@ -48,7 +76,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
= note: expected slice `[u8]`
|
||||
found array `[_; 0]`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308, E0412.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -11,7 +11,7 @@ impl A {
|
||||
}
|
||||
async fn f() {
|
||||
let mut buf = [0; 512];
|
||||
let m2 = &buf[..]; //~ ERROR `buf` does not live long enough
|
||||
let m2 = &buf[..];
|
||||
let m = Self::g(m2).await;
|
||||
Self::f2(m).await;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ impl A {
|
||||
}
|
||||
async fn f() {
|
||||
let mut buf = [0; 512];
|
||||
let m2 = &buf[..]; //~ ERROR `buf` does not live long enough
|
||||
let m2 = &buf[..];
|
||||
let m = Self::g(m2).await;
|
||||
Self::f2(m).await;
|
||||
}
|
||||
|
@ -9,20 +9,6 @@ help: indicate the anonymous lifetime
|
||||
LL | async fn f2(m: Msg<'_>) {}
|
||||
| ++++
|
||||
|
||||
error[E0597]: `buf` does not live long enough
|
||||
--> $DIR/issue-69314.rs:14:19
|
||||
|
|
||||
LL | let mut buf = [0; 512];
|
||||
| ------- binding `buf` declared here
|
||||
LL | let m2 = &buf[..];
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | let m = Self::g(m2).await;
|
||||
| ----------- argument requires that `buf` is borrowed for `'static`
|
||||
LL | Self::f2(m).await;
|
||||
LL | }
|
||||
| - `buf` dropped here while still borrowed
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0597, E0726.
|
||||
For more information about an error, try `rustc --explain E0597`.
|
||||
For more information about this error, try `rustc --explain E0726`.
|
||||
|
@ -2,9 +2,8 @@ struct S<'a>(&'a u8);
|
||||
fn foo() {}
|
||||
|
||||
// Paren generic args in AnonConst
|
||||
fn a() -> [u8; foo::()] {
|
||||
//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
|
||||
//~| ERROR mismatched types
|
||||
fn a() -> [u8; foo()] {
|
||||
//~^ ERROR mismatched types
|
||||
panic!()
|
||||
}
|
||||
|
||||
@ -26,5 +25,6 @@ fn d<const C: S>() {}
|
||||
trait Foo<'a> {}
|
||||
struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
|
||||
//~^ ERROR the type of const parameters must not depend on other generic parameters
|
||||
//~| ERROR `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/unusual-rib-combinations.rs:22:15
|
||||
--> $DIR/unusual-rib-combinations.rs:21:15
|
||||
|
|
||||
LL | fn d<const C: S>() {}
|
||||
| ^ expected named lifetime parameter
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/unusual-rib-combinations.rs:27:22
|
||||
--> $DIR/unusual-rib-combinations.rs:26:22
|
||||
|
|
||||
LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
|
||||
| ^^ the type must not depend on the parameter `'a`
|
||||
@ -13,25 +13,19 @@ LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
|
||||
= note: lifetime parameters may not be used in the type of const parameters
|
||||
|
||||
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
|
||||
--> $DIR/unusual-rib-combinations.rs:5:16
|
||||
|
|
||||
LL | fn a() -> [u8; foo::()] {
|
||||
| ^^^^^^^ only `Fn` traits may use parentheses
|
||||
|
||||
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
|
||||
--> $DIR/unusual-rib-combinations.rs:12:15
|
||||
--> $DIR/unusual-rib-combinations.rs:11:15
|
||||
|
|
||||
LL | fn b<const C: u8()>() {}
|
||||
| ^^^^ only `Fn` traits may use parentheses
|
||||
|
||||
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
|
||||
--> $DIR/unusual-rib-combinations.rs:16:10
|
||||
--> $DIR/unusual-rib-combinations.rs:15:10
|
||||
|
|
||||
LL | fn c<T = u8()>() {}
|
||||
| ^^^^ only `Fn` traits may use parentheses
|
||||
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/unusual-rib-combinations.rs:16:6
|
||||
--> $DIR/unusual-rib-combinations.rs:15:6
|
||||
|
|
||||
LL | fn c<T = u8()>() {}
|
||||
| ^^^^^^^^
|
||||
@ -43,14 +37,11 @@ LL | fn c<T = u8()>() {}
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unusual-rib-combinations.rs:5:16
|
||||
|
|
||||
LL | fn a() -> [u8; foo::()] {
|
||||
| ^^^^^^^ expected `usize`, found fn item
|
||||
|
|
||||
= note: expected type `usize`
|
||||
found fn item `fn() {foo}`
|
||||
LL | fn a() -> [u8; foo()] {
|
||||
| ^^^^^ expected `usize`, found `()`
|
||||
|
||||
error: `S<'_>` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/unusual-rib-combinations.rs:22:15
|
||||
--> $DIR/unusual-rib-combinations.rs:21:15
|
||||
|
|
||||
LL | fn d<const C: S>() {}
|
||||
| ^
|
||||
@ -61,6 +52,18 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
|
||||
LL + #![feature(adt_const_params)]
|
||||
|
|
||||
|
||||
error: `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/unusual-rib-combinations.rs:26:21
|
||||
|
|
||||
LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
||||
|
|
||||
LL + #![feature(adt_const_params)]
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0214, E0308, E0770.
|
||||
|
@ -7,7 +7,7 @@ LL | macro_rules! _a {
|
||||
LL | format_args!(a!());
|
||||
| ^
|
||||
|
|
||||
help: a macro with a similar name exists, consider renaming `_a` into `a`
|
||||
help: the leading underscore in `_a` marks it as unused, consider renaming it to `a`
|
||||
|
|
||||
LL | macro_rules! a {
|
||||
| ~
|
||||
@ -21,7 +21,7 @@ LL | macro_rules! _a {
|
||||
LL | env!(a!());
|
||||
| ^
|
||||
|
|
||||
help: a macro with a similar name exists, consider renaming `_a` into `a`
|
||||
help: the leading underscore in `_a` marks it as unused, consider renaming it to `a`
|
||||
|
|
||||
LL | macro_rules! a {
|
||||
| ~
|
||||
|
@ -5,3 +5,4 @@ struct Apple((Apple, Option(Banana ? Citron)));
|
||||
//~| ERROR expected one of `)` or `,`, found `Citron`
|
||||
//~| ERROR cannot find type `Citron` in this scope [E0412]
|
||||
//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
|
||||
//~| ERROR `Apple` has infinite size
|
||||
|
@ -34,7 +34,18 @@ help: use angle brackets instead
|
||||
LL | struct Apple((Apple, Option<Banana ? Citron>));
|
||||
| ~ ~
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0072]: recursive type `Apple` has infinite size
|
||||
--> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
|
||||
|
|
||||
LL | struct Apple((Apple, Option(Banana ? Citron)));
|
||||
| ^^^^^^^^^^^^ ----- recursive without indirection
|
||||
|
|
||||
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
||||
|
|
||||
LL | struct Apple((Box<Apple>, Option(Banana ? Citron)));
|
||||
| ++++ +
|
||||
|
||||
Some errors have detailed explanations: E0214, E0412.
|
||||
For more information about an error, try `rustc --explain E0214`.
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0072, E0214, E0412.
|
||||
For more information about an error, try `rustc --explain E0072`.
|
||||
|
@ -74,6 +74,7 @@ where
|
||||
{
|
||||
type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
//~^ ERROR private type
|
||||
//~| ERROR private type
|
||||
fn assoc_fn() -> Self::AssocTy {
|
||||
Const
|
||||
}
|
||||
|
@ -77,6 +77,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||
|
||||
error: aborting due to 1 previous error; 5 warnings emitted
|
||||
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
||||
--> $DIR/where-priv-type.rs:75:5
|
||||
|
|
||||
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
| ^^^^^^^^^^^^ can't leak private type
|
||||
...
|
||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors; 5 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0446`.
|
||||
|
@ -0,0 +1,24 @@
|
||||
//@ check-fail
|
||||
// Fixes #119830
|
||||
|
||||
#![feature(effects)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
trait Specialize {}
|
||||
|
||||
trait Foo {}
|
||||
|
||||
impl<T> const Foo for T {}
|
||||
//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||
//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207]
|
||||
|
||||
impl<T> const Foo for T where T: const Specialize {}
|
||||
//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||
//~| error: `const` can only be applied to `#[const_trait]` traits
|
||||
//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207]
|
||||
//~| error: specialization impl does not specialize any associated items
|
||||
//~| error: could not resolve generic parameters on overridden impl
|
||||
|
||||
fn main() {
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||
--> $DIR/spec-effectvar-ice.rs:12:15
|
||||
|
|
||||
LL | trait Foo {}
|
||||
| - help: mark `Foo` as const: `#[const_trait]`
|
||||
LL |
|
||||
LL | impl<T> const Foo for T {}
|
||||
| ^^^
|
||||
|
|
||||
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
|
||||
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||
--> $DIR/spec-effectvar-ice.rs:16:15
|
||||
|
|
||||
LL | trait Foo {}
|
||||
| - help: mark `Foo` as const: `#[const_trait]`
|
||||
...
|
||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||
| ^^^
|
||||
|
|
||||
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
|
||||
error: `const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/spec-effectvar-ice.rs:16:40
|
||||
|
|
||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/spec-effectvar-ice.rs:12:9
|
||||
|
|
||||
LL | impl<T> const Foo for T {}
|
||||
| ^^^^^ unconstrained const parameter
|
||||
|
|
||||
= note: expressions using a const parameter must map each value to a distinct output value
|
||||
= note: proving the result of expressions other than the parameter are unique is not supported
|
||||
|
||||
error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/spec-effectvar-ice.rs:16:9
|
||||
|
|
||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||
| ^^^^^ unconstrained const parameter
|
||||
|
|
||||
= note: expressions using a const parameter must map each value to a distinct output value
|
||||
= note: proving the result of expressions other than the parameter are unique is not supported
|
||||
|
||||
error: specialization impl does not specialize any associated items
|
||||
--> $DIR/spec-effectvar-ice.rs:16:1
|
||||
|
|
||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: impl is a specialization of this impl
|
||||
--> $DIR/spec-effectvar-ice.rs:12:1
|
||||
|
|
||||
LL | impl<T> const Foo for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: could not resolve generic parameters on overridden impl
|
||||
--> $DIR/spec-effectvar-ice.rs:16:1
|
||||
|
|
||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0207`.
|
@ -1,10 +1,12 @@
|
||||
error[E0425]: cannot find value `x` in this scope
|
||||
--> $DIR/silenced-binding-typo.rs:4:14
|
||||
|
|
||||
LL | let _x = 42;
|
||||
| -- `_x` defined here
|
||||
LL | let _y = x;
|
||||
| ^
|
||||
|
|
||||
help: a local variable with a similar name exists, consider renaming `_x` into `x`
|
||||
help: the leading underscore in `_x` marks it as unused, consider renaming it to `x`
|
||||
|
|
||||
LL | let x = 42;
|
||||
| ~
|
||||
|
Loading…
Reference in New Issue
Block a user