Auto merge of #136905 - matthiaskrgr:rollup-8zwcgta, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #135549 (Document some safety constraints and use more safe wrappers) - #135965 (In "specify type" suggestion, skip type params that are already known) - #136193 (Implement pattern type ffi checks) - #136646 (Add a TyPat in the AST to reuse the generic arg lowering logic) - #136874 (Change the issue number for `likely_unlikely` and `cold_path`) - #136884 (Lower fn items as ZST valtrees and delay a bug) - #136885 (i686-linux-android: increase CPU baseline to Pentium 4 (without an actual change) - #136891 (Check sig for errors before checking for unconstrained anonymous lifetime) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
33d92df3e6
57 changed files with 739 additions and 557 deletions
|
@ -2249,7 +2249,7 @@ pub enum TyKind {
|
||||||
CVarArgs,
|
CVarArgs,
|
||||||
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
|
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
|
||||||
/// just as part of the type system.
|
/// just as part of the type system.
|
||||||
Pat(P<Ty>, P<Pat>),
|
Pat(P<Ty>, P<TyPat>),
|
||||||
/// Sometimes we need a dummy value when no error has occurred.
|
/// Sometimes we need a dummy value when no error has occurred.
|
||||||
Dummy,
|
Dummy,
|
||||||
/// Placeholder for a kind that has failed to be defined.
|
/// Placeholder for a kind that has failed to be defined.
|
||||||
|
@ -2277,6 +2277,27 @@ impl TyKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A pattern type pattern.
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub struct TyPat {
|
||||||
|
pub id: NodeId,
|
||||||
|
pub kind: TyPatKind,
|
||||||
|
pub span: Span,
|
||||||
|
pub tokens: Option<LazyAttrTokenStream>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// All the different flavors of pattern that Rust recognizes.
|
||||||
|
//
|
||||||
|
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub enum TyPatKind {
|
||||||
|
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
|
||||||
|
Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
|
||||||
|
|
||||||
|
/// Placeholder for a pattern that wasn't syntactically well formed in some way.
|
||||||
|
Err(ErrorGuaranteed),
|
||||||
|
}
|
||||||
|
|
||||||
/// Syntax used to declare a trait object.
|
/// Syntax used to declare a trait object.
|
||||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
|
|
@ -210,6 +210,10 @@ pub trait MutVisitor: Sized {
|
||||||
walk_ty(self, t);
|
walk_ty(self, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_ty_pat(&mut self, t: &mut P<TyPat>) {
|
||||||
|
walk_ty_pat(self, t);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_lifetime(&mut self, l: &mut Lifetime) {
|
fn visit_lifetime(&mut self, l: &mut Lifetime) {
|
||||||
walk_lifetime(self, l);
|
walk_lifetime(self, l);
|
||||||
}
|
}
|
||||||
|
@ -570,7 +574,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
|
||||||
TyKind::Paren(ty) => vis.visit_ty(ty),
|
TyKind::Paren(ty) => vis.visit_ty(ty),
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
vis.visit_ty(ty);
|
vis.visit_ty(ty);
|
||||||
vis.visit_pat(pat);
|
vis.visit_ty_pat(pat);
|
||||||
}
|
}
|
||||||
TyKind::Path(qself, path) => {
|
TyKind::Path(qself, path) => {
|
||||||
vis.visit_qself(qself);
|
vis.visit_qself(qself);
|
||||||
|
@ -594,6 +598,20 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
|
||||||
|
let TyPat { id, kind, span, tokens } = ty.deref_mut();
|
||||||
|
vis.visit_id(id);
|
||||||
|
match kind {
|
||||||
|
TyPatKind::Range(start, end, _include_end) => {
|
||||||
|
visit_opt(start, |c| vis.visit_anon_const(c));
|
||||||
|
visit_opt(end, |c| vis.visit_anon_const(c));
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {}
|
||||||
|
}
|
||||||
|
visit_lazy_tts(vis, tokens);
|
||||||
|
vis.visit_span(span);
|
||||||
|
}
|
||||||
|
|
||||||
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
||||||
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
||||||
visit_safety(vis, safety);
|
visit_safety(vis, safety);
|
||||||
|
|
|
@ -179,6 +179,9 @@ pub trait Visitor<'ast>: Sized {
|
||||||
fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
|
fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
|
||||||
walk_ty(self, t)
|
walk_ty(self, t)
|
||||||
}
|
}
|
||||||
|
fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
|
||||||
|
walk_ty_pat(self, t)
|
||||||
|
}
|
||||||
fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result {
|
fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result {
|
||||||
walk_generic_param(self, param)
|
walk_generic_param(self, param)
|
||||||
}
|
}
|
||||||
|
@ -534,7 +537,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||||
}
|
}
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
try_visit!(visitor.visit_pat(pat));
|
try_visit!(visitor.visit_ty_pat(pat));
|
||||||
}
|
}
|
||||||
TyKind::Array(ty, length) => {
|
TyKind::Array(ty, length) => {
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
|
@ -555,6 +558,18 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||||
V::Result::output()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result {
|
||||||
|
let TyPat { id: _, kind, span: _, tokens: _ } = tp;
|
||||||
|
match kind {
|
||||||
|
TyPatKind::Range(start, end, _include_end) => {
|
||||||
|
visit_opt!(visitor, visit_anon_const, start);
|
||||||
|
visit_opt!(visitor, visit_anon_const, end);
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {}
|
||||||
|
}
|
||||||
|
V::Result::output()
|
||||||
|
}
|
||||||
|
|
||||||
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
|
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
|
||||||
if let Some(qself) = qself {
|
if let Some(qself) = qself {
|
||||||
let QSelf { ty, path_span: _, position: _ } = &**qself;
|
let QSelf { ty, path_span: _, position: _ } = &**qself;
|
||||||
|
|
|
@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::Res;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_span::source_map::{Spanned, respan};
|
use rustc_span::source_map::{Spanned, respan};
|
||||||
use rustc_span::{Ident, Span, kw};
|
use rustc_span::{Ident, Span};
|
||||||
|
|
||||||
use super::errors::{
|
use super::errors::{
|
||||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||||
|
@ -430,78 +430,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
|
pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
|
||||||
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
|
fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
|
||||||
// loop here to avoid recursion
|
// loop here to avoid recursion
|
||||||
let pat_hir_id = self.lower_node_id(pattern.id);
|
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||||
let node = loop {
|
let node = match &pattern.kind {
|
||||||
match &pattern.kind {
|
TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
|
||||||
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||||
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
|
e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||||
// That requires first modifying the AST to have const args here.
|
self.lower_range_end(end, e2.is_some()),
|
||||||
let mut lower_expr = |e: &Expr| -> &_ {
|
),
|
||||||
if let ExprKind::Path(None, path) = &e.kind
|
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
|
||||||
&& let Some(res) = self
|
|
||||||
.resolver
|
|
||||||
.get_partial_res(e.id)
|
|
||||||
.and_then(|partial_res| partial_res.full_res())
|
|
||||||
{
|
|
||||||
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
|
|
||||||
} else {
|
|
||||||
let node_id = self.next_node_id();
|
|
||||||
let def_id = self.create_def(
|
|
||||||
self.current_hir_id_owner.def_id,
|
|
||||||
node_id,
|
|
||||||
kw::Empty,
|
|
||||||
DefKind::AnonConst,
|
|
||||||
e.span,
|
|
||||||
);
|
|
||||||
let hir_id = self.lower_node_id(node_id);
|
|
||||||
let ac = self.arena.alloc(hir::AnonConst {
|
|
||||||
def_id,
|
|
||||||
hir_id,
|
|
||||||
body: self.lower_const_body(pattern.span, Some(e)),
|
|
||||||
span: self.lower_span(pattern.span),
|
|
||||||
});
|
|
||||||
self.arena.alloc(hir::ConstArg {
|
|
||||||
hir_id: self.next_id(),
|
|
||||||
kind: hir::ConstArgKind::Anon(ac),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break hir::TyPatKind::Range(
|
|
||||||
e1.as_deref().map(|e| lower_expr(e)),
|
|
||||||
e2.as_deref().map(|e| lower_expr(e)),
|
|
||||||
self.lower_range_end(end, e2.is_some()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// return inner to be processed in next loop
|
|
||||||
PatKind::Paren(inner) => pattern = inner,
|
|
||||||
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
|
||||||
PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
|
|
||||||
PatKind::Deref(..)
|
|
||||||
| PatKind::Box(..)
|
|
||||||
| PatKind::Or(..)
|
|
||||||
| PatKind::Struct(..)
|
|
||||||
| PatKind::TupleStruct(..)
|
|
||||||
| PatKind::Tuple(..)
|
|
||||||
| PatKind::Ref(..)
|
|
||||||
| PatKind::Expr(..)
|
|
||||||
| PatKind::Guard(..)
|
|
||||||
| PatKind::Slice(_)
|
|
||||||
| PatKind::Ident(..)
|
|
||||||
| PatKind::Path(..)
|
|
||||||
| PatKind::Wild
|
|
||||||
| PatKind::Never
|
|
||||||
| PatKind::Rest => {
|
|
||||||
break hir::TyPatKind::Err(
|
|
||||||
self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
||||||
|
|
|
@ -1148,6 +1148,28 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_ty_pat(&mut self, pat: &ast::TyPat) {
|
||||||
|
match &pat.kind {
|
||||||
|
rustc_ast::TyPatKind::Range(start, end, include_end) => {
|
||||||
|
if let Some(start) = start {
|
||||||
|
self.print_expr_anon_const(start, &[]);
|
||||||
|
}
|
||||||
|
self.word("..");
|
||||||
|
if let Some(end) = end {
|
||||||
|
if let RangeEnd::Included(_) = include_end.node {
|
||||||
|
self.word("=");
|
||||||
|
}
|
||||||
|
self.print_expr_anon_const(end, &[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rustc_ast::TyPatKind::Err(_) => {
|
||||||
|
self.popen();
|
||||||
|
self.word("/*ERROR*/");
|
||||||
|
self.pclose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_type(&mut self, ty: &ast::Ty) {
|
pub fn print_type(&mut self, ty: &ast::Ty) {
|
||||||
self.maybe_print_comment(ty.span.lo());
|
self.maybe_print_comment(ty.span.lo());
|
||||||
self.ibox(0);
|
self.ibox(0);
|
||||||
|
@ -1252,7 +1274,7 @@ impl<'a> State<'a> {
|
||||||
ast::TyKind::Pat(ty, pat) => {
|
ast::TyKind::Pat(ty, pat) => {
|
||||||
self.print_type(ty);
|
self.print_type(ty);
|
||||||
self.word(" is ");
|
self.word(" is ");
|
||||||
self.print_pat(pat);
|
self.print_ty_pat(pat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.end();
|
self.end();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::{Pat, Ty, ast};
|
use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast};
|
||||||
use rustc_errors::PResult;
|
use rustc_errors::PResult;
|
||||||
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
|
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
|
||||||
use rustc_parse::exp;
|
use rustc_parse::exp;
|
||||||
|
@ -21,12 +21,24 @@ pub(crate) fn expand<'cx>(
|
||||||
ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::Pat(ty, pat))))
|
ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::Pat(ty, pat))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<Pat>)> {
|
fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<TyPat>)> {
|
||||||
let mut parser = cx.new_parser_from_tts(stream);
|
let mut parser = cx.new_parser_from_tts(stream);
|
||||||
|
|
||||||
let ty = parser.parse_ty()?;
|
let ty = parser.parse_ty()?;
|
||||||
parser.expect_keyword(exp!(Is))?;
|
parser.expect_keyword(exp!(Is))?;
|
||||||
let pat = parser.parse_pat_no_top_alt(None, None)?;
|
let pat = parser.parse_pat_no_top_alt(None, None)?.into_inner();
|
||||||
|
|
||||||
|
let kind = match pat.kind {
|
||||||
|
ast::PatKind::Range(start, end, include_end) => TyPatKind::Range(
|
||||||
|
start.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
|
||||||
|
end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
|
||||||
|
include_end,
|
||||||
|
),
|
||||||
|
ast::PatKind::Err(guar) => TyPatKind::Err(guar),
|
||||||
|
_ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pat = P(TyPat { id: pat.id, kind, span: pat.span, tokens: pat.tokens });
|
||||||
|
|
||||||
Ok((ty, pat))
|
Ok((ty, pat))
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,13 +81,13 @@ pub(crate) unsafe fn codegen(
|
||||||
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
||||||
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
|
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
|
||||||
let llval = llvm::LLVMConstInt(i8, val as u64, False);
|
let llval = llvm::LLVMConstInt(i8, val as u64, False);
|
||||||
llvm::LLVMSetInitializer(ll_g, llval);
|
llvm::set_initializer(ll_g, llval);
|
||||||
|
|
||||||
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
|
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
|
||||||
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8);
|
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8);
|
||||||
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
||||||
let llval = llvm::LLVMConstInt(i8, 0, False);
|
let llval = llvm::LLVMConstInt(i8, 0, False);
|
||||||
llvm::LLVMSetInitializer(ll_g, llval);
|
llvm::set_initializer(ll_g, llval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcx.sess.opts.debuginfo != DebugInfo::None {
|
if tcx.sess.opts.debuginfo != DebugInfo::None {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use rustc_codegen_ssa::back::archive::{
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
|
||||||
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
||||||
use crate::llvm::{self, ArchiveKind};
|
use crate::llvm::{self, ArchiveKind, last_error};
|
||||||
|
|
||||||
/// Helper for adding many files to an archive.
|
/// Helper for adding many files to an archive.
|
||||||
#[must_use = "must call build() to finish building the archive"]
|
#[must_use = "must call build() to finish building the archive"]
|
||||||
|
@ -169,6 +169,8 @@ impl<'a> LlvmArchiveBuilder<'a> {
|
||||||
.unwrap_or_else(|kind| self.sess.dcx().emit_fatal(UnknownArchiveKind { kind }));
|
.unwrap_or_else(|kind| self.sess.dcx().emit_fatal(UnknownArchiveKind { kind }));
|
||||||
|
|
||||||
let mut additions = mem::take(&mut self.additions);
|
let mut additions = mem::take(&mut self.additions);
|
||||||
|
// Values in the `members` list below will contain pointers to the strings allocated here.
|
||||||
|
// So they need to get dropped after all elements of `members` get freed.
|
||||||
let mut strings = Vec::new();
|
let mut strings = Vec::new();
|
||||||
let mut members = Vec::new();
|
let mut members = Vec::new();
|
||||||
|
|
||||||
|
@ -229,12 +231,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
|
||||||
self.sess.target.arch == "arm64ec",
|
self.sess.target.arch == "arm64ec",
|
||||||
);
|
);
|
||||||
let ret = if r.into_result().is_err() {
|
let ret = if r.into_result().is_err() {
|
||||||
let err = llvm::LLVMRustGetLastError();
|
let msg = last_error().unwrap_or_else(|| "failed to write archive".into());
|
||||||
let msg = if err.is_null() {
|
|
||||||
"failed to write archive".into()
|
|
||||||
} else {
|
|
||||||
String::from_utf8_lossy(CStr::from_ptr(err).to_bytes())
|
|
||||||
};
|
|
||||||
Err(io::Error::new(io::ErrorKind::Other, msg))
|
Err(io::Error::new(io::ErrorKind::Other, msg))
|
||||||
} else {
|
} else {
|
||||||
Ok(!members.is_empty())
|
Ok(!members.is_empty())
|
||||||
|
|
|
@ -40,7 +40,7 @@ use crate::errors::{
|
||||||
WithLlvmError, WriteBytecode,
|
WithLlvmError, WriteBytecode,
|
||||||
};
|
};
|
||||||
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
|
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
|
||||||
use crate::llvm::{self, DiagnosticInfo, PassManager};
|
use crate::llvm::{self, DiagnosticInfo};
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
|
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> Fatal
|
||||||
fn write_output_file<'ll>(
|
fn write_output_file<'ll>(
|
||||||
dcx: DiagCtxtHandle<'_>,
|
dcx: DiagCtxtHandle<'_>,
|
||||||
target: &'ll llvm::TargetMachine,
|
target: &'ll llvm::TargetMachine,
|
||||||
pm: &llvm::PassManager<'ll>,
|
no_builtins: bool,
|
||||||
m: &'ll llvm::Module,
|
m: &'ll llvm::Module,
|
||||||
output: &Path,
|
output: &Path,
|
||||||
dwo_output: Option<&Path>,
|
dwo_output: Option<&Path>,
|
||||||
|
@ -63,16 +63,19 @@ fn write_output_file<'ll>(
|
||||||
verify_llvm_ir: bool,
|
verify_llvm_ir: bool,
|
||||||
) -> Result<(), FatalError> {
|
) -> Result<(), FatalError> {
|
||||||
debug!("write_output_file output={:?} dwo_output={:?}", output, dwo_output);
|
debug!("write_output_file output={:?} dwo_output={:?}", output, dwo_output);
|
||||||
unsafe {
|
let output_c = path_to_c_string(output);
|
||||||
let output_c = path_to_c_string(output);
|
let dwo_output_c;
|
||||||
let dwo_output_c;
|
let dwo_output_ptr = if let Some(dwo_output) = dwo_output {
|
||||||
let dwo_output_ptr = if let Some(dwo_output) = dwo_output {
|
dwo_output_c = path_to_c_string(dwo_output);
|
||||||
dwo_output_c = path_to_c_string(dwo_output);
|
dwo_output_c.as_ptr()
|
||||||
dwo_output_c.as_ptr()
|
} else {
|
||||||
} else {
|
std::ptr::null()
|
||||||
std::ptr::null()
|
};
|
||||||
};
|
let result = unsafe {
|
||||||
let result = llvm::LLVMRustWriteOutputFile(
|
let pm = llvm::LLVMCreatePassManager();
|
||||||
|
llvm::LLVMAddAnalysisPasses(target, pm);
|
||||||
|
llvm::LLVMRustAddLibraryInfo(pm, m, no_builtins);
|
||||||
|
llvm::LLVMRustWriteOutputFile(
|
||||||
target,
|
target,
|
||||||
pm,
|
pm,
|
||||||
m,
|
m,
|
||||||
|
@ -80,22 +83,22 @@ fn write_output_file<'ll>(
|
||||||
dwo_output_ptr,
|
dwo_output_ptr,
|
||||||
file_type,
|
file_type,
|
||||||
verify_llvm_ir,
|
verify_llvm_ir,
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// Record artifact sizes for self-profiling
|
// Record artifact sizes for self-profiling
|
||||||
if result == llvm::LLVMRustResult::Success {
|
if result == llvm::LLVMRustResult::Success {
|
||||||
let artifact_kind = match file_type {
|
let artifact_kind = match file_type {
|
||||||
llvm::FileType::ObjectFile => "object_file",
|
llvm::FileType::ObjectFile => "object_file",
|
||||||
llvm::FileType::AssemblyFile => "assembly_file",
|
llvm::FileType::AssemblyFile => "assembly_file",
|
||||||
};
|
};
|
||||||
record_artifact_size(self_profiler_ref, artifact_kind, output);
|
record_artifact_size(self_profiler_ref, artifact_kind, output);
|
||||||
if let Some(dwo_file) = dwo_output {
|
if let Some(dwo_file) = dwo_output {
|
||||||
record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
|
record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_informational_target_machine(
|
pub(crate) fn create_informational_target_machine(
|
||||||
|
@ -325,13 +328,17 @@ pub(crate) fn save_temp_bitcode(
|
||||||
if !cgcx.save_temps {
|
if !cgcx.save_temps {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let ext = format!("{name}.bc");
|
||||||
|
let cgu = Some(&module.name[..]);
|
||||||
|
let path = cgcx.output_filenames.temp_path_ext(&ext, cgu);
|
||||||
|
write_bitcode_to_file(module, &path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_bitcode_to_file(module: &ModuleCodegen<ModuleLlvm>, path: &Path) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ext = format!("{name}.bc");
|
let path = path_to_c_string(&path);
|
||||||
let cgu = Some(&module.name[..]);
|
|
||||||
let path = cgcx.output_filenames.temp_path_ext(&ext, cgu);
|
|
||||||
let cstr = path_to_c_string(&path);
|
|
||||||
let llmod = module.module_llvm.llmod();
|
let llmod = module.module_llvm.llmod();
|
||||||
llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr());
|
llvm::LLVMWriteBitcodeToFile(llmod, path.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +683,6 @@ pub(crate) unsafe fn optimize(
|
||||||
) -> Result<(), FatalError> {
|
) -> Result<(), FatalError> {
|
||||||
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name);
|
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name);
|
||||||
|
|
||||||
let llmod = module.module_llvm.llmod();
|
|
||||||
let llcx = &*module.module_llvm.llcx;
|
let llcx = &*module.module_llvm.llcx;
|
||||||
let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt);
|
let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt);
|
||||||
|
|
||||||
|
@ -685,8 +691,7 @@ pub(crate) unsafe fn optimize(
|
||||||
|
|
||||||
if config.emit_no_opt_bc {
|
if config.emit_no_opt_bc {
|
||||||
let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
|
let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
|
||||||
let out = path_to_c_string(&out);
|
write_bitcode_to_file(module, &out)
|
||||||
unsafe { llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(ZuseZ4): support SanitizeHWAddress and prevent illegal/unsupported opts
|
// FIXME(ZuseZ4): support SanitizeHWAddress and prevent illegal/unsupported opts
|
||||||
|
@ -755,31 +760,6 @@ pub(crate) unsafe fn codegen(
|
||||||
create_msvc_imps(cgcx, llcx, llmod);
|
create_msvc_imps(cgcx, llcx, llmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A codegen-specific pass manager is used to generate object
|
|
||||||
// files for an LLVM module.
|
|
||||||
//
|
|
||||||
// Apparently each of these pass managers is a one-shot kind of
|
|
||||||
// thing, so we create a new one for each type of output. The
|
|
||||||
// pass manager passed to the closure should be ensured to not
|
|
||||||
// escape the closure itself, and the manager should only be
|
|
||||||
// used once.
|
|
||||||
unsafe fn with_codegen<'ll, F, R>(
|
|
||||||
tm: &'ll llvm::TargetMachine,
|
|
||||||
llmod: &'ll llvm::Module,
|
|
||||||
no_builtins: bool,
|
|
||||||
f: F,
|
|
||||||
) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(&'ll mut PassManager<'ll>) -> R,
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
let cpm = llvm::LLVMCreatePassManager();
|
|
||||||
llvm::LLVMAddAnalysisPasses(tm, cpm);
|
|
||||||
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
|
|
||||||
f(cpm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that if object files are just LLVM bitcode we write bitcode,
|
// Note that if object files are just LLVM bitcode we write bitcode,
|
||||||
// copy it to the .o file, and delete the bitcode if it wasn't
|
// copy it to the .o file, and delete the bitcode if it wasn't
|
||||||
// otherwise requested.
|
// otherwise requested.
|
||||||
|
@ -898,21 +878,17 @@ pub(crate) unsafe fn codegen(
|
||||||
} else {
|
} else {
|
||||||
llmod
|
llmod
|
||||||
};
|
};
|
||||||
unsafe {
|
write_output_file(
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
dcx,
|
||||||
write_output_file(
|
tm,
|
||||||
dcx,
|
config.no_builtins,
|
||||||
tm,
|
llmod,
|
||||||
cpm,
|
&path,
|
||||||
llmod,
|
None,
|
||||||
&path,
|
llvm::FileType::AssemblyFile,
|
||||||
None,
|
&cgcx.prof,
|
||||||
llvm::FileType::AssemblyFile,
|
config.verify_llvm_ir,
|
||||||
&cgcx.prof,
|
)?;
|
||||||
config.verify_llvm_ir,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match config.emit_obj {
|
match config.emit_obj {
|
||||||
|
@ -936,21 +912,17 @@ pub(crate) unsafe fn codegen(
|
||||||
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
|
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
write_output_file(
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
dcx,
|
||||||
write_output_file(
|
tm,
|
||||||
dcx,
|
config.no_builtins,
|
||||||
tm,
|
llmod,
|
||||||
cpm,
|
&obj_out,
|
||||||
llmod,
|
dwo_out,
|
||||||
&obj_out,
|
llvm::FileType::ObjectFile,
|
||||||
dwo_out,
|
&cgcx.prof,
|
||||||
llvm::FileType::ObjectFile,
|
config.verify_llvm_ir,
|
||||||
&cgcx.prof,
|
)?;
|
||||||
config.verify_llvm_ir,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitObj::Bitcode => {
|
EmitObj::Bitcode => {
|
||||||
|
@ -1077,24 +1049,18 @@ unsafe fn embed_bitcode(
|
||||||
{
|
{
|
||||||
// We don't need custom section flags, create LLVM globals.
|
// We don't need custom section flags, create LLVM globals.
|
||||||
let llconst = common::bytes_in_context(llcx, bitcode);
|
let llconst = common::bytes_in_context(llcx, bitcode);
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal =
|
||||||
llmod,
|
llvm::add_global(llmod, common::val_ty(llconst), c"rustc.embedded.module");
|
||||||
common::val_ty(llconst),
|
llvm::set_initializer(llglobal, llconst);
|
||||||
c"rustc.embedded.module".as_ptr(),
|
|
||||||
);
|
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
|
||||||
|
|
||||||
llvm::set_section(llglobal, bitcode_section_name(cgcx));
|
llvm::set_section(llglobal, bitcode_section_name(cgcx));
|
||||||
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
|
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
|
||||||
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
|
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
|
||||||
|
|
||||||
let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
|
let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal =
|
||||||
llmod,
|
llvm::add_global(llmod, common::val_ty(llconst), c"rustc.embedded.cmdline");
|
||||||
common::val_ty(llconst),
|
llvm::set_initializer(llglobal, llconst);
|
||||||
c"rustc.embedded.cmdline".as_ptr(),
|
|
||||||
);
|
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
|
||||||
let section = if cgcx.target_is_like_osx {
|
let section = if cgcx.target_is_like_osx {
|
||||||
c"__LLVM,__cmdline"
|
c"__LLVM,__cmdline"
|
||||||
} else if cgcx.target_is_like_aix {
|
} else if cgcx.target_is_like_aix {
|
||||||
|
@ -1134,31 +1100,29 @@ fn create_msvc_imps(
|
||||||
// underscores added in front).
|
// underscores added in front).
|
||||||
let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
|
let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
|
||||||
|
|
||||||
unsafe {
|
let ptr_ty = Type::ptr_llcx(llcx);
|
||||||
let ptr_ty = Type::ptr_llcx(llcx);
|
let globals = base::iter_globals(llmod)
|
||||||
let globals = base::iter_globals(llmod)
|
.filter(|&val| {
|
||||||
.filter(|&val| {
|
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage && !llvm::is_declaration(val)
|
||||||
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage
|
})
|
||||||
&& llvm::LLVMIsDeclaration(val) == 0
|
.filter_map(|val| {
|
||||||
})
|
// Exclude some symbols that we know are not Rust symbols.
|
||||||
.filter_map(|val| {
|
let name = llvm::get_value_name(val);
|
||||||
// Exclude some symbols that we know are not Rust symbols.
|
if ignored(name) { None } else { Some((val, name)) }
|
||||||
let name = llvm::get_value_name(val);
|
})
|
||||||
if ignored(name) { None } else { Some((val, name)) }
|
.map(move |(val, name)| {
|
||||||
})
|
let mut imp_name = prefix.as_bytes().to_vec();
|
||||||
.map(move |(val, name)| {
|
imp_name.extend(name);
|
||||||
let mut imp_name = prefix.as_bytes().to_vec();
|
let imp_name = CString::new(imp_name).unwrap();
|
||||||
imp_name.extend(name);
|
(imp_name, val)
|
||||||
let imp_name = CString::new(imp_name).unwrap();
|
})
|
||||||
(imp_name, val)
|
.collect::<Vec<_>>();
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
for (imp_name, val) in globals {
|
for (imp_name, val) in globals {
|
||||||
let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr());
|
let imp = llvm::add_global(llmod, ptr_ty, &imp_name);
|
||||||
llvm::LLVMSetInitializer(imp, val);
|
|
||||||
llvm::set_linkage(imp, llvm::Linkage::ExternalLinkage);
|
llvm::set_initializer(imp, val);
|
||||||
}
|
llvm::set_linkage(imp, llvm::Linkage::ExternalLinkage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this function to exclude certain symbols from `__imp` generation.
|
// Use this function to exclude certain symbols from `__imp` generation.
|
||||||
|
|
|
@ -219,8 +219,8 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
|
let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
|
||||||
bug!("symbol `{}` is already defined", sym);
|
bug!("symbol `{}` is already defined", sym);
|
||||||
});
|
});
|
||||||
|
llvm::set_initializer(g, sc);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetInitializer(g, sc);
|
|
||||||
llvm::LLVMSetGlobalConstant(g, True);
|
llvm::LLVMSetGlobalConstant(g, True);
|
||||||
llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
|
llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
llvm::set_linkage(g2, llvm::Linkage::InternalLinkage);
|
llvm::set_linkage(g2, llvm::Linkage::InternalLinkage);
|
||||||
unsafe { llvm::LLVMSetInitializer(g2, g1) };
|
llvm::set_initializer(g2, g1);
|
||||||
g2
|
g2
|
||||||
} else if cx.tcx.sess.target.arch == "x86"
|
} else if cx.tcx.sess.target.arch == "x86"
|
||||||
&& common::is_mingw_gnu_toolchain(&cx.tcx.sess.target)
|
&& common::is_mingw_gnu_toolchain(&cx.tcx.sess.target)
|
||||||
|
@ -235,7 +235,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
||||||
}
|
}
|
||||||
_ => self.define_private_global(self.val_ty(cv)),
|
_ => self.define_private_global(self.val_ty(cv)),
|
||||||
};
|
};
|
||||||
unsafe { llvm::LLVMSetInitializer(gv, cv) };
|
llvm::set_initializer(gv, cv);
|
||||||
set_global_alignment(self, gv, align);
|
set_global_alignment(self, gv, align);
|
||||||
llvm::SetUnnamedAddress(gv, llvm::UnnamedAddr::Global);
|
llvm::SetUnnamedAddress(gv, llvm::UnnamedAddr::Global);
|
||||||
gv
|
gv
|
||||||
|
@ -458,7 +458,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
||||||
new_g
|
new_g
|
||||||
};
|
};
|
||||||
set_global_alignment(self, g, alloc.align);
|
set_global_alignment(self, g, alloc.align);
|
||||||
llvm::LLVMSetInitializer(g, v);
|
llvm::set_initializer(g, v);
|
||||||
|
|
||||||
if self.should_assume_dso_local(g, true) {
|
if self.should_assume_dso_local(g, true) {
|
||||||
llvm::LLVMRustSetDSOLocal(g, true);
|
llvm::LLVMRustSetDSOLocal(g, true);
|
||||||
|
|
|
@ -616,12 +616,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||||
pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
|
pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
|
||||||
let array = self.const_array(self.type_ptr(), values);
|
let array = self.const_array(self.type_ptr(), values);
|
||||||
|
|
||||||
unsafe {
|
let g = llvm::add_global(self.llmod, self.val_ty(array), name);
|
||||||
let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
|
llvm::set_initializer(g, array);
|
||||||
llvm::LLVMSetInitializer(g, array);
|
llvm::set_linkage(g, llvm::Linkage::AppendingLinkage);
|
||||||
llvm::set_linkage(g, llvm::Linkage::AppendingLinkage);
|
llvm::set_section(g, c"llvm.metadata");
|
||||||
llvm::set_section(g, c"llvm.metadata");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'ll> SimpleCx<'ll> {
|
impl<'ll> SimpleCx<'ll> {
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
|
||||||
.define_global(section_var_name, llvm_type)
|
.define_global(section_var_name, llvm_type)
|
||||||
.unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
|
.unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
|
||||||
llvm::set_section(section_var, c".debug_gdb_scripts");
|
llvm::set_section(section_var, c".debug_gdb_scripts");
|
||||||
llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
|
llvm::set_initializer(section_var, cx.const_bytes(section_contents));
|
||||||
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
|
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
|
||||||
llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
|
llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
|
||||||
llvm::set_linkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
|
llvm::set_linkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
|
||||||
|
|
|
@ -235,7 +235,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||||
/// name.
|
/// name.
|
||||||
pub(crate) fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
|
pub(crate) fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
|
||||||
self.get_declared_value(name).and_then(|val| {
|
self.get_declared_value(name).and_then(|val| {
|
||||||
let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 };
|
let declaration = llvm::is_declaration(val);
|
||||||
if !declaration { Some(val) } else { None }
|
if !declaration { Some(val) } else { None }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -824,7 +824,7 @@ fn codegen_msvc_try<'ll>(
|
||||||
if bx.cx.tcx.sess.target.supports_comdat() {
|
if bx.cx.tcx.sess.target.supports_comdat() {
|
||||||
llvm::SetUniqueComdat(bx.llmod, tydesc);
|
llvm::SetUniqueComdat(bx.llmod, tydesc);
|
||||||
}
|
}
|
||||||
unsafe { llvm::LLVMSetInitializer(tydesc, type_info) };
|
llvm::set_initializer(tydesc, type_info);
|
||||||
|
|
||||||
// The flag value of 8 indicates that we are catching the exception by
|
// The flag value of 8 indicates that we are catching the exception by
|
||||||
// reference instead of by value. We can't use catch by value because
|
// reference instead of by value. We can't use catch by value because
|
||||||
|
|
|
@ -2359,7 +2359,7 @@ unsafe extern "C" {
|
||||||
);
|
);
|
||||||
pub fn LLVMRustWriteOutputFile<'a>(
|
pub fn LLVMRustWriteOutputFile<'a>(
|
||||||
T: &'a TargetMachine,
|
T: &'a TargetMachine,
|
||||||
PM: &PassManager<'a>,
|
PM: *mut PassManager<'a>,
|
||||||
M: &'a Module,
|
M: &'a Module,
|
||||||
Output: *const c_char,
|
Output: *const c_char,
|
||||||
DwoOutput: *const c_char,
|
DwoOutput: *const c_char,
|
||||||
|
|
|
@ -241,6 +241,10 @@ pub fn set_linkage(llglobal: &Value, linkage: Linkage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_declaration(llglobal: &Value) -> bool {
|
||||||
|
unsafe { LLVMIsDeclaration(llglobal) == ffi::True }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_visibility(llglobal: &Value) -> Visibility {
|
pub fn get_visibility(llglobal: &Value) -> Visibility {
|
||||||
unsafe { LLVMGetVisibility(llglobal) }.to_rust()
|
unsafe { LLVMGetVisibility(llglobal) }.to_rust()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2154,11 +2154,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
|
span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
|
||||||
}
|
}
|
||||||
// FIXME(const_generics): create real const to allow fn items as const paths
|
// FIXME(const_generics): create real const to allow fn items as const paths
|
||||||
Res::Def(DefKind::Fn | DefKind::AssocFn, _) => ty::Const::new_error_with_message(
|
Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
|
||||||
tcx,
|
self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
|
||||||
span,
|
let args = self.lower_generic_args_of_path_segment(
|
||||||
"fn items cannot be used as const args",
|
span,
|
||||||
),
|
did,
|
||||||
|
path.segments.last().unwrap(),
|
||||||
|
);
|
||||||
|
ty::Const::new_value(tcx, ty::ValTree::zst(), Ty::new_fn_def(tcx, did, args))
|
||||||
|
}
|
||||||
|
|
||||||
// Exhaustive match to be clear about what exactly we're considering to be
|
// Exhaustive match to be clear about what exactly we're considering to be
|
||||||
// an invalid Res for a const path.
|
// an invalid Res for a const path.
|
||||||
|
@ -2557,27 +2561,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
// reject function types that violate cmse ABI requirements
|
// reject function types that violate cmse ABI requirements
|
||||||
cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
|
cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
|
||||||
|
|
||||||
// Find any late-bound regions declared in return type that do
|
if !bare_fn_ty.references_error() {
|
||||||
// not appear in the arguments. These are not well-formed.
|
// Find any late-bound regions declared in return type that do
|
||||||
//
|
// not appear in the arguments. These are not well-formed.
|
||||||
// Example:
|
//
|
||||||
// for<'a> fn() -> &'a str <-- 'a is bad
|
// Example:
|
||||||
// for<'a> fn(&'a String) -> &'a str <-- 'a is ok
|
// for<'a> fn() -> &'a str <-- 'a is bad
|
||||||
let inputs = bare_fn_ty.inputs();
|
// for<'a> fn(&'a String) -> &'a str <-- 'a is ok
|
||||||
let late_bound_in_args =
|
let inputs = bare_fn_ty.inputs();
|
||||||
tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
|
let late_bound_in_args =
|
||||||
let output = bare_fn_ty.output();
|
tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
|
||||||
let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
|
let output = bare_fn_ty.output();
|
||||||
|
let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
|
||||||
|
|
||||||
self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
|
self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
|
||||||
struct_span_code_err!(
|
struct_span_code_err!(
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
decl.output.span(),
|
decl.output.span(),
|
||||||
E0581,
|
E0581,
|
||||||
"return type references {}, which is not constrained by the fn input types",
|
"return type references {}, which is not constrained by the fn input types",
|
||||||
br_name
|
br_name
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bare_fn_ty
|
bare_fn_ty
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,9 +390,6 @@ lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
|
||||||
|
|
||||||
lint_improper_ctypes_opaque = opaque types have no C equivalent
|
lint_improper_ctypes_opaque = opaque types have no C equivalent
|
||||||
|
|
||||||
lint_improper_ctypes_pat_help = consider using the base type instead
|
|
||||||
|
|
||||||
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
|
|
||||||
lint_improper_ctypes_slice_help = consider using a raw pointer instead
|
lint_improper_ctypes_slice_help = consider using a raw pointer instead
|
||||||
|
|
||||||
lint_improper_ctypes_slice_reason = slices have no C equivalent
|
lint_improper_ctypes_slice_reason = slices have no C equivalent
|
||||||
|
|
|
@ -241,10 +241,7 @@ fn structurally_same_type_impl<'tcx>(
|
||||||
if let ty::Adt(def, args) = *ty.kind() {
|
if let ty::Adt(def, args) = *ty.kind() {
|
||||||
let is_transparent = def.repr().transparent();
|
let is_transparent = def.repr().transparent();
|
||||||
let is_non_null = types::nonnull_optimization_guaranteed(tcx, def);
|
let is_non_null = types::nonnull_optimization_guaranteed(tcx, def);
|
||||||
debug!(
|
debug!(?ty, is_transparent, is_non_null);
|
||||||
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
|
|
||||||
ty, is_transparent, is_non_null
|
|
||||||
);
|
|
||||||
if is_transparent && !is_non_null {
|
if is_transparent && !is_non_null {
|
||||||
debug_assert_eq!(def.variants().len(), 1);
|
debug_assert_eq!(def.variants().len(), 1);
|
||||||
let v = &def.variant(FIRST_VARIANT);
|
let v = &def.variant(FIRST_VARIANT);
|
||||||
|
@ -378,14 +375,14 @@ fn structurally_same_type_impl<'tcx>(
|
||||||
|
|
||||||
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
|
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
|
||||||
// enum layout optimisation is being applied.
|
// enum layout optimisation is being applied.
|
||||||
(Adt(..), _) if is_primitive_or_pointer(b) => {
|
(Adt(..) | Pat(..), _) if is_primitive_or_pointer(b) => {
|
||||||
if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) {
|
if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) {
|
||||||
a_inner == b
|
a_inner == b
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(_, Adt(..)) if is_primitive_or_pointer(a) => {
|
(_, Adt(..) | Pat(..)) if is_primitive_or_pointer(a) => {
|
||||||
if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) {
|
if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) {
|
||||||
b_inner == a
|
b_inner == a
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![feature(try_blocks)]
|
||||||
#![warn(unreachable_pub)]
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
|
|
|
@ -877,6 +877,37 @@ fn ty_is_known_nonnull<'tcx>(
|
||||||
.filter_map(|variant| transparent_newtype_field(tcx, variant))
|
.filter_map(|variant| transparent_newtype_field(tcx, variant))
|
||||||
.any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode))
|
.any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode))
|
||||||
}
|
}
|
||||||
|
ty::Pat(base, pat) => {
|
||||||
|
ty_is_known_nonnull(tcx, typing_env, *base, mode)
|
||||||
|
|| Option::unwrap_or_default(
|
||||||
|
try {
|
||||||
|
match **pat {
|
||||||
|
ty::PatternKind::Range { start, end, include_end } => {
|
||||||
|
match (start, end) {
|
||||||
|
(Some(start), None) => {
|
||||||
|
start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0
|
||||||
|
}
|
||||||
|
(Some(start), Some(end)) => {
|
||||||
|
let start =
|
||||||
|
start.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||||
|
let end =
|
||||||
|
end.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||||
|
|
||||||
|
if include_end {
|
||||||
|
// This also works for negative numbers, as we just need
|
||||||
|
// to ensure we aren't wrapping over zero.
|
||||||
|
start > 0 && end >= start
|
||||||
|
} else {
|
||||||
|
start > 0 && end > start
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -907,9 +938,8 @@ fn get_nullable_type<'tcx>(
|
||||||
};
|
};
|
||||||
return get_nullable_type(tcx, typing_env, inner_field_ty);
|
return get_nullable_type(tcx, typing_env, inner_field_ty);
|
||||||
}
|
}
|
||||||
ty::Int(ty) => Ty::new_int(tcx, ty),
|
ty::Pat(base, ..) => return get_nullable_type(tcx, typing_env, base),
|
||||||
ty::Uint(ty) => Ty::new_uint(tcx, ty),
|
ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => ty,
|
||||||
ty::RawPtr(ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
|
|
||||||
// As these types are always non-null, the nullable equivalent of
|
// As these types are always non-null, the nullable equivalent of
|
||||||
// `Option<T>` of these types are their raw pointer counterparts.
|
// `Option<T>` of these types are their raw pointer counterparts.
|
||||||
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
|
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
|
||||||
|
@ -965,63 +995,69 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
|
||||||
ckind: CItemKind,
|
ckind: CItemKind,
|
||||||
) -> Option<Ty<'tcx>> {
|
) -> Option<Ty<'tcx>> {
|
||||||
debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty);
|
debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty);
|
||||||
if let ty::Adt(ty_def, args) = ty.kind() {
|
match ty.kind() {
|
||||||
let field_ty = match &ty_def.variants().raw[..] {
|
ty::Adt(ty_def, args) => {
|
||||||
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
|
let field_ty = match &ty_def.variants().raw[..] {
|
||||||
([], [field]) | ([field], []) => field.ty(tcx, args),
|
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
|
||||||
([field1], [field2]) => {
|
([], [field]) | ([field], []) => field.ty(tcx, args),
|
||||||
let ty1 = field1.ty(tcx, args);
|
([field1], [field2]) => {
|
||||||
let ty2 = field2.ty(tcx, args);
|
let ty1 = field1.ty(tcx, args);
|
||||||
|
let ty2 = field2.ty(tcx, args);
|
||||||
|
|
||||||
if is_niche_optimization_candidate(tcx, typing_env, ty1) {
|
if is_niche_optimization_candidate(tcx, typing_env, ty1) {
|
||||||
ty2
|
ty2
|
||||||
} else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
|
} else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
|
||||||
ty1
|
ty1
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => return None,
|
||||||
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, the field's type is known to be nonnull and the parent enum is Option-like.
|
|
||||||
// If the computed size for the field and the enum are different, the nonnull optimization isn't
|
|
||||||
// being applied (and we've got a problem somewhere).
|
|
||||||
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok();
|
|
||||||
if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
|
|
||||||
bug!("improper_ctypes: Option nonnull optimization not applied?");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the nullable type this Option-like enum can be safely represented with.
|
|
||||||
let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty));
|
|
||||||
if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
|
|
||||||
bug!("should be able to compute the layout of non-polymorphic type");
|
|
||||||
}
|
|
||||||
|
|
||||||
let field_ty_abi = &field_ty_layout.ok()?.backend_repr;
|
|
||||||
if let BackendRepr::Scalar(field_ty_scalar) = field_ty_abi {
|
|
||||||
match field_ty_scalar.valid_range(&tcx) {
|
|
||||||
WrappingRange { start: 0, end }
|
|
||||||
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
|
|
||||||
{
|
|
||||||
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
|
|
||||||
}
|
|
||||||
WrappingRange { start: 1, .. } => {
|
|
||||||
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
|
|
||||||
}
|
|
||||||
WrappingRange { start, end } => {
|
|
||||||
unreachable!("Unhandled start and end range: ({}, {})", start, end)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, the field's type is known to be nonnull and the parent enum is Option-like.
|
||||||
|
// If the computed size for the field and the enum are different, the nonnull optimization isn't
|
||||||
|
// being applied (and we've got a problem somewhere).
|
||||||
|
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok();
|
||||||
|
if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
|
||||||
|
bug!("improper_ctypes: Option nonnull optimization not applied?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the nullable type this Option-like enum can be safely represented with.
|
||||||
|
let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty));
|
||||||
|
if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
|
||||||
|
bug!("should be able to compute the layout of non-polymorphic type");
|
||||||
|
}
|
||||||
|
|
||||||
|
let field_ty_abi = &field_ty_layout.ok()?.backend_repr;
|
||||||
|
if let BackendRepr::Scalar(field_ty_scalar) = field_ty_abi {
|
||||||
|
match field_ty_scalar.valid_range(&tcx) {
|
||||||
|
WrappingRange { start: 0, end }
|
||||||
|
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
|
||||||
|
{
|
||||||
|
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
|
||||||
|
}
|
||||||
|
WrappingRange { start: 1, .. } => {
|
||||||
|
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
|
||||||
|
}
|
||||||
|
WrappingRange { start, end } => {
|
||||||
|
unreachable!("Unhandled start and end range: ({}, {})", start, end)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
ty::Pat(base, pat) => match **pat {
|
||||||
|
ty::PatternKind::Range { .. } => get_nullable_type(tcx, typing_env, *base),
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
|
@ -1256,11 +1292,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
help: Some(fluent::lint_improper_ctypes_char_help),
|
help: Some(fluent::lint_improper_ctypes_char_help),
|
||||||
},
|
},
|
||||||
|
|
||||||
ty::Pat(..) => FfiUnsafe {
|
// It's just extra invariants on the type that you need to uphold,
|
||||||
ty,
|
// but only the base type is relevant for being representable in FFI.
|
||||||
reason: fluent::lint_improper_ctypes_pat_reason,
|
ty::Pat(base, ..) => self.check_type_for_ffi(acc, base),
|
||||||
help: Some(fluent::lint_improper_ctypes_pat_help),
|
|
||||||
},
|
|
||||||
|
|
||||||
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
|
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
|
||||||
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_128bit, help: None }
|
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_128bit, help: None }
|
||||||
|
|
|
@ -1800,7 +1800,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
}
|
}
|
||||||
|
|
||||||
let u8_type = self.tcx().types.u8;
|
let u8_type = self.tcx().types.u8;
|
||||||
match (cv.valtree, cv.ty.kind()) {
|
match (cv.valtree, *cv.ty.kind()) {
|
||||||
(ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) => match inner_ty.kind() {
|
(ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) => match inner_ty.kind() {
|
||||||
ty::Slice(t) if *t == u8_type => {
|
ty::Slice(t) if *t == u8_type => {
|
||||||
let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
|
let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
|
||||||
|
@ -1820,13 +1820,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let cv = ty::Value { valtree: cv.valtree, ty: *inner_ty };
|
let cv = ty::Value { valtree: cv.valtree, ty: inner_ty };
|
||||||
p!("&");
|
p!("&");
|
||||||
p!(pretty_print_const_valtree(cv, print_ty));
|
p!(pretty_print_const_valtree(cv, print_ty));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => {
|
(ty::ValTree::Branch(_), ty::Array(t, _)) if t == u8_type => {
|
||||||
let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
|
let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
|
||||||
bug!("expected to convert valtree to raw bytes for type {:?}", t)
|
bug!("expected to convert valtree to raw bytes for type {:?}", t)
|
||||||
});
|
});
|
||||||
|
@ -1893,11 +1893,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
}
|
}
|
||||||
(ty::ValTree::Leaf(leaf), ty::Ref(_, inner_ty, _)) => {
|
(ty::ValTree::Leaf(leaf), ty::Ref(_, inner_ty, _)) => {
|
||||||
p!(write("&"));
|
p!(write("&"));
|
||||||
return self.pretty_print_const_scalar_int(leaf, *inner_ty, print_ty);
|
return self.pretty_print_const_scalar_int(leaf, inner_ty, print_ty);
|
||||||
}
|
}
|
||||||
(ty::ValTree::Leaf(leaf), _) => {
|
(ty::ValTree::Leaf(leaf), _) => {
|
||||||
return self.pretty_print_const_scalar_int(leaf, cv.ty, print_ty);
|
return self.pretty_print_const_scalar_int(leaf, cv.ty, print_ty);
|
||||||
}
|
}
|
||||||
|
(_, ty::FnDef(def_id, args)) => {
|
||||||
|
// Never allowed today, but we still encounter them in invalid const args.
|
||||||
|
p!(print_value_path(def_id, args));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
|
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
|
||||||
// their fields instead of just dumping the memory.
|
// their fields instead of just dumping the memory.
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -923,6 +923,21 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
|
||||||
self.diag_metadata.current_trait_object = prev;
|
self.diag_metadata.current_trait_object = prev;
|
||||||
self.diag_metadata.current_type_path = prev_ty;
|
self.diag_metadata.current_type_path = prev_ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
|
||||||
|
match &t.kind {
|
||||||
|
TyPatKind::Range(start, end, _) => {
|
||||||
|
if let Some(start) = start {
|
||||||
|
self.resolve_anon_const(start, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
||||||
|
}
|
||||||
|
if let Some(end) = end {
|
||||||
|
self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
|
fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
|
||||||
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
|
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
|
||||||
self.with_generic_param_rib(
|
self.with_generic_param_rib(
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
|
|
||||||
// https://developer.android.com/ndk/guides/abis.html#x86
|
// https://developer.android.com/ndk/guides/abis.html#x86
|
||||||
base.cpu = "pentiumpro".into();
|
base.cpu = "pentium4".into();
|
||||||
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into();
|
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into();
|
||||||
base.stack_probes = StackProbeType::Inline;
|
base.stack_probes = StackProbeType::Inline;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ use rustc_middle::ty::{
|
||||||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
|
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
|
||||||
};
|
};
|
||||||
use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym};
|
use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym};
|
||||||
|
use rustc_type_ir::inherent::*;
|
||||||
|
use rustc_type_ir::visit::TypeVisitableExt;
|
||||||
use tracing::{debug, instrument, warn};
|
use tracing::{debug, instrument, warn};
|
||||||
|
|
||||||
use super::nice_region_error::placeholder_error::Highlighted;
|
use super::nice_region_error::placeholder_error::Highlighted;
|
||||||
|
@ -155,27 +157,92 @@ impl UnderspecifiedArgKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClosureEraser<'tcx> {
|
struct ClosureEraser<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
infcx: &'a InferCtxt<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
|
impl<'a, 'tcx> ClosureEraser<'a, 'tcx> {
|
||||||
|
fn new_infer(&mut self) -> Ty<'tcx> {
|
||||||
|
self.infcx.next_ty_var(DUMMY_SP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'a, 'tcx> {
|
||||||
fn cx(&self) -> TyCtxt<'tcx> {
|
fn cx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Closure(_, args) => {
|
ty::Closure(_, args) => {
|
||||||
|
// For a closure type, we turn it into a function pointer so that it gets rendered
|
||||||
|
// as `fn(args) -> Ret`.
|
||||||
let closure_sig = args.as_closure().sig();
|
let closure_sig = args.as_closure().sig();
|
||||||
Ty::new_fn_ptr(
|
Ty::new_fn_ptr(
|
||||||
self.tcx,
|
self.cx(),
|
||||||
self.tcx.signature_unclosure(closure_sig, hir::Safety::Safe),
|
self.cx().signature_unclosure(closure_sig, hir::Safety::Safe),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => ty.super_fold_with(self),
|
ty::Adt(_, args) if !args.iter().any(|a| a.has_infer()) => {
|
||||||
|
// We have a type that doesn't have any inference variables, so we replace
|
||||||
|
// the whole thing with `_`. The type system already knows about this type in
|
||||||
|
// its entirety and it is redundant to specify it for the user. The user only
|
||||||
|
// needs to specify the type parameters that we *couldn't* figure out.
|
||||||
|
self.new_infer()
|
||||||
|
}
|
||||||
|
ty::Adt(def, args) => {
|
||||||
|
let generics = self.cx().generics_of(def.did());
|
||||||
|
let generics: Vec<bool> = generics
|
||||||
|
.own_params
|
||||||
|
.iter()
|
||||||
|
.map(|param| param.default_value(self.cx()).is_some())
|
||||||
|
.collect();
|
||||||
|
let ty = Ty::new_adt(
|
||||||
|
self.cx(),
|
||||||
|
*def,
|
||||||
|
self.cx().mk_args_from_iter(generics.into_iter().zip(args.iter()).map(
|
||||||
|
|(has_default, arg)| {
|
||||||
|
if arg.has_infer() {
|
||||||
|
// This param has an unsubstituted type variable, meaning that this
|
||||||
|
// type has a (potentially deeply nested) type parameter from the
|
||||||
|
// corresponding type's definition. We have explicitly asked this
|
||||||
|
// type to not be hidden. In either case, we keep the type and don't
|
||||||
|
// substitute with `_` just yet.
|
||||||
|
arg.fold_with(self)
|
||||||
|
} else if has_default {
|
||||||
|
// We have a type param that has a default type, like the allocator
|
||||||
|
// in Vec. We decided to show `Vec` itself, because it hasn't yet
|
||||||
|
// been replaced by an `_` `Infer`, but we want to ensure that the
|
||||||
|
// type parameter with default types does *not* get replaced with
|
||||||
|
// `_` because then we'd end up with `Vec<_, _>`, instead of
|
||||||
|
// `Vec<_>`.
|
||||||
|
arg
|
||||||
|
} else if let GenericArgKind::Type(_) = arg.kind() {
|
||||||
|
// We don't replace lifetime or const params, only type params.
|
||||||
|
self.new_infer().into()
|
||||||
|
} else {
|
||||||
|
arg.fold_with(self)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
_ if ty.has_infer() => {
|
||||||
|
// This type has a (potentially nested) type parameter that we couldn't figure out.
|
||||||
|
// We will print this depth of type, so at least the type name and at least one of
|
||||||
|
// its type parameters.
|
||||||
|
ty.super_fold_with(self)
|
||||||
|
}
|
||||||
|
// We don't have an unknown type parameter anywhere, replace with `_`.
|
||||||
|
_ => self.new_infer(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
|
// Avoid accidentally erasing the type of the const.
|
||||||
|
c
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
|
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
|
||||||
|
@ -219,9 +286,9 @@ fn ty_to_string<'tcx>(
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut printer = fmt_printer(infcx, Namespace::TypeNS);
|
let mut printer = fmt_printer(infcx, Namespace::TypeNS);
|
||||||
let ty = infcx.resolve_vars_if_possible(ty);
|
let ty = infcx.resolve_vars_if_possible(ty);
|
||||||
// We use `fn` ptr syntax for closures, but this only works when the closure
|
// We use `fn` ptr syntax for closures, but this only works when the closure does not capture
|
||||||
// does not capture anything.
|
// anything. We also remove all type parameters that are fully known to the type system.
|
||||||
let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx });
|
let ty = ty.fold_with(&mut ClosureEraser { infcx });
|
||||||
|
|
||||||
match (ty.kind(), called_method_def_id) {
|
match (ty.kind(), called_method_def_id) {
|
||||||
// We don't want the regular output for `fn`s because it includes its path in
|
// We don't want the regular output for `fn`s because it includes its path in
|
||||||
|
|
|
@ -646,7 +646,7 @@ pub const fn must_use<T>(value: T) -> T {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
#[unstable(feature = "likely_unlikely", issue = "26179")]
|
#[unstable(feature = "likely_unlikely", issue = "136873")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn likely(b: bool) -> bool {
|
pub const fn likely(b: bool) -> bool {
|
||||||
crate::intrinsics::likely(b)
|
crate::intrinsics::likely(b)
|
||||||
|
@ -696,7 +696,7 @@ pub const fn likely(b: bool) -> bool {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "likely_unlikely", issue = "26179")]
|
#[unstable(feature = "likely_unlikely", issue = "136873")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn unlikely(b: bool) -> bool {
|
pub const fn unlikely(b: bool) -> bool {
|
||||||
crate::intrinsics::unlikely(b)
|
crate::intrinsics::unlikely(b)
|
||||||
|
@ -729,7 +729,7 @@ pub const fn unlikely(b: bool) -> bool {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "cold_path", issue = "26179")]
|
#[unstable(feature = "cold_path", issue = "136873")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn cold_path() {
|
pub const fn cold_path() {
|
||||||
crate::intrinsics::cold_path()
|
crate::intrinsics::cold_path()
|
||||||
|
|
|
@ -165,7 +165,7 @@ target | std | notes
|
||||||
`i586-pc-windows-msvc` | * | 32-bit Windows (original Pentium) [^x86_32-floats-x87]
|
`i586-pc-windows-msvc` | * | 32-bit Windows (original Pentium) [^x86_32-floats-x87]
|
||||||
`i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87]
|
`i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87]
|
||||||
`i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87]
|
`i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87]
|
||||||
[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([PentiumPro with SSE](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI]
|
[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI]
|
||||||
[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI]
|
[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI]
|
||||||
[`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD (Pentium 4) [^x86_32-floats-return-ABI]
|
[`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD (Pentium 4) [^x86_32-floats-return-ABI]
|
||||||
`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 (Pentium 4) [^x86_32-floats-return-ABI]
|
`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 (Pentium 4) [^x86_32-floats-return-ABI]
|
||||||
|
|
|
@ -75,12 +75,12 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct RangeOperand<'a> {
|
pub(crate) struct RangeOperand<'a, T> {
|
||||||
operand: &'a Option<ptr::P<ast::Expr>>,
|
pub operand: &'a Option<ptr::P<T>>,
|
||||||
pub(crate) span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Rewrite for RangeOperand<'a> {
|
impl<'a, T: Rewrite> Rewrite for RangeOperand<'a, T> {
|
||||||
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
self.rewrite_result(context, shape).ok()
|
self.rewrite_result(context, shape).ok()
|
||||||
}
|
}
|
||||||
|
@ -259,40 +259,7 @@ impl Rewrite for Pat {
|
||||||
}
|
}
|
||||||
PatKind::Never => Err(RewriteError::Unknown),
|
PatKind::Never => Err(RewriteError::Unknown),
|
||||||
PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
||||||
let infix = match end_kind.node {
|
rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
|
||||||
RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
|
|
||||||
RangeEnd::Included(RangeSyntax::DotDotEq) => "..=",
|
|
||||||
RangeEnd::Excluded => "..",
|
|
||||||
};
|
|
||||||
let infix = if context.config.spaces_around_ranges() {
|
|
||||||
let lhs_spacing = match lhs {
|
|
||||||
None => "",
|
|
||||||
Some(_) => " ",
|
|
||||||
};
|
|
||||||
let rhs_spacing = match rhs {
|
|
||||||
None => "",
|
|
||||||
Some(_) => " ",
|
|
||||||
};
|
|
||||||
format!("{lhs_spacing}{infix}{rhs_spacing}")
|
|
||||||
} else {
|
|
||||||
infix.to_owned()
|
|
||||||
};
|
|
||||||
let lspan = self.span.with_hi(end_kind.span.lo());
|
|
||||||
let rspan = self.span.with_lo(end_kind.span.hi());
|
|
||||||
rewrite_pair(
|
|
||||||
&RangeOperand {
|
|
||||||
operand: lhs,
|
|
||||||
span: lspan,
|
|
||||||
},
|
|
||||||
&RangeOperand {
|
|
||||||
operand: rhs,
|
|
||||||
span: rspan,
|
|
||||||
},
|
|
||||||
PairParts::infix(&infix),
|
|
||||||
context,
|
|
||||||
shape,
|
|
||||||
SeparatorPlace::Front,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
PatKind::Ref(ref pat, mutability) => {
|
PatKind::Ref(ref pat, mutability) => {
|
||||||
let prefix = format!("&{}", format_mutability(mutability));
|
let prefix = format!("&{}", format_mutability(mutability));
|
||||||
|
@ -359,6 +326,50 @@ impl Rewrite for Pat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rewrite_range_pat<T: Rewrite>(
|
||||||
|
context: &RewriteContext<'_>,
|
||||||
|
shape: Shape,
|
||||||
|
lhs: &Option<ptr::P<T>>,
|
||||||
|
rhs: &Option<ptr::P<T>>,
|
||||||
|
end_kind: &rustc_span::source_map::Spanned<RangeEnd>,
|
||||||
|
span: Span,
|
||||||
|
) -> RewriteResult {
|
||||||
|
let infix = match end_kind.node {
|
||||||
|
RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
|
||||||
|
RangeEnd::Included(RangeSyntax::DotDotEq) => "..=",
|
||||||
|
RangeEnd::Excluded => "..",
|
||||||
|
};
|
||||||
|
let infix = if context.config.spaces_around_ranges() {
|
||||||
|
let lhs_spacing = match lhs {
|
||||||
|
None => "",
|
||||||
|
Some(_) => " ",
|
||||||
|
};
|
||||||
|
let rhs_spacing = match rhs {
|
||||||
|
None => "",
|
||||||
|
Some(_) => " ",
|
||||||
|
};
|
||||||
|
format!("{lhs_spacing}{infix}{rhs_spacing}")
|
||||||
|
} else {
|
||||||
|
infix.to_owned()
|
||||||
|
};
|
||||||
|
let lspan = span.with_hi(end_kind.span.lo());
|
||||||
|
let rspan = span.with_lo(end_kind.span.hi());
|
||||||
|
rewrite_pair(
|
||||||
|
&RangeOperand {
|
||||||
|
operand: lhs,
|
||||||
|
span: lspan,
|
||||||
|
},
|
||||||
|
&RangeOperand {
|
||||||
|
operand: rhs,
|
||||||
|
span: rspan,
|
||||||
|
},
|
||||||
|
PairParts::infix(&infix),
|
||||||
|
context,
|
||||||
|
shape,
|
||||||
|
SeparatorPlace::Front,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn rewrite_struct_pat(
|
fn rewrite_struct_pat(
|
||||||
qself: &Option<ptr::P<ast::QSelf>>,
|
qself: &Option<ptr::P<ast::QSelf>>,
|
||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
|
|
|
@ -211,7 +211,7 @@ impl Spanned for ast::PreciseCapturingArg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Spanned for RangeOperand<'a> {
|
impl<'a, T> Spanned for RangeOperand<'a, T> {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
self.span
|
self.span
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ use crate::lists::{
|
||||||
use crate::macros::{MacroPosition, rewrite_macro};
|
use crate::macros::{MacroPosition, rewrite_macro};
|
||||||
use crate::overflow;
|
use crate::overflow;
|
||||||
use crate::pairs::{PairParts, rewrite_pair};
|
use crate::pairs::{PairParts, rewrite_pair};
|
||||||
|
use crate::patterns::rewrite_range_pat;
|
||||||
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
|
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
|
||||||
use crate::shape::Shape;
|
use crate::shape::Shape;
|
||||||
use crate::source_map::SpanUtils;
|
use crate::source_map::SpanUtils;
|
||||||
|
@ -1045,6 +1046,21 @@ impl Rewrite for ast::Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Rewrite for ast::TyPat {
|
||||||
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
|
self.rewrite_result(context, shape).ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
||||||
|
match self.kind {
|
||||||
|
ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
||||||
|
rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
|
||||||
|
}
|
||||||
|
ast::TyPatKind::Err(_) => Err(RewriteError::Unknown),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn rewrite_bare_fn(
|
fn rewrite_bare_fn(
|
||||||
bare_fn: &ast::BareFnTy,
|
bare_fn: &ast::BareFnTy,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
9
tests/ui/async-await/unconstrained-lifetimes.rs
Normal file
9
tests/ui/async-await/unconstrained-lifetimes.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
// Make sure we don't complain about the implicit `-> impl Future` capturing an
|
||||||
|
// unconstrained anonymous lifetime.
|
||||||
|
|
||||||
|
async fn foo(_: Missing<'_>) {}
|
||||||
|
//~^ ERROR cannot find type `Missing` in this scope
|
||||||
|
|
||||||
|
fn main() {}
|
9
tests/ui/async-await/unconstrained-lifetimes.stderr
Normal file
9
tests/ui/async-await/unconstrained-lifetimes.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0412]: cannot find type `Missing` in this scope
|
||||||
|
--> $DIR/unconstrained-lifetimes.rs:6:17
|
||||||
|
|
|
||||||
|
LL | async fn foo(_: Missing<'_>) {}
|
||||||
|
| ^^^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0412`.
|
13
tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs
Normal file
13
tests/ui/const-generics/mgca/unexpected-fn-item-in-array.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Make sure we don't ICE when encountering an fn item during lowering in mGCA.
|
||||||
|
|
||||||
|
#![feature(min_generic_const_args)]
|
||||||
|
//~^ WARN the feature `min_generic_const_args` is incomplete
|
||||||
|
|
||||||
|
trait A<T> {}
|
||||||
|
|
||||||
|
impl A<[usize; fn_item]> for () {}
|
||||||
|
//~^ ERROR the constant `fn_item` is not of type `usize`
|
||||||
|
|
||||||
|
fn fn_item() {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,19 @@
|
||||||
|
warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/unexpected-fn-item-in-array.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(min_generic_const_args)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: the constant `fn_item` is not of type `usize`
|
||||||
|
--> $DIR/unexpected-fn-item-in-array.rs:8:6
|
||||||
|
|
|
||||||
|
LL | impl A<[usize; fn_item]> for () {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found fn item
|
||||||
|
|
|
||||||
|
= note: the length of array `[usize; fn_item]` must be type `usize`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error; 1 warning emitted
|
||||||
|
|
|
@ -9,8 +9,8 @@ LL | Ok(v)
|
||||||
|
|
|
|
||||||
help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified
|
help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified
|
||||||
|
|
|
|
||||||
LL | let x = |r: Result<(), E>| {
|
LL | let x = |r: Result<_, E>| {
|
||||||
| +++++++++++++++
|
| ++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ LL | fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
|
||||||
| ^^^^^^^ required by this bound in `foo`
|
| ^^^^^^^ required by this bound in `foo`
|
||||||
help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified
|
help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified
|
||||||
|
|
|
|
||||||
LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
|
LL | let foo: Foo<_, &_, W, Z> = foo(1, "");
|
||||||
| ++++++++++++++++++++++
|
| ++++++++++++++++++
|
||||||
|
|
||||||
error[E0283]: type annotations needed for `Bar<i32, &str, _>`
|
error[E0283]: type annotations needed for `Bar<i32, &str, _>`
|
||||||
--> $DIR/erase-type-params-in-label.rs:5:9
|
--> $DIR/erase-type-params-in-label.rs:5:9
|
||||||
|
@ -29,8 +29,8 @@ LL | fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
|
||||||
| ^^^^^^^ required by this bound in `bar`
|
| ^^^^^^^ required by this bound in `bar`
|
||||||
help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified
|
help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified
|
||||||
|
|
|
|
||||||
LL | let bar: Bar<i32, &str, Z> = bar(1, "");
|
LL | let bar: Bar<_, &_, Z> = bar(1, "");
|
||||||
| +++++++++++++++++++
|
| +++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ LL | let a = A(Result::Ok(Result::Ok(())));
|
||||||
|
|
|
|
||||||
help: consider giving `a` an explicit type, where the type for type parameter `E` is specified
|
help: consider giving `a` an explicit type, where the type for type parameter `E` is specified
|
||||||
|
|
|
|
||||||
LL | let a: A<std::result::Result<std::result::Result<(), E>, Error>> = A(Result::Ok(Result::Ok(())));
|
LL | let a: A<std::result::Result<std::result::Result<_, E>, _>> = A(Result::Ok(Result::Ok(())));
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ LL | fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
|
||||||
| ^^^^^^^^^^^^^^ required by this const generic parameter in `foo`
|
| ^^^^^^^^^^^^^^ required by this const generic parameter in `foo`
|
||||||
help: consider giving this pattern a type, where the value of const parameter `N` is specified
|
help: consider giving this pattern a type, where the value of const parameter `N` is specified
|
||||||
|
|
|
|
||||||
LL | let _: [usize; N] = foo("foo");
|
LL | let _: [_; N] = foo("foo");
|
||||||
| ++++++++++++
|
| ++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
type A = (i32, i32, i32, i32);
|
||||||
|
type B = (A, A, A, A);
|
||||||
|
type C = (B, B, B, B);
|
||||||
|
type D = (C, C, C, C);
|
||||||
|
|
||||||
|
fn foo(x: D) {
|
||||||
|
let y = Err(x); //~ ERROR type annotations needed for `Result<_
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0282]: type annotations needed for `Result<_, ((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))>`
|
||||||
|
--> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:7:9
|
||||||
|
|
|
||||||
|
LL | let y = Err(x);
|
||||||
|
| ^ ------ type must be known at this point
|
||||||
|
|
|
||||||
|
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
|
||||||
|
|
|
||||||
|
LL | let y: Result<T, _> = Err(x);
|
||||||
|
| ++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0282`.
|
|
@ -1,7 +1,7 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
//@ aux-build:external_extern_fn.rs
|
//@ aux-build:external_extern_fn.rs
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
#![feature(pattern_type_macro, pattern_types)]
|
||||||
mod redeclared_different_signature {
|
mod redeclared_different_signature {
|
||||||
mod a {
|
mod a {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -490,3 +490,33 @@ mod hidden_niche {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod pattern_types {
|
||||||
|
mod a {
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct NonZeroUsize(pattern_type!(usize is 1..));
|
||||||
|
extern "C" {
|
||||||
|
fn pt_non_zero_usize() -> pattern_type!(usize is 1..);
|
||||||
|
fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>;
|
||||||
|
fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
|
||||||
|
//~^ WARN not FFI-safe
|
||||||
|
fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
|
||||||
|
fn pt_non_zero_usize_wrapper() -> NonZeroUsize;
|
||||||
|
fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod b {
|
||||||
|
extern "C" {
|
||||||
|
// If there's a clash in either of these cases you're either gaining an incorrect
|
||||||
|
// invariant that the value is non-zero, or you're missing out on that invariant. Both
|
||||||
|
// cases are warning for, from both a caller-convenience and optimisation perspective.
|
||||||
|
fn pt_non_zero_usize() -> usize;
|
||||||
|
fn pt_non_zero_usize_opt() -> usize;
|
||||||
|
fn pt_non_null_ptr() -> *const ();
|
||||||
|
//~^ WARN `pt_non_null_ptr` redeclared with a different signature
|
||||||
|
fn pt_non_zero_usize_wrapper() -> usize;
|
||||||
|
fn pt_non_zero_usize_wrapper_opt() -> usize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,15 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
|
warning: `extern` block uses type `Option<(usize) is 0..=>`, which is not FFI-safe
|
||||||
|
--> $DIR/clashing-extern-fn.rs:502:54
|
||||||
|
|
|
||||||
|
LL | fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
|
|
||||||
warning: `clash` redeclared with a different signature
|
warning: `clash` redeclared with a different signature
|
||||||
--> $DIR/clashing-extern-fn.rs:13:13
|
--> $DIR/clashing-extern-fn.rs:13:13
|
||||||
|
|
|
|
||||||
|
@ -258,5 +267,17 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
|
||||||
= note: expected `unsafe extern "C" fn() -> usize`
|
= note: expected `unsafe extern "C" fn() -> usize`
|
||||||
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
|
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
|
||||||
|
|
||||||
warning: 22 warnings emitted
|
warning: `pt_non_null_ptr` redeclared with a different signature
|
||||||
|
--> $DIR/clashing-extern-fn.rs:516:13
|
||||||
|
|
|
||||||
|
LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
|
||||||
|
| ---------------------------------------------------- `pt_non_null_ptr` previously declared here
|
||||||
|
...
|
||||||
|
LL | fn pt_non_null_ptr() -> *const ();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||||
|
|
|
||||||
|
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
|
||||||
|
found `unsafe extern "C" fn() -> *const ()`
|
||||||
|
|
||||||
|
warning: 24 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ extern "C" {
|
||||||
fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
|
fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
|
||||||
//~^ ERROR `extern` block uses type
|
//~^ ERROR `extern` block uses type
|
||||||
fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>); //~ ERROR `extern` block uses type
|
fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>); //~ ERROR `extern` block uses type
|
||||||
|
fn option_u8(x: Option<u8>); //~ ERROR `extern` block uses type
|
||||||
|
|
||||||
fn result_ref_t(x: Result<&'static u8, ()>);
|
fn result_ref_t(x: Result<&'static u8, ()>);
|
||||||
fn result_fn_t(x: Result<extern "C" fn(), ()>);
|
fn result_fn_t(x: Result<extern "C" fn(), ()>);
|
||||||
|
|
|
@ -79,8 +79,17 @@ LL | fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
|
error: `extern` block uses type `Option<u8>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:97:21
|
||||||
|
|
|
||||||
|
LL | fn option_u8(x: Option<u8>);
|
||||||
|
| ^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:106:33
|
--> $DIR/lint-ctypes-enum.rs:107:33
|
||||||
|
|
|
|
||||||
LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
|
LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -88,7 +97,7 @@ LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
|
||||||
= note: 128-bit integers don't currently have a known stable ABI
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:113:33
|
--> $DIR/lint-ctypes-enum.rs:114:33
|
||||||
|
|
|
|
||||||
LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
|
LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -96,7 +105,7 @@ LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
|
||||||
= note: 128-bit integers don't currently have a known stable ABI
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, which is not FFI-safe
|
error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:118:38
|
--> $DIR/lint-ctypes-enum.rs:119:38
|
||||||
|
|
|
|
||||||
LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u8>>, ()>);
|
LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u8>>, ()>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -105,7 +114,7 @@ LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, which is not FFI-safe
|
error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:120:30
|
--> $DIR/lint-ctypes-enum.rs:121:30
|
||||||
|
|
|
|
||||||
LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
|
LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -114,7 +123,7 @@ LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe
|
error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:124:51
|
--> $DIR/lint-ctypes-enum.rs:125:51
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
|
LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -123,7 +132,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>,
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe
|
error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:126:53
|
--> $DIR/lint-ctypes-enum.rs:127:53
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -132,7 +141,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
|
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:128:51
|
--> $DIR/lint-ctypes-enum.rs:129:51
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -141,7 +150,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>,
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
|
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:131:49
|
--> $DIR/lint-ctypes-enum.rs:132:49
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
|
LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -150,7 +159,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Fi
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
|
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:133:30
|
--> $DIR/lint-ctypes-enum.rs:134:30
|
||||||
|
|
|
|
||||||
LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -159,7 +168,7 @@ LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:144:33
|
--> $DIR/lint-ctypes-enum.rs:145:33
|
||||||
|
|
|
|
||||||
LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -167,7 +176,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
||||||
= note: 128-bit integers don't currently have a known stable ABI
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:151:33
|
--> $DIR/lint-ctypes-enum.rs:152:33
|
||||||
|
|
|
|
||||||
LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -175,7 +184,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
||||||
= note: 128-bit integers don't currently have a known stable ABI
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:156:38
|
--> $DIR/lint-ctypes-enum.rs:157:38
|
||||||
|
|
|
|
||||||
LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
|
LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -184,7 +193,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:158:30
|
--> $DIR/lint-ctypes-enum.rs:159:30
|
||||||
|
|
|
|
||||||
LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -193,7 +202,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:162:51
|
--> $DIR/lint-ctypes-enum.rs:163:51
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
|
LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -202,7 +211,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:164:53
|
--> $DIR/lint-ctypes-enum.rs:165:53
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -211,7 +220,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:166:51
|
--> $DIR/lint-ctypes-enum.rs:167:51
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -220,7 +229,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:169:49
|
--> $DIR/lint-ctypes-enum.rs:170:49
|
||||||
|
|
|
|
||||||
LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
|
LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -229,7 +238,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
|
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:171:30
|
--> $DIR/lint-ctypes-enum.rs:172:30
|
||||||
|
|
|
|
||||||
LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -238,7 +247,7 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe
|
error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:173:27
|
--> $DIR/lint-ctypes-enum.rs:174:27
|
||||||
|
|
|
|
||||||
LL | fn result_unit_t_e(x: Result<(), ()>);
|
LL | fn result_unit_t_e(x: Result<(), ()>);
|
||||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
@ -246,5 +255,5 @@ LL | fn result_unit_t_e(x: Result<(), ()>);
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: aborting due to 26 previous errors
|
error: aborting due to 27 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ LL | .or_else(|err| {
|
||||||
|
|
|
|
||||||
help: try giving this closure an explicit return type
|
help: try giving this closure an explicit return type
|
||||||
|
|
|
|
||||||
LL | .or_else(|err| -> Result<Child, F> {
|
LL | .or_else(|err| -> Result<_, F> {
|
||||||
| +++++++++++++++++++
|
| +++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,79 +1,38 @@
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:17:19
|
--> $DIR/assoc_const.rs:17:41
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:17:19
|
--> $DIR/assoc_const.rs:17:61
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:17:19
|
--> $DIR/assoc_const.rs:20:40
|
||||||
|
|
|
||||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this may fail depending on what value the parameter takes
|
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
|
||||||
--> $DIR/assoc_const.rs:17:19
|
|
||||||
|
|
|
||||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this may fail depending on what value the parameter takes
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
--> $DIR/assoc_const.rs:22:19
|
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:22:19
|
--> $DIR/assoc_const.rs:20:51
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/assoc_const.rs:22:19
|
|
||||||
|
|
|
||||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this may fail depending on what value the parameter takes
|
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
|
||||||
--> $DIR/assoc_const.rs:22:19
|
|
||||||
|
|
|
||||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this may fail depending on what value the parameter takes
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
||||||
|
|
|
@ -15,14 +15,10 @@ trait Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
//[default]~^ ERROR: constant expression depends on a generic parameter
|
//[default]~^ ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
//[default]~| ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
//[default]~^ ERROR: constant expression depends on a generic parameter
|
//[default]~^ ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
//[default]~| ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
||||||
//@ rustc-env:RUST_BACKTRACE=0
|
//@ rustc-env:RUST_BACKTRACE=0
|
||||||
|
|
||||||
#![feature(pattern_types, pattern_type_macro)]
|
#![feature(pattern_types, pattern_type_macro, generic_const_exprs)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
type Pat<const START: u32, const END: u32> =
|
type Pat<const START: u32, const END: u32> =
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible
|
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/bad_const_generics_args_on_const_param.rs:8:47
|
||||||
|
|
|
||||||
|
LL | #![feature(pattern_types, pattern_type_macro, generic_const_exprs)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||||
|
= error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:12:36
|
--> $DIR/bad_const_generics_args_on_const_param.rs:12:36
|
||||||
|
|
|
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
|
@ -10,5 +17,5 @@ query stack during panic:
|
||||||
#0 [type_of] expanding type alias `Pat`
|
#0 [type_of] expanding type alias `Pat`
|
||||||
#1 [check_well_formed] checking that `Pat` is well-formed
|
#1 [check_well_formed] checking that `Pat` is well-formed
|
||||||
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#![feature(pattern_types)]
|
#![feature(pattern_types)]
|
||||||
#![feature(pattern_type_macro)]
|
#![feature(pattern_type_macro)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
use std::pat::pattern_type;
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
//~^ ERROR: cycle
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
error[E0391]: cycle detected when evaluating type-level constant
|
|
||||||
--> $DIR/const_block.rs:7:36
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: ...which requires const-evaluating + checking `bar::{constant#2}`...
|
|
||||||
--> $DIR/const_block.rs:7:36
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
note: ...which requires caching mir of `bar::{constant#2}` for CTFE...
|
|
||||||
--> $DIR/const_block.rs:7:36
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
note: ...which requires elaborating drops for `bar::{constant#2}`...
|
|
||||||
--> $DIR/const_block.rs:7:36
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
note: ...which requires borrow-checking `bar::{constant#2}`...
|
|
||||||
--> $DIR/const_block.rs:7:36
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
note: ...which requires borrow-checking `bar::{constant#0}`...
|
|
||||||
--> $DIR/const_block.rs:7:41
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
note: ...which requires promoting constants in MIR for `bar::{constant#0}`...
|
|
||||||
--> $DIR/const_block.rs:7:41
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
note: ...which requires const checking `bar::{constant#0}`...
|
|
||||||
--> $DIR/const_block.rs:7:41
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
note: ...which requires building MIR for `bar::{constant#0}`...
|
|
||||||
--> $DIR/const_block.rs:7:41
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
note: ...which requires match-checking `bar::{constant#0}`...
|
|
||||||
--> $DIR/const_block.rs:7:41
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
note: ...which requires type-checking `bar::{constant#0}`...
|
|
||||||
--> $DIR/const_block.rs:7:41
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
note: ...which requires type-checking `bar`...
|
|
||||||
--> $DIR/const_block.rs:7:1
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: ...which again requires evaluating type-level constant, completing the cycle
|
|
||||||
note: cycle used when checking that `bar` is well-formed
|
|
||||||
--> $DIR/const_block.rs:7:1
|
|
||||||
|
|
|
||||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0391`.
|
|
|
@ -12,3 +12,4 @@ type Positive = pattern_type!(i32 is 0..);
|
||||||
//~^ use of unstable library feature `pattern_type_macro`
|
//~^ use of unstable library feature `pattern_type_macro`
|
||||||
type Always = pattern_type!(Option<u32> is Some(_));
|
type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
//~^ use of unstable library feature `pattern_type_macro`
|
//~^ use of unstable library feature `pattern_type_macro`
|
||||||
|
//~| ERROR pattern not supported in pattern types
|
||||||
|
|
|
@ -48,6 +48,12 @@ LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
= help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable
|
= help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: pattern not supported in pattern types
|
||||||
|
--> $DIR/feature-gate-pattern_types.rs:13:44
|
||||||
|
|
|
||||||
|
LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//@ compile-flags: -Zno-analysis
|
//@ compile-flags: -Zno-analysis
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
#![feature(pattern_type_macro)]
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
@ -10,3 +9,4 @@ type Percent = pattern_type!(u32 is 0..=100);
|
||||||
type Negative = pattern_type!(i32 is ..=0);
|
type Negative = pattern_type!(i32 is ..=0);
|
||||||
type Positive = pattern_type!(i32 is 0..);
|
type Positive = pattern_type!(i32 is 0..);
|
||||||
type Always = pattern_type!(Option<u32> is Some(_));
|
type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
|
//~^ ERROR: pattern not supported in pattern types
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
error: pattern not supported in pattern types
|
||||||
|
--> $DIR/feature-gate-pattern_types2.rs:11:44
|
||||||
|
|
|
||||||
|
LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -678,7 +678,7 @@ mod types {
|
||||||
/*! FIXME: todo */
|
/*! FIXME: todo */
|
||||||
}
|
}
|
||||||
/// TyKind::Pat
|
/// TyKind::Pat
|
||||||
fn ty_pat() { let _: u32 is 1..; }
|
fn ty_pat() { let _: u32 is const 1..; }
|
||||||
}
|
}
|
||||||
mod visibilities {
|
mod visibilities {
|
||||||
/// VisibilityKind::Public
|
/// VisibilityKind::Public
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue