Auto merge of #3232 - rust-lang:rustup-2023-12-19, r=saethlin
Automatic Rustup
This commit is contained in:
commit
f36251f689
623 changed files with 10571 additions and 5336 deletions
|
|
@ -598,7 +598,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"quine-mc_cluskey",
|
||||
"regex",
|
||||
"regex-syntax 0.7.2",
|
||||
"regex-syntax 0.8.2",
|
||||
"rustc-semver",
|
||||
"semver",
|
||||
"serde",
|
||||
|
|
@ -3195,6 +3195,12 @@ version = "0.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "remote-test-client"
|
||||
version = "0.1.0"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
Version 1.74.1 (2023-12-07)
|
||||
===========================
|
||||
|
||||
- [Resolved spurious STATUS_ACCESS_VIOLATIONs in LLVM](https://github.com/rust-lang/rust/pull/118464)
|
||||
- [Clarify guarantees for std::mem::discriminant](https://github.com/rust-lang/rust/pull/118006)
|
||||
- [Fix some subtyping-related regressions](https://github.com/rust-lang/rust/pull/116415)
|
||||
|
||||
Version 1.74.0 (2023-11-16)
|
||||
==========================
|
||||
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ pub trait LayoutCalculator {
|
|||
*offset += this_offset;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
|
||||
panic!("Layout of fields should be Arbitrary for variants")
|
||||
}
|
||||
}
|
||||
|
|
@ -600,7 +600,9 @@ pub trait LayoutCalculator {
|
|||
variant.size = new_ity_size;
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
|
||||
panic!("encountered a non-arbitrary layout during enum layout")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -628,7 +630,7 @@ pub trait LayoutCalculator {
|
|||
let mut common_prim_initialized_in_all_variants = true;
|
||||
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
|
||||
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
|
||||
panic!();
|
||||
panic!("encountered a non-arbitrary layout during enum layout");
|
||||
};
|
||||
// We skip *all* ZST here and later check if we are good in terms of alignment.
|
||||
// This lets us handle some cases involving aligned ZST.
|
||||
|
|
@ -681,7 +683,7 @@ pub trait LayoutCalculator {
|
|||
assert_eq!(memory_index.raw, [0, 1]);
|
||||
offsets
|
||||
}
|
||||
_ => panic!(),
|
||||
_ => panic!("encountered a non-arbitrary layout during enum layout"),
|
||||
};
|
||||
if pair_offsets[FieldIdx::new(0)] == Size::ZERO
|
||||
&& pair_offsets[FieldIdx::new(1)] == *offset
|
||||
|
|
@ -758,7 +760,9 @@ pub trait LayoutCalculator {
|
|||
Variants::Multiple { tag, tag_encoding, tag_field, .. } => {
|
||||
Variants::Multiple { tag, tag_encoding, tag_field, variants: best_layout.variants }
|
||||
}
|
||||
_ => panic!(),
|
||||
Variants::Single { .. } => {
|
||||
panic!("encountered a single-variant enum during multi-variant layout")
|
||||
}
|
||||
};
|
||||
Some(best_layout.layout)
|
||||
}
|
||||
|
|
@ -1154,7 +1158,11 @@ fn univariant<
|
|||
assert_eq!(memory_index.raw, [0, 1]);
|
||||
offsets
|
||||
}
|
||||
_ => panic!(),
|
||||
FieldsShape::Primitive
|
||||
| FieldsShape::Array { .. }
|
||||
| FieldsShape::Union(..) => {
|
||||
panic!("encountered a non-arbitrary layout during enum layout")
|
||||
}
|
||||
};
|
||||
if offsets[i] == pair_offsets[FieldIdx::new(0)]
|
||||
&& offsets[j] == pair_offsets[FieldIdx::new(1)]
|
||||
|
|
|
|||
|
|
@ -2845,6 +2845,28 @@ impl Item {
|
|||
pub fn span_with_attributes(&self) -> Span {
|
||||
self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
|
||||
}
|
||||
|
||||
pub fn opt_generics(&self) -> Option<&Generics> {
|
||||
match &self.kind {
|
||||
ItemKind::ExternCrate(_)
|
||||
| ItemKind::Use(_)
|
||||
| ItemKind::Mod(_, _)
|
||||
| ItemKind::ForeignMod(_)
|
||||
| ItemKind::GlobalAsm(_)
|
||||
| ItemKind::MacCall(_)
|
||||
| ItemKind::MacroDef(_) => None,
|
||||
ItemKind::Static(_) => None,
|
||||
ItemKind::Const(i) => Some(&i.generics),
|
||||
ItemKind::Fn(i) => Some(&i.generics),
|
||||
ItemKind::TyAlias(i) => Some(&i.generics),
|
||||
ItemKind::TraitAlias(generics, _)
|
||||
| ItemKind::Enum(_, generics)
|
||||
| ItemKind::Struct(_, generics)
|
||||
| ItemKind::Union(_, generics) => Some(&generics),
|
||||
ItemKind::Trait(i) => Some(&i.generics),
|
||||
ItemKind::Impl(i) => Some(&i.generics),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `extern` qualifier on a function item or function type.
|
||||
|
|
|
|||
|
|
@ -40,15 +40,44 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
|
|||
| Range(_, Some(e), _)
|
||||
| Ret(Some(e))
|
||||
| Unary(_, e)
|
||||
| Yield(Some(e)) => {
|
||||
| Yield(Some(e))
|
||||
| Yeet(Some(e))
|
||||
| Become(e) => {
|
||||
expr = e;
|
||||
}
|
||||
Closure(closure) => {
|
||||
expr = &closure.body;
|
||||
}
|
||||
Gen(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
|
||||
| TryBlock(..) | While(..) => break Some(expr),
|
||||
_ => break None,
|
||||
| TryBlock(..) | While(..) | ConstBlock(_) => break Some(expr),
|
||||
|
||||
// FIXME: These can end in `}`, but changing these would break stable code.
|
||||
InlineAsm(_) | OffsetOf(_, _) | MacCall(_) | IncludedBytes(_) | FormatArgs(_) => {
|
||||
break None;
|
||||
}
|
||||
|
||||
Break(_, None)
|
||||
| Range(_, None, _)
|
||||
| Ret(None)
|
||||
| Yield(None)
|
||||
| Array(_)
|
||||
| Call(_, _)
|
||||
| MethodCall(_)
|
||||
| Tup(_)
|
||||
| Lit(_)
|
||||
| Cast(_, _)
|
||||
| Type(_, _)
|
||||
| Await(_, _)
|
||||
| Field(_, _)
|
||||
| Index(_, _, _)
|
||||
| Underscore
|
||||
| Path(_, _)
|
||||
| Continue(_)
|
||||
| Repeat(_, _)
|
||||
| Paren(_)
|
||||
| Try(_)
|
||||
| Yeet(None)
|
||||
| Err => break None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ impl LitKind {
|
|||
// new symbol because the string in the LitKind is different to the
|
||||
// string in the token.
|
||||
let s = symbol.as_str();
|
||||
// Vanilla strings are so common we optimize for the common case where no chars
|
||||
// requiring special behaviour are present.
|
||||
let symbol = if s.contains(['\\', '\r']) {
|
||||
let mut buf = String::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
|
|
@ -104,27 +106,20 @@ impl LitKind {
|
|||
LitKind::Str(symbol, ast::StrStyle::Cooked)
|
||||
}
|
||||
token::StrRaw(n) => {
|
||||
// Ditto.
|
||||
let s = symbol.as_str();
|
||||
let symbol =
|
||||
if s.contains('\r') {
|
||||
let mut buf = String::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| {
|
||||
match unescaped_char {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
// Raw strings have no escapes, so we only need to check for invalid chars, and we
|
||||
// can reuse the symbol on success.
|
||||
let mut error = Ok(());
|
||||
unescape_literal(symbol.as_str(), Mode::RawStr, &mut |_, unescaped_char| {
|
||||
match unescaped_char {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
});
|
||||
error?;
|
||||
Symbol::intern(&buf)
|
||||
} else {
|
||||
symbol
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
error?;
|
||||
LitKind::Str(symbol, ast::StrStyle::Raw(n))
|
||||
}
|
||||
token::ByteStr => {
|
||||
|
|
@ -143,25 +138,19 @@ impl LitKind {
|
|||
LitKind::ByteStr(buf.into(), StrStyle::Cooked)
|
||||
}
|
||||
token::ByteStrRaw(n) => {
|
||||
// Raw strings have no escapes, so we only need to check for invalid chars, and we
|
||||
// can convert the symbol directly to a `Lrc<u8>` on success.
|
||||
let s = symbol.as_str();
|
||||
let bytes = if s.contains('\r') {
|
||||
let mut buf = Vec::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
|
||||
Ok(c) => buf.push(byte_from_char(c)),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
let mut error = Ok(());
|
||||
unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
});
|
||||
error?;
|
||||
buf
|
||||
} else {
|
||||
symbol.to_string().into_bytes()
|
||||
};
|
||||
|
||||
LitKind::ByteStr(bytes.into(), StrStyle::Raw(n))
|
||||
}
|
||||
});
|
||||
LitKind::ByteStr(s.to_owned().into_bytes().into(), StrStyle::Raw(n))
|
||||
}
|
||||
token::CStr => {
|
||||
let s = symbol.as_str();
|
||||
|
|
@ -172,7 +161,6 @@ impl LitKind {
|
|||
error = Err(LitError::NulInCStr(span));
|
||||
}
|
||||
Ok(CStrUnit::Byte(b)) => buf.push(b),
|
||||
Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8),
|
||||
Ok(CStrUnit::Char(c)) => {
|
||||
buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
|
||||
}
|
||||
|
|
@ -187,18 +175,15 @@ impl LitKind {
|
|||
LitKind::CStr(buf.into(), StrStyle::Cooked)
|
||||
}
|
||||
token::CStrRaw(n) => {
|
||||
// Raw strings have no escapes, so we only need to check for invalid chars, and we
|
||||
// can convert the symbol directly to a `Lrc<u8>` on success.
|
||||
let s = symbol.as_str();
|
||||
let mut buf = Vec::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_c_string(s, Mode::RawCStr, &mut |span, c| match c {
|
||||
Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) => {
|
||||
error = Err(LitError::NulInCStr(span));
|
||||
}
|
||||
Ok(CStrUnit::Byte(b)) => buf.push(b),
|
||||
Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8),
|
||||
Ok(CStrUnit::Char(c)) => {
|
||||
buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
|
||||
}
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
|
|
@ -206,6 +191,7 @@ impl LitKind {
|
|||
}
|
||||
});
|
||||
error?;
|
||||
let mut buf = s.to_owned().into_bytes();
|
||||
buf.push(0);
|
||||
LitKind::CStr(buf.into(), StrStyle::Raw(n))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
hir::InlineAsmOperand::Const { .. }
|
||||
| hir::InlineAsmOperand::SymFn { .. }
|
||||
| hir::InlineAsmOperand::SymStatic { .. } => {
|
||||
unreachable!()
|
||||
unreachable!("{op:?} is not a register operand");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -380,7 +380,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
{
|
||||
reg_sym.as_str()
|
||||
} else {
|
||||
unreachable!();
|
||||
unreachable!("{op:?} is not a register operand");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -917,12 +917,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let poll_expr = {
|
||||
let awaitee = self.expr_ident(span, awaitee_ident, awaitee_pat_hid);
|
||||
let ref_mut_awaitee = self.expr_mut_addr_of(span, awaitee);
|
||||
let task_context = if let Some(task_context_hid) = self.task_context {
|
||||
self.expr_ident_mut(span, task_context_ident, task_context_hid)
|
||||
} else {
|
||||
// Use of `await` outside of an async context, we cannot use `task_context` here.
|
||||
self.expr_err(span, self.tcx.sess.span_delayed_bug(span, "no task_context hir id"))
|
||||
|
||||
let Some(task_context_hid) = self.task_context else {
|
||||
unreachable!("use of `await` outside of an async context.");
|
||||
};
|
||||
|
||||
let task_context = self.expr_ident_mut(span, task_context_ident, task_context_hid);
|
||||
|
||||
let new_unchecked = self.expr_call_lang_item_fn_mut(
|
||||
span,
|
||||
hir::LangItem::PinNewUnchecked,
|
||||
|
|
@ -991,16 +992,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
let yield_expr = self.arena.alloc(yield_expr);
|
||||
|
||||
if let Some(task_context_hid) = self.task_context {
|
||||
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
||||
let assign =
|
||||
self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)));
|
||||
self.stmt_expr(span, assign)
|
||||
} else {
|
||||
// Use of `await` outside of an async context. Return `yield_expr` so that we can
|
||||
// proceed with type checking.
|
||||
self.stmt(span, hir::StmtKind::Semi(yield_expr))
|
||||
}
|
||||
let Some(task_context_hid) = self.task_context else {
|
||||
unreachable!("use of `await` outside of an async context.");
|
||||
};
|
||||
|
||||
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
||||
let assign =
|
||||
self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)));
|
||||
self.stmt_expr(span, assign)
|
||||
};
|
||||
|
||||
let loop_block = self.block_all(span, arena_vec![self; inner_match_stmt, yield_stmt], None);
|
||||
|
|
@ -1260,9 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
|
||||
// `a = lhs1; b = lhs2;`.
|
||||
let stmts = self
|
||||
.arena
|
||||
.alloc_from_iter(std::iter::once(destructure_let).chain(assignments.into_iter()));
|
||||
let stmts = self.arena.alloc_from_iter(std::iter::once(destructure_let).chain(assignments));
|
||||
|
||||
// Wrap everything in a block.
|
||||
hir::ExprKind::Block(self.block_all(whole_span, stmts, None), None)
|
||||
|
|
@ -1637,19 +1634,32 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
};
|
||||
|
||||
let mut yielded =
|
||||
let yielded =
|
||||
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
|
||||
|
||||
if is_async_gen {
|
||||
// yield async_gen_ready($expr);
|
||||
yielded = self.expr_call_lang_item_fn(
|
||||
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
|
||||
// This ensures that we store our resumed `ResumeContext` correctly, and also that
|
||||
// the apparent value of the `yield` expression is `()`.
|
||||
let wrapped_yielded = self.expr_call_lang_item_fn(
|
||||
span,
|
||||
hir::LangItem::AsyncGenReady,
|
||||
std::slice::from_ref(yielded),
|
||||
);
|
||||
}
|
||||
let yield_expr = self.arena.alloc(
|
||||
self.expr(span, hir::ExprKind::Yield(wrapped_yielded, hir::YieldSource::Yield)),
|
||||
);
|
||||
|
||||
hir::ExprKind::Yield(yielded, hir::YieldSource::Yield)
|
||||
let Some(task_context_hid) = self.task_context else {
|
||||
unreachable!("use of `await` outside of an async context.");
|
||||
};
|
||||
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
|
||||
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
||||
|
||||
hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span))
|
||||
} else {
|
||||
hir::ExprKind::Yield(yielded, hir::YieldSource::Yield)
|
||||
}
|
||||
}
|
||||
|
||||
/// Desugar `ExprForLoop` from: `[opt_ident]: for <pat> in <head> <body>` into:
|
||||
|
|
|
|||
|
|
@ -421,8 +421,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
|
||||
let body = P(self.lower_delim_args(body));
|
||||
let DefKind::Macro(macro_kind) = self.tcx.def_kind(self.local_def_id(id)) else {
|
||||
unreachable!()
|
||||
let def_id = self.local_def_id(id);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
let DefKind::Macro(macro_kind) = def_kind else {
|
||||
unreachable!(
|
||||
"expected DefKind::Macro for macro item, found {}",
|
||||
def_kind.descr(def_id.to_def_id())
|
||||
);
|
||||
};
|
||||
let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
|
||||
hir::ItemKind::Macro(macro_def, macro_kind)
|
||||
|
|
|
|||
|
|
@ -59,10 +59,8 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
|||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
|
||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||
use rustc_middle::{
|
||||
span_bug,
|
||||
ty::{ResolverAstLowering, TyCtxt},
|
||||
};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{ResolverAstLowering, TyCtxt, Visibility};
|
||||
use rustc_session::parse::{add_feature_diagnostics, feature_err};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{DesugaringKind, Span, DUMMY_SP};
|
||||
|
|
@ -453,6 +451,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
|
|||
tcx.ensure_with_value().output_filenames(());
|
||||
tcx.ensure_with_value().early_lint_checks(());
|
||||
tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
|
||||
tcx.ensure_with_value().get_lang_items(());
|
||||
let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();
|
||||
|
||||
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
|
||||
|
|
@ -765,6 +764,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.resolver.get_import_res(id).present_items()
|
||||
}
|
||||
|
||||
fn make_lang_item_path(
|
||||
&mut self,
|
||||
lang_item: hir::LangItem,
|
||||
span: Span,
|
||||
args: Option<&'hir hir::GenericArgs<'hir>>,
|
||||
) -> &'hir hir::Path<'hir> {
|
||||
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
let res = Res::Def(def_kind, def_id);
|
||||
self.arena.alloc(hir::Path {
|
||||
span,
|
||||
res,
|
||||
segments: self.arena.alloc_from_iter([hir::PathSegment {
|
||||
ident: Ident::new(lang_item.name(), span),
|
||||
hir_id: self.next_id(),
|
||||
res,
|
||||
args,
|
||||
infer_args: false,
|
||||
}]),
|
||||
})
|
||||
}
|
||||
|
||||
/// Reuses the span but adds information like the kind of the desugaring and features that are
|
||||
/// allowed inside this span.
|
||||
fn mark_span_with_reason(
|
||||
|
|
@ -1630,6 +1651,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
);
|
||||
debug!(?opaque_ty_def_id);
|
||||
|
||||
// Meaningless, but provided so that all items have visibilities.
|
||||
let parent_mod = self.tcx.parent_module_from_def_id(opaque_ty_def_id).to_def_id();
|
||||
self.tcx.feed_local_def_id(opaque_ty_def_id).visibility(Visibility::Restricted(parent_mod));
|
||||
|
||||
// Map from captured (old) lifetime to synthetic (new) lifetime.
|
||||
// Used to resolve lifetimes in the bounds of the opaque.
|
||||
let mut captured_to_synthesized_mapping = FxHashMap::default();
|
||||
|
|
@ -1976,18 +2001,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
|
||||
};
|
||||
|
||||
let future_args = self.arena.alloc(hir::GenericArgs {
|
||||
let bound_args = self.arena.alloc(hir::GenericArgs {
|
||||
args: &[],
|
||||
bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
|
||||
parenthesized: hir::GenericArgsParentheses::No,
|
||||
span_ext: DUMMY_SP,
|
||||
});
|
||||
|
||||
hir::GenericBound::LangItemTrait(
|
||||
trait_lang_item,
|
||||
opaque_ty_span,
|
||||
self.next_id(),
|
||||
future_args,
|
||||
hir::GenericBound::Trait(
|
||||
hir::PolyTraitRef {
|
||||
bound_generic_params: &[],
|
||||
trait_ref: hir::TraitRef {
|
||||
path: self.make_lang_item_path(
|
||||
trait_lang_item,
|
||||
opaque_ty_span,
|
||||
Some(bound_args),
|
||||
),
|
||||
hir_ref_id: self.next_id(),
|
||||
},
|
||||
span: opaque_ty_span,
|
||||
},
|
||||
hir::TraitBoundModifier::None,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use rustc_ast::{self as ast, *};
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
|
|
@ -139,7 +140,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// We should've returned in the for loop above.
|
||||
|
||||
self.tcx.sess.diagnostic().span_bug(
|
||||
self.tcx.sess.dcx().span_bug(
|
||||
p.span,
|
||||
format!(
|
||||
"lower_qpath: no final extension segment in {}..{}",
|
||||
|
|
@ -285,7 +286,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let (start, end) = match self.resolver.get_lifetime_res(segment_id) {
|
||||
Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end),
|
||||
None => return,
|
||||
Some(_) => panic!(),
|
||||
Some(res) => {
|
||||
span_bug!(path_span, "expected an elided lifetime to insert. found {res:?}")
|
||||
}
|
||||
};
|
||||
let expected_lifetimes = end.as_usize() - start.as_usize();
|
||||
debug!(expected_lifetimes);
|
||||
|
|
|
|||
|
|
@ -225,7 +225,8 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here
|
|||
.closure = closures cannot have `~const` trait bounds
|
||||
.function = this function is not `const`, so it cannot have `~const` trait bounds
|
||||
.trait = this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
|
||||
.impl = this impl is not `const`, so it cannot have `~const` trait bounds
|
||||
.trait_impl = this impl is not `const`, so it cannot have `~const` trait bounds
|
||||
.impl = inherent impls cannot have `~const` trait bounds
|
||||
.object = trait objects cannot have `~const` trait bounds
|
||||
.item = this item cannot have `~const` trait bounds
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ enum DisallowTildeConstContext<'a> {
|
|||
TraitObject,
|
||||
Fn(FnKind<'a>),
|
||||
Trait(Span),
|
||||
TraitImpl(Span),
|
||||
Impl(Span),
|
||||
Item,
|
||||
}
|
||||
|
|
@ -220,8 +221,8 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn err_handler(&self) -> &rustc_errors::Handler {
|
||||
self.session.diagnostic()
|
||||
fn dcx(&self) -> &rustc_errors::DiagCtxt {
|
||||
self.session.dcx()
|
||||
}
|
||||
|
||||
fn check_lifetime(&self, ident: Ident) {
|
||||
|
|
@ -269,7 +270,7 @@ impl<'a> AstValidator<'a> {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
self.err_handler().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
|
||||
self.dcx().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
|
||||
}
|
||||
|
||||
fn deny_anon_struct_or_union(&self, ty: &Ty) {
|
||||
|
|
@ -278,15 +279,14 @@ impl<'a> AstValidator<'a> {
|
|||
TyKind::AnonUnion(..) => "union",
|
||||
_ => return,
|
||||
};
|
||||
self.err_handler()
|
||||
.emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
|
||||
self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
|
||||
}
|
||||
|
||||
fn deny_unnamed_field(&self, field: &FieldDef) {
|
||||
if let Some(ident) = field.ident
|
||||
&& ident.name == kw::Underscore
|
||||
{
|
||||
self.err_handler()
|
||||
self.dcx()
|
||||
.emit_err(errors::InvalidUnnamedField { span: field.span, ident_span: ident.span });
|
||||
}
|
||||
}
|
||||
|
|
@ -392,7 +392,7 @@ impl<'a> AstValidator<'a> {
|
|||
[b0] => b0.span(),
|
||||
[b0, .., bl] => b0.span().to(bl.span()),
|
||||
};
|
||||
self.err_handler().emit_err(errors::BoundInContext { span, ctx });
|
||||
self.dcx().emit_err(errors::BoundInContext { span, ctx });
|
||||
}
|
||||
|
||||
fn check_foreign_ty_genericless(
|
||||
|
|
@ -402,7 +402,7 @@ impl<'a> AstValidator<'a> {
|
|||
after_where_clause: &TyAliasWhereClause,
|
||||
) {
|
||||
let cannot_have = |span, descr, remove_descr| {
|
||||
self.err_handler().emit_err(errors::ExternTypesCannotHave {
|
||||
self.dcx().emit_err(errors::ExternTypesCannotHave {
|
||||
span,
|
||||
descr,
|
||||
remove_descr,
|
||||
|
|
@ -428,7 +428,7 @@ impl<'a> AstValidator<'a> {
|
|||
let Some(body) = body else {
|
||||
return;
|
||||
};
|
||||
self.err_handler().emit_err(errors::BodyInExtern {
|
||||
self.dcx().emit_err(errors::BodyInExtern {
|
||||
span: ident.span,
|
||||
body,
|
||||
block: self.current_extern_span(),
|
||||
|
|
@ -441,7 +441,7 @@ impl<'a> AstValidator<'a> {
|
|||
let Some(body) = body else {
|
||||
return;
|
||||
};
|
||||
self.err_handler().emit_err(errors::FnBodyInExtern {
|
||||
self.dcx().emit_err(errors::FnBodyInExtern {
|
||||
span: ident.span,
|
||||
body: body.span,
|
||||
block: self.current_extern_span(),
|
||||
|
|
@ -455,7 +455,7 @@ impl<'a> AstValidator<'a> {
|
|||
/// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
|
||||
fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) {
|
||||
if header.has_qualifiers() {
|
||||
self.err_handler().emit_err(errors::FnQualifierInExtern {
|
||||
self.dcx().emit_err(errors::FnQualifierInExtern {
|
||||
span: ident.span,
|
||||
block: self.current_extern_span(),
|
||||
sugg_span: span.until(ident.span.shrink_to_lo()),
|
||||
|
|
@ -466,7 +466,7 @@ impl<'a> AstValidator<'a> {
|
|||
/// An item in `extern { ... }` cannot use non-ascii identifier.
|
||||
fn check_foreign_item_ascii_only(&self, ident: Ident) {
|
||||
if !ident.as_str().is_ascii() {
|
||||
self.err_handler().emit_err(errors::ExternItemAscii {
|
||||
self.dcx().emit_err(errors::ExternItemAscii {
|
||||
span: ident.span,
|
||||
block: self.current_extern_span(),
|
||||
});
|
||||
|
|
@ -495,7 +495,7 @@ impl<'a> AstValidator<'a> {
|
|||
if let Const::Yes(const_span) = header.constness {
|
||||
let mut spans = variadic_spans.clone();
|
||||
spans.push(const_span);
|
||||
self.err_handler().emit_err(errors::ConstAndCVariadic {
|
||||
self.dcx().emit_err(errors::ConstAndCVariadic {
|
||||
spans,
|
||||
const_span,
|
||||
variadic_spans: variadic_spans.clone(),
|
||||
|
|
@ -517,14 +517,14 @@ impl<'a> AstValidator<'a> {
|
|||
_ => {}
|
||||
};
|
||||
|
||||
self.err_handler().emit_err(errors::BadCVariadic { span: variadic_spans });
|
||||
self.dcx().emit_err(errors::BadCVariadic { span: variadic_spans });
|
||||
}
|
||||
|
||||
fn check_item_named(&self, ident: Ident, kind: &str) {
|
||||
if ident.name != kw::Underscore {
|
||||
return;
|
||||
}
|
||||
self.err_handler().emit_err(errors::ItemUnderscore { span: ident.span, kind });
|
||||
self.dcx().emit_err(errors::ItemUnderscore { span: ident.span, kind });
|
||||
}
|
||||
|
||||
fn check_nomangle_item_asciionly(&self, ident: Ident, item_span: Span) {
|
||||
|
|
@ -615,7 +615,7 @@ impl<'a> AstValidator<'a> {
|
|||
let args_len = arg_spans.len();
|
||||
let constraint_len = constraint_spans.len();
|
||||
// ...and then error:
|
||||
self.err_handler().emit_err(errors::ArgsBeforeConstraint {
|
||||
self.dcx().emit_err(errors::ArgsBeforeConstraint {
|
||||
arg_spans: arg_spans.clone(),
|
||||
constraints: constraint_spans[0],
|
||||
args: *arg_spans.iter().last().unwrap(),
|
||||
|
|
@ -667,7 +667,7 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
|
||||
if !bounds.iter().any(|b| matches!(b, GenericBound::Trait(..))) {
|
||||
self.err_handler().emit_err(errors::AtLeastOneTrait { span: ty.span });
|
||||
self.dcx().emit_err(errors::AtLeastOneTrait { span: ty.span });
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -697,7 +697,7 @@ impl<'a> AstValidator<'a> {
|
|||
/// Checks that generic parameters are in the correct order,
|
||||
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
|
||||
fn validate_generic_param_order(
|
||||
handler: &rustc_errors::Handler,
|
||||
dcx: &rustc_errors::DiagCtxt,
|
||||
generics: &[GenericParam],
|
||||
span: Span,
|
||||
) {
|
||||
|
|
@ -760,7 +760,7 @@ fn validate_generic_param_order(
|
|||
ordered_params += ">";
|
||||
|
||||
for (param_ord, (max_param, spans)) in &out_of_order {
|
||||
handler.emit_err(errors::OutOfOrderParams {
|
||||
dcx.emit_err(errors::OutOfOrderParams {
|
||||
spans: spans.clone(),
|
||||
sugg_span: span,
|
||||
param_ord,
|
||||
|
|
@ -823,7 +823,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
errors::VisibilityNotPermittedNote::TraitImpl,
|
||||
);
|
||||
if let TyKind::Err = self_ty.kind {
|
||||
this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
|
||||
this.dcx().emit_err(errors::ObsoleteAuto { span: item.span });
|
||||
}
|
||||
if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity)
|
||||
{
|
||||
|
|
@ -837,7 +837,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
this.visit_vis(&item.vis);
|
||||
this.visit_ident(item.ident);
|
||||
let disallowed = matches!(constness, Const::No)
|
||||
.then(|| DisallowTildeConstContext::Impl(item.span));
|
||||
.then(|| DisallowTildeConstContext::TraitImpl(item.span));
|
||||
this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
|
||||
this.visit_trait_ref(t);
|
||||
this.visit_ty(self_ty);
|
||||
|
|
@ -871,7 +871,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
errors::VisibilityNotPermittedNote::IndividualImplItems,
|
||||
);
|
||||
if let &Unsafe::Yes(span) = unsafety {
|
||||
self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
|
||||
self.dcx().emit_err(errors::InherentImplCannotUnsafe {
|
||||
span: self_ty.span,
|
||||
annotation_span: span,
|
||||
annotation: "unsafe",
|
||||
|
|
@ -879,18 +879,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
});
|
||||
}
|
||||
if let &ImplPolarity::Negative(span) = polarity {
|
||||
self.err_handler().emit_err(error(span, "negative", false));
|
||||
self.dcx().emit_err(error(span, "negative", false));
|
||||
}
|
||||
if let &Defaultness::Default(def_span) = defaultness {
|
||||
self.err_handler().emit_err(error(def_span, "`default`", true));
|
||||
self.dcx().emit_err(error(def_span, "`default`", true));
|
||||
}
|
||||
if let &Const::Yes(span) = constness {
|
||||
self.err_handler().emit_err(error(span, "`const`", true));
|
||||
self.dcx().emit_err(error(span, "`const`", true));
|
||||
}
|
||||
|
||||
self.visit_vis(&item.vis);
|
||||
self.visit_ident(item.ident);
|
||||
self.with_tilde_const(None, |this| this.visit_generics(generics));
|
||||
self.with_tilde_const(Some(DisallowTildeConstContext::Impl(item.span)), |this| {
|
||||
this.visit_generics(generics)
|
||||
});
|
||||
self.visit_ty(self_ty);
|
||||
walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
|
|
@ -937,7 +939,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
errors::VisibilityNotPermittedNote::IndividualForeignItems,
|
||||
);
|
||||
if let &Unsafe::Yes(span) = unsafety {
|
||||
self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
|
||||
self.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
|
||||
}
|
||||
if abi.is_none() {
|
||||
self.maybe_lint_missing_abi(item.span, item.id);
|
||||
|
|
@ -988,7 +990,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
ItemKind::Mod(unsafety, mod_kind) => {
|
||||
if let &Unsafe::Yes(span) = unsafety {
|
||||
self.err_handler().emit_err(errors::UnsafeItem { span, kind: "module" });
|
||||
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
|
||||
}
|
||||
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
|
||||
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
|
||||
|
|
@ -1011,7 +1013,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
},
|
||||
ItemKind::Union(vdata, generics) => {
|
||||
if vdata.fields().is_empty() {
|
||||
self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
|
||||
self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
|
||||
}
|
||||
match vdata {
|
||||
VariantData::Struct(fields, ..) => {
|
||||
|
|
@ -1026,12 +1028,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => {
|
||||
ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
self.session.emit_err(errors::ConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
if expr.is_none() {
|
||||
self.session.emit_err(errors::ConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
}
|
||||
ItemKind::Static(box StaticItem { expr: None, .. }) => {
|
||||
self.session.emit_err(errors::StaticWithoutBody {
|
||||
|
|
@ -1053,10 +1057,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
|
||||
if self.features.lazy_type_alias {
|
||||
if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
|
||||
self.err_handler().emit_err(err);
|
||||
self.dcx().emit_err(err);
|
||||
}
|
||||
} else if where_clauses.1.0 {
|
||||
self.err_handler().emit_err(errors::WhereClauseAfterTypeAlias {
|
||||
self.dcx().emit_err(errors::WhereClauseAfterTypeAlias {
|
||||
span: where_clauses.1.1,
|
||||
help: self.session.is_nightly_build().then_some(()),
|
||||
});
|
||||
|
|
@ -1141,14 +1145,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
|
||||
if let Some(span) = prev_param_default {
|
||||
self.err_handler().emit_err(errors::GenericDefaultTrailing { span });
|
||||
self.dcx().emit_err(errors::GenericDefaultTrailing { span });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
|
||||
validate_generic_param_order(self.dcx(), &generics.params, generics.span);
|
||||
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
if let WherePredicate::EqPredicate(predicate) = predicate {
|
||||
|
|
@ -1169,7 +1173,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
match bound {
|
||||
GenericBound::Trait(t, _) => {
|
||||
if !t.bound_generic_params.is_empty() {
|
||||
self.err_handler()
|
||||
self.dcx()
|
||||
.emit_err(errors::NestedLifetimes { span: t.span });
|
||||
}
|
||||
}
|
||||
|
|
@ -1195,13 +1199,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
if let GenericBound::Trait(poly, modify) = bound {
|
||||
match (ctxt, modify) {
|
||||
(BoundKind::SuperTraits, TraitBoundModifier::Maybe) => {
|
||||
self.err_handler().emit_err(errors::OptionalTraitSupertrait {
|
||||
self.dcx().emit_err(errors::OptionalTraitSupertrait {
|
||||
span: poly.span,
|
||||
path_str: pprust::path_to_string(&poly.trait_ref.path),
|
||||
});
|
||||
}
|
||||
(BoundKind::TraitObject, TraitBoundModifier::Maybe) => {
|
||||
self.err_handler().emit_err(errors::OptionalTraitObject { span: poly.span });
|
||||
self.dcx().emit_err(errors::OptionalTraitObject { span: poly.span });
|
||||
}
|
||||
(_, &TraitBoundModifier::MaybeConst(span))
|
||||
if let Some(reason) = &self.disallow_tilde_const =>
|
||||
|
|
@ -1216,7 +1220,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
&DisallowTildeConstContext::Trait(span) => {
|
||||
errors::TildeConstReason::Trait { span }
|
||||
}
|
||||
&DisallowTildeConstContext::TraitImpl(span) => {
|
||||
errors::TildeConstReason::TraitImpl { span }
|
||||
}
|
||||
&DisallowTildeConstContext::Impl(span) => {
|
||||
// FIXME(effects): Consider providing a help message or even a structured
|
||||
// suggestion for moving such bounds to the assoc const fns if available.
|
||||
errors::TildeConstReason::Impl { span }
|
||||
}
|
||||
DisallowTildeConstContext::TraitObject => {
|
||||
|
|
@ -1224,16 +1233,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
|
||||
};
|
||||
self.err_handler().emit_err(errors::TildeConstDisallowed { span, reason });
|
||||
self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
|
||||
}
|
||||
(_, TraitBoundModifier::MaybeConstMaybe) => {
|
||||
self.err_handler().emit_err(errors::OptionalConstExclusive {
|
||||
self.dcx().emit_err(errors::OptionalConstExclusive {
|
||||
span: bound.span(),
|
||||
modifier: "?",
|
||||
});
|
||||
}
|
||||
(_, TraitBoundModifier::MaybeConstNegative) => {
|
||||
self.err_handler().emit_err(errors::OptionalConstExclusive {
|
||||
self.dcx().emit_err(errors::OptionalConstExclusive {
|
||||
span: bound.span(),
|
||||
modifier: "!",
|
||||
});
|
||||
|
|
@ -1249,7 +1258,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
{
|
||||
for arg in &args.args {
|
||||
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
|
||||
self.err_handler()
|
||||
self.dcx()
|
||||
.emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
|
||||
}
|
||||
}
|
||||
|
|
@ -1281,7 +1290,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
| CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
|
||||
};
|
||||
// FIXME(gen_blocks): Report a different error for `const gen`
|
||||
self.err_handler().emit_err(errors::ConstAndAsync {
|
||||
self.dcx().emit_err(errors::ConstAndAsync {
|
||||
spans: vec![cspan, aspan],
|
||||
cspan,
|
||||
aspan,
|
||||
|
|
@ -1321,10 +1330,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
} else {
|
||||
match ctxt {
|
||||
FnCtxt::Foreign => {
|
||||
self.err_handler().emit_err(errors::PatternInForeign { span })
|
||||
}
|
||||
_ => self.err_handler().emit_err(errors::PatternInBodiless { span }),
|
||||
FnCtxt::Foreign => self.dcx().emit_err(errors::PatternInForeign { span }),
|
||||
_ => self.dcx().emit_err(errors::PatternInBodiless { span }),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
@ -1523,7 +1530,7 @@ fn deny_equality_constraints(
|
|||
}
|
||||
}
|
||||
}
|
||||
this.err_handler().emit_err(err);
|
||||
this.dcx().emit_err(err);
|
||||
}
|
||||
|
||||
pub fn check_crate(
|
||||
|
|
|
|||
|
|
@ -563,6 +563,11 @@ pub enum TildeConstReason {
|
|||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(ast_passes_trait_impl)]
|
||||
TraitImpl {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(ast_passes_impl)]
|
||||
Impl {
|
||||
#[primary_span]
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ impl<'a> PostExpansionVisitor<'a> {
|
|||
}
|
||||
Err(abi::AbiDisabled::Unrecognized) => {
|
||||
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
|
||||
self.sess.diagnostic().span_delayed_bug(
|
||||
self.sess.dcx().span_delayed_bug(
|
||||
span,
|
||||
format!(
|
||||
"unrecognized ABI not caught in lowering: {}",
|
||||
|
|
@ -654,7 +654,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
|
|||
if all_stable {
|
||||
err.sugg = Some(attr.span);
|
||||
}
|
||||
sess.diagnostic().emit_err(err);
|
||||
sess.dcx().emit_err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,37 +31,37 @@ impl FromStr for Mode {
|
|||
}
|
||||
|
||||
struct ShowSpanVisitor<'a> {
|
||||
span_diagnostic: &'a rustc_errors::Handler,
|
||||
dcx: &'a rustc_errors::DiagCtxt,
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for ShowSpanVisitor<'a> {
|
||||
fn visit_expr(&mut self, e: &'a ast::Expr) {
|
||||
if let Mode::Expression = self.mode {
|
||||
self.span_diagnostic.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" });
|
||||
self.dcx.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" });
|
||||
}
|
||||
visit::walk_expr(self, e);
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &'a ast::Pat) {
|
||||
if let Mode::Pattern = self.mode {
|
||||
self.span_diagnostic.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" });
|
||||
self.dcx.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" });
|
||||
}
|
||||
visit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &'a ast::Ty) {
|
||||
if let Mode::Type = self.mode {
|
||||
self.span_diagnostic.emit_warning(errors::ShowSpan { span: t.span, msg: "type" });
|
||||
self.dcx.emit_warning(errors::ShowSpan { span: t.span, msg: "type" });
|
||||
}
|
||||
visit::walk_ty(self, t);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(span_diagnostic: &rustc_errors::Handler, mode: &str, krate: &ast::Crate) {
|
||||
pub fn run(dcx: &rustc_errors::DiagCtxt, mode: &str, krate: &ast::Crate) {
|
||||
let Ok(mode) = mode.parse() else {
|
||||
return;
|
||||
};
|
||||
let mut v = ShowSpanVisitor { span_diagnostic, mode };
|
||||
let mut v = ShowSpanVisitor { dcx, mode };
|
||||
visit::walk_crate(&mut v, krate);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1597,7 +1597,9 @@ impl<'a> State<'a> {
|
|||
}
|
||||
match bound {
|
||||
ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
||||
_ => panic!(),
|
||||
_ => {
|
||||
panic!("expected a lifetime bound, found a trait bound")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
|||
assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}");
|
||||
use ReprAttr::*;
|
||||
let mut acc = Vec::new();
|
||||
let diagnostic = sess.diagnostic();
|
||||
let diagnostic = sess.dcx();
|
||||
|
||||
if let Some(items) = attr.meta_item_list() {
|
||||
for item in items {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::num::IntErrorKind;
|
|||
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::{
|
||||
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
|
||||
error_code, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
|
||||
};
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
|
@ -51,9 +51,9 @@ pub(crate) struct UnknownMetaItem<'a> {
|
|||
|
||||
// Manual implementation to be able to format `expected` items correctly.
|
||||
impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> {
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
|
||||
let mut diag = handler.struct_span_err_with_code(
|
||||
let mut diag = dcx.struct_span_err_with_code(
|
||||
self.span,
|
||||
fluent::attr_unknown_meta_item,
|
||||
error_code!(E0541),
|
||||
|
|
@ -201,8 +201,8 @@ pub(crate) struct UnsupportedLiteral {
|
|||
}
|
||||
|
||||
impl<'a> IntoDiagnostic<'a> for UnsupportedLiteral {
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let mut diag = handler.struct_span_err_with_code(
|
||||
fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let mut diag = dcx.struct_span_err_with_code(
|
||||
self.span,
|
||||
match self.reason {
|
||||
UnsupportedLiteralReason::Generic => fluent::attr_unsupported_literal_generic,
|
||||
|
|
|
|||
|
|
@ -1138,7 +1138,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
});
|
||||
} else {
|
||||
issued_spans.var_subdiag(
|
||||
Some(self.infcx.tcx.sess.diagnostic()),
|
||||
Some(self.infcx.tcx.sess.dcx()),
|
||||
&mut err,
|
||||
Some(issued_borrow.kind),
|
||||
|kind, var_span| {
|
||||
|
|
@ -1155,7 +1155,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
);
|
||||
|
||||
borrow_spans.var_subdiag(
|
||||
Some(self.infcx.tcx.sess.diagnostic()),
|
||||
Some(self.infcx.tcx.sess.dcx()),
|
||||
&mut err,
|
||||
Some(gen_borrow_kind),
|
||||
|kind, var_span| {
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let did = did.expect_local();
|
||||
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
|
||||
diag.eager_subdiagnostic(
|
||||
self.infcx.tcx.sess.diagnostic(),
|
||||
self.infcx.tcx.sess.dcx(),
|
||||
OnClosureNote::InvokedTwice {
|
||||
place_name: &ty::place_to_string_for_capture(
|
||||
self.infcx.tcx,
|
||||
|
|
@ -146,7 +146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let did = did.expect_local();
|
||||
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
|
||||
diag.eager_subdiagnostic(
|
||||
self.infcx.tcx.sess.diagnostic(),
|
||||
self.infcx.tcx.sess.dcx(),
|
||||
OnClosureNote::MovedTwice {
|
||||
place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place),
|
||||
span: *span,
|
||||
|
|
@ -624,7 +624,7 @@ impl UseSpans<'_> {
|
|||
/// Add a subdiagnostic to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_subdiag(
|
||||
self,
|
||||
handler: Option<&rustc_errors::Handler>,
|
||||
dcx: Option<&rustc_errors::DiagCtxt>,
|
||||
err: &mut Diagnostic,
|
||||
kind: Option<rustc_middle::mir::BorrowKind>,
|
||||
f: impl FnOnce(Option<CoroutineKind>, Span) -> CaptureVarCause,
|
||||
|
|
@ -646,7 +646,7 @@ impl UseSpans<'_> {
|
|||
});
|
||||
};
|
||||
let diag = f(coroutine_kind, path_span);
|
||||
match handler {
|
||||
match dcx {
|
||||
Some(hd) => err.eager_subdiagnostic(hd, diag),
|
||||
None => err.subdiagnostic(diag),
|
||||
};
|
||||
|
|
@ -1150,7 +1150,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&& self.infcx.can_eq(self.param_env, ty, self_ty)
|
||||
{
|
||||
err.eager_subdiagnostic(
|
||||
self.infcx.tcx.sess.diagnostic(),
|
||||
self.infcx.tcx.sess.dcx(),
|
||||
CaptureReasonSuggest::FreshReborrow {
|
||||
span: move_span.shrink_to_hi(),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl OutlivesSuggestionBuilder {
|
|||
// If there is exactly one suggestable constraints, then just suggest it. Otherwise, emit a
|
||||
// list of diagnostics.
|
||||
let mut diag = if suggested.len() == 1 {
|
||||
mbcx.infcx.tcx.sess.diagnostic().struct_help(match suggested.last().unwrap() {
|
||||
mbcx.infcx.tcx.sess.dcx().struct_help(match suggested.last().unwrap() {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect();
|
||||
format!("add bound `{a}: {}`", bs.join(" + "))
|
||||
|
|
@ -223,7 +223,7 @@ impl OutlivesSuggestionBuilder {
|
|||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.diagnostic()
|
||||
.dcx()
|
||||
.struct_help("the following changes may resolve your lifetime errors");
|
||||
|
||||
// Add suggestions.
|
||||
|
|
|
|||
|
|
@ -788,28 +788,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
};
|
||||
let opaque_ty = hir.item(id);
|
||||
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
bounds:
|
||||
[
|
||||
hir::GenericBound::LangItemTrait(
|
||||
hir::LangItem::Future,
|
||||
_,
|
||||
_,
|
||||
hir::GenericArgs {
|
||||
bindings:
|
||||
[
|
||||
hir::TypeBinding {
|
||||
ident: Ident { name: sym::Output, .. },
|
||||
kind:
|
||||
hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
|
||||
..
|
||||
},
|
||||
],
|
||||
..
|
||||
},
|
||||
),
|
||||
],
|
||||
bounds: [hir::GenericBound::Trait(trait_ref, _)],
|
||||
..
|
||||
}) = opaque_ty.kind
|
||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||
&& let Some(args) = segment.args
|
||||
&& let [
|
||||
hir::TypeBinding {
|
||||
ident: Ident { name: sym::Output, .. },
|
||||
kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
|
||||
..
|
||||
},
|
||||
] = args.bindings
|
||||
{
|
||||
ty
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2503,7 +2503,7 @@ mod error {
|
|||
self.errors.buffered.sort_by_key(|diag| diag.sort_span);
|
||||
|
||||
for diag in self.errors.buffered.drain(..) {
|
||||
self.infcx.tcx.sess.diagnostic().emit_diagnostic(diag);
|
||||
self.infcx.tcx.sess.dcx().emit_diagnostic(diag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ pub(super) fn dump_annotation<'tcx>(
|
|||
|
||||
let def_span = tcx.def_span(body.source.def_id());
|
||||
let mut err = if let Some(closure_region_requirements) = closure_region_requirements {
|
||||
let mut err = tcx.sess.diagnostic().struct_span_note(def_span, "external requirements");
|
||||
let mut err = tcx.sess.dcx().struct_span_note(def_span, "external requirements");
|
||||
|
||||
regioncx.annotate(tcx, &mut err);
|
||||
|
||||
|
|
@ -299,7 +299,7 @@ pub(super) fn dump_annotation<'tcx>(
|
|||
|
||||
err
|
||||
} else {
|
||||
let mut err = tcx.sess.diagnostic().struct_span_note(def_span, "no external requirements");
|
||||
let mut err = tcx.sess.dcx().struct_span_note(def_span, "no external requirements");
|
||||
regioncx.annotate(tcx, &mut err);
|
||||
|
||||
err
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: String) {
|
|||
// We sometimes see MIR failures (notably predicate failures) due to
|
||||
// the fact that we check rvalue sized predicates here. So use `span_delayed_bug`
|
||||
// to avoid reporting bugs in those cases.
|
||||
tcx.sess.diagnostic().span_delayed_bug(span, msg);
|
||||
tcx.sess.dcx().span_delayed_bug(span, msg);
|
||||
}
|
||||
|
||||
enum FieldAccessError {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub fn expand(
|
|||
{
|
||||
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||
} else {
|
||||
ecx.sess.diagnostic().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
|
||||
ecx.sess.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
|
||||
return vec![orig_item];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ pub fn parse_asm_args<'a>(
|
|||
sp: Span,
|
||||
is_global_asm: bool,
|
||||
) -> PResult<'a, AsmArgs> {
|
||||
let diag = &sess.span_diagnostic;
|
||||
let dcx = &sess.dcx;
|
||||
|
||||
if p.token == token::Eof {
|
||||
return Err(diag.create_err(errors::AsmRequiresTemplate { span: sp }));
|
||||
return Err(dcx.create_err(errors::AsmRequiresTemplate { span: sp }));
|
||||
}
|
||||
|
||||
let first_template = p.parse_expr()?;
|
||||
|
|
@ -69,7 +69,7 @@ pub fn parse_asm_args<'a>(
|
|||
if !p.eat(&token::Comma) {
|
||||
if allow_templates {
|
||||
// After a template string, we always expect *only* a comma...
|
||||
return Err(diag.create_err(errors::AsmExpectedComma { span: p.token.span }));
|
||||
return Err(dcx.create_err(errors::AsmExpectedComma { span: p.token.span }));
|
||||
} else {
|
||||
// ...after that delegate to `expect` to also include the other expected tokens.
|
||||
return Err(p.expect(&token::Comma).err().unwrap());
|
||||
|
|
@ -110,7 +110,7 @@ pub fn parse_asm_args<'a>(
|
|||
let op = if !is_global_asm && p.eat_keyword(kw::In) {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = diag.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
return Err(err);
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
|
|
@ -126,7 +126,7 @@ pub fn parse_asm_args<'a>(
|
|||
} else if !is_global_asm && p.eat_keyword(sym::inout) {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = diag.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
return Err(err);
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
|
|
@ -140,7 +140,7 @@ pub fn parse_asm_args<'a>(
|
|||
} else if !is_global_asm && p.eat_keyword(sym::inlateout) {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = diag.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
return Err(err);
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
|
|
@ -157,7 +157,7 @@ pub fn parse_asm_args<'a>(
|
|||
} else if p.eat_keyword(sym::sym) {
|
||||
let expr = p.parse_expr()?;
|
||||
let ast::ExprKind::Path(qself, path) = &expr.kind else {
|
||||
let err = diag.create_err(errors::AsmSymNoPath { span: expr.span });
|
||||
let err = dcx.create_err(errors::AsmSymNoPath { span: expr.span });
|
||||
return Err(err);
|
||||
};
|
||||
let sym = ast::InlineAsmSym {
|
||||
|
|
@ -178,7 +178,7 @@ pub fn parse_asm_args<'a>(
|
|||
) => {}
|
||||
ast::ExprKind::MacCall(..) => {}
|
||||
_ => {
|
||||
let err = diag.create_err(errors::AsmExpectedOther {
|
||||
let err = dcx.create_err(errors::AsmExpectedOther {
|
||||
span: template.span,
|
||||
is_global_asm,
|
||||
});
|
||||
|
|
@ -201,12 +201,12 @@ pub fn parse_asm_args<'a>(
|
|||
// of the argument available.
|
||||
if explicit_reg {
|
||||
if name.is_some() {
|
||||
diag.emit_err(errors::AsmExplicitRegisterName { span });
|
||||
dcx.emit_err(errors::AsmExplicitRegisterName { span });
|
||||
}
|
||||
args.reg_args.insert(slot);
|
||||
} else if let Some(name) = name {
|
||||
if let Some(&prev) = args.named_args.get(&name) {
|
||||
diag.emit_err(errors::AsmDuplicateArg { span, name, prev: args.operands[prev].1 });
|
||||
dcx.emit_err(errors::AsmDuplicateArg { span, name, prev: args.operands[prev].1 });
|
||||
continue;
|
||||
}
|
||||
args.named_args.insert(name, slot);
|
||||
|
|
@ -215,7 +215,7 @@ pub fn parse_asm_args<'a>(
|
|||
let named = args.named_args.values().map(|p| args.operands[*p].1).collect();
|
||||
let explicit = args.reg_args.iter().map(|p| args.operands[p].1).collect();
|
||||
|
||||
diag.emit_err(errors::AsmPositionalAfter { span, named, explicit });
|
||||
dcx.emit_err(errors::AsmPositionalAfter { span, named, explicit });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -224,19 +224,19 @@ pub fn parse_asm_args<'a>(
|
|||
&& args.options.contains(ast::InlineAsmOptions::READONLY)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
diag.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "nomem", opt2: "readonly" });
|
||||
dcx.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "nomem", opt2: "readonly" });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
diag.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "pure", opt2: "noreturn" });
|
||||
dcx.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "pure", opt2: "noreturn" });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
diag.emit_err(errors::AsmPureCombine { spans });
|
||||
dcx.emit_err(errors::AsmPureCombine { spans });
|
||||
}
|
||||
|
||||
let mut have_real_output = false;
|
||||
|
|
@ -263,17 +263,17 @@ pub fn parse_asm_args<'a>(
|
|||
}
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
|
||||
diag.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() });
|
||||
dcx.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
|
||||
let err = diag.create_err(errors::AsmNoReturn { outputs_sp });
|
||||
let err = dcx.create_err(errors::AsmNoReturn { outputs_sp });
|
||||
// Bail out now since this is likely to confuse MIR
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
if args.clobber_abis.len() > 0 {
|
||||
if is_global_asm {
|
||||
let err = diag.create_err(errors::GlobalAsmClobberAbi {
|
||||
let err = dcx.create_err(errors::GlobalAsmClobberAbi {
|
||||
spans: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
|
||||
});
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ pub fn parse_asm_args<'a>(
|
|||
return Err(err);
|
||||
}
|
||||
if !regclass_outputs.is_empty() {
|
||||
diag.emit_err(errors::AsmClobberNoReg {
|
||||
dcx.emit_err(errors::AsmClobberNoReg {
|
||||
spans: regclass_outputs,
|
||||
clobbers: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
|
||||
});
|
||||
|
|
@ -298,7 +298,7 @@ pub fn parse_asm_args<'a>(
|
|||
fn err_duplicate_option(p: &mut Parser<'_>, symbol: Symbol, span: Span) {
|
||||
// Tool-only output
|
||||
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
|
||||
p.sess.span_diagnostic.emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
|
||||
p.sess.dcx.emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
|
||||
}
|
||||
|
||||
/// Try to set the provided option in the provided `AsmArgs`.
|
||||
|
|
@ -370,7 +370,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
|
|||
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
|
||||
|
||||
if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
|
||||
return Err(p.sess.span_diagnostic.create_err(errors::NonABI { span: p.token.span }));
|
||||
return Err(p.sess.dcx.create_err(errors::NonABI { span: p.token.span }));
|
||||
}
|
||||
|
||||
let mut new_abis = Vec::new();
|
||||
|
|
@ -381,8 +381,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
|
|||
}
|
||||
Err(opt_lit) => {
|
||||
let span = opt_lit.map_or(p.token.span, |lit| lit.span);
|
||||
let mut err =
|
||||
p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
|
||||
let mut err = p.sess.dcx.struct_span_err(span, "expected string literal");
|
||||
err.span_label(span, "not a string literal");
|
||||
return Err(err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ pub fn inject(krate: &mut ast::Crate, parse_sess: &ParseSess, attrs: &[String])
|
|||
};
|
||||
let end_span = parser.token.span;
|
||||
if parser.token != token::Eof {
|
||||
parse_sess
|
||||
.span_diagnostic
|
||||
.emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
|
||||
parse_sess.dcx.emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_errors::{
|
||||
AddToDiagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, MultiSpan,
|
||||
AddToDiagnostic, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan,
|
||||
SingleLabelManySpans,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
|
|
@ -448,12 +448,12 @@ pub(crate) struct EnvNotDefinedWithUserMessage {
|
|||
// Hand-written implementation to support custom user messages.
|
||||
impl<'a> IntoDiagnostic<'a> for EnvNotDefinedWithUserMessage {
|
||||
#[track_caller]
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
#[expect(
|
||||
rustc::untranslatable_diagnostic,
|
||||
reason = "cannot translate user-provided messages"
|
||||
)]
|
||||
let mut diag = handler.struct_err(self.msg_from_user.to_string());
|
||||
let mut diag = dcx.struct_err(self.msg_from_user.to_string());
|
||||
diag.set_span(self.span);
|
||||
diag
|
||||
}
|
||||
|
|
@ -802,17 +802,16 @@ pub(crate) struct AsmClobberNoReg {
|
|||
}
|
||||
|
||||
impl<'a> IntoDiagnostic<'a> for AsmClobberNoReg {
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let mut diag =
|
||||
handler.struct_err(crate::fluent_generated::builtin_macros_asm_clobber_no_reg);
|
||||
fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let mut diag = dcx.struct_err(crate::fluent_generated::builtin_macros_asm_clobber_no_reg);
|
||||
diag.set_span(self.spans.clone());
|
||||
// eager translation as `span_labels` takes `AsRef<str>`
|
||||
let lbl1 = handler.eagerly_translate_to_string(
|
||||
let lbl1 = dcx.eagerly_translate_to_string(
|
||||
crate::fluent_generated::builtin_macros_asm_clobber_abi,
|
||||
[].into_iter(),
|
||||
);
|
||||
diag.span_labels(self.clobbers, &lbl1);
|
||||
let lbl2 = handler.eagerly_translate_to_string(
|
||||
let lbl2 = dcx.eagerly_translate_to_string(
|
||||
crate::fluent_generated::builtin_macros_asm_clobber_outputs,
|
||||
[].into_iter(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ pub fn expand(
|
|||
{
|
||||
(item, true, ecx.with_def_site_ctxt(ty.span))
|
||||
} else {
|
||||
ecx.sess.diagnostic().emit_err(errors::AllocMustStatics { span: item.span() });
|
||||
ecx.sess.dcx().emit_err(errors::AllocMustStatics { span: item.span() });
|
||||
return vec![orig_item];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ enum ProcMacro {
|
|||
struct CollectProcMacros<'a> {
|
||||
macros: Vec<ProcMacro>,
|
||||
in_root: bool,
|
||||
handler: &'a rustc_errors::Handler,
|
||||
dcx: &'a rustc_errors::DiagCtxt,
|
||||
source_map: &'a SourceMap,
|
||||
is_proc_macro_crate: bool,
|
||||
is_test_crate: bool,
|
||||
|
|
@ -52,7 +52,7 @@ pub fn inject(
|
|||
is_proc_macro_crate: bool,
|
||||
has_proc_macro_decls: bool,
|
||||
is_test_crate: bool,
|
||||
handler: &rustc_errors::Handler,
|
||||
dcx: &rustc_errors::DiagCtxt,
|
||||
) {
|
||||
let ecfg = ExpansionConfig::default("proc_macro".to_string(), features);
|
||||
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
|
||||
|
|
@ -60,7 +60,7 @@ pub fn inject(
|
|||
let mut collect = CollectProcMacros {
|
||||
macros: Vec::new(),
|
||||
in_root: true,
|
||||
handler,
|
||||
dcx,
|
||||
source_map: sess.source_map(),
|
||||
is_proc_macro_crate,
|
||||
is_test_crate,
|
||||
|
|
@ -86,13 +86,13 @@ pub fn inject(
|
|||
impl<'a> CollectProcMacros<'a> {
|
||||
fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
|
||||
if self.is_proc_macro_crate && self.in_root && vis.kind.is_pub() {
|
||||
self.handler.emit_err(errors::ProcMacro { span: sp });
|
||||
self.dcx.emit_err(errors::ProcMacro { span: sp });
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
|
||||
let Some((trait_name, proc_attrs)) =
|
||||
parse_macro_name_and_helper_attrs(self.handler, attr, "derive")
|
||||
parse_macro_name_and_helper_attrs(self.dcx, attr, "derive")
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -112,7 +112,7 @@ impl<'a> CollectProcMacros<'a> {
|
|||
} else {
|
||||
"functions tagged with `#[proc_macro_derive]` must be `pub`"
|
||||
};
|
||||
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
||||
self.dcx.span_err(self.source_map.guess_head_span(item.span), msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ impl<'a> CollectProcMacros<'a> {
|
|||
} else {
|
||||
"functions tagged with `#[proc_macro_attribute]` must be `pub`"
|
||||
};
|
||||
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
||||
self.dcx.span_err(self.source_map.guess_head_span(item.span), msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ impl<'a> CollectProcMacros<'a> {
|
|||
} else {
|
||||
"functions tagged with `#[proc_macro]` must be `pub`"
|
||||
};
|
||||
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
||||
self.dcx.span_err(self.source_map.guess_head_span(item.span), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
fn visit_item(&mut self, item: &'a ast::Item) {
|
||||
if let ast::ItemKind::MacroDef(..) = item.kind {
|
||||
if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) {
|
||||
self.handler.emit_err(errors::ExportMacroRules {
|
||||
self.dcx.emit_err(errors::ExportMacroRules {
|
||||
span: self.source_map.guess_head_span(item.span),
|
||||
});
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
)
|
||||
};
|
||||
|
||||
self.handler
|
||||
self.dcx
|
||||
.struct_span_err(attr.span, msg)
|
||||
.span_label(prev_attr.span, "previous attribute here")
|
||||
.emit();
|
||||
|
|
@ -218,7 +218,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
pprust::path_to_string(&attr.get_normal_item().path),
|
||||
);
|
||||
|
||||
self.handler.span_err(attr.span, msg);
|
||||
self.dcx.span_err(attr.span, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
pprust::path_to_string(&attr.get_normal_item().path),
|
||||
);
|
||||
|
||||
self.handler.span_err(attr.span, msg);
|
||||
self.dcx.span_err(attr.span, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -389,16 +389,16 @@ pub fn expand_test_or_bench(
|
|||
}
|
||||
|
||||
fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
|
||||
let diag = cx.sess.diagnostic();
|
||||
let dcx = cx.sess.dcx();
|
||||
let msg = "the `#[test]` attribute may only be used on a non-associated function";
|
||||
let mut err = match item.map(|i| &i.kind) {
|
||||
// These were a warning before #92959 and need to continue being that to avoid breaking
|
||||
// stable user code (#94508).
|
||||
Some(ast::ItemKind::MacCall(_)) => diag.struct_span_warn(attr_sp, msg),
|
||||
Some(ast::ItemKind::MacCall(_)) => dcx.struct_span_warn(attr_sp, msg),
|
||||
// `.forget_guarantee()` needed to get these two arms to match types. Because of how
|
||||
// locally close the `.emit()` call is I'm comfortable with it, but if it can be
|
||||
// reworked in the future to not need it, it'd be nice.
|
||||
_ => diag.struct_span_err(attr_sp, msg).forget_guarantee(),
|
||||
_ => dcx.struct_span_err(attr_sp, msg).forget_guarantee(),
|
||||
};
|
||||
if let Some(item) = item {
|
||||
err.span_label(
|
||||
|
|
@ -466,7 +466,7 @@ fn should_ignore_message(i: &ast::Item) -> Option<Symbol> {
|
|||
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
|
||||
match attr::find_by_name(&i.attrs, sym::should_panic) {
|
||||
Some(attr) => {
|
||||
let sd = cx.sess.diagnostic();
|
||||
let dcx = cx.sess.dcx();
|
||||
|
||||
match attr.meta_item_list() {
|
||||
// Handle #[should_panic(expected = "foo")]
|
||||
|
|
@ -477,7 +477,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
|
|||
.and_then(|mi| mi.meta_item())
|
||||
.and_then(|mi| mi.value_str());
|
||||
if list.len() != 1 || msg.is_none() {
|
||||
sd.struct_span_warn(
|
||||
dcx.struct_span_warn(
|
||||
attr.span,
|
||||
"argument must be of the form: \
|
||||
`expected = \"error message\"`",
|
||||
|
|
@ -535,30 +535,30 @@ fn check_test_signature(
|
|||
f: &ast::Fn,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
|
||||
let sd = cx.sess.diagnostic();
|
||||
let dcx = cx.sess.dcx();
|
||||
|
||||
if let ast::Unsafe::Yes(span) = f.sig.header.unsafety {
|
||||
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
|
||||
return Err(dcx.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
|
||||
}
|
||||
|
||||
if let Some(coroutine_kind) = f.sig.header.coroutine_kind {
|
||||
match coroutine_kind {
|
||||
ast::CoroutineKind::Async { span, .. } => {
|
||||
return Err(sd.emit_err(errors::TestBadFn {
|
||||
return Err(dcx.emit_err(errors::TestBadFn {
|
||||
span: i.span,
|
||||
cause: span,
|
||||
kind: "async",
|
||||
}));
|
||||
}
|
||||
ast::CoroutineKind::Gen { span, .. } => {
|
||||
return Err(sd.emit_err(errors::TestBadFn {
|
||||
return Err(dcx.emit_err(errors::TestBadFn {
|
||||
span: i.span,
|
||||
cause: span,
|
||||
kind: "gen",
|
||||
}));
|
||||
}
|
||||
ast::CoroutineKind::AsyncGen { span, .. } => {
|
||||
return Err(sd.emit_err(errors::TestBadFn {
|
||||
return Err(dcx.emit_err(errors::TestBadFn {
|
||||
span: i.span,
|
||||
cause: span,
|
||||
kind: "async gen",
|
||||
|
|
@ -576,15 +576,15 @@ fn check_test_signature(
|
|||
};
|
||||
|
||||
if !f.sig.decl.inputs.is_empty() {
|
||||
return Err(sd.span_err(i.span, "functions used as tests can not have any arguments"));
|
||||
return Err(dcx.span_err(i.span, "functions used as tests can not have any arguments"));
|
||||
}
|
||||
|
||||
if has_should_panic_attr && has_output {
|
||||
return Err(sd.span_err(i.span, "functions using `#[should_panic]` must return `()`"));
|
||||
return Err(dcx.span_err(i.span, "functions using `#[should_panic]` must return `()`"));
|
||||
}
|
||||
|
||||
if f.generics.params.iter().any(|param| !matches!(param.kind, GenericParamKind::Lifetime)) {
|
||||
return Err(sd.span_err(
|
||||
return Err(dcx.span_err(
|
||||
i.span,
|
||||
"functions used as tests can not have any non-lifetime generic parameters",
|
||||
));
|
||||
|
|
@ -601,7 +601,7 @@ fn check_bench_signature(
|
|||
// N.B., inadequate check, but we're running
|
||||
// well before resolve, can't get too deep.
|
||||
if f.sig.decl.inputs.len() != 1 {
|
||||
return Err(cx.sess.diagnostic().emit_err(errors::BenchSig { span: i.span }));
|
||||
return Err(cx.sess.dcx().emit_err(errors::BenchSig { span: i.span }));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ pub fn inject(
|
|||
features: &Features,
|
||||
resolver: &mut dyn ResolverExpand,
|
||||
) {
|
||||
let span_diagnostic = sess.diagnostic();
|
||||
let dcx = sess.dcx();
|
||||
let panic_strategy = sess.panic_strategy();
|
||||
let platform_panic_strategy = sess.target.panic_strategy;
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ pub fn inject(
|
|||
|
||||
// Do this here so that the test_runner crate attribute gets marked as used
|
||||
// even in non-test builds
|
||||
let test_runner = get_test_runner(span_diagnostic, krate);
|
||||
let test_runner = get_test_runner(dcx, krate);
|
||||
|
||||
if sess.is_test_crate() {
|
||||
let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) {
|
||||
|
|
@ -70,7 +70,7 @@ pub fn inject(
|
|||
// Silently allow compiling with panic=abort on these platforms,
|
||||
// but with old behavior (abort if a test fails).
|
||||
} else {
|
||||
span_diagnostic.emit_err(errors::TestsNotSupport {});
|
||||
dcx.emit_err(errors::TestsNotSupport {});
|
||||
}
|
||||
PanicStrategy::Unwind
|
||||
}
|
||||
|
|
@ -389,7 +389,7 @@ fn get_test_name(i: &ast::Item) -> Option<Symbol> {
|
|||
attr::first_attr_value_str_by_name(&i.attrs, sym::rustc_test_marker)
|
||||
}
|
||||
|
||||
fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
|
||||
fn get_test_runner(dcx: &rustc_errors::DiagCtxt, krate: &ast::Crate) -> Option<ast::Path> {
|
||||
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
|
||||
let meta_list = test_attr.meta_item_list()?;
|
||||
let span = test_attr.span;
|
||||
|
|
@ -397,11 +397,11 @@ fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast
|
|||
[single] => match single.meta_item() {
|
||||
Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
|
||||
_ => {
|
||||
sd.emit_err(errors::TestRunnerInvalid { span });
|
||||
dcx.emit_err(errors::TestRunnerInvalid { span });
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
sd.emit_err(errors::TestRunnerNargs { span });
|
||||
dcx.emit_err(errors::TestRunnerNargs { span });
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
|||
|
|
@ -176,10 +176,10 @@ pub(crate) fn compile_fn(
|
|||
match module.define_function(codegened_func.func_id, context) {
|
||||
Ok(()) => {}
|
||||
Err(ModuleError::Compilation(CodegenError::ImplLimitExceeded)) => {
|
||||
let handler = rustc_session::EarlyErrorHandler::new(
|
||||
let early_dcx = rustc_session::EarlyDiagCtxt::new(
|
||||
rustc_session::config::ErrorOutputType::default(),
|
||||
);
|
||||
handler.early_error(format!(
|
||||
early_dcx.early_error(format!(
|
||||
"backend implementation limit exceeded while compiling {name}",
|
||||
name = codegened_func.symbol_name
|
||||
));
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ impl ConcurrencyLimiter {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn acquire(&mut self, handler: &rustc_errors::Handler) -> ConcurrencyLimiterToken {
|
||||
pub(super) fn acquire(&mut self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken {
|
||||
let mut state = self.state.lock().unwrap();
|
||||
loop {
|
||||
state.assert_invariants();
|
||||
|
|
@ -64,7 +64,7 @@ impl ConcurrencyLimiter {
|
|||
// Make sure to drop the mutex guard first to prevent poisoning the mutex.
|
||||
drop(state);
|
||||
if let Some(err) = err {
|
||||
handler.fatal(err);
|
||||
dcx.fatal(err);
|
||||
} else {
|
||||
// The error was already emitted, but compilation continued. Raise a silent
|
||||
// fatal error.
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ pub(crate) fn run_aot(
|
|||
backend_config.clone(),
|
||||
global_asm_config.clone(),
|
||||
cgu.name(),
|
||||
concurrency_limiter.acquire(tcx.sess.diagnostic()),
|
||||
concurrency_limiter.acquire(tcx.sess.dcx()),
|
||||
),
|
||||
module_codegen,
|
||||
Some(rustc_middle::dep_graph::hash_result),
|
||||
|
|
|
|||
|
|
@ -231,9 +231,8 @@ pub(crate) fn write_ir_file(
|
|||
let res = std::fs::File::create(clif_file_name).and_then(|mut file| write(&mut file));
|
||||
if let Err(err) = res {
|
||||
// Using early_warn as no Session is available here
|
||||
let handler = rustc_session::EarlyErrorHandler::new(
|
||||
rustc_session::config::ErrorOutputType::default(),
|
||||
);
|
||||
let handler =
|
||||
rustc_session::EarlyDiagCtxt::new(rustc_session::config::ErrorOutputType::default());
|
||||
handler.early_warn(format!("error writing ir file: {}", err));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
|
|||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use rustc_errors::{FatalError, DiagCtxt};
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::dep_graph::WorkProduct;
|
||||
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
|
||||
|
|
@ -61,7 +61,7 @@ struct LtoData {
|
|||
tmp_path: TempDir,
|
||||
}
|
||||
|
||||
fn prepare_lto(cgcx: &CodegenContext<GccCodegenBackend>, diag_handler: &Handler) -> Result<LtoData, FatalError> {
|
||||
fn prepare_lto(cgcx: &CodegenContext<GccCodegenBackend>, dcx: &DiagCtxt) -> Result<LtoData, FatalError> {
|
||||
let export_threshold = match cgcx.lto {
|
||||
// We're just doing LTO for our one crate
|
||||
Lto::ThinLocal => SymbolExportLevel::Rust,
|
||||
|
|
@ -106,18 +106,18 @@ fn prepare_lto(cgcx: &CodegenContext<GccCodegenBackend>, diag_handler: &Handler)
|
|||
// Make sure we actually can run LTO
|
||||
for crate_type in cgcx.crate_types.iter() {
|
||||
if !crate_type_allows_lto(*crate_type) {
|
||||
diag_handler.emit_err(LtoDisallowed);
|
||||
dcx.emit_err(LtoDisallowed);
|
||||
return Err(FatalError);
|
||||
} else if *crate_type == CrateType::Dylib {
|
||||
if !cgcx.opts.unstable_opts.dylib_lto {
|
||||
diag_handler.emit_err(LtoDylib);
|
||||
dcx.emit_err(LtoDylib);
|
||||
return Err(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cgcx.opts.cg.prefer_dynamic && !cgcx.opts.unstable_opts.dylib_lto {
|
||||
diag_handler.emit_err(DynamicLinkingWithLTO);
|
||||
dcx.emit_err(DynamicLinkingWithLTO);
|
||||
return Err(FatalError);
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ fn prepare_lto(cgcx: &CodegenContext<GccCodegenBackend>, diag_handler: &Handler)
|
|||
upstream_modules.push((module, CString::new(name).unwrap()));
|
||||
}
|
||||
Err(e) => {
|
||||
diag_handler.emit_err(e);
|
||||
dcx.emit_err(e);
|
||||
return Err(FatalError);
|
||||
}
|
||||
}
|
||||
|
|
@ -183,16 +183,16 @@ pub(crate) fn run_fat(
|
|||
modules: Vec<FatLtoInput<GccCodegenBackend>>,
|
||||
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
|
||||
) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let lto_data = prepare_lto(cgcx, &diag_handler)?;
|
||||
let dcx = cgcx.create_dcx();
|
||||
let lto_data = prepare_lto(cgcx, &dcx)?;
|
||||
/*let symbols_below_threshold =
|
||||
lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
|
||||
fat_lto(cgcx, &diag_handler, modules, cached_modules, lto_data.upstream_modules, lto_data.tmp_path,
|
||||
fat_lto(cgcx, &dcx, modules, cached_modules, lto_data.upstream_modules, lto_data.tmp_path,
|
||||
//&symbols_below_threshold,
|
||||
)
|
||||
}
|
||||
|
||||
fn fat_lto(cgcx: &CodegenContext<GccCodegenBackend>, _diag_handler: &Handler, modules: Vec<FatLtoInput<GccCodegenBackend>>, cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>, tmp_path: TempDir,
|
||||
fn fat_lto(cgcx: &CodegenContext<GccCodegenBackend>, _dcx: &DiagCtxt, modules: Vec<FatLtoInput<GccCodegenBackend>>, cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>, tmp_path: TempDir,
|
||||
//symbols_below_threshold: &[*const libc::c_char],
|
||||
) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> {
|
||||
let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module");
|
||||
|
|
@ -257,7 +257,7 @@ fn fat_lto(cgcx: &CodegenContext<GccCodegenBackend>, _diag_handler: &Handler, mo
|
|||
let (buffer, name) = serialized_modules.remove(0);
|
||||
info!("no in-memory regular modules to choose from, parsing {:?}", name);
|
||||
ModuleCodegen {
|
||||
module_llvm: GccContext::parse(cgcx, &name, buffer.data(), diag_handler)?,
|
||||
module_llvm: GccContext::parse(cgcx, &name, buffer.data(), dcx)?,
|
||||
name: name.into_string().unwrap(),
|
||||
kind: ModuleKind::Regular,
|
||||
}*/
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use gccjit::OutputKind;
|
|||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
|
||||
use rustc_codegen_ssa::back::link::ensure_removed;
|
||||
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
|
||||
use rustc_errors::Handler;
|
||||
use rustc_errors::DiagCtxt;
|
||||
use rustc_fs_util::link_or_copy;
|
||||
use rustc_session::config::OutputType;
|
||||
use rustc_span::fatal_error::FatalError;
|
||||
|
|
@ -13,7 +13,7 @@ use rustc_target::spec::SplitDebuginfo;
|
|||
use crate::{GccCodegenBackend, GccContext};
|
||||
use crate::errors::CopyBitcode;
|
||||
|
||||
pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, diag_handler: &Handler, module: ModuleCodegen<GccContext>, config: &ModuleConfig) -> Result<CompiledModule, FatalError> {
|
||||
pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, dcx: &DiagCtxt, module: ModuleCodegen<GccContext>, config: &ModuleConfig) -> Result<CompiledModule, FatalError> {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name);
|
||||
{
|
||||
let context = &module.module_llvm.context;
|
||||
|
|
@ -127,12 +127,12 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, diag_hand
|
|||
EmitObj::Bitcode => {
|
||||
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
|
||||
if let Err(err) = link_or_copy(&bc_out, &obj_out) {
|
||||
diag_handler.emit_err(CopyBitcode { err });
|
||||
dcx.emit_err(CopyBitcode { err });
|
||||
}
|
||||
|
||||
if !config.emit_bc {
|
||||
debug!("removing_bitcode {:?}", bc_out);
|
||||
ensure_removed(diag_handler, &bc_out);
|
||||
ensure_removed(dcx, &bc_out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<GccCodegenBackend>, diag_hand
|
|||
))
|
||||
}
|
||||
|
||||
pub(crate) fn link(_cgcx: &CodegenContext<GccCodegenBackend>, _diag_handler: &Handler, mut _modules: Vec<ModuleCodegen<GccContext>>) -> Result<ModuleCodegen<GccContext>, FatalError> {
|
||||
pub(crate) fn link(_cgcx: &CodegenContext<GccCodegenBackend>, _dcx: &DiagCtxt, mut _modules: Vec<ModuleCodegen<GccContext>>) -> Result<ModuleCodegen<GccContext>, FatalError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -377,9 +377,6 @@ pub trait TypeReflection<'gcc, 'tcx> {
|
|||
fn is_i128(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool;
|
||||
fn is_u128(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool;
|
||||
|
||||
fn is_f32(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool;
|
||||
fn is_f64(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool;
|
||||
|
||||
fn is_vector(&self) -> bool;
|
||||
}
|
||||
|
||||
|
|
@ -464,14 +461,6 @@ impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> {
|
|||
self.unqualified() == cx.u128_type.unqualified()
|
||||
}
|
||||
|
||||
fn is_f32(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool {
|
||||
self.unqualified() == cx.context.new_type::<f32>()
|
||||
}
|
||||
|
||||
fn is_f64(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool {
|
||||
self.unqualified() == cx.context.new_type::<f64>()
|
||||
}
|
||||
|
||||
fn is_vector(&self) -> bool {
|
||||
let mut typ = self.clone();
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -22,12 +22,6 @@ use rustc_target::spec::{HasTargetSpec, Target, TlsModel};
|
|||
use crate::callee::get_fn;
|
||||
use crate::common::SignType;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FuncSig<'gcc> {
|
||||
pub params: Vec<Type<'gcc>>,
|
||||
pub return_type: Type<'gcc>,
|
||||
}
|
||||
|
||||
pub struct CodegenCx<'gcc, 'tcx> {
|
||||
pub check_overflow: bool,
|
||||
pub codegen_unit: &'tcx CodegenUnit<'tcx>,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use rustc_errors::{
|
||||
DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, IntoDiagnosticArg,
|
||||
DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
|
||||
IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::Span;
|
||||
|
|
@ -111,8 +112,8 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> {
|
|||
pub(crate) struct MissingFeatures;
|
||||
|
||||
impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> {
|
||||
fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = handler.struct_err(fluent::codegen_gcc_target_feature_disable_or_enable);
|
||||
fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = dcx.struct_err(fluent::codegen_gcc_target_feature_disable_or_enable);
|
||||
if let Some(span) = self.span {
|
||||
diag.set_span(span);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModul
|
|||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sync::IntoDynSyncSend;
|
||||
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods};
|
||||
use rustc_errors::{ErrorGuaranteed, Handler};
|
||||
use rustc_errors::{ErrorGuaranteed, DiagCtxt};
|
||||
use rustc_metadata::EncodedMetadata;
|
||||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||
use rustc_middle::util::Providers;
|
||||
|
|
@ -330,7 +330,7 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
|
||||
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _dcx: &DiagCtxt, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
|
||||
module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -344,8 +344,8 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
unimplemented!();
|
||||
}
|
||||
|
||||
unsafe fn codegen(cgcx: &CodegenContext<Self>, diag_handler: &Handler, module: ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<CompiledModule, FatalError> {
|
||||
back::write::codegen(cgcx, diag_handler, module, config)
|
||||
unsafe fn codegen(cgcx: &CodegenContext<Self>, dcx: &DiagCtxt, module: ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<CompiledModule, FatalError> {
|
||||
back::write::codegen(cgcx, dcx, module, config)
|
||||
}
|
||||
|
||||
fn prepare_thin(_module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
|
||||
|
|
@ -356,8 +356,8 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
unimplemented!();
|
||||
}
|
||||
|
||||
fn run_link(cgcx: &CodegenContext<Self>, diag_handler: &Handler, modules: Vec<ModuleCodegen<Self::Module>>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
back::write::link(cgcx, diag_handler, modules)
|
||||
fn run_link(cgcx: &CodegenContext<Self>, dcx: &DiagCtxt, modules: Vec<ModuleCodegen<Self::Module>>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
back::write::link(cgcx, dcx, modules)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use rustc_codegen_ssa::traits::*;
|
|||
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use rustc_errors::{DiagCtxt, FatalError};
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::WorkProduct;
|
||||
|
|
@ -47,7 +47,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
|
|||
|
||||
fn prepare_lto(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
) -> Result<(Vec<CString>, Vec<(SerializedModule<ModuleBuffer>, CString)>), FatalError> {
|
||||
let export_threshold = match cgcx.lto {
|
||||
// We're just doing LTO for our one crate
|
||||
|
|
@ -84,23 +84,23 @@ fn prepare_lto(
|
|||
// Make sure we actually can run LTO
|
||||
for crate_type in cgcx.crate_types.iter() {
|
||||
if !crate_type_allows_lto(*crate_type) {
|
||||
diag_handler.emit_err(LtoDisallowed);
|
||||
dcx.emit_err(LtoDisallowed);
|
||||
return Err(FatalError);
|
||||
} else if *crate_type == CrateType::Dylib {
|
||||
if !cgcx.opts.unstable_opts.dylib_lto {
|
||||
diag_handler.emit_err(LtoDylib);
|
||||
dcx.emit_err(LtoDylib);
|
||||
return Err(FatalError);
|
||||
}
|
||||
} else if *crate_type == CrateType::ProcMacro {
|
||||
if !cgcx.opts.unstable_opts.dylib_lto {
|
||||
diag_handler.emit_err(LtoProcMacro);
|
||||
dcx.emit_err(LtoProcMacro);
|
||||
return Err(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cgcx.opts.cg.prefer_dynamic && !cgcx.opts.unstable_opts.dylib_lto {
|
||||
diag_handler.emit_err(DynamicLinkingWithLTO);
|
||||
dcx.emit_err(DynamicLinkingWithLTO);
|
||||
return Err(FatalError);
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ fn prepare_lto(
|
|||
upstream_modules.push((module, CString::new(name).unwrap()));
|
||||
}
|
||||
Err(e) => {
|
||||
diag_handler.emit_err(e);
|
||||
dcx.emit_err(e);
|
||||
return Err(FatalError);
|
||||
}
|
||||
}
|
||||
|
|
@ -200,18 +200,11 @@ pub(crate) fn run_fat(
|
|||
modules: Vec<FatLtoInput<LlvmCodegenBackend>>,
|
||||
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
|
||||
) -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, &diag_handler)?;
|
||||
let dcx = cgcx.create_dcx();
|
||||
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, &dcx)?;
|
||||
let symbols_below_threshold =
|
||||
symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
|
||||
fat_lto(
|
||||
cgcx,
|
||||
&diag_handler,
|
||||
modules,
|
||||
cached_modules,
|
||||
upstream_modules,
|
||||
&symbols_below_threshold,
|
||||
)
|
||||
fat_lto(cgcx, &dcx, modules, cached_modules, upstream_modules, &symbols_below_threshold)
|
||||
}
|
||||
|
||||
/// Performs thin LTO by performing necessary global analysis and returning two
|
||||
|
|
@ -222,8 +215,8 @@ pub(crate) fn run_thin(
|
|||
modules: Vec<(String, ThinBuffer)>,
|
||||
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
|
||||
) -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, &diag_handler)?;
|
||||
let dcx = cgcx.create_dcx();
|
||||
let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, &dcx)?;
|
||||
let symbols_below_threshold =
|
||||
symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
|
||||
if cgcx.opts.cg.linker_plugin_lto.enabled() {
|
||||
|
|
@ -232,14 +225,7 @@ pub(crate) fn run_thin(
|
|||
is deferred to the linker"
|
||||
);
|
||||
}
|
||||
thin_lto(
|
||||
cgcx,
|
||||
&diag_handler,
|
||||
modules,
|
||||
upstream_modules,
|
||||
cached_modules,
|
||||
&symbols_below_threshold,
|
||||
)
|
||||
thin_lto(cgcx, &dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold)
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
|
||||
|
|
@ -250,7 +236,7 @@ pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBu
|
|||
|
||||
fn fat_lto(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
modules: Vec<FatLtoInput<LlvmCodegenBackend>>,
|
||||
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
|
||||
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
|
||||
|
|
@ -316,7 +302,7 @@ fn fat_lto(
|
|||
let (buffer, name) = serialized_modules.remove(0);
|
||||
info!("no in-memory regular modules to choose from, parsing {:?}", name);
|
||||
ModuleCodegen {
|
||||
module_llvm: ModuleLlvm::parse(cgcx, &name, buffer.data(), diag_handler)?,
|
||||
module_llvm: ModuleLlvm::parse(cgcx, &name, buffer.data(), dcx)?,
|
||||
name: name.into_string().unwrap(),
|
||||
kind: ModuleKind::Regular,
|
||||
}
|
||||
|
|
@ -333,13 +319,8 @@ fn fat_lto(
|
|||
// The linking steps below may produce errors and diagnostics within LLVM
|
||||
// which we'd like to handle and print, so set up our diagnostic handlers
|
||||
// (which get unregistered when they go out of scope below).
|
||||
let _handler = DiagnosticHandlers::new(
|
||||
cgcx,
|
||||
diag_handler,
|
||||
llcx,
|
||||
&module,
|
||||
CodegenDiagnosticsStage::LTO,
|
||||
);
|
||||
let _handler =
|
||||
DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::LTO);
|
||||
|
||||
// For all other modules we codegened we'll need to link them into our own
|
||||
// bitcode. All modules were codegened in their own LLVM context, however,
|
||||
|
|
@ -367,9 +348,7 @@ fn fat_lto(
|
|||
});
|
||||
info!("linking {:?}", name);
|
||||
let data = bc_decoded.data();
|
||||
linker
|
||||
.add(data)
|
||||
.map_err(|()| write::llvm_err(diag_handler, LlvmError::LoadBitcode { name }))?;
|
||||
linker.add(data).map_err(|()| write::llvm_err(dcx, LlvmError::LoadBitcode { name }))?;
|
||||
serialized_bitcode.push(bc_decoded);
|
||||
}
|
||||
drop(linker);
|
||||
|
|
@ -452,7 +431,7 @@ impl Drop for Linker<'_> {
|
|||
/// they all go out of scope.
|
||||
fn thin_lto(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
modules: Vec<(String, ThinBuffer)>,
|
||||
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
|
||||
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
|
||||
|
|
@ -527,7 +506,7 @@ fn thin_lto(
|
|||
symbols_below_threshold.as_ptr(),
|
||||
symbols_below_threshold.len() as u32,
|
||||
)
|
||||
.ok_or_else(|| write::llvm_err(diag_handler, LlvmError::PrepareThinLtoContext))?;
|
||||
.ok_or_else(|| write::llvm_err(dcx, LlvmError::PrepareThinLtoContext))?;
|
||||
|
||||
let data = ThinData(data);
|
||||
|
||||
|
|
@ -599,7 +578,7 @@ fn thin_lto(
|
|||
// session, overwriting the previous serialized data (if any).
|
||||
if let Some(path) = key_map_path {
|
||||
if let Err(err) = curr_key_map.save_to_file(&path) {
|
||||
return Err(write::llvm_err(diag_handler, LlvmError::WriteThinLtoKey { err }));
|
||||
return Err(write::llvm_err(dcx, LlvmError::WriteThinLtoKey { err }));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -609,7 +588,7 @@ fn thin_lto(
|
|||
|
||||
pub(crate) fn run_pass_manager(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: &mut ModuleCodegen<ModuleLlvm>,
|
||||
thin: bool,
|
||||
) -> Result<(), FatalError> {
|
||||
|
|
@ -637,7 +616,7 @@ pub(crate) fn run_pass_manager(
|
|||
}
|
||||
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
|
||||
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
|
||||
write::llvm_optimize(cgcx, diag_handler, module, config, opt_level, opt_stage)?;
|
||||
write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage)?;
|
||||
}
|
||||
debug!("lto done");
|
||||
Ok(())
|
||||
|
|
@ -721,11 +700,11 @@ pub unsafe fn optimize_thin_module(
|
|||
thin_module: ThinModule<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let dcx = cgcx.create_dcx();
|
||||
|
||||
let module_name = &thin_module.shared.module_names[thin_module.idx];
|
||||
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
|
||||
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&diag_handler, e))?;
|
||||
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;
|
||||
|
||||
// Right now the implementation we've got only works over serialized
|
||||
// modules, so we create a fresh new LLVM context and parse the module
|
||||
|
|
@ -733,7 +712,7 @@ pub unsafe fn optimize_thin_module(
|
|||
// crates but for locally codegened modules we may be able to reuse
|
||||
// that LLVM Context and Module.
|
||||
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
|
||||
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _;
|
||||
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &dcx)? as *const _;
|
||||
let mut module = ModuleCodegen {
|
||||
module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
|
||||
name: thin_module.name().to_string(),
|
||||
|
|
@ -756,7 +735,7 @@ pub unsafe fn optimize_thin_module(
|
|||
let _timer =
|
||||
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
|
||||
if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) {
|
||||
return Err(write::llvm_err(&diag_handler, LlvmError::PrepareThinLtoModule));
|
||||
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
|
||||
}
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
|
||||
}
|
||||
|
|
@ -766,7 +745,7 @@ pub unsafe fn optimize_thin_module(
|
|||
.prof
|
||||
.generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name());
|
||||
if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) {
|
||||
return Err(write::llvm_err(&diag_handler, LlvmError::PrepareThinLtoModule));
|
||||
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
|
||||
}
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve");
|
||||
}
|
||||
|
|
@ -776,7 +755,7 @@ pub unsafe fn optimize_thin_module(
|
|||
.prof
|
||||
.generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name());
|
||||
if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) {
|
||||
return Err(write::llvm_err(&diag_handler, LlvmError::PrepareThinLtoModule));
|
||||
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
|
||||
}
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize");
|
||||
}
|
||||
|
|
@ -785,7 +764,7 @@ pub unsafe fn optimize_thin_module(
|
|||
let _timer =
|
||||
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
|
||||
if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) {
|
||||
return Err(write::llvm_err(&diag_handler, LlvmError::PrepareThinLtoModule));
|
||||
return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule));
|
||||
}
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
|
||||
}
|
||||
|
|
@ -797,7 +776,7 @@ pub unsafe fn optimize_thin_module(
|
|||
// little differently.
|
||||
{
|
||||
info!("running thin lto passes over {}", module.name);
|
||||
run_pass_manager(cgcx, &diag_handler, &mut module, true)?;
|
||||
run_pass_manager(cgcx, &dcx, &mut module, true)?;
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
|
||||
}
|
||||
}
|
||||
|
|
@ -868,10 +847,10 @@ pub fn parse_module<'a>(
|
|||
cx: &'a llvm::Context,
|
||||
name: &CStr,
|
||||
data: &[u8],
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
) -> Result<&'a llvm::Module, FatalError> {
|
||||
unsafe {
|
||||
llvm::LLVMRustParseBitcodeForLTO(cx, data.as_ptr(), data.len(), name.as_ptr())
|
||||
.ok_or_else(|| write::llvm_err(diag_handler, LlvmError::ParseBitcode))
|
||||
.ok_or_else(|| write::llvm_err(dcx, LlvmError::ParseBitcode))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use rustc_codegen_ssa::traits::*;
|
|||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_errors::{FatalError, Handler, Level};
|
||||
use rustc_errors::{DiagCtxt, FatalError, Level};
|
||||
use rustc_fs_util::{link_or_copy, path_to_c_string};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
|
||||
|
|
@ -45,15 +45,15 @@ use std::slice;
|
|||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn llvm_err<'a>(handler: &rustc_errors::Handler, err: LlvmError<'a>) -> FatalError {
|
||||
pub fn llvm_err<'a>(dcx: &rustc_errors::DiagCtxt, err: LlvmError<'a>) -> FatalError {
|
||||
match llvm::last_error() {
|
||||
Some(llvm_err) => handler.emit_almost_fatal(WithLlvmError(err, llvm_err)),
|
||||
None => handler.emit_almost_fatal(err),
|
||||
Some(llvm_err) => dcx.emit_almost_fatal(WithLlvmError(err, llvm_err)),
|
||||
None => dcx.emit_almost_fatal(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_output_file<'ll>(
|
||||
handler: &rustc_errors::Handler,
|
||||
dcx: &rustc_errors::DiagCtxt,
|
||||
target: &'ll llvm::TargetMachine,
|
||||
pm: &llvm::PassManager<'ll>,
|
||||
m: &'ll llvm::Module,
|
||||
|
|
@ -93,9 +93,7 @@ pub fn write_output_file<'ll>(
|
|||
}
|
||||
}
|
||||
|
||||
result
|
||||
.into_result()
|
||||
.map_err(|()| llvm_err(handler, LlvmError::WriteOutput { path: output }))
|
||||
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +103,7 @@ pub fn create_informational_target_machine(sess: &Session) -> OwnedTargetMachine
|
|||
// system/tcx is set up.
|
||||
let features = llvm_util::global_llvm_features(sess, false);
|
||||
target_machine_factory(sess, config::OptLevel::No, &features)(config)
|
||||
.unwrap_or_else(|err| llvm_err(sess.diagnostic(), err).raise())
|
||||
.unwrap_or_else(|err| llvm_err(sess.dcx(), err).raise())
|
||||
}
|
||||
|
||||
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
|
||||
|
|
@ -128,7 +126,7 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMach
|
|||
tcx.backend_optimization_level(()),
|
||||
tcx.global_backend_features(()),
|
||||
)(config)
|
||||
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), err).raise())
|
||||
.unwrap_or_else(|err| llvm_err(tcx.sess.dcx(), err).raise())
|
||||
}
|
||||
|
||||
pub fn to_llvm_opt_settings(
|
||||
|
|
@ -332,7 +330,7 @@ pub enum CodegenDiagnosticsStage {
|
|||
}
|
||||
|
||||
pub struct DiagnosticHandlers<'a> {
|
||||
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, &'a Handler),
|
||||
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, &'a DiagCtxt),
|
||||
llcx: &'a llvm::Context,
|
||||
old_handler: Option<&'a llvm::DiagnosticHandler>,
|
||||
}
|
||||
|
|
@ -340,7 +338,7 @@ pub struct DiagnosticHandlers<'a> {
|
|||
impl<'a> DiagnosticHandlers<'a> {
|
||||
pub fn new(
|
||||
cgcx: &'a CodegenContext<LlvmCodegenBackend>,
|
||||
handler: &'a Handler,
|
||||
dcx: &'a DiagCtxt,
|
||||
llcx: &'a llvm::Context,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
stage: CodegenDiagnosticsStage,
|
||||
|
|
@ -375,7 +373,7 @@ impl<'a> DiagnosticHandlers<'a> {
|
|||
.and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok()));
|
||||
|
||||
let pgo_available = cgcx.opts.cg.profile_use.is_some();
|
||||
let data = Box::into_raw(Box::new((cgcx, handler)));
|
||||
let data = Box::into_raw(Box::new((cgcx, dcx)));
|
||||
unsafe {
|
||||
let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx);
|
||||
llvm::LLVMRustContextConfigureDiagnosticHandler(
|
||||
|
|
@ -429,7 +427,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
|
|||
if user.is_null() {
|
||||
return;
|
||||
}
|
||||
let (cgcx, diag_handler) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));
|
||||
let (cgcx, dcx) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &DiagCtxt));
|
||||
|
||||
match llvm::diagnostic::Diagnostic::unpack(info) {
|
||||
llvm::diagnostic::InlineAsm(inline) => {
|
||||
|
|
@ -437,7 +435,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
|
|||
}
|
||||
|
||||
llvm::diagnostic::Optimization(opt) => {
|
||||
diag_handler.emit_note(FromLlvmOptimizationDiag {
|
||||
dcx.emit_note(FromLlvmOptimizationDiag {
|
||||
filename: &opt.filename,
|
||||
line: opt.line,
|
||||
column: opt.column,
|
||||
|
|
@ -459,14 +457,14 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
|
|||
llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
|
||||
})
|
||||
.expect("non-UTF8 diagnostic");
|
||||
diag_handler.emit_warning(FromLlvmDiag { message });
|
||||
dcx.emit_warning(FromLlvmDiag { message });
|
||||
}
|
||||
llvm::diagnostic::Unsupported(diagnostic_ref) => {
|
||||
let message = llvm::build_string(|s| {
|
||||
llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
|
||||
})
|
||||
.expect("non-UTF8 diagnostic");
|
||||
diag_handler.emit_err(FromLlvmDiag { message });
|
||||
dcx.emit_err(FromLlvmDiag { message });
|
||||
}
|
||||
llvm::diagnostic::UnknownDiagnostic(..) => {}
|
||||
}
|
||||
|
|
@ -507,7 +505,7 @@ fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
|
|||
|
||||
pub(crate) unsafe fn llvm_optimize(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
opt_level: config::OptLevel,
|
||||
|
|
@ -588,13 +586,13 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
llvm_plugins.as_ptr().cast(),
|
||||
llvm_plugins.len(),
|
||||
);
|
||||
result.into_result().map_err(|()| llvm_err(diag_handler, LlvmError::RunLlvmPasses))
|
||||
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::RunLlvmPasses))
|
||||
}
|
||||
|
||||
// Unsafe due to LLVM calls.
|
||||
pub(crate) unsafe fn optimize(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<(), FatalError> {
|
||||
|
|
@ -602,8 +600,7 @@ pub(crate) unsafe fn optimize(
|
|||
|
||||
let llmod = module.module_llvm.llmod();
|
||||
let llcx = &*module.module_llvm.llcx;
|
||||
let _handlers =
|
||||
DiagnosticHandlers::new(cgcx, diag_handler, llcx, module, CodegenDiagnosticsStage::Opt);
|
||||
let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt);
|
||||
|
||||
let module_name = module.name.clone();
|
||||
let module_name = Some(&module_name[..]);
|
||||
|
|
@ -621,14 +618,14 @@ pub(crate) unsafe fn optimize(
|
|||
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
|
||||
_ => llvm::OptStage::PreLinkNoLTO,
|
||||
};
|
||||
return llvm_optimize(cgcx, diag_handler, module, config, opt_level, opt_stage);
|
||||
return llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn link(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
mut modules: Vec<ModuleCodegen<ModuleLlvm>>,
|
||||
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
|
||||
use super::lto::{Linker, ModuleBuffer};
|
||||
|
|
@ -641,9 +638,9 @@ pub(crate) fn link(
|
|||
for module in elements {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_link_module", &*module.name);
|
||||
let buffer = ModuleBuffer::new(module.module_llvm.llmod());
|
||||
linker.add(buffer.data()).map_err(|()| {
|
||||
llvm_err(diag_handler, LlvmError::SerializeModule { name: &module.name })
|
||||
})?;
|
||||
linker
|
||||
.add(buffer.data())
|
||||
.map_err(|()| llvm_err(dcx, LlvmError::SerializeModule { name: &module.name }))?;
|
||||
}
|
||||
drop(linker);
|
||||
Ok(modules.remove(0))
|
||||
|
|
@ -651,7 +648,7 @@ pub(crate) fn link(
|
|||
|
||||
pub(crate) unsafe fn codegen(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<CompiledModule, FatalError> {
|
||||
|
|
@ -662,13 +659,8 @@ pub(crate) unsafe fn codegen(
|
|||
let tm = &*module.module_llvm.tm;
|
||||
let module_name = module.name.clone();
|
||||
let module_name = Some(&module_name[..]);
|
||||
let _handlers = DiagnosticHandlers::new(
|
||||
cgcx,
|
||||
diag_handler,
|
||||
llcx,
|
||||
&module,
|
||||
CodegenDiagnosticsStage::Codegen,
|
||||
);
|
||||
let _handlers =
|
||||
DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::Codegen);
|
||||
|
||||
if cgcx.msvc_imps_needed {
|
||||
create_msvc_imps(cgcx, llcx, llmod);
|
||||
|
|
@ -726,7 +718,7 @@ pub(crate) unsafe fn codegen(
|
|||
.prof
|
||||
.generic_activity_with_arg("LLVM_module_codegen_emit_bitcode", &*module.name);
|
||||
if let Err(err) = fs::write(&bc_out, data) {
|
||||
diag_handler.emit_err(WriteBytecode { path: &bc_out, err });
|
||||
dcx.emit_err(WriteBytecode { path: &bc_out, err });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -776,9 +768,7 @@ pub(crate) unsafe fn codegen(
|
|||
record_artifact_size(&cgcx.prof, "llvm_ir", &out);
|
||||
}
|
||||
|
||||
result
|
||||
.into_result()
|
||||
.map_err(|()| llvm_err(diag_handler, LlvmError::WriteIr { path: &out }))?;
|
||||
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteIr { path: &out }))?;
|
||||
}
|
||||
|
||||
if config.emit_asm {
|
||||
|
|
@ -797,7 +787,7 @@ pub(crate) unsafe fn codegen(
|
|||
};
|
||||
with_codegen(tm, llmod, |cpm| {
|
||||
write_output_file(
|
||||
diag_handler,
|
||||
dcx,
|
||||
tm,
|
||||
cpm,
|
||||
llmod,
|
||||
|
|
@ -832,7 +822,7 @@ pub(crate) unsafe fn codegen(
|
|||
|
||||
with_codegen(tm, llmod, |cpm| {
|
||||
write_output_file(
|
||||
diag_handler,
|
||||
dcx,
|
||||
tm,
|
||||
cpm,
|
||||
llmod,
|
||||
|
|
@ -847,12 +837,12 @@ pub(crate) unsafe fn codegen(
|
|||
EmitObj::Bitcode => {
|
||||
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
|
||||
if let Err(err) = link_or_copy(&bc_out, &obj_out) {
|
||||
diag_handler.emit_err(CopyBitcode { err });
|
||||
dcx.emit_err(CopyBitcode { err });
|
||||
}
|
||||
|
||||
if !config.emit_bc {
|
||||
debug!("removing_bitcode {:?}", bc_out);
|
||||
ensure_removed(diag_handler, &bc_out);
|
||||
ensure_removed(dcx, &bc_out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
let new_kind = match ty.kind() {
|
||||
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
|
||||
Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),
|
||||
t @ (Uint(_) | Int(_)) => t.clone(),
|
||||
t @ (Uint(_) | Int(_)) => *t,
|
||||
_ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,14 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
|
||||
let bx = self;
|
||||
|
||||
match coverage.kind {
|
||||
// Marker statements have no effect during codegen,
|
||||
// so return early and don't create `func_coverage`.
|
||||
CoverageKind::SpanMarker => return,
|
||||
// Match exhaustively to ensure that newly-added kinds are classified correctly.
|
||||
CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. } => {}
|
||||
}
|
||||
|
||||
let Some(function_coverage_info) =
|
||||
bx.tcx.instance_mir(instance.def).function_coverage_info.as_deref()
|
||||
else {
|
||||
|
|
@ -100,9 +108,9 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
|
||||
let Coverage { kind } = coverage;
|
||||
match *kind {
|
||||
// Span markers are only meaningful during MIR instrumentation,
|
||||
// and have no effect during codegen.
|
||||
CoverageKind::SpanMarker => {}
|
||||
CoverageKind::SpanMarker => unreachable!(
|
||||
"unexpected marker statement {kind:?} should have caused an early return"
|
||||
),
|
||||
CoverageKind::CounterIncrement { id } => {
|
||||
func_coverage.mark_counter_id_seen(id);
|
||||
// We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
|
|||
|
||||
if let Ok(rel_path) = abs_path.strip_prefix(working_directory) {
|
||||
(
|
||||
working_directory.to_string_lossy().into(),
|
||||
working_directory.to_string_lossy(),
|
||||
rel_path.to_string_lossy().into_owned(),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -977,6 +977,27 @@ fn build_field_di_node<'ll, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the `DIFlags` corresponding to the visibility of the item identified by `did`.
|
||||
///
|
||||
/// `DIFlags::Flag{Public,Protected,Private}` correspond to `DW_AT_accessibility`
|
||||
/// (public/protected/private) aren't exactly right for Rust, but neither is `DW_AT_visibility`
|
||||
/// (local/exported/qualified), and there's no way to set `DW_AT_visibility` in LLVM's API.
|
||||
fn visibility_di_flags<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
did: DefId,
|
||||
type_did: DefId,
|
||||
) -> DIFlags {
|
||||
let parent_did = cx.tcx.parent(type_did);
|
||||
let visibility = cx.tcx.visibility(did);
|
||||
match visibility {
|
||||
Visibility::Public => DIFlags::FlagPublic,
|
||||
// Private fields have a restricted visibility of the module containing the type.
|
||||
Visibility::Restricted(did) if did == parent_did => DIFlags::FlagPrivate,
|
||||
// `pub(crate)`/`pub(super)` visibilities are any other restricted visibility.
|
||||
Visibility::Restricted(..) => DIFlags::FlagProtected,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the debuginfo node for a Rust struct type. Maybe be a regular struct or a tuple-struct.
|
||||
fn build_struct_type_di_node<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
|
|
@ -1000,7 +1021,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
|
|||
&compute_debuginfo_type_name(cx.tcx, struct_type, false),
|
||||
size_and_align_of(struct_type_and_layout),
|
||||
Some(containing_scope),
|
||||
DIFlags::FlagZero,
|
||||
visibility_di_flags(cx, adt_def.did(), adt_def.did()),
|
||||
),
|
||||
// Fields:
|
||||
|cx, owner| {
|
||||
|
|
@ -1023,7 +1044,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
|
|||
&field_name[..],
|
||||
(field_layout.size, field_layout.align.abi),
|
||||
struct_type_and_layout.fields.offset(i),
|
||||
DIFlags::FlagZero,
|
||||
visibility_di_flags(cx, f.did, adt_def.did()),
|
||||
type_di_node(cx, field_layout.ty),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ use crate::{
|
|||
enums::{tag_base_type, DiscrResult},
|
||||
file_metadata, size_and_align_of, type_di_node,
|
||||
type_map::{self, Stub, UniqueTypeId},
|
||||
unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
|
||||
UNKNOWN_LINE_NUMBER,
|
||||
unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec,
|
||||
NO_GENERICS, NO_SCOPE_METADATA, UNKNOWN_LINE_NUMBER,
|
||||
},
|
||||
utils::DIB,
|
||||
},
|
||||
|
|
@ -215,7 +215,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
&enum_type_name,
|
||||
cx.size_and_align_of(enum_type),
|
||||
NO_SCOPE_METADATA,
|
||||
DIFlags::FlagZero,
|
||||
visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()),
|
||||
),
|
||||
|cx, enum_type_di_node| {
|
||||
match enum_type_and_layout.variants {
|
||||
|
|
@ -320,6 +320,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
|
|||
variant_index: VariantIdx,
|
||||
) -> SmallVec<&'ll DIType> {
|
||||
let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
|
||||
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
||||
let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
|
||||
cx,
|
||||
enum_type_and_layout,
|
||||
|
|
@ -327,6 +328,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
|
|||
variant_index,
|
||||
enum_adt_def.variant(variant_index),
|
||||
variant_layout,
|
||||
visibility_flags,
|
||||
);
|
||||
|
||||
let tag_base_type = cx.tcx.types.u32;
|
||||
|
|
@ -364,7 +366,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
|
|||
// since the later is sometimes smaller (if it has fewer fields).
|
||||
size_and_align_of(enum_type_and_layout),
|
||||
Size::ZERO,
|
||||
DIFlags::FlagZero,
|
||||
visibility_flags,
|
||||
variant_struct_type_wrapper_di_node,
|
||||
),
|
||||
unsafe {
|
||||
|
|
@ -376,7 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
|
|||
unknown_file_metadata(cx),
|
||||
UNKNOWN_LINE_NUMBER,
|
||||
variant_names_type_di_node,
|
||||
DIFlags::FlagZero,
|
||||
visibility_flags,
|
||||
Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)),
|
||||
tag_base_type_align.bits() as u32,
|
||||
)
|
||||
|
|
@ -403,6 +405,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
|
|||
(variant_index, variant_name)
|
||||
}),
|
||||
);
|
||||
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
||||
|
||||
let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices
|
||||
.map(|variant_index| {
|
||||
|
|
@ -417,6 +420,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
|
|||
variant_index,
|
||||
variant_def,
|
||||
variant_layout,
|
||||
visibility_flags,
|
||||
);
|
||||
|
||||
VariantFieldInfo {
|
||||
|
|
@ -437,6 +441,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
|
|||
tag_base_type,
|
||||
tag_field,
|
||||
untagged_variant_index,
|
||||
visibility_flags,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -744,6 +749,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
|
|||
tag_base_type,
|
||||
tag_field,
|
||||
None,
|
||||
DIFlags::FlagZero,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -758,6 +764,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
tag_base_type: Ty<'tcx>,
|
||||
tag_field: usize,
|
||||
untagged_variant_index: Option<VariantIdx>,
|
||||
di_flags: DIFlags,
|
||||
) -> SmallVec<&'ll DIType> {
|
||||
let tag_base_type_di_node = type_di_node(cx, tag_base_type);
|
||||
let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
|
||||
|
|
@ -801,7 +808,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
align.bits() as u32,
|
||||
// Union fields are always at offset zero
|
||||
Size::ZERO.bits(),
|
||||
DIFlags::FlagZero,
|
||||
di_flags,
|
||||
variant_struct_type_wrapper,
|
||||
)
|
||||
}
|
||||
|
|
@ -835,7 +842,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
TAG_FIELD_NAME_128_LO,
|
||||
size_and_align,
|
||||
lo_offset,
|
||||
DIFlags::FlagZero,
|
||||
di_flags,
|
||||
type_di_node,
|
||||
));
|
||||
|
||||
|
|
@ -855,7 +862,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
TAG_FIELD_NAME,
|
||||
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
||||
enum_type_and_layout.fields.offset(tag_field),
|
||||
DIFlags::FlagZero,
|
||||
di_flags,
|
||||
tag_base_type_di_node,
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
variant_index: VariantIdx,
|
||||
variant_def: &VariantDef,
|
||||
variant_layout: TyAndLayout<'tcx>,
|
||||
di_flags: DIFlags,
|
||||
) -> &'ll DIType {
|
||||
debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
|
||||
|
||||
|
|
@ -267,7 +268,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
// NOTE: We use size and align of enum_type, not from variant_layout:
|
||||
size_and_align_of(enum_type_and_layout),
|
||||
Some(enum_type_di_node),
|
||||
DIFlags::FlagZero,
|
||||
di_flags,
|
||||
),
|
||||
|cx, struct_type_di_node| {
|
||||
(0..variant_layout.fields.count())
|
||||
|
|
@ -289,7 +290,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
&field_name,
|
||||
(field_layout.size, field_layout.align.abi),
|
||||
variant_layout.fields.offset(field_index),
|
||||
DIFlags::FlagZero,
|
||||
di_flags,
|
||||
type_di_node(cx, field_layout.ty),
|
||||
)
|
||||
})
|
||||
|
|
@ -395,7 +396,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
})
|
||||
.collect();
|
||||
|
||||
state_specific_fields.into_iter().chain(common_fields.into_iter()).collect()
|
||||
state_specific_fields.into_iter().chain(common_fields).collect()
|
||||
},
|
||||
|cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use crate::{
|
|||
enums::tag_base_type,
|
||||
file_metadata, size_and_align_of, type_di_node,
|
||||
type_map::{self, Stub, StubInfo, UniqueTypeId},
|
||||
unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS,
|
||||
UNKNOWN_LINE_NUMBER,
|
||||
unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec,
|
||||
NO_GENERICS, UNKNOWN_LINE_NUMBER,
|
||||
},
|
||||
utils::{create_DIArray, get_namespace_for_item, DIB},
|
||||
},
|
||||
|
|
@ -63,6 +63,8 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
||||
|
||||
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
|
|
@ -74,7 +76,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
&enum_type_name,
|
||||
size_and_align_of(enum_type_and_layout),
|
||||
Some(containing_scope),
|
||||
DIFlags::FlagZero,
|
||||
visibility_flags,
|
||||
),
|
||||
|cx, enum_type_di_node| {
|
||||
// Build the struct type for each variant. These will be referenced by the
|
||||
|
|
@ -92,6 +94,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
variant_index,
|
||||
enum_adt_def.variant(variant_index),
|
||||
enum_type_and_layout.for_variant(cx, variant_index),
|
||||
visibility_flags,
|
||||
),
|
||||
source_info: None,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::path::Path;
|
|||
use crate::fluent_generated as fluent;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_errors::{
|
||||
DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, FatalError, Handler, IntoDiagnostic,
|
||||
DiagCtxt, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, FatalError, IntoDiagnostic,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::Span;
|
||||
|
|
@ -102,13 +102,12 @@ pub(crate) struct DynamicLinkingWithLTO;
|
|||
pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>);
|
||||
|
||||
impl IntoDiagnostic<'_, FatalError> for ParseTargetMachineConfig<'_> {
|
||||
fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, FatalError> {
|
||||
let diag: DiagnosticBuilder<'_, FatalError> = self.0.into_diagnostic(handler);
|
||||
fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, FatalError> {
|
||||
let diag: DiagnosticBuilder<'_, FatalError> = self.0.into_diagnostic(dcx);
|
||||
let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message");
|
||||
let message = handler.eagerly_translate_to_string(message.clone(), diag.args());
|
||||
let message = dcx.eagerly_translate_to_string(message.clone(), diag.args());
|
||||
|
||||
let mut diag =
|
||||
handler.struct_almost_fatal(fluent::codegen_llvm_parse_target_machine_config);
|
||||
let mut diag = dcx.struct_almost_fatal(fluent::codegen_llvm_parse_target_machine_config);
|
||||
diag.set_arg("error", message);
|
||||
diag
|
||||
}
|
||||
|
|
@ -125,8 +124,8 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> {
|
|||
pub(crate) struct MissingFeatures;
|
||||
|
||||
impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> {
|
||||
fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = handler.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable);
|
||||
fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = dcx.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable);
|
||||
if let Some(span) = self.span {
|
||||
diag.set_span(span);
|
||||
};
|
||||
|
|
@ -185,7 +184,7 @@ pub enum LlvmError<'a> {
|
|||
pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String);
|
||||
|
||||
impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for WithLlvmError<'_> {
|
||||
fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, G> {
|
||||
fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, G> {
|
||||
use LlvmError::*;
|
||||
let msg_with_llvm_err = match &self.0 {
|
||||
WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err,
|
||||
|
|
@ -202,7 +201,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for WithLlvmError<'_> {
|
|||
PrepareThinLtoModule => fluent::codegen_llvm_prepare_thin_lto_module_with_llvm_err,
|
||||
ParseBitcode => fluent::codegen_llvm_parse_bitcode_with_llvm_err,
|
||||
};
|
||||
let mut diag = self.0.into_diagnostic(handler);
|
||||
let mut diag = self.0.into_diagnostic(dcx);
|
||||
diag.set_primary_message(msg_with_llvm_err);
|
||||
diag.set_arg("llvm_err", self.1);
|
||||
diag
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ use rustc_codegen_ssa::traits::*;
|
|||
use rustc_codegen_ssa::ModuleCodegen;
|
||||
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_errors::{ErrorGuaranteed, FatalError, Handler};
|
||||
use rustc_errors::{DiagCtxt, ErrorGuaranteed, FatalError};
|
||||
use rustc_metadata::EncodedMetadata;
|
||||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
|
@ -200,10 +200,10 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
}
|
||||
fn run_link(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
modules: Vec<ModuleCodegen<Self::Module>>,
|
||||
) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
back::write::link(cgcx, diag_handler, modules)
|
||||
back::write::link(cgcx, dcx, modules)
|
||||
}
|
||||
fn run_fat_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
|
|
@ -221,18 +221,18 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
}
|
||||
unsafe fn optimize(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<(), FatalError> {
|
||||
back::write::optimize(cgcx, diag_handler, module, config)
|
||||
back::write::optimize(cgcx, dcx, module, config)
|
||||
}
|
||||
fn optimize_fat(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
module: &mut ModuleCodegen<Self::Module>,
|
||||
) -> Result<(), FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
back::lto::run_pass_manager(cgcx, &diag_handler, module, false)
|
||||
let dcx = cgcx.create_dcx();
|
||||
back::lto::run_pass_manager(cgcx, &dcx, module, false)
|
||||
}
|
||||
unsafe fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
|
|
@ -242,11 +242,11 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
}
|
||||
unsafe fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<CompiledModule, FatalError> {
|
||||
back::write::codegen(cgcx, diag_handler, module, config)
|
||||
back::write::codegen(cgcx, dcx, module, config)
|
||||
}
|
||||
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
|
||||
back::lto::prepare_thin(module)
|
||||
|
|
@ -447,16 +447,16 @@ impl ModuleLlvm {
|
|||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
name: &CStr,
|
||||
buffer: &[u8],
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
) -> Result<Self, FatalError> {
|
||||
unsafe {
|
||||
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
|
||||
let llmod_raw = back::lto::parse_module(llcx, name, buffer, handler)?;
|
||||
let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx)?;
|
||||
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, name.to_str().unwrap());
|
||||
let tm = match (cgcx.tm_factory)(tm_factory_config) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
return Err(handler.emit_almost_fatal(ParseTargetMachineConfig(e)));
|
||||
return Err(dcx.emit_almost_fatal(ParseTargetMachineConfig(e)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||
use rustc_errors::{ErrorGuaranteed, Handler};
|
||||
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
|
||||
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_metadata::find_native_static_library;
|
||||
|
|
@ -52,10 +52,10 @@ use std::path::{Path, PathBuf};
|
|||
use std::process::{ExitStatus, Output, Stdio};
|
||||
use std::{env, fmt, fs, io, mem, str};
|
||||
|
||||
pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
|
||||
pub fn ensure_removed(dcx: &DiagCtxt, path: &Path) {
|
||||
if let Err(e) = fs::remove_file(path) {
|
||||
if e.kind() != io::ErrorKind::NotFound {
|
||||
diag_handler.err(format!("failed to remove {}: {}", path.display(), e));
|
||||
dcx.err(format!("failed to remove {}: {}", path.display(), e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ pub fn link_binary<'a>(
|
|||
}
|
||||
}
|
||||
if sess.opts.json_artifact_notifications {
|
||||
sess.diagnostic().emit_artifact_notification(&out_filename, "link");
|
||||
sess.dcx().emit_artifact_notification(&out_filename, "link");
|
||||
}
|
||||
|
||||
if sess.prof.enabled() {
|
||||
|
|
@ -183,13 +183,13 @@ pub fn link_binary<'a>(
|
|||
|preserve_objects: bool, preserve_dwarf_objects: bool, module: &CompiledModule| {
|
||||
if !preserve_objects {
|
||||
if let Some(ref obj) = module.object {
|
||||
ensure_removed(sess.diagnostic(), obj);
|
||||
ensure_removed(sess.dcx(), obj);
|
||||
}
|
||||
}
|
||||
|
||||
if !preserve_dwarf_objects {
|
||||
if let Some(ref dwo_obj) = module.dwarf_object {
|
||||
ensure_removed(sess.diagnostic(), dwo_obj);
|
||||
ensure_removed(sess.dcx(), dwo_obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -208,7 +208,7 @@ pub fn link_binary<'a>(
|
|||
|
||||
// Remove the temporary files if output goes to stdout
|
||||
for temp in tempfiles_for_stdout_output {
|
||||
ensure_removed(sess.diagnostic(), &temp);
|
||||
ensure_removed(sess.dcx(), &temp);
|
||||
}
|
||||
|
||||
// If no requested outputs require linking, then the object temporaries should
|
||||
|
|
@ -933,7 +933,7 @@ fn link_natively<'a>(
|
|||
command: &cmd,
|
||||
escaped_output,
|
||||
};
|
||||
sess.diagnostic().emit_err(err);
|
||||
sess.dcx().emit_err(err);
|
||||
// If MSVC's `link.exe` was expected but the return code
|
||||
// is not a Microsoft LNK error then suggest a way to fix or
|
||||
// install the Visual Studio build tools.
|
||||
|
|
|
|||
|
|
@ -158,12 +158,13 @@ pub(super) fn get_metadata_xcoff<'a>(path: &Path, data: &'a [u8]) -> Result<&'a
|
|||
file.symbols().find(|sym| sym.name() == Ok(AIX_METADATA_SYMBOL_NAME))
|
||||
{
|
||||
let offset = metadata_symbol.address() as usize;
|
||||
if offset < 8 {
|
||||
// The offset specifies the location of rustc metadata in the .info section of XCOFF.
|
||||
// Each string stored in .info section of XCOFF is preceded by a 4-byte length field.
|
||||
if offset < 4 {
|
||||
return Err(format!("Invalid metadata symbol offset: {offset}"));
|
||||
}
|
||||
// The offset specifies the location of rustc metadata in the comment section.
|
||||
// The metadata is preceded by a 8-byte length field.
|
||||
let len = u64::from_le_bytes(info_data[(offset - 8)..offset].try_into().unwrap()) as usize;
|
||||
// XCOFF format uses big-endian byte order.
|
||||
let len = u32::from_be_bytes(info_data[(offset - 4)..offset].try_into().unwrap()) as usize;
|
||||
if offset + len > (info_data.len() as usize) {
|
||||
return Err(format!(
|
||||
"Metadata at offset {offset} with size {len} is beyond .info section"
|
||||
|
|
@ -478,9 +479,12 @@ pub fn create_wrapper_file(
|
|||
file.add_section(Vec::new(), b".text".to_vec(), SectionKind::Text);
|
||||
file.section_mut(section).flags =
|
||||
SectionFlags::Xcoff { s_flags: xcoff::STYP_INFO as u32 };
|
||||
|
||||
let len = data.len() as u64;
|
||||
let offset = file.append_section_data(section, &len.to_le_bytes(), 1);
|
||||
// Encode string stored in .info section of XCOFF.
|
||||
// FIXME: The length of data here is not guaranteed to fit in a u32.
|
||||
// We may have to split the data into multiple pieces in order to
|
||||
// store in .info section.
|
||||
let len: u32 = data.len().try_into().unwrap();
|
||||
let offset = file.append_section_data(section, &len.to_be_bytes(), 1);
|
||||
// Add a symbol referring to the data in .info section.
|
||||
file.add_symbol(Symbol {
|
||||
name: AIX_METADATA_SYMBOL_NAME.into(),
|
||||
|
|
@ -599,12 +603,12 @@ pub fn create_compressed_metadata_file_for_xcoff(
|
|||
section: SymbolSection::Section(data_section),
|
||||
flags: SymbolFlags::None,
|
||||
});
|
||||
let len = data.len() as u64;
|
||||
let offset = file.append_section_data(section, &len.to_le_bytes(), 1);
|
||||
let len: u32 = data.len().try_into().unwrap();
|
||||
let offset = file.append_section_data(section, &len.to_be_bytes(), 1);
|
||||
// Add a symbol referring to the rustc metadata.
|
||||
file.add_symbol(Symbol {
|
||||
name: AIX_METADATA_SYMBOL_NAME.into(),
|
||||
value: offset + 8, // The metadata is preceded by a 8-byte length field.
|
||||
value: offset + 4, // The metadata is preceded by a 4-byte length field.
|
||||
size: 0,
|
||||
kind: SymbolKind::Unknown,
|
||||
scope: SymbolScope::Dynamic,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use rustc_data_structures::memmap::Mmap;
|
|||
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::emitter::Emitter;
|
||||
use rustc_errors::{translation::Translate, DiagnosticId, FatalError, Handler, Level};
|
||||
use rustc_errors::{translation::Translate, DiagCtxt, DiagnosticId, FatalError, Level};
|
||||
use rustc_errors::{DiagnosticMessage, Style};
|
||||
use rustc_fs_util::link_or_copy;
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
|
|
@ -344,7 +344,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
|
|||
/// how to call the compiler with the same arguments.
|
||||
pub expanded_args: Vec<String>,
|
||||
|
||||
/// Handler to use for diagnostics produced during codegen.
|
||||
/// Emitter to use for diagnostics produced during codegen.
|
||||
pub diag_emitter: SharedEmitter,
|
||||
/// LLVM optimizations for which we want to print remarks.
|
||||
pub remark: Passes,
|
||||
|
|
@ -359,8 +359,8 @@ pub struct CodegenContext<B: WriteBackendMethods> {
|
|||
}
|
||||
|
||||
impl<B: WriteBackendMethods> CodegenContext<B> {
|
||||
pub fn create_diag_handler(&self) -> Handler {
|
||||
Handler::with_emitter(Box::new(self.diag_emitter.clone()))
|
||||
pub fn create_dcx(&self) -> DiagCtxt {
|
||||
DiagCtxt::with_emitter(Box::new(self.diag_emitter.clone()))
|
||||
}
|
||||
|
||||
pub fn config(&self, kind: ModuleKind) -> &ModuleConfig {
|
||||
|
|
@ -558,7 +558,7 @@ fn produce_final_output_artifacts(
|
|||
}
|
||||
if !sess.opts.cg.save_temps && !keep_numbered {
|
||||
// The user just wants `foo.x`, not `foo.#module-name#.x`.
|
||||
ensure_removed(sess.diagnostic(), &path);
|
||||
ensure_removed(sess.dcx(), &path);
|
||||
}
|
||||
} else {
|
||||
let extension = crate_output
|
||||
|
|
@ -649,19 +649,19 @@ fn produce_final_output_artifacts(
|
|||
for module in compiled_modules.modules.iter() {
|
||||
if let Some(ref path) = module.object {
|
||||
if !keep_numbered_objects {
|
||||
ensure_removed(sess.diagnostic(), path);
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref path) = module.dwarf_object {
|
||||
if !keep_numbered_objects {
|
||||
ensure_removed(sess.diagnostic(), path);
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref path) = module.bytecode {
|
||||
if !keep_numbered_bitcode {
|
||||
ensure_removed(sess.diagnostic(), path);
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -669,7 +669,7 @@ fn produce_final_output_artifacts(
|
|||
if !user_wants_bitcode {
|
||||
if let Some(ref allocator_module) = compiled_modules.allocator_module {
|
||||
if let Some(ref path) = allocator_module.bytecode {
|
||||
ensure_removed(sess.diagnostic(), path);
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -825,10 +825,10 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
|
|||
module: ModuleCodegen<B::Module>,
|
||||
module_config: &ModuleConfig,
|
||||
) -> Result<WorkItemResult<B>, FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let dcx = cgcx.create_dcx();
|
||||
|
||||
unsafe {
|
||||
B::optimize(cgcx, &diag_handler, &module, module_config)?;
|
||||
B::optimize(cgcx, &dcx, &module, module_config)?;
|
||||
}
|
||||
|
||||
// After we've done the initial round of optimizations we need to
|
||||
|
|
@ -891,11 +891,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
|
|||
match link_or_copy(&source_file, &output_path) {
|
||||
Ok(_) => Some(output_path),
|
||||
Err(error) => {
|
||||
cgcx.create_diag_handler().emit_err(errors::CopyPathBuf {
|
||||
source_file,
|
||||
output_path,
|
||||
error,
|
||||
});
|
||||
cgcx.create_dcx().emit_err(errors::CopyPathBuf { source_file, output_path, error });
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -939,13 +935,13 @@ fn finish_intra_module_work<B: ExtraBackendMethods>(
|
|||
module: ModuleCodegen<B::Module>,
|
||||
module_config: &ModuleConfig,
|
||||
) -> Result<WorkItemResult<B>, FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let dcx = cgcx.create_dcx();
|
||||
|
||||
if !cgcx.opts.unstable_opts.combine_cgu
|
||||
|| module.kind == ModuleKind::Metadata
|
||||
|| module.kind == ModuleKind::Allocator
|
||||
{
|
||||
let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config)? };
|
||||
let module = unsafe { B::codegen(cgcx, &dcx, module, module_config)? };
|
||||
Ok(WorkItemResult::Finished(module))
|
||||
} else {
|
||||
Ok(WorkItemResult::NeedsLink(module))
|
||||
|
|
@ -1595,11 +1591,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
let needs_link = mem::take(&mut needs_link);
|
||||
if !needs_link.is_empty() {
|
||||
assert!(compiled_modules.is_empty());
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
let module = B::run_link(&cgcx, &diag_handler, needs_link).map_err(|_| ())?;
|
||||
let dcx = cgcx.create_dcx();
|
||||
let module = B::run_link(&cgcx, &dcx, needs_link).map_err(|_| ())?;
|
||||
let module = unsafe {
|
||||
B::codegen(&cgcx, &diag_handler, module, cgcx.config(ModuleKind::Regular))
|
||||
.map_err(|_| ())?
|
||||
B::codegen(&cgcx, &dcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())?
|
||||
};
|
||||
compiled_modules.push(module);
|
||||
}
|
||||
|
|
@ -1842,13 +1837,13 @@ impl SharedEmitterMain {
|
|||
|
||||
match message {
|
||||
Ok(SharedEmitterMessage::Diagnostic(diag)) => {
|
||||
let handler = sess.diagnostic();
|
||||
let dcx = sess.dcx();
|
||||
let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msg);
|
||||
if let Some(code) = diag.code {
|
||||
d.code(code);
|
||||
}
|
||||
d.replace_args(diag.args);
|
||||
handler.emit_diagnostic(d);
|
||||
dcx.emit_diagnostic(d);
|
||||
}
|
||||
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
|
||||
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
[sym::arm, sym::a32] | [sym::arm, sym::t32] => {
|
||||
if !tcx.sess.target.has_thumb_interworking {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
tcx.sess.dcx(),
|
||||
attr.span,
|
||||
E0779,
|
||||
"target does not support `#[instruction_set]`"
|
||||
|
|
@ -403,7 +403,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
tcx.sess.dcx(),
|
||||
attr.span,
|
||||
E0779,
|
||||
"invalid instruction set specified",
|
||||
|
|
@ -415,7 +415,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
[] => {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
tcx.sess.dcx(),
|
||||
attr.span,
|
||||
E0778,
|
||||
"`#[instruction_set]` requires an argument"
|
||||
|
|
@ -425,7 +425,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
tcx.sess.dcx(),
|
||||
attr.span,
|
||||
E0779,
|
||||
"cannot specify more than one instruction set"
|
||||
|
|
@ -443,7 +443,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
rustc_attr::parse_alignment(&literal.kind)
|
||||
.map_err(|msg| {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
tcx.sess.dcx(),
|
||||
attr.span,
|
||||
E0589,
|
||||
"invalid `repr(align)` attribute: {}",
|
||||
|
|
@ -469,27 +469,17 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
Some(MetaItemKind::List(ref items)) => {
|
||||
inline_span = Some(attr.span);
|
||||
if items.len() != 1 {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
attr.span,
|
||||
E0534,
|
||||
"expected one argument"
|
||||
)
|
||||
.emit();
|
||||
struct_span_err!(tcx.sess.dcx(), attr.span, E0534, "expected one argument")
|
||||
.emit();
|
||||
InlineAttr::None
|
||||
} else if list_contains_name(items, sym::always) {
|
||||
InlineAttr::Always
|
||||
} else if list_contains_name(items, sym::never) {
|
||||
InlineAttr::Never
|
||||
} else {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
items[0].span(),
|
||||
E0535,
|
||||
"invalid argument"
|
||||
)
|
||||
.help("valid inline arguments are `always` and `never`")
|
||||
.emit();
|
||||
struct_span_err!(tcx.sess.dcx(), items[0].span(), E0535, "invalid argument")
|
||||
.help("valid inline arguments are `always` and `never`")
|
||||
.emit();
|
||||
|
||||
InlineAttr::None
|
||||
}
|
||||
|
|
@ -503,7 +493,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
if !attr.has_name(sym::optimize) {
|
||||
return ia;
|
||||
}
|
||||
let err = |sp, s| struct_span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s).emit();
|
||||
let err = |sp, s| struct_span_err!(tcx.sess.dcx(), sp, E0722, "{}", s).emit();
|
||||
match attr.meta_kind() {
|
||||
Some(MetaItemKind::Word) => {
|
||||
err(attr.span, "expected one argument");
|
||||
|
|
@ -578,7 +568,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
hir_id,
|
||||
no_sanitize_span,
|
||||
"`no_sanitize` will have no effect after inlining",
|
||||
|lint| lint.span_note(inline_span, "inlining requested here"),
|
||||
|lint| {
|
||||
lint.span_note(inline_span, "inlining requested here");
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::assert_module_sources::CguReuse;
|
|||
use crate::back::command::Command;
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_errors::{
|
||||
DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
|
||||
DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
|
||||
IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_macros::Diagnostic;
|
||||
|
|
@ -210,192 +210,191 @@ pub enum LinkRlibError {
|
|||
pub struct ThorinErrorWrapper(pub thorin::Error);
|
||||
|
||||
impl IntoDiagnostic<'_> for ThorinErrorWrapper {
|
||||
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag;
|
||||
match self.0 {
|
||||
thorin::Error::ReadInput(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_read_input_failure);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_read_input_failure);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseFileKind(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_input_file_kind);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_input_file_kind);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseObjectFile(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_input_object_file);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_input_object_file);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseArchiveFile(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_input_archive_file);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_input_archive_file);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseArchiveMember(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_archive_member);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_archive_member);
|
||||
diag
|
||||
}
|
||||
thorin::Error::InvalidInputKind => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_invalid_input_kind);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_invalid_input_kind);
|
||||
diag
|
||||
}
|
||||
thorin::Error::DecompressData(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_decompress_data);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_decompress_data);
|
||||
diag
|
||||
}
|
||||
thorin::Error::NamelessSection(_, offset) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_section_without_name);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_section_without_name);
|
||||
diag.set_arg("offset", format!("0x{offset:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::RelocationWithInvalidSymbol(section, offset) => {
|
||||
diag =
|
||||
handler.struct_err(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol);
|
||||
diag.set_arg("section", section);
|
||||
diag.set_arg("offset", format!("0x{offset:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::MultipleRelocations(section, offset) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_relocations);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_relocations);
|
||||
diag.set_arg("section", section);
|
||||
diag.set_arg("offset", format!("0x{offset:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::UnsupportedRelocation(section, offset) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_unsupported_relocation);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_unsupported_relocation);
|
||||
diag.set_arg("section", section);
|
||||
diag.set_arg("offset", format!("0x{offset:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::MissingDwoName(id) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_dwo_name);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_dwo_name);
|
||||
diag.set_arg("id", format!("0x{id:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::NoCompilationUnits => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_no_compilation_units);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_no_compilation_units);
|
||||
diag
|
||||
}
|
||||
thorin::Error::NoDie => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_no_die);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_no_die);
|
||||
diag
|
||||
}
|
||||
thorin::Error::TopLevelDieNotUnit => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_top_level_die_not_unit);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_top_level_die_not_unit);
|
||||
diag
|
||||
}
|
||||
thorin::Error::MissingRequiredSection(section) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_required_section);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_required_section);
|
||||
diag.set_arg("section", section);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseUnitAbbreviations(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit_abbreviations);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_abbreviations);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseUnitAttribute(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit_attribute);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_attribute);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseUnitHeader(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit_header);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_header);
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseUnit(_) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit);
|
||||
diag
|
||||
}
|
||||
thorin::Error::IncompatibleIndexVersion(section, format, actual) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_incompatible_index_version);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_incompatible_index_version);
|
||||
diag.set_arg("section", section);
|
||||
diag.set_arg("actual", actual);
|
||||
diag.set_arg("format", format);
|
||||
diag
|
||||
}
|
||||
thorin::Error::OffsetAtIndex(_, index) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_offset_at_index);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_offset_at_index);
|
||||
diag.set_arg("index", index);
|
||||
diag
|
||||
}
|
||||
thorin::Error::StrAtOffset(_, offset) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_str_at_offset);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_str_at_offset);
|
||||
diag.set_arg("offset", format!("0x{offset:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::ParseIndex(_, section) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_index);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_index);
|
||||
diag.set_arg("section", section);
|
||||
diag
|
||||
}
|
||||
thorin::Error::UnitNotInIndex(unit) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_unit_not_in_index);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_unit_not_in_index);
|
||||
diag.set_arg("unit", format!("0x{unit:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::RowNotInIndex(_, row) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_row_not_in_index);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_row_not_in_index);
|
||||
diag.set_arg("row", row);
|
||||
diag
|
||||
}
|
||||
thorin::Error::SectionNotInRow => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_section_not_in_row);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_section_not_in_row);
|
||||
diag
|
||||
}
|
||||
thorin::Error::EmptyUnit(unit) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_empty_unit);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_empty_unit);
|
||||
diag.set_arg("unit", format!("0x{unit:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::MultipleDebugInfoSection => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_debug_info_section);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_debug_info_section);
|
||||
diag
|
||||
}
|
||||
thorin::Error::MultipleDebugTypesSection => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_debug_types_section);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_debug_types_section);
|
||||
diag
|
||||
}
|
||||
thorin::Error::NotSplitUnit => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_not_split_unit);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_not_split_unit);
|
||||
diag
|
||||
}
|
||||
thorin::Error::DuplicateUnit(unit) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_duplicate_unit);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_duplicate_unit);
|
||||
diag.set_arg("unit", format!("0x{unit:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::MissingReferencedUnit(unit) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_referenced_unit);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_referenced_unit);
|
||||
diag.set_arg("unit", format!("0x{unit:08x}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::NoOutputObjectCreated => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_not_output_object_created);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_not_output_object_created);
|
||||
diag
|
||||
}
|
||||
thorin::Error::MixedInputEncodings => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_mixed_input_encodings);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_mixed_input_encodings);
|
||||
diag
|
||||
}
|
||||
thorin::Error::Io(e) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_io);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_io);
|
||||
diag.set_arg("error", format!("{e}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::ObjectRead(e) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_object_read);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_object_read);
|
||||
diag.set_arg("error", format!("{e}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::ObjectWrite(e) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_object_write);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_object_write);
|
||||
diag.set_arg("error", format!("{e}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::GimliRead(e) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_gimli_read);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_gimli_read);
|
||||
diag.set_arg("error", format!("{e}"));
|
||||
diag
|
||||
}
|
||||
thorin::Error::GimliWrite(e) => {
|
||||
diag = handler.struct_err(fluent::codegen_ssa_thorin_gimli_write);
|
||||
diag = dcx.struct_err(fluent::codegen_ssa_thorin_gimli_write);
|
||||
diag.set_arg("error", format!("{e}"));
|
||||
diag
|
||||
}
|
||||
|
|
@ -412,8 +411,8 @@ pub struct LinkingFailed<'a> {
|
|||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for LinkingFailed<'_> {
|
||||
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = handler.struct_err(fluent::codegen_ssa_linking_failed);
|
||||
fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = dcx.struct_err(fluent::codegen_ssa_linking_failed);
|
||||
diag.set_arg("linker_path", format!("{}", self.linker_path.display()));
|
||||
diag.set_arg("exit_status", format!("{}", self.exit_status));
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
|
|||
use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig};
|
||||
use crate::{CompiledModule, ModuleCodegen};
|
||||
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use rustc_errors::{DiagCtxt, FatalError};
|
||||
use rustc_middle::dep_graph::WorkProduct;
|
||||
|
||||
pub trait WriteBackendMethods: 'static + Sized + Clone {
|
||||
|
|
@ -16,7 +16,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
|
|||
/// Merge all modules into main_module and returning it
|
||||
fn run_link(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
modules: Vec<ModuleCodegen<Self::Module>>,
|
||||
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
|
||||
/// Performs fat LTO by merging all modules into a single one and returning it
|
||||
|
|
@ -38,7 +38,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
|
|||
fn print_statistics(&self);
|
||||
unsafe fn optimize(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<(), FatalError>;
|
||||
|
|
@ -52,7 +52,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
|
|||
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
|
||||
unsafe fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
diag_handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<CompiledModule, FatalError>;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ where
|
|||
let mut err = tcx.sess.create_err(err);
|
||||
|
||||
let msg = error.diagnostic_message();
|
||||
error.add_args(tcx.sess.diagnostic(), &mut err);
|
||||
error.add_args(tcx.sess.dcx(), &mut err);
|
||||
|
||||
// Use *our* span to label the interp error
|
||||
err.span_label(our_span, msg);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_errors::{
|
||||
DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler,
|
||||
DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee,
|
||||
IntoDiagnostic,
|
||||
};
|
||||
use rustc_hir::ConstContext;
|
||||
|
|
@ -432,11 +432,7 @@ pub struct UndefinedBehavior {
|
|||
pub trait ReportErrorExt {
|
||||
/// Returns the diagnostic message for this error.
|
||||
fn diagnostic_message(&self) -> DiagnosticMessage;
|
||||
fn add_args<G: EmissionGuarantee>(
|
||||
self,
|
||||
handler: &Handler,
|
||||
builder: &mut DiagnosticBuilder<'_, G>,
|
||||
);
|
||||
fn add_args<G: EmissionGuarantee>(self, dcx: &DiagCtxt, builder: &mut DiagnosticBuilder<'_, G>);
|
||||
|
||||
fn debug(self) -> String
|
||||
where
|
||||
|
|
@ -444,17 +440,17 @@ pub trait ReportErrorExt {
|
|||
{
|
||||
ty::tls::with(move |tcx| {
|
||||
let mut builder = tcx.sess.struct_allow(DiagnosticMessage::Str(String::new().into()));
|
||||
let handler = tcx.sess.diagnostic();
|
||||
let dcx = tcx.sess.dcx();
|
||||
let message = self.diagnostic_message();
|
||||
self.add_args(handler, &mut builder);
|
||||
let s = handler.eagerly_translate_to_string(message, builder.args());
|
||||
self.add_args(dcx, &mut builder);
|
||||
let s = dcx.eagerly_translate_to_string(message, builder.args());
|
||||
builder.cancel();
|
||||
s
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String {
|
||||
fn bad_pointer_message(msg: CheckInAllocMsg, dcx: &DiagCtxt) -> String {
|
||||
use crate::fluent_generated::*;
|
||||
|
||||
let msg = match msg {
|
||||
|
|
@ -464,7 +460,7 @@ fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String {
|
|||
CheckInAllocMsg::InboundsTest => const_eval_in_bounds_test,
|
||||
};
|
||||
|
||||
handler.eagerly_translate_to_string(msg, [].into_iter())
|
||||
dcx.eagerly_translate_to_string(msg, [].into_iter())
|
||||
}
|
||||
|
||||
impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
||||
|
|
@ -514,7 +510,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
|
||||
fn add_args<G: EmissionGuarantee>(
|
||||
self,
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
builder: &mut DiagnosticBuilder<'_, G>,
|
||||
) {
|
||||
use UndefinedBehaviorInfo::*;
|
||||
|
|
@ -525,7 +521,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
builder.set_arg(name, value);
|
||||
});
|
||||
}
|
||||
ValidationError(e) => e.add_args(handler, builder),
|
||||
ValidationError(e) => e.add_args(dcx, builder),
|
||||
|
||||
Unreachable
|
||||
| DivisionByZero
|
||||
|
|
@ -549,7 +545,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
PointerUseAfterFree(alloc_id, msg) => {
|
||||
builder
|
||||
.set_arg("alloc_id", alloc_id)
|
||||
.set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
|
||||
.set_arg("bad_pointer_message", bad_pointer_message(msg, dcx));
|
||||
}
|
||||
PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => {
|
||||
builder
|
||||
|
|
@ -557,14 +553,14 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
.set_arg("alloc_size", alloc_size.bytes())
|
||||
.set_arg("ptr_offset", ptr_offset)
|
||||
.set_arg("ptr_size", ptr_size.bytes())
|
||||
.set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
|
||||
.set_arg("bad_pointer_message", bad_pointer_message(msg, dcx));
|
||||
}
|
||||
DanglingIntPointer(ptr, msg) => {
|
||||
if ptr != 0 {
|
||||
builder.set_arg("pointer", format!("{ptr:#x}[noalloc]"));
|
||||
}
|
||||
|
||||
builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
|
||||
builder.set_arg("bad_pointer_message", bad_pointer_message(msg, dcx));
|
||||
}
|
||||
AlignmentCheckFailed(Misalignment { required, has }, msg) => {
|
||||
builder.set_arg("required", required.bytes());
|
||||
|
|
@ -678,7 +674,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_args<G: EmissionGuarantee>(self, handler: &Handler, err: &mut DiagnosticBuilder<'_, G>) {
|
||||
fn add_args<G: EmissionGuarantee>(self, dcx: &DiagCtxt, err: &mut DiagnosticBuilder<'_, G>) {
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_middle::mir::interpret::ValidationErrorKind::*;
|
||||
|
||||
|
|
@ -688,12 +684,12 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
}
|
||||
|
||||
let message = if let Some(path) = self.path {
|
||||
handler.eagerly_translate_to_string(
|
||||
dcx.eagerly_translate_to_string(
|
||||
fluent::const_eval_validation_front_matter_invalid_value_with_path,
|
||||
[("path".into(), DiagnosticArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
|
||||
)
|
||||
} else {
|
||||
handler.eagerly_translate_to_string(
|
||||
dcx.eagerly_translate_to_string(
|
||||
fluent::const_eval_validation_front_matter_invalid_value,
|
||||
[].into_iter(),
|
||||
)
|
||||
|
|
@ -704,7 +700,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
fn add_range_arg<G: EmissionGuarantee>(
|
||||
r: WrappingRange,
|
||||
max_hi: u128,
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
err: &mut DiagnosticBuilder<'_, G>,
|
||||
) {
|
||||
let WrappingRange { start: lo, end: hi } = r;
|
||||
|
|
@ -728,7 +724,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
("hi".into(), DiagnosticArgValue::Str(hi.to_string().into())),
|
||||
];
|
||||
let args = args.iter().map(|(a, b)| (a, b));
|
||||
let message = handler.eagerly_translate_to_string(msg, args);
|
||||
let message = dcx.eagerly_translate_to_string(msg, args);
|
||||
err.set_arg("in_range", message);
|
||||
}
|
||||
|
||||
|
|
@ -750,7 +746,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag,
|
||||
ExpectedKind::Str => fluent::const_eval_validation_expected_str,
|
||||
};
|
||||
let msg = handler.eagerly_translate_to_string(msg, [].into_iter());
|
||||
let msg = dcx.eagerly_translate_to_string(msg, [].into_iter());
|
||||
err.set_arg("expected", msg);
|
||||
}
|
||||
InvalidEnumTag { value }
|
||||
|
|
@ -761,11 +757,11 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
err.set_arg("value", value);
|
||||
}
|
||||
NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => {
|
||||
add_range_arg(range, max_value, handler, err)
|
||||
add_range_arg(range, max_value, dcx, err)
|
||||
}
|
||||
OutOfRange { range, max_value, value } => {
|
||||
err.set_arg("value", value);
|
||||
add_range_arg(range, max_value, handler, err);
|
||||
add_range_arg(range, max_value, dcx, err);
|
||||
}
|
||||
UnalignedPtr { required_bytes, found_bytes, .. } => {
|
||||
err.set_arg("required_bytes", required_bytes);
|
||||
|
|
@ -804,7 +800,7 @@ impl ReportErrorExt for UnsupportedOpInfo {
|
|||
UnsupportedOpInfo::ReadExternStatic(_) => const_eval_read_extern_static,
|
||||
}
|
||||
}
|
||||
fn add_args<G: EmissionGuarantee>(self, _: &Handler, builder: &mut DiagnosticBuilder<'_, G>) {
|
||||
fn add_args<G: EmissionGuarantee>(self, _: &DiagCtxt, builder: &mut DiagnosticBuilder<'_, G>) {
|
||||
use crate::fluent_generated::*;
|
||||
|
||||
use UnsupportedOpInfo::*;
|
||||
|
|
@ -839,14 +835,14 @@ impl<'tcx> ReportErrorExt for InterpError<'tcx> {
|
|||
}
|
||||
fn add_args<G: EmissionGuarantee>(
|
||||
self,
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
builder: &mut DiagnosticBuilder<'_, G>,
|
||||
) {
|
||||
match self {
|
||||
InterpError::UndefinedBehavior(ub) => ub.add_args(handler, builder),
|
||||
InterpError::Unsupported(e) => e.add_args(handler, builder),
|
||||
InterpError::InvalidProgram(e) => e.add_args(handler, builder),
|
||||
InterpError::ResourceExhaustion(e) => e.add_args(handler, builder),
|
||||
InterpError::UndefinedBehavior(ub) => ub.add_args(dcx, builder),
|
||||
InterpError::Unsupported(e) => e.add_args(dcx, builder),
|
||||
InterpError::InvalidProgram(e) => e.add_args(dcx, builder),
|
||||
InterpError::ResourceExhaustion(e) => e.add_args(dcx, builder),
|
||||
InterpError::MachineStop(e) => e.add_args(&mut |name, value| {
|
||||
builder.set_arg(name, value);
|
||||
}),
|
||||
|
|
@ -871,7 +867,7 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
|
|||
}
|
||||
fn add_args<G: EmissionGuarantee>(
|
||||
self,
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
builder: &mut DiagnosticBuilder<'_, G>,
|
||||
) {
|
||||
match self {
|
||||
|
|
@ -879,7 +875,7 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
|
|||
| InvalidProgramInfo::AlreadyReported(_)
|
||||
| InvalidProgramInfo::ConstPropNonsense => {}
|
||||
InvalidProgramInfo::Layout(e) => {
|
||||
let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler);
|
||||
let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(dcx);
|
||||
for (name, val) in diag.args() {
|
||||
builder.set_arg(name.clone(), val.clone());
|
||||
}
|
||||
|
|
@ -904,5 +900,5 @@ impl ReportErrorExt for ResourceExhaustionInfo {
|
|||
ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
|
||||
}
|
||||
}
|
||||
fn add_args<G: EmissionGuarantee>(self, _: &Handler, _: &mut DiagnosticBuilder<'_, G>) {}
|
||||
fn add_args<G: EmissionGuarantee>(self, _: &DiagCtxt, _: &mut DiagnosticBuilder<'_, G>) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -473,12 +473,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
backtrace.print_backtrace();
|
||||
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
|
||||
// label and arguments from the InterpError.
|
||||
let handler = self.tcx.sess.diagnostic();
|
||||
let dcx = self.tcx.sess.dcx();
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
let mut diag = self.tcx.sess.struct_allow("");
|
||||
let msg = e.diagnostic_message();
|
||||
e.add_args(handler, &mut diag);
|
||||
let s = handler.eagerly_translate_to_string(msg, diag.args());
|
||||
e.add_args(dcx, &mut diag);
|
||||
let s = dcx.eagerly_translate_to_string(msg, diag.args());
|
||||
diag.cancel();
|
||||
s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
|||
let secondary_errors = mem::take(&mut self.secondary_errors);
|
||||
if self.error_emitted.is_none() {
|
||||
for error in secondary_errors {
|
||||
self.tcx.sess.diagnostic().emit_diagnostic(error);
|
||||
self.tcx.sess.dcx().emit_diagnostic(error);
|
||||
}
|
||||
} else {
|
||||
assert!(self.tcx.sess.has_errors().is_some());
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
|
|||
let span = self.body.source_info(location).span;
|
||||
// We use `span_delayed_bug` as we might see broken MIR when other errors have already
|
||||
// occurred.
|
||||
self.tcx.sess.diagnostic().span_delayed_bug(
|
||||
self.tcx.sess.dcx().span_delayed_bug(
|
||||
span,
|
||||
format!(
|
||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||
|
|
@ -571,7 +571,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
|
|||
|
||||
fn visit_source_scope(&mut self, scope: SourceScope) {
|
||||
if self.body.source_scopes.get(scope).is_none() {
|
||||
self.tcx.sess.diagnostic().span_delayed_bug(
|
||||
self.tcx.sess.dcx().span_delayed_bug(
|
||||
self.body.span,
|
||||
format!(
|
||||
"broken MIR in {:?} ({}):\ninvalid source scope {:?}",
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ impl<K: Ord, V> SortedMap<K, V> {
|
|||
if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 {
|
||||
// We can copy the whole range without having to mix with
|
||||
// existing elements.
|
||||
self.data.splice(index..index, elements.into_iter());
|
||||
self.data.splice(index..index, elements);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
|||
use std::fs;
|
||||
use std::io;
|
||||
|
||||
use rustc_session::EarlyErrorHandler;
|
||||
use rustc_session::EarlyDiagCtxt;
|
||||
|
||||
fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
||||
if let Some(path) = arg.strip_prefix('@') {
|
||||
|
|
@ -23,12 +23,12 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
|||
/// **Note:** This function doesn't interpret argument 0 in any special way.
|
||||
/// If this function is intended to be used with command line arguments,
|
||||
/// `argv[0]` must be removed prior to calling it manually.
|
||||
pub fn arg_expand_all(handler: &EarlyErrorHandler, at_args: &[String]) -> Vec<String> {
|
||||
pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> {
|
||||
let mut args = Vec::new();
|
||||
for arg in at_args {
|
||||
match arg_expand(arg.clone()) {
|
||||
Ok(arg) => args.extend(arg),
|
||||
Err(err) => handler.early_error(format!("Failed to load argument file: {err}")),
|
||||
Err(err) => early_dcx.early_error(format!("Failed to load argument file: {err}")),
|
||||
}
|
||||
}
|
||||
args
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use rustc_data_structures::profiling::{
|
|||
use rustc_data_structures::sync::SeqCst;
|
||||
use rustc_errors::registry::{InvalidErrorCode, Registry};
|
||||
use rustc_errors::{markdown, ColorConfig};
|
||||
use rustc_errors::{ErrorGuaranteed, Handler, PResult};
|
||||
use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
|
||||
use rustc_feature::find_gated_cfg;
|
||||
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
|
||||
use rustc_interface::{interface, Queries};
|
||||
|
|
@ -38,7 +38,7 @@ use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
|
|||
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
|
||||
use rustc_session::getopts::{self, Matches};
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
use rustc_session::{config, EarlyErrorHandler, Session};
|
||||
use rustc_session::{config, EarlyDiagCtxt, Session};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::source_map::FileLoader;
|
||||
use rustc_span::symbol::sym;
|
||||
|
|
@ -291,7 +291,7 @@ fn run_compiler(
|
|||
>,
|
||||
using_internal_features: Arc<std::sync::atomic::AtomicBool>,
|
||||
) -> interface::Result<()> {
|
||||
let mut default_handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let mut default_early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
|
||||
// Throw away the first argument, the name of the binary.
|
||||
// In case of at_args being empty, as might be the case by
|
||||
|
|
@ -303,14 +303,14 @@ fn run_compiler(
|
|||
// the compiler with @empty_file as argv[0] and no more arguments.
|
||||
let at_args = at_args.get(1..).unwrap_or_default();
|
||||
|
||||
let args = args::arg_expand_all(&default_handler, at_args);
|
||||
let args = args::arg_expand_all(&default_early_dcx, at_args);
|
||||
|
||||
let Some(matches) = handle_options(&default_handler, &args) else { return Ok(()) };
|
||||
let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };
|
||||
|
||||
let sopts = config::build_session_options(&mut default_handler, &matches);
|
||||
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
|
||||
|
||||
if let Some(ref code) = matches.opt_str("explain") {
|
||||
handle_explain(&default_handler, diagnostics_registry(), code, sopts.color);
|
||||
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ fn run_compiler(
|
|||
expanded_args: args,
|
||||
};
|
||||
|
||||
let has_input = match make_input(&default_handler, &matches.free) {
|
||||
let has_input = match make_input(&default_early_dcx, &matches.free) {
|
||||
Err(reported) => return Err(reported),
|
||||
Ok(Some(input)) => {
|
||||
config.input = input;
|
||||
|
|
@ -345,7 +345,7 @@ fn run_compiler(
|
|||
Ok(None) => match matches.free.len() {
|
||||
0 => false, // no input: we will exit early
|
||||
1 => panic!("make_input should have provided valid inputs"),
|
||||
_ => default_handler.early_error(format!(
|
||||
_ => default_early_dcx.early_error(format!(
|
||||
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
||||
matches.free[0], matches.free[1],
|
||||
)),
|
||||
|
|
@ -354,8 +354,8 @@ fn run_compiler(
|
|||
|
||||
callbacks.config(&mut config);
|
||||
|
||||
default_handler.abort_if_errors();
|
||||
drop(default_handler);
|
||||
default_early_dcx.abort_if_errors();
|
||||
drop(default_early_dcx);
|
||||
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sess = &compiler.sess;
|
||||
|
|
@ -369,18 +369,18 @@ fn run_compiler(
|
|||
return sess.compile_status();
|
||||
}
|
||||
|
||||
let handler = EarlyErrorHandler::new(sess.opts.error_format);
|
||||
let early_dcx = EarlyDiagCtxt::new(sess.opts.error_format);
|
||||
|
||||
if print_crate_info(&handler, codegen_backend, sess, has_input) == Compilation::Stop {
|
||||
if print_crate_info(&early_dcx, codegen_backend, sess, has_input) == Compilation::Stop {
|
||||
return sess.compile_status();
|
||||
}
|
||||
|
||||
if !has_input {
|
||||
handler.early_error("no input filename given"); // this is fatal
|
||||
early_dcx.early_error("no input filename given"); // this is fatal
|
||||
}
|
||||
|
||||
if !sess.opts.unstable_opts.ls.is_empty() {
|
||||
list_metadata(&handler, sess, &*codegen_backend.metadata_loader());
|
||||
list_metadata(&early_dcx, sess, &*codegen_backend.metadata_loader());
|
||||
return sess.compile_status();
|
||||
}
|
||||
|
||||
|
|
@ -495,7 +495,7 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileNa
|
|||
|
||||
// Extract input (string or file and optional path) from matches.
|
||||
fn make_input(
|
||||
handler: &EarlyErrorHandler,
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
free_matches: &[String],
|
||||
) -> Result<Option<Input>, ErrorGuaranteed> {
|
||||
if free_matches.len() == 1 {
|
||||
|
|
@ -505,7 +505,7 @@ fn make_input(
|
|||
if io::stdin().read_to_string(&mut src).is_err() {
|
||||
// Immediately stop compilation if there was an issue reading
|
||||
// the input (for example if the input stream is not UTF-8).
|
||||
let reported = handler.early_error_no_abort(
|
||||
let reported = early_dcx.early_error_no_abort(
|
||||
"couldn't read from stdin, as it did not contain valid UTF-8",
|
||||
);
|
||||
return Err(reported);
|
||||
|
|
@ -537,7 +537,7 @@ pub enum Compilation {
|
|||
Continue,
|
||||
}
|
||||
|
||||
fn handle_explain(handler: &EarlyErrorHandler, registry: Registry, code: &str, color: ColorConfig) {
|
||||
fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) {
|
||||
let upper_cased_code = code.to_ascii_uppercase();
|
||||
let normalised =
|
||||
if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
|
||||
|
|
@ -567,7 +567,7 @@ fn handle_explain(handler: &EarlyErrorHandler, registry: Registry, code: &str, c
|
|||
}
|
||||
}
|
||||
Err(InvalidErrorCode) => {
|
||||
handler.early_error(format!("{code} is not a valid error code"));
|
||||
early_dcx.early_error(format!("{code} is not a valid error code"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -669,11 +669,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
|
|||
}
|
||||
}
|
||||
|
||||
fn list_metadata(
|
||||
handler: &EarlyErrorHandler,
|
||||
sess: &Session,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
) {
|
||||
fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dyn MetadataLoader) {
|
||||
match sess.io.input {
|
||||
Input::File(ref ifile) => {
|
||||
let path = &(*ifile);
|
||||
|
|
@ -689,13 +685,13 @@ fn list_metadata(
|
|||
safe_println!("{}", String::from_utf8(v).unwrap());
|
||||
}
|
||||
Input::Str { .. } => {
|
||||
handler.early_error("cannot list metadata for stdin");
|
||||
early_dcx.early_error("cannot list metadata for stdin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_crate_info(
|
||||
handler: &EarlyErrorHandler,
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
codegen_backend: &dyn CodegenBackend,
|
||||
sess: &Session,
|
||||
parse_attrs: bool,
|
||||
|
|
@ -842,7 +838,7 @@ fn print_crate_info(
|
|||
.expect("unknown Apple target OS");
|
||||
println_info!("deployment_target={}", format!("{major}.{minor}"))
|
||||
} else {
|
||||
handler
|
||||
early_dcx
|
||||
.early_error("only Apple targets currently support deployment version info")
|
||||
}
|
||||
}
|
||||
|
|
@ -856,12 +852,12 @@ fn print_crate_info(
|
|||
/// Prints version information
|
||||
///
|
||||
/// NOTE: this is a macro to support drivers built at a different time than the main `rustc_driver` crate.
|
||||
pub macro version($handler: expr, $binary: literal, $matches: expr) {
|
||||
pub macro version($early_dcx: expr, $binary: literal, $matches: expr) {
|
||||
fn unw(x: Option<&str>) -> &str {
|
||||
x.unwrap_or("unknown")
|
||||
}
|
||||
$crate::version_at_macro_invocation(
|
||||
$handler,
|
||||
$early_dcx,
|
||||
$binary,
|
||||
$matches,
|
||||
unw(option_env!("CFG_VERSION")),
|
||||
|
|
@ -873,7 +869,7 @@ pub macro version($handler: expr, $binary: literal, $matches: expr) {
|
|||
|
||||
#[doc(hidden)] // use the macro instead
|
||||
pub fn version_at_macro_invocation(
|
||||
handler: &EarlyErrorHandler,
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
binary: &str,
|
||||
matches: &getopts::Matches,
|
||||
version: &str,
|
||||
|
|
@ -894,7 +890,7 @@ pub fn version_at_macro_invocation(
|
|||
|
||||
let debug_flags = matches.opt_strs("Z");
|
||||
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
|
||||
get_codegen_backend(handler, &None, backend_name).print_version();
|
||||
get_codegen_backend(early_dcx, &None, backend_name).print_version();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1072,7 +1068,7 @@ Available lint options:
|
|||
/// Show help for flag categories shared between rustdoc and rustc.
|
||||
///
|
||||
/// Returns whether a help option was printed.
|
||||
pub fn describe_flag_categories(handler: &EarlyErrorHandler, matches: &Matches) -> bool {
|
||||
pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> bool {
|
||||
// Handle the special case of -Wall.
|
||||
let wall = matches.opt_strs("W");
|
||||
if wall.iter().any(|x| *x == "all") {
|
||||
|
|
@ -1094,12 +1090,12 @@ pub fn describe_flag_categories(handler: &EarlyErrorHandler, matches: &Matches)
|
|||
}
|
||||
|
||||
if cg_flags.iter().any(|x| *x == "no-stack-check") {
|
||||
handler.early_warn("the --no-stack-check flag is deprecated and does nothing");
|
||||
early_dcx.early_warn("the --no-stack-check flag is deprecated and does nothing");
|
||||
}
|
||||
|
||||
if cg_flags.iter().any(|x| *x == "passes=list") {
|
||||
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
|
||||
get_codegen_backend(handler, &None, backend_name).print_passes();
|
||||
get_codegen_backend(early_dcx, &None, backend_name).print_passes();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1160,7 +1156,7 @@ fn print_flag_list<T>(
|
|||
/// This does not need to be `pub` for rustc itself, but @chaosite needs it to
|
||||
/// be public when using rustc as a library, see
|
||||
/// <https://github.com/rust-lang/rust/commit/2b4c33817a5aaecabf4c6598d41e190080ec119e>
|
||||
pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option<getopts::Matches> {
|
||||
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<getopts::Matches> {
|
||||
if args.is_empty() {
|
||||
// user did not write `-v` nor `-Z unstable-options`, so do not
|
||||
// include that extra information.
|
||||
|
|
@ -1186,7 +1182,7 @@ pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option<ge
|
|||
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
|
||||
_ => None,
|
||||
};
|
||||
handler.early_error(msg.unwrap_or_else(|| e.to_string()));
|
||||
early_dcx.early_error(msg.unwrap_or_else(|| e.to_string()));
|
||||
});
|
||||
|
||||
// For all options we just parsed, we check a few aspects:
|
||||
|
|
@ -1200,7 +1196,7 @@ pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option<ge
|
|||
// we're good to go.
|
||||
// * Otherwise, if we're an unstable option then we generate an error
|
||||
// (unstable option being used on stable)
|
||||
nightly_options::check_nightly_options(handler, &matches, &config::rustc_optgroups());
|
||||
nightly_options::check_nightly_options(early_dcx, &matches, &config::rustc_optgroups());
|
||||
|
||||
if matches.opt_present("h") || matches.opt_present("help") {
|
||||
// Only show unstable options in --help if we accept unstable options.
|
||||
|
|
@ -1210,12 +1206,12 @@ pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option<ge
|
|||
return None;
|
||||
}
|
||||
|
||||
if describe_flag_categories(handler, &matches) {
|
||||
if describe_flag_categories(early_dcx, &matches) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if matches.opt_present("version") {
|
||||
version!(handler, "rustc", &matches);
|
||||
version!(early_dcx, "rustc", &matches);
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
@ -1310,7 +1306,10 @@ fn ice_path() -> &'static Option<PathBuf> {
|
|||
/// internal features.
|
||||
///
|
||||
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
|
||||
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) -> Arc<AtomicBool> {
|
||||
pub fn install_ice_hook(
|
||||
bug_report_url: &'static str,
|
||||
extra_info: fn(&DiagCtxt),
|
||||
) -> Arc<AtomicBool> {
|
||||
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
|
||||
// full backtraces. When a compiler ICE happens, we want to gather
|
||||
// as much information as possible to present in the issue opened
|
||||
|
|
@ -1333,8 +1332,8 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
|
|||
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)")
|
||||
{
|
||||
// the error code is already going to be reported when the panic unwinds up the stack
|
||||
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let _ = handler.early_error_no_abort(msg.clone());
|
||||
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
let _ = early_dcx.early_error_no_abort(msg.clone());
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
@ -1388,7 +1387,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
|
|||
fn report_ice(
|
||||
info: &panic::PanicInfo<'_>,
|
||||
bug_report_url: &str,
|
||||
extra_info: fn(&Handler),
|
||||
extra_info: fn(&DiagCtxt),
|
||||
using_internal_features: &AtomicBool,
|
||||
) {
|
||||
let fallback_bundle =
|
||||
|
|
@ -1397,20 +1396,20 @@ fn report_ice(
|
|||
rustc_errors::ColorConfig::Auto,
|
||||
fallback_bundle,
|
||||
));
|
||||
let handler = rustc_errors::Handler::with_emitter(emitter);
|
||||
let dcx = rustc_errors::DiagCtxt::with_emitter(emitter);
|
||||
|
||||
// a .span_bug or .bug call has already printed what
|
||||
// it wants to print.
|
||||
if !info.payload().is::<rustc_errors::ExplicitBug>()
|
||||
&& !info.payload().is::<rustc_errors::DelayedBugPanic>()
|
||||
{
|
||||
handler.emit_err(session_diagnostics::Ice);
|
||||
dcx.emit_err(session_diagnostics::Ice);
|
||||
}
|
||||
|
||||
if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
handler.emit_note(session_diagnostics::IceBugReportInternalFeature);
|
||||
dcx.emit_note(session_diagnostics::IceBugReportInternalFeature);
|
||||
} else {
|
||||
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
|
||||
dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });
|
||||
}
|
||||
|
||||
let version = util::version_str!().unwrap_or("unknown_version");
|
||||
|
|
@ -1422,7 +1421,7 @@ fn report_ice(
|
|||
// Create the ICE dump target file.
|
||||
match crate::fs::File::options().create(true).append(true).open(&path) {
|
||||
Ok(mut file) => {
|
||||
handler.emit_note(session_diagnostics::IcePath { path: path.clone() });
|
||||
dcx.emit_note(session_diagnostics::IcePath { path: path.clone() });
|
||||
if FIRST_PANIC.swap(false, Ordering::SeqCst) {
|
||||
let _ = write!(file, "\n\nrustc version: {version}\nplatform: {triple}");
|
||||
}
|
||||
|
|
@ -1430,26 +1429,26 @@ fn report_ice(
|
|||
}
|
||||
Err(err) => {
|
||||
// The path ICE couldn't be written to disk, provide feedback to the user as to why.
|
||||
handler.emit_warning(session_diagnostics::IcePathError {
|
||||
dcx.emit_warning(session_diagnostics::IcePathError {
|
||||
path: path.clone(),
|
||||
error: err.to_string(),
|
||||
env_var: std::env::var_os("RUSTC_ICE")
|
||||
.map(PathBuf::from)
|
||||
.map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }),
|
||||
});
|
||||
handler.emit_note(session_diagnostics::IceVersion { version, triple });
|
||||
dcx.emit_note(session_diagnostics::IceVersion { version, triple });
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handler.emit_note(session_diagnostics::IceVersion { version, triple });
|
||||
dcx.emit_note(session_diagnostics::IceVersion { version, triple });
|
||||
None
|
||||
};
|
||||
|
||||
if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() {
|
||||
handler.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") });
|
||||
dcx.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") });
|
||||
if excluded_cargo_defaults {
|
||||
handler.emit_note(session_diagnostics::IceExcludeCargoDefaults);
|
||||
dcx.emit_note(session_diagnostics::IceExcludeCargoDefaults);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1458,11 +1457,11 @@ fn report_ice(
|
|||
|
||||
let num_frames = if backtrace { None } else { Some(2) };
|
||||
|
||||
interface::try_print_query_stack(&handler, num_frames, file);
|
||||
interface::try_print_query_stack(&dcx, num_frames, file);
|
||||
|
||||
// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
|
||||
// printed all the relevant info.
|
||||
extra_info(&handler);
|
||||
extra_info(&dcx);
|
||||
|
||||
#[cfg(windows)]
|
||||
if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
|
||||
|
|
@ -1473,16 +1472,16 @@ fn report_ice(
|
|||
|
||||
/// This allows tools to enable rust logging without having to magically match rustc's
|
||||
/// tracing crate version.
|
||||
pub fn init_rustc_env_logger(handler: &EarlyErrorHandler) {
|
||||
init_logger(handler, rustc_log::LoggerConfig::from_env("RUSTC_LOG"));
|
||||
pub fn init_rustc_env_logger(early_dcx: &EarlyDiagCtxt) {
|
||||
init_logger(early_dcx, rustc_log::LoggerConfig::from_env("RUSTC_LOG"));
|
||||
}
|
||||
|
||||
/// This allows tools to enable rust logging without having to magically match rustc's
|
||||
/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose
|
||||
/// the values directly rather than having to set an environment variable.
|
||||
pub fn init_logger(handler: &EarlyErrorHandler, cfg: rustc_log::LoggerConfig) {
|
||||
pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) {
|
||||
if let Err(error) = rustc_log::init_logger(cfg) {
|
||||
handler.early_error(error.to_string());
|
||||
early_dcx.early_error(error.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1490,9 +1489,9 @@ pub fn main() -> ! {
|
|||
let start_time = Instant::now();
|
||||
let start_rss = get_resident_set_size();
|
||||
|
||||
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
|
||||
init_rustc_env_logger(&handler);
|
||||
init_rustc_env_logger(&early_dcx);
|
||||
signal_handler::install();
|
||||
let mut callbacks = TimePassesCallbacks::default();
|
||||
let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
|
||||
|
|
@ -1501,7 +1500,7 @@ pub fn main() -> ! {
|
|||
.enumerate()
|
||||
.map(|(i, arg)| {
|
||||
arg.into_string().unwrap_or_else(|arg| {
|
||||
handler.early_error(format!("argument {i} is not valid Unicode: {arg:?}"))
|
||||
early_dcx.early_error(format!("argument {i} is not valid Unicode: {arg:?}"))
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
|||
|
|
@ -91,10 +91,7 @@ where
|
|||
#[rustc_diagnostic_item = "DecorateLint"]
|
||||
pub trait DecorateLint<'a, G: EmissionGuarantee> {
|
||||
/// Decorate and emit a lint.
|
||||
fn decorate_lint<'b>(
|
||||
self,
|
||||
diag: &'b mut DiagnosticBuilder<'a, G>,
|
||||
) -> &'b mut DiagnosticBuilder<'a, G>;
|
||||
fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, G>);
|
||||
|
||||
fn msg(&self) -> DiagnosticMessage;
|
||||
}
|
||||
|
|
@ -889,13 +886,13 @@ impl Diagnostic {
|
|||
/// interpolated variables).
|
||||
pub fn eager_subdiagnostic(
|
||||
&mut self,
|
||||
handler: &crate::Handler,
|
||||
dcx: &crate::DiagCtxt,
|
||||
subdiagnostic: impl AddToDiagnostic,
|
||||
) -> &mut Self {
|
||||
subdiagnostic.add_to_diagnostic_with(self, |diag, msg| {
|
||||
let args = diag.args();
|
||||
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
|
||||
handler.eagerly_translate(msg, args)
|
||||
dcx.eagerly_translate(msg, args)
|
||||
});
|
||||
self
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use crate::diagnostic::IntoDiagnosticArg;
|
||||
use crate::{DiagCtxt, Level, MultiSpan, StashKey};
|
||||
use crate::{
|
||||
Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed,
|
||||
ExplicitBug, SubdiagnosticMessage,
|
||||
};
|
||||
use crate::{Handler, Level, MultiSpan, StashKey};
|
||||
use rustc_lint_defs::Applicability;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
||||
|
|
@ -19,9 +19,9 @@ use std::thread::panicking;
|
|||
/// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic].
|
||||
#[rustc_diagnostic_item = "IntoDiagnostic"]
|
||||
pub trait IntoDiagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
|
||||
/// Write out as a diagnostic out of `Handler`.
|
||||
/// Write out as a diagnostic out of `DiagCtxt`.
|
||||
#[must_use]
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G>;
|
||||
fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, G>;
|
||||
}
|
||||
|
||||
impl<'a, T, G> IntoDiagnostic<'a, G> for Spanned<T>
|
||||
|
|
@ -29,8 +29,8 @@ where
|
|||
T: IntoDiagnostic<'a, G>,
|
||||
G: EmissionGuarantee,
|
||||
{
|
||||
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G> {
|
||||
let mut diag = self.node.into_diagnostic(handler);
|
||||
fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, G> {
|
||||
let mut diag = self.node.into_diagnostic(dcx);
|
||||
diag.set_span(self.span);
|
||||
diag
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ where
|
|||
///
|
||||
/// If there is some state in a downstream crate you would like to
|
||||
/// access in the methods of `DiagnosticBuilder` here, consider
|
||||
/// extending `HandlerFlags`, accessed via `self.handler.flags`.
|
||||
/// extending `DiagCtxtFlags`.
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
pub struct DiagnosticBuilder<'a, G: EmissionGuarantee> {
|
||||
|
|
@ -74,8 +74,8 @@ struct DiagnosticBuilderInner<'a> {
|
|||
enum DiagnosticBuilderState<'a> {
|
||||
/// Initial state of a `DiagnosticBuilder`, before `.emit()` or `.cancel()`.
|
||||
///
|
||||
/// The `Diagnostic` will be emitted through this `Handler`.
|
||||
Emittable(&'a Handler),
|
||||
/// The `Diagnostic` will be emitted through this `DiagCtxt`.
|
||||
Emittable(&'a DiagCtxt),
|
||||
|
||||
/// State of a `DiagnosticBuilder`, after `.emit()` or *during* `.cancel()`.
|
||||
///
|
||||
|
|
@ -95,7 +95,7 @@ enum DiagnosticBuilderState<'a> {
|
|||
// `DiagnosticBuilderState` should be pointer-sized.
|
||||
rustc_data_structures::static_assert_size!(
|
||||
DiagnosticBuilderState<'_>,
|
||||
std::mem::size_of::<&Handler>()
|
||||
std::mem::size_of::<&DiagCtxt>()
|
||||
);
|
||||
|
||||
/// Trait for types that `DiagnosticBuilder::emit` can return as a "guarantee"
|
||||
|
|
@ -110,7 +110,7 @@ pub trait EmissionGuarantee: Sized {
|
|||
/// Creates a new `DiagnosticBuilder` that will return this type of guarantee.
|
||||
#[track_caller]
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self>;
|
||||
}
|
||||
|
|
@ -128,11 +128,11 @@ impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
|||
impl EmissionGuarantee for ErrorGuaranteed {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
let guar = handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
let guar = dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
|
||||
// Only allow a guarantee if the `level` wasn't switched to a
|
||||
// non-error - the field isn't `pub`, but the whole `Diagnostic`
|
||||
|
|
@ -166,10 +166,10 @@ impl EmissionGuarantee for ErrorGuaranteed {
|
|||
|
||||
#[track_caller]
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(handler, Level::Error { lint: false }, msg)
|
||||
DiagnosticBuilder::new(dcx, Level::Error { lint: false }, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,11 +177,11 @@ impl EmissionGuarantee for ErrorGuaranteed {
|
|||
impl EmissionGuarantee for () {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
|
|
@ -189,10 +189,10 @@ impl EmissionGuarantee for () {
|
|||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(handler, Level::Warning(None), msg)
|
||||
DiagnosticBuilder::new(dcx, Level::Warning(None), msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,10 +204,10 @@ pub struct Noted;
|
|||
impl EmissionGuarantee for Noted {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
|
|
@ -217,10 +217,10 @@ impl EmissionGuarantee for Noted {
|
|||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(handler, Level::Note, msg)
|
||||
DiagnosticBuilder::new(dcx, Level::Note, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,11 +232,11 @@ pub struct Bug;
|
|||
impl EmissionGuarantee for Bug {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
|
|
@ -246,21 +246,21 @@ impl EmissionGuarantee for Bug {
|
|||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(handler, Level::Bug, msg)
|
||||
DiagnosticBuilder::new(dcx, Level::Bug, msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl EmissionGuarantee for ! {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
|
|
@ -270,21 +270,21 @@ impl EmissionGuarantee for ! {
|
|||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(handler, Level::Fatal, msg)
|
||||
DiagnosticBuilder::new(dcx, Level::Fatal, msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
|
|
@ -294,10 +294,10 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
|
|||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
handler: &Handler,
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(handler, Level::Fatal, msg)
|
||||
DiagnosticBuilder::new(dcx, Level::Fatal, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -340,25 +340,25 @@ impl<G: EmissionGuarantee> DerefMut for DiagnosticBuilder<'_, G> {
|
|||
|
||||
impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
/// `struct_*` methods on [`Handler`].
|
||||
/// `struct_*` methods on [`DiagCtxt`].
|
||||
#[track_caller]
|
||||
pub(crate) fn new<M: Into<DiagnosticMessage>>(
|
||||
handler: &'a Handler,
|
||||
dcx: &'a DiagCtxt,
|
||||
level: Level,
|
||||
message: M,
|
||||
) -> Self {
|
||||
let diagnostic = Diagnostic::new(level, message);
|
||||
Self::new_diagnostic(handler, diagnostic)
|
||||
Self::new_diagnostic(dcx, diagnostic)
|
||||
}
|
||||
|
||||
/// Creates a new `DiagnosticBuilder` with an already constructed
|
||||
/// diagnostic.
|
||||
#[track_caller]
|
||||
pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
|
||||
pub(crate) fn new_diagnostic(dcx: &'a DiagCtxt, diagnostic: Diagnostic) -> Self {
|
||||
debug!("Created new diagnostic");
|
||||
Self {
|
||||
inner: DiagnosticBuilderInner {
|
||||
state: DiagnosticBuilderState::Emittable(handler),
|
||||
state: DiagnosticBuilderState::Emittable(dcx),
|
||||
diagnostic: Box::new(diagnostic),
|
||||
},
|
||||
_marker: PhantomData,
|
||||
|
|
@ -398,7 +398,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
|
||||
/// Stashes diagnostic for possible later improvement in a different,
|
||||
/// later stage of the compiler. The diagnostic can be accessed with
|
||||
/// the provided `span` and `key` through [`Handler::steal_diagnostic()`].
|
||||
/// the provided `span` and `key` through [`DiagCtxt::steal_diagnostic()`].
|
||||
///
|
||||
/// As with `buffer`, this is unless the handler has disabled such buffering.
|
||||
pub fn stash(self, span: Span, key: StashKey) {
|
||||
|
|
@ -409,18 +409,18 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
|
||||
/// Converts the builder to a `Diagnostic` for later emission,
|
||||
/// unless handler has disabled such buffering, or `.emit()` was called.
|
||||
pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a Handler)> {
|
||||
let handler = match self.inner.state {
|
||||
// No `.emit()` calls, the `&Handler` is still available.
|
||||
DiagnosticBuilderState::Emittable(handler) => handler,
|
||||
pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> {
|
||||
let dcx = match self.inner.state {
|
||||
// No `.emit()` calls, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => dcx,
|
||||
// `.emit()` was previously called, nothing we can do.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
if handler.inner.lock().flags.dont_buffer_diagnostics
|
||||
|| handler.inner.lock().flags.treat_err_as_bug.is_some()
|
||||
if dcx.inner.lock().flags.dont_buffer_diagnostics
|
||||
|| dcx.inner.lock().flags.treat_err_as_bug.is_some()
|
||||
{
|
||||
self.emit();
|
||||
return None;
|
||||
|
|
@ -437,13 +437,13 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
// actually emitted.
|
||||
debug!("buffer: diagnostic={:?}", diagnostic);
|
||||
|
||||
Some((diagnostic, handler))
|
||||
Some((diagnostic, dcx))
|
||||
}
|
||||
|
||||
/// Retrieves the [`Handler`] if available
|
||||
pub fn handler(&self) -> Option<&Handler> {
|
||||
/// Retrieves the [`DiagCtxt`] if available
|
||||
pub fn dcx(&self) -> Option<&DiagCtxt> {
|
||||
match self.inner.state {
|
||||
DiagnosticBuilderState::Emittable(handler) => Some(handler),
|
||||
DiagnosticBuilderState::Emittable(dcx) => Some(dcx),
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -640,15 +640,15 @@ impl Drop for DiagnosticBuilderInner<'_> {
|
|||
fn drop(&mut self) {
|
||||
match self.state {
|
||||
// No `.emit()` or `.cancel()` calls.
|
||||
DiagnosticBuilderState::Emittable(handler) => {
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
if !panicking() {
|
||||
handler.emit_diagnostic(Diagnostic::new(
|
||||
dcx.emit_diagnostic(Diagnostic::new(
|
||||
Level::Bug,
|
||||
DiagnosticMessage::from(
|
||||
"the following error was constructed but not emitted",
|
||||
),
|
||||
));
|
||||
handler.emit_diagnostic_without_consuming(&mut self.diagnostic);
|
||||
dcx.emit_diagnostic_without_consuming(&mut self.diagnostic);
|
||||
panic!("error was constructed but not emitted");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::diagnostic::DiagnosticLocation;
|
||||
use crate::{fluent_generated as fluent, AddToDiagnostic};
|
||||
use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg};
|
||||
use crate::{DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, IntoDiagnostic, IntoDiagnosticArg};
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -246,18 +246,18 @@ impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
|
|||
}
|
||||
|
||||
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
|
||||
fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, !> {
|
||||
let mut diag;
|
||||
match self {
|
||||
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_invalid_address_space);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_invalid_address_space);
|
||||
diag.set_arg("addr_space", addr_space);
|
||||
diag.set_arg("cause", cause);
|
||||
diag.set_arg("err", err);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_invalid_bits);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_invalid_bits);
|
||||
diag.set_arg("kind", kind);
|
||||
diag.set_arg("bit", bit);
|
||||
diag.set_arg("cause", cause);
|
||||
|
|
@ -265,31 +265,31 @@ impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
|||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::MissingAlignment { cause } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_missing_alignment);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_missing_alignment);
|
||||
diag.set_arg("cause", cause);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_invalid_alignment);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_invalid_alignment);
|
||||
diag.set_arg("cause", cause);
|
||||
diag.set_arg("err_kind", err.diag_ident());
|
||||
diag.set_arg("align", err.align());
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_inconsistent_architecture);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_inconsistent_architecture);
|
||||
diag.set_arg("dl", dl);
|
||||
diag.set_arg("target", target);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_inconsistent_pointer_width);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_inconsistent_pointer_width);
|
||||
diag.set_arg("pointer_size", pointer_size);
|
||||
diag.set_arg("target", target);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidBitsSize { err } => {
|
||||
diag = handler.struct_fatal(fluent::errors_target_invalid_bits_size);
|
||||
diag = dcx.struct_fatal(fluent::errors_target_invalid_bits_size);
|
||||
diag.set_arg("err", err);
|
||||
diag
|
||||
}
|
||||
|
|
@ -378,3 +378,9 @@ pub struct IndicateAnonymousLifetime {
|
|||
pub count: usize,
|
||||
pub suggestion: String,
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for type_ir::ClosureKind {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(self.as_str().into())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use crate::snippet::{
|
|||
use crate::styled_buffer::StyledBuffer;
|
||||
use crate::translation::{to_fluent_args, Translate};
|
||||
use crate::{
|
||||
diagnostic::DiagnosticLocation, CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage,
|
||||
FluentBundle, Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic,
|
||||
diagnostic::DiagnosticLocation, CodeSuggestion, DiagCtxt, Diagnostic, DiagnosticId,
|
||||
DiagnosticMessage, FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic,
|
||||
SubstitutionHighlight, SuggestionStyle, TerminalUrl,
|
||||
};
|
||||
use rustc_lint_defs::pluralize;
|
||||
|
|
@ -553,10 +553,10 @@ impl Emitter for EmitterWriter {
|
|||
}
|
||||
|
||||
/// An emitter that does nothing when emitting a non-fatal diagnostic.
|
||||
/// Fatal diagnostics are forwarded to `fatal_handler` to avoid silent
|
||||
/// Fatal diagnostics are forwarded to `fatal_dcx` to avoid silent
|
||||
/// failures of rustc, as witnessed e.g. in issue #89358.
|
||||
pub struct SilentEmitter {
|
||||
pub fatal_handler: Handler,
|
||||
pub fatal_dcx: DiagCtxt,
|
||||
pub fatal_note: Option<String>,
|
||||
}
|
||||
|
||||
|
|
@ -581,7 +581,7 @@ impl Emitter for SilentEmitter {
|
|||
if let Some(ref note) = self.fatal_note {
|
||||
d.note(note.clone());
|
||||
}
|
||||
self.fatal_handler.emit_diagnostic(d);
|
||||
self.fatal_dcx.emit_diagnostic(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2677,10 +2677,7 @@ fn from_stderr(color: ColorConfig) -> Destination {
|
|||
/// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
|
||||
///
|
||||
/// See #36178.
|
||||
#[cfg(windows)]
|
||||
const BRIGHT_BLUE: Color = Color::Cyan;
|
||||
#[cfg(not(windows))]
|
||||
const BRIGHT_BLUE: Color = Color::Blue;
|
||||
const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue };
|
||||
|
||||
impl Style {
|
||||
fn color_spec(&self, lvl: Level) -> ColorSpec {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::*;
|
||||
|
||||
use crate::emitter::ColorConfig;
|
||||
use crate::Handler;
|
||||
use crate::DiagCtxt;
|
||||
use rustc_span::BytePos;
|
||||
|
||||
use std::str;
|
||||
|
|
@ -61,8 +61,8 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
|
|||
);
|
||||
|
||||
let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1));
|
||||
let handler = Handler::with_emitter(Box::new(je));
|
||||
handler.span_err(span, "foo");
|
||||
let dcx = DiagCtxt::with_emitter(Box::new(je));
|
||||
dcx.span_err(span, "foo");
|
||||
|
||||
let bytes = output.lock().unwrap();
|
||||
let actual_output = str::from_utf8(&bytes).unwrap();
|
||||
|
|
|
|||
|
|
@ -412,15 +412,15 @@ use std::backtrace::{Backtrace, BacktraceStatus};
|
|||
/// A handler deals with errors and other compiler output.
|
||||
/// Certain errors (fatal, bug, unimpl) may cause immediate exit,
|
||||
/// others log errors for later reporting.
|
||||
pub struct Handler {
|
||||
inner: Lock<HandlerInner>,
|
||||
pub struct DiagCtxt {
|
||||
inner: Lock<DiagCtxtInner>,
|
||||
}
|
||||
|
||||
/// This inner struct exists to keep it all behind a single lock;
|
||||
/// this is done to prevent possible deadlocks in a multi-threaded compiler,
|
||||
/// as well as inconsistent state observation.
|
||||
struct HandlerInner {
|
||||
flags: HandlerFlags,
|
||||
struct DiagCtxtInner {
|
||||
flags: DiagCtxtFlags,
|
||||
/// The number of lint errors that have been emitted.
|
||||
lint_err_count: usize,
|
||||
/// The number of errors that have been emitted, including duplicates.
|
||||
|
|
@ -518,7 +518,7 @@ pub static TRACK_DIAGNOSTICS: AtomicRef<fn(&mut Diagnostic, &mut dyn FnMut(&mut
|
|||
AtomicRef::new(&(default_track_diagnostic as _));
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct HandlerFlags {
|
||||
pub struct DiagCtxtFlags {
|
||||
/// If false, warning-level lints are suppressed.
|
||||
/// (rustc: see `--allow warnings` and `--cap-lints`)
|
||||
pub can_emit_warnings: bool,
|
||||
|
|
@ -540,7 +540,7 @@ pub struct HandlerFlags {
|
|||
pub track_diagnostics: bool,
|
||||
}
|
||||
|
||||
impl Drop for HandlerInner {
|
||||
impl Drop for DiagCtxtInner {
|
||||
fn drop(&mut self) {
|
||||
self.emit_stashed_diagnostics();
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ impl Drop for HandlerInner {
|
|||
}
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
impl DiagCtxt {
|
||||
pub fn with_tty_emitter(
|
||||
sm: Option<Lrc<SourceMap>>,
|
||||
fallback_bundle: LazyFallbackBundle,
|
||||
|
|
@ -585,7 +585,7 @@ impl Handler {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_flags(mut self, flags: HandlerFlags) -> Self {
|
||||
pub fn with_flags(mut self, flags: DiagCtxtFlags) -> Self {
|
||||
self.inner.get_mut().flags = flags;
|
||||
self
|
||||
}
|
||||
|
|
@ -597,8 +597,8 @@ impl Handler {
|
|||
|
||||
pub fn with_emitter(emitter: Box<DynEmitter>) -> Self {
|
||||
Self {
|
||||
inner: Lock::new(HandlerInner {
|
||||
flags: HandlerFlags { can_emit_warnings: true, ..Default::default() },
|
||||
inner: Lock::new(DiagCtxtInner {
|
||||
flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
|
||||
lint_err_count: 0,
|
||||
err_count: 0,
|
||||
warn_count: 0,
|
||||
|
|
@ -1057,7 +1057,7 @@ impl Handler {
|
|||
inner.emit_diagnostic(diagnostic).unwrap()
|
||||
}
|
||||
|
||||
// FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
|
||||
// FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
|
||||
// where the explanation of what "good path" is (also, it should be renamed).
|
||||
pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
|
|
@ -1396,12 +1396,12 @@ impl Handler {
|
|||
}
|
||||
|
||||
/// This methods steals all [`LintExpectationId`]s that are stored inside
|
||||
/// [`HandlerInner`] and indicate that the linked expectation has been fulfilled.
|
||||
/// [`DiagCtxtInner`] and indicate that the linked expectation has been fulfilled.
|
||||
#[must_use]
|
||||
pub fn steal_fulfilled_expectation_ids(&self) -> FxHashSet<LintExpectationId> {
|
||||
assert!(
|
||||
self.inner.borrow().unstable_expect_diagnostics.is_empty(),
|
||||
"`HandlerInner::unstable_expect_diagnostics` should be empty at this point",
|
||||
"`DiagCtxtInner::unstable_expect_diagnostics` should be empty at this point",
|
||||
);
|
||||
std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
|
||||
}
|
||||
|
|
@ -1413,11 +1413,11 @@ impl Handler {
|
|||
}
|
||||
}
|
||||
|
||||
// Note: we prefer implementing operations on `Handler`, rather than
|
||||
// `HandlerInner`, whenever possible. This minimizes functions where
|
||||
// `Handler::foo()` just borrows `inner` and forwards a call to
|
||||
// Note: we prefer implementing operations on `DiagCtxt`, rather than
|
||||
// `DiagCtxtInner`, whenever possible. This minimizes functions where
|
||||
// `DiagCtxt::foo()` just borrows `inner` and forwards a call to
|
||||
// `HanderInner::foo`.
|
||||
impl HandlerInner {
|
||||
impl DiagCtxtInner {
|
||||
/// Emit all stashed diagnostics.
|
||||
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
|
||||
let has_errors = self.has_errors();
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@ impl SyntaxExtension {
|
|||
.map(|attr| {
|
||||
// Override `helper_attrs` passed above if it's a built-in macro,
|
||||
// marking `proc_macro_derive` macros as built-in is not a realistic use case.
|
||||
parse_macro_name_and_helper_attrs(sess.diagnostic(), attr, "built-in").map_or_else(
|
||||
parse_macro_name_and_helper_attrs(sess.dcx(), attr, "built-in").map_or_else(
|
||||
|| (Some(name), Vec::new()),
|
||||
|(name, helper_attrs)| (Some(name), helper_attrs),
|
||||
)
|
||||
|
|
@ -1119,7 +1119,7 @@ impl<'a> ExtCtxt<'a> {
|
|||
sp: S,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
self.sess.diagnostic().struct_span_err(sp, msg)
|
||||
self.sess.dcx().struct_span_err(sp, msg)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
|
|
@ -1143,10 +1143,10 @@ impl<'a> ExtCtxt<'a> {
|
|||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
|
||||
self.sess.diagnostic().span_err(sp, msg);
|
||||
self.sess.dcx().span_err(sp, msg);
|
||||
}
|
||||
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
|
||||
self.sess.diagnostic().span_bug(sp, msg);
|
||||
self.sess.dcx().span_bug(sp, msg);
|
||||
}
|
||||
pub fn trace_macros_diag(&mut self) {
|
||||
for (span, notes) in self.expansions.iter() {
|
||||
|
|
@ -1160,7 +1160,7 @@ impl<'a> ExtCtxt<'a> {
|
|||
self.expansions.clear();
|
||||
}
|
||||
pub fn bug(&self, msg: &'static str) -> ! {
|
||||
self.sess.diagnostic().bug(msg);
|
||||
self.sess.dcx().bug(msg);
|
||||
}
|
||||
pub fn trace_macros(&self) -> bool {
|
||||
self.ecfg.trace_mac
|
||||
|
|
@ -1208,7 +1208,7 @@ pub fn resolve_path(
|
|||
span,
|
||||
path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(),
|
||||
}
|
||||
.into_diagnostic(&parse_sess.span_diagnostic));
|
||||
.into_diagnostic(&parse_sess.dcx));
|
||||
}
|
||||
};
|
||||
result.pop();
|
||||
|
|
@ -1350,7 +1350,7 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>, tts: TokenStream) -> Option<Vec<
|
|||
}
|
||||
|
||||
pub fn parse_macro_name_and_helper_attrs(
|
||||
diag: &rustc_errors::Handler,
|
||||
dcx: &rustc_errors::DiagCtxt,
|
||||
attr: &Attribute,
|
||||
macro_type: &str,
|
||||
) -> Option<(Symbol, Vec<Symbol>)> {
|
||||
|
|
@ -1359,23 +1359,23 @@ pub fn parse_macro_name_and_helper_attrs(
|
|||
// `#[proc_macro_derive(Foo, attributes(A, ..))]`
|
||||
let list = attr.meta_item_list()?;
|
||||
if list.len() != 1 && list.len() != 2 {
|
||||
diag.emit_err(errors::AttrNoArguments { span: attr.span });
|
||||
dcx.emit_err(errors::AttrNoArguments { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
let Some(trait_attr) = list[0].meta_item() else {
|
||||
diag.emit_err(errors::NotAMetaItem { span: list[0].span() });
|
||||
dcx.emit_err(errors::NotAMetaItem { span: list[0].span() });
|
||||
return None;
|
||||
};
|
||||
let trait_ident = match trait_attr.ident() {
|
||||
Some(trait_ident) if trait_attr.is_word() => trait_ident,
|
||||
_ => {
|
||||
diag.emit_err(errors::OnlyOneWord { span: trait_attr.span });
|
||||
dcx.emit_err(errors::OnlyOneWord { span: trait_attr.span });
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
if !trait_ident.name.can_be_raw() {
|
||||
diag.emit_err(errors::CannotBeNameOfMacro {
|
||||
dcx.emit_err(errors::CannotBeNameOfMacro {
|
||||
span: trait_attr.span,
|
||||
trait_ident,
|
||||
macro_type,
|
||||
|
|
@ -1385,29 +1385,29 @@ pub fn parse_macro_name_and_helper_attrs(
|
|||
let attributes_attr = list.get(1);
|
||||
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
|
||||
if !attr.has_name(sym::attributes) {
|
||||
diag.emit_err(errors::ArgumentNotAttributes { span: attr.span() });
|
||||
dcx.emit_err(errors::ArgumentNotAttributes { span: attr.span() });
|
||||
}
|
||||
attr.meta_item_list()
|
||||
.unwrap_or_else(|| {
|
||||
diag.emit_err(errors::AttributesWrongForm { span: attr.span() });
|
||||
dcx.emit_err(errors::AttributesWrongForm { span: attr.span() });
|
||||
&[]
|
||||
})
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
let Some(attr) = attr.meta_item() else {
|
||||
diag.emit_err(errors::AttributeMetaItem { span: attr.span() });
|
||||
dcx.emit_err(errors::AttributeMetaItem { span: attr.span() });
|
||||
return None;
|
||||
};
|
||||
|
||||
let ident = match attr.ident() {
|
||||
Some(ident) if attr.is_word() => ident,
|
||||
_ => {
|
||||
diag.emit_err(errors::AttributeSingleWord { span: attr.span });
|
||||
dcx.emit_err(errors::AttributeSingleWord { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
};
|
||||
if !ident.name.can_be_raw() {
|
||||
diag.emit_err(errors::HelperAttributeNameInvalid {
|
||||
dcx.emit_err(errors::HelperAttributeNameInvalid {
|
||||
span: attr.span,
|
||||
name: ident,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ pub(super) fn check_meta_variables(
|
|||
rhses: &[TokenTree],
|
||||
) -> bool {
|
||||
if lhses.len() != rhses.len() {
|
||||
sess.span_diagnostic.span_bug(span, "length mismatch between LHSes and RHSes")
|
||||
sess.dcx.span_bug(span, "length mismatch between LHSes and RHSes")
|
||||
}
|
||||
let mut valid = true;
|
||||
for (lhs, rhs) in iter::zip(lhses, rhses) {
|
||||
|
|
@ -244,7 +244,7 @@ fn check_binders(
|
|||
// MetaVar(fragment) and not as MetaVarDecl(y, fragment).
|
||||
TokenTree::MetaVar(span, name) => {
|
||||
if macros.is_empty() {
|
||||
sess.span_diagnostic.span_bug(span, "unexpected MetaVar in lhs");
|
||||
sess.dcx.span_bug(span, "unexpected MetaVar in lhs");
|
||||
}
|
||||
let name = MacroRulesNormalizedIdent::new(name);
|
||||
// There are 3 possibilities:
|
||||
|
|
@ -275,14 +275,13 @@ fn check_binders(
|
|||
);
|
||||
}
|
||||
if !macros.is_empty() {
|
||||
sess.span_diagnostic.span_bug(span, "unexpected MetaVarDecl in nested lhs");
|
||||
sess.dcx.span_bug(span, "unexpected MetaVarDecl in nested lhs");
|
||||
}
|
||||
let name = MacroRulesNormalizedIdent::new(name);
|
||||
if let Some(prev_info) = get_binder_info(macros, binders, name) {
|
||||
// Duplicate binders at the top-level macro definition are errors. The lint is only
|
||||
// for nested macro definitions.
|
||||
sess.span_diagnostic
|
||||
.emit_err(errors::DuplicateMatcherBinding { span, prev: prev_info.span });
|
||||
sess.dcx.emit_err(errors::DuplicateMatcherBinding { span, prev: prev_info.span });
|
||||
*valid = false;
|
||||
} else {
|
||||
binders.insert(name, BinderInfo { span, ops: ops.into() });
|
||||
|
|
@ -341,7 +340,7 @@ fn check_occurrences(
|
|||
match *rhs {
|
||||
TokenTree::Token(..) => {}
|
||||
TokenTree::MetaVarDecl(span, _name, _kind) => {
|
||||
sess.span_diagnostic.span_bug(span, "unexpected MetaVarDecl in rhs")
|
||||
sess.dcx.span_bug(span, "unexpected MetaVarDecl in rhs")
|
||||
}
|
||||
TokenTree::MetaVar(span, name) => {
|
||||
let name = MacroRulesNormalizedIdent::new(name);
|
||||
|
|
|
|||
|
|
@ -236,6 +236,13 @@ fn expand_macro<'cx>(
|
|||
target_sp.open = source_sp.open.with_ctxt(ctxt);
|
||||
target_sp.close = source_sp.close.with_ctxt(ctxt);
|
||||
}
|
||||
(
|
||||
TokenTree::Delimited(target_sp, ..),
|
||||
mbe::TokenTree::MetaVar(source_sp, ..),
|
||||
) => {
|
||||
target_sp.open = source_sp.with_ctxt(ctxt);
|
||||
target_sp.close = source_sp.with_ctxt(ctxt).shrink_to_hi();
|
||||
}
|
||||
_ => {
|
||||
let sp = rhs_tt.span().with_ctxt(ctxt);
|
||||
tt.set_span(sp);
|
||||
|
|
@ -395,7 +402,7 @@ pub fn compile_declarative_macro(
|
|||
};
|
||||
let dummy_syn_ext = || (mk_syn_ext(Box::new(macro_rules_dummy_expander)), Vec::new());
|
||||
|
||||
let diag = &sess.parse_sess.span_diagnostic;
|
||||
let dcx = &sess.parse_sess.dcx;
|
||||
let lhs_nm = Ident::new(sym::lhs, def.span);
|
||||
let rhs_nm = Ident::new(sym::rhs, def.span);
|
||||
let tt_spec = Some(NonterminalKind::TT);
|
||||
|
|
@ -475,14 +482,14 @@ pub fn compile_declarative_macro(
|
|||
|
||||
let s = parse_failure_msg(&token);
|
||||
let sp = token.span.substitute_dummy(def.span);
|
||||
let mut err = sess.diagnostic().struct_span_err(sp, s);
|
||||
let mut err = sess.dcx().struct_span_err(sp, s);
|
||||
err.span_label(sp, msg);
|
||||
annotate_doc_comment(&mut err, sess.source_map(), sp);
|
||||
err.emit();
|
||||
return dummy_syn_ext();
|
||||
}
|
||||
Error(sp, msg) => {
|
||||
sess.diagnostic().struct_span_err(sp.substitute_dummy(def.span), msg).emit();
|
||||
sess.dcx().struct_span_err(sp.substitute_dummy(def.span), msg).emit();
|
||||
return dummy_syn_ext();
|
||||
}
|
||||
ErrorReported(_) => {
|
||||
|
|
@ -511,10 +518,10 @@ pub fn compile_declarative_macro(
|
|||
valid &= check_lhs_nt_follows(&sess.parse_sess, def, &tt);
|
||||
return tt;
|
||||
}
|
||||
sess.diagnostic().span_bug(def.span, "wrong-structured lhs")
|
||||
sess.dcx().span_bug(def.span, "wrong-structured lhs")
|
||||
})
|
||||
.collect::<Vec<mbe::TokenTree>>(),
|
||||
_ => sess.diagnostic().span_bug(def.span, "wrong-structured lhs"),
|
||||
_ => sess.dcx().span_bug(def.span, "wrong-structured lhs"),
|
||||
};
|
||||
|
||||
let rhses = match &argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] {
|
||||
|
|
@ -533,10 +540,10 @@ pub fn compile_declarative_macro(
|
|||
.pop()
|
||||
.unwrap();
|
||||
}
|
||||
sess.diagnostic().span_bug(def.span, "wrong-structured rhs")
|
||||
sess.dcx().span_bug(def.span, "wrong-structured rhs")
|
||||
})
|
||||
.collect::<Vec<mbe::TokenTree>>(),
|
||||
_ => sess.diagnostic().span_bug(def.span, "wrong-structured rhs"),
|
||||
_ => sess.dcx().span_bug(def.span, "wrong-structured rhs"),
|
||||
};
|
||||
|
||||
for rhs in &rhses {
|
||||
|
|
@ -553,10 +560,10 @@ pub fn compile_declarative_macro(
|
|||
let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules);
|
||||
match transparency_error {
|
||||
Some(TransparencyError::UnknownTransparency(value, span)) => {
|
||||
diag.span_err(span, format!("unknown macro transparency: `{value}`"));
|
||||
dcx.span_err(span, format!("unknown macro transparency: `{value}`"));
|
||||
}
|
||||
Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => {
|
||||
diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes");
|
||||
dcx.span_err(vec![old_span, new_span], "multiple macro transparency attributes");
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
@ -592,7 +599,7 @@ pub fn compile_declarative_macro(
|
|||
mbe::TokenTree::Delimited(.., delimited) => {
|
||||
mbe::macro_parser::compute_locs(&delimited.tts)
|
||||
}
|
||||
_ => sess.diagnostic().span_bug(def.span, "malformed macro lhs"),
|
||||
_ => sess.dcx().span_bug(def.span, "malformed macro lhs"),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
|
@ -619,7 +626,7 @@ fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree)
|
|||
check_matcher(sess, def, &delimited.tts)
|
||||
} else {
|
||||
let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
|
||||
sess.span_diagnostic.span_err(lhs.span(), msg);
|
||||
sess.dcx.span_err(lhs.span(), msg);
|
||||
false
|
||||
}
|
||||
// we don't abort on errors on rejection, the driver will do that for us
|
||||
|
|
@ -645,8 +652,7 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool
|
|||
iter.next();
|
||||
}
|
||||
let span = t.span.to(now.span);
|
||||
sess.span_diagnostic
|
||||
.span_note(span, "doc comments are ignored in matcher position");
|
||||
sess.dcx.span_note(span, "doc comments are ignored in matcher position");
|
||||
}
|
||||
mbe::TokenTree::Sequence(_, sub_seq)
|
||||
if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|
||||
|
|
@ -676,7 +682,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
|
|||
TokenTree::Sequence(span, seq) => {
|
||||
if is_empty_token_tree(sess, seq) {
|
||||
let sp = span.entire();
|
||||
sess.span_diagnostic.span_err(sp, "repetition matches empty token tree");
|
||||
sess.dcx.span_err(sp, "repetition matches empty token tree");
|
||||
return false;
|
||||
}
|
||||
if !check_lhs_no_empty_seq(sess, &seq.tts) {
|
||||
|
|
@ -693,7 +699,7 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
|
|||
match *rhs {
|
||||
mbe::TokenTree::Delimited(..) => return true,
|
||||
_ => {
|
||||
sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited");
|
||||
sess.dcx.span_err(rhs.span(), "macro rhs must be delimited");
|
||||
}
|
||||
}
|
||||
false
|
||||
|
|
@ -702,9 +708,9 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
|
|||
fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
|
||||
let first_sets = FirstSets::new(matcher);
|
||||
let empty_suffix = TokenSet::empty();
|
||||
let err = sess.span_diagnostic.err_count();
|
||||
let err = sess.dcx.err_count();
|
||||
check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix);
|
||||
err == sess.span_diagnostic.err_count()
|
||||
err == sess.dcx.err_count()
|
||||
}
|
||||
|
||||
fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
|
||||
|
|
@ -1183,7 +1189,7 @@ fn check_matcher_core<'tt>(
|
|||
};
|
||||
|
||||
let sp = next_token.span();
|
||||
let mut err = sess.span_diagnostic.struct_span_err(
|
||||
let mut err = sess.dcx.struct_span_err(
|
||||
sp,
|
||||
format!(
|
||||
"`${name}:{frag}` {may_be} followed by `{next}`, which \
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ impl MetaVarExpr {
|
|||
let ident = parse_ident(&mut tts, sess, outer_span)?;
|
||||
let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = tts.next() else {
|
||||
let msg = "meta-variable expression parameter must be wrapped in parentheses";
|
||||
return Err(sess.span_diagnostic.struct_span_err(ident.span, msg));
|
||||
return Err(sess.dcx.struct_span_err(ident.span, msg));
|
||||
};
|
||||
check_trailing_token(&mut tts, sess)?;
|
||||
let mut iter = args.trees();
|
||||
|
|
@ -50,7 +50,7 @@ impl MetaVarExpr {
|
|||
"length" => MetaVarExpr::Length(parse_depth(&mut iter, sess, ident.span)?),
|
||||
_ => {
|
||||
let err_msg = "unrecognized meta-variable expression";
|
||||
let mut err = sess.span_diagnostic.struct_span_err(ident.span, err_msg);
|
||||
let mut err = sess.dcx.struct_span_err(ident.span, err_msg);
|
||||
err.span_suggestion(
|
||||
ident.span,
|
||||
"supported expressions are count, ignore, index and length",
|
||||
|
|
@ -79,7 +79,7 @@ fn check_trailing_token<'sess>(
|
|||
) -> PResult<'sess, ()> {
|
||||
if let Some(tt) = iter.next() {
|
||||
let mut diag = sess
|
||||
.span_diagnostic
|
||||
.dcx
|
||||
.struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt)));
|
||||
diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens");
|
||||
Err(diag)
|
||||
|
|
@ -98,7 +98,7 @@ fn parse_count<'sess>(
|
|||
let ident = parse_ident(iter, sess, span)?;
|
||||
let depth = if try_eat_comma(iter) {
|
||||
if iter.look_ahead(0).is_none() {
|
||||
return Err(sess.span_diagnostic.struct_span_err(
|
||||
return Err(sess.dcx.struct_span_err(
|
||||
span,
|
||||
"`count` followed by a comma must have an associated index indicating its depth",
|
||||
));
|
||||
|
|
@ -119,7 +119,7 @@ fn parse_depth<'sess>(
|
|||
let Some(tt) = iter.next() else { return Ok(0) };
|
||||
let TokenTree::Token(token::Token { kind: token::TokenKind::Literal(lit), .. }, _) = tt else {
|
||||
return Err(sess
|
||||
.span_diagnostic
|
||||
.dcx
|
||||
.struct_span_err(span, "meta-variable expression depth must be a literal"));
|
||||
};
|
||||
if let Ok(lit_kind) = LitKind::from_token_lit(*lit)
|
||||
|
|
@ -129,7 +129,7 @@ fn parse_depth<'sess>(
|
|||
Ok(n_usize)
|
||||
} else {
|
||||
let msg = "only unsuffixes integer literals are supported in meta-variable expressions";
|
||||
Err(sess.span_diagnostic.struct_span_err(span, msg))
|
||||
Err(sess.dcx.struct_span_err(span, msg))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -146,9 +146,8 @@ fn parse_ident<'sess>(
|
|||
return Ok(elem);
|
||||
}
|
||||
let token_str = pprust::token_to_string(token);
|
||||
let mut err = sess
|
||||
.span_diagnostic
|
||||
.struct_span_err(span, format!("expected identifier, found `{}`", &token_str));
|
||||
let mut err =
|
||||
sess.dcx.struct_span_err(span, format!("expected identifier, found `{}`", &token_str));
|
||||
err.span_suggestion(
|
||||
token.span,
|
||||
format!("try removing `{}`", &token_str),
|
||||
|
|
@ -157,7 +156,7 @@ fn parse_ident<'sess>(
|
|||
);
|
||||
return Err(err);
|
||||
}
|
||||
Err(sess.span_diagnostic.struct_span_err(span, "expected identifier"))
|
||||
Err(sess.dcx.struct_span_err(span, "expected identifier"))
|
||||
}
|
||||
|
||||
/// Tries to move the iterator forward returning `true` if there is a comma. If not, then the
|
||||
|
|
@ -181,7 +180,7 @@ fn eat_dollar<'sess>(
|
|||
let _ = iter.next();
|
||||
return Ok(());
|
||||
}
|
||||
Err(sess.span_diagnostic.struct_span_err(
|
||||
Err(sess.dcx.struct_span_err(
|
||||
span,
|
||||
"meta-variables within meta-variable expressions must be referenced using a dollar sign",
|
||||
))
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ pub(super) fn parse(
|
|||
"invalid fragment specifier `{}`",
|
||||
frag.name
|
||||
);
|
||||
sess.span_diagnostic
|
||||
sess.dcx
|
||||
.struct_span_err(span, msg)
|
||||
.help(VALID_FRAGMENT_NAMES_MSG)
|
||||
.emit();
|
||||
|
|
@ -195,7 +195,7 @@ fn parse_tree<'a>(
|
|||
_ => {
|
||||
let tok = pprust::token_kind_to_string(&token::OpenDelim(delim));
|
||||
let msg = format!("expected `(` or `{{`, found `{tok}`");
|
||||
sess.span_diagnostic.span_err(delim_span.entire(), msg);
|
||||
sess.dcx.span_err(delim_span.entire(), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -244,7 +244,7 @@ fn parse_tree<'a>(
|
|||
Some(tokenstream::TokenTree::Token(token, _)) => {
|
||||
let msg =
|
||||
format!("expected identifier, found `{}`", pprust::token_to_string(token),);
|
||||
sess.span_diagnostic.span_err(token.span, msg);
|
||||
sess.dcx.span_err(token.span, msg);
|
||||
TokenTree::MetaVar(token.span, Ident::empty())
|
||||
}
|
||||
|
||||
|
|
@ -325,7 +325,7 @@ fn parse_sep_and_kleene_op<'a>(
|
|||
// #2 is the `?` Kleene op, which does not take a separator (error)
|
||||
Ok(Ok((KleeneOp::ZeroOrOne, span))) => {
|
||||
// Error!
|
||||
sess.span_diagnostic.span_err(
|
||||
sess.dcx.span_err(
|
||||
token.span,
|
||||
"the `?` macro repetition operator does not take a separator",
|
||||
);
|
||||
|
|
@ -346,7 +346,7 @@ fn parse_sep_and_kleene_op<'a>(
|
|||
};
|
||||
|
||||
// If we ever get to this point, we have experienced an "unexpected token" error
|
||||
sess.span_diagnostic.span_err(span, "expected one of: `*`, `+`, or `?`");
|
||||
sess.dcx.span_err(span, "expected one of: `*`, `+`, or `?`");
|
||||
|
||||
// Return a dummy
|
||||
(None, KleeneToken::new(KleeneOp::ZeroOrMore, span))
|
||||
|
|
@ -356,9 +356,8 @@ fn parse_sep_and_kleene_op<'a>(
|
|||
//
|
||||
// For example, `macro_rules! foo { ( ${length()} ) => {} }`
|
||||
fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) {
|
||||
sess.span_diagnostic
|
||||
.span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
|
||||
sess.span_diagnostic.span_note(
|
||||
sess.dcx.span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
|
||||
sess.dcx.span_note(
|
||||
token.span,
|
||||
"`$$` and meta-variable expressions are not allowed inside macro parameter definitions",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ impl MultiItemModifier for DeriveProcMacro {
|
|||
}
|
||||
};
|
||||
|
||||
let error_count_before = ecx.sess.diagnostic().err_count();
|
||||
let error_count_before = ecx.sess.dcx().err_count();
|
||||
let mut parser =
|
||||
rustc_parse::stream_to_parser(&ecx.sess.parse_sess, stream, Some("proc-macro derive"));
|
||||
let mut items = vec![];
|
||||
|
|
@ -179,7 +179,7 @@ impl MultiItemModifier for DeriveProcMacro {
|
|||
}
|
||||
|
||||
// fail if there have been errors emitted
|
||||
if ecx.sess.diagnostic().err_count() > error_count_before {
|
||||
if ecx.sess.dcx().err_count() > error_count_before {
|
||||
ecx.sess.emit_err(errors::ProcMacroDeriveTokens { span });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -426,6 +426,10 @@ impl server::Types for Rustc<'_, '_> {
|
|||
}
|
||||
|
||||
impl server::FreeFunctions for Rustc<'_, '_> {
|
||||
fn injected_env_var(&mut self, var: &str) -> Option<String> {
|
||||
self.ecx.sess.opts.logical_env.get(var).cloned()
|
||||
}
|
||||
|
||||
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
|
||||
self.sess()
|
||||
.env_depinfo
|
||||
|
|
@ -502,7 +506,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
|
|||
None,
|
||||
);
|
||||
}
|
||||
self.sess().span_diagnostic.emit_diagnostic(diag);
|
||||
self.sess().dcx.emit_diagnostic(diag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_span::{BytePos, Span};
|
|||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::emitter::EmitterWriter;
|
||||
use rustc_errors::{Handler, MultiSpan, PResult};
|
||||
use rustc_errors::{DiagCtxt, MultiSpan, PResult};
|
||||
use termcolor::WriteColor;
|
||||
|
||||
use std::io;
|
||||
|
|
@ -23,7 +23,7 @@ fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> {
|
|||
new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str)
|
||||
}
|
||||
|
||||
fn create_test_handler() -> (Handler, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
|
||||
fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
|
||||
let output = Arc::new(Mutex::new(Vec::new()));
|
||||
let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
|
||||
|
|
@ -33,8 +33,8 @@ fn create_test_handler() -> (Handler, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
|
|||
let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
|
||||
.sm(Some(source_map.clone()))
|
||||
.diagnostic_width(Some(140));
|
||||
let handler = Handler::with_emitter(Box::new(emitter));
|
||||
(handler, source_map, output)
|
||||
let dcx = DiagCtxt::with_emitter(Box::new(emitter));
|
||||
(dcx, source_map, output)
|
||||
}
|
||||
|
||||
/// Returns the result of parsing the given string via the given callback.
|
||||
|
|
@ -46,7 +46,7 @@ where
|
|||
{
|
||||
let mut p = string_to_parser(&ps, s);
|
||||
let x = f(&mut p).unwrap();
|
||||
p.sess.span_diagnostic.abort_if_errors();
|
||||
p.sess.dcx.abort_if_errors();
|
||||
x
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ where
|
|||
F: for<'a> FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
{
|
||||
let (handler, source_map, output) = create_test_handler();
|
||||
let ps = ParseSess::with_span_handler(handler, source_map);
|
||||
let ps = ParseSess::with_dcx(handler, source_map);
|
||||
let mut p = string_to_parser(&ps, source_str.to_string());
|
||||
let result = f(&mut p);
|
||||
assert!(result.is_ok());
|
||||
|
|
|
|||
|
|
@ -435,8 +435,6 @@ pub enum TraitBoundModifier {
|
|||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||
pub enum GenericBound<'hir> {
|
||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
||||
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
|
||||
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
|
||||
Outlives(&'hir Lifetime),
|
||||
}
|
||||
|
||||
|
|
@ -451,7 +449,6 @@ impl GenericBound<'_> {
|
|||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
GenericBound::Trait(t, ..) => t.span,
|
||||
GenericBound::LangItemTrait(_, span, ..) => *span,
|
||||
GenericBound::Outlives(l) => l.ident.span,
|
||||
}
|
||||
}
|
||||
|
|
@ -1560,7 +1557,7 @@ impl Expr<'_> {
|
|||
ExprKind::Call(..) => ExprPrecedence::Call,
|
||||
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
|
||||
ExprKind::Tup(_) => ExprPrecedence::Tup,
|
||||
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node.into()),
|
||||
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
|
||||
ExprKind::Unary(..) => ExprPrecedence::Unary,
|
||||
ExprKind::Lit(_) => ExprPrecedence::Lit,
|
||||
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
|
||||
|
|
@ -1700,11 +1697,9 @@ impl Expr<'_> {
|
|||
// them being used only for its side-effects.
|
||||
base.can_have_side_effects()
|
||||
}
|
||||
ExprKind::Struct(_, fields, init) => fields
|
||||
.iter()
|
||||
.map(|field| field.expr)
|
||||
.chain(init.into_iter())
|
||||
.any(|e| e.can_have_side_effects()),
|
||||
ExprKind::Struct(_, fields, init) => {
|
||||
fields.iter().map(|field| field.expr).chain(init).any(|e| e.can_have_side_effects())
|
||||
}
|
||||
|
||||
ExprKind::Array(args)
|
||||
| ExprKind::Tup(args)
|
||||
|
|
@ -2815,7 +2810,7 @@ impl TraitRef<'_> {
|
|||
match self.path.res {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
|
||||
Res::Err => None,
|
||||
_ => unreachable!(),
|
||||
res => panic!("{res:?} did not resolve to a trait or trait alias"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
|
|||
GenericBound::Trait(ref typ, _modifier) => {
|
||||
visitor.visit_poly_trait_ref(typ);
|
||||
}
|
||||
GenericBound::LangItemTrait(_, _span, hir_id, args) => {
|
||||
visitor.visit_id(hir_id);
|
||||
visitor.visit_generic_args(args);
|
||||
}
|
||||
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,42 @@ impl Display for Target {
|
|||
}
|
||||
|
||||
impl Target {
|
||||
pub fn is_associated_item(self) -> bool {
|
||||
match self {
|
||||
Target::AssocConst | Target::AssocTy | Target::Method(_) => true,
|
||||
Target::ExternCrate
|
||||
| Target::Use
|
||||
| Target::Static
|
||||
| Target::Const
|
||||
| Target::Fn
|
||||
| Target::Closure
|
||||
| Target::Mod
|
||||
| Target::ForeignMod
|
||||
| Target::GlobalAsm
|
||||
| Target::TyAlias
|
||||
| Target::OpaqueTy
|
||||
| Target::Enum
|
||||
| Target::Variant
|
||||
| Target::Struct
|
||||
| Target::Field
|
||||
| Target::Union
|
||||
| Target::Trait
|
||||
| Target::TraitAlias
|
||||
| Target::Impl
|
||||
| Target::Expression
|
||||
| Target::Statement
|
||||
| Target::Arm
|
||||
| Target::ForeignFn
|
||||
| Target::ForeignStatic
|
||||
| Target::ForeignTy
|
||||
| Target::GenericParam(_)
|
||||
| Target::MacroDef
|
||||
| Target::Param
|
||||
| Target::PatField
|
||||
| Target::ExprField => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_item(item: &Item<'_>) -> Target {
|
||||
match item.kind {
|
||||
ItemKind::ExternCrate(..) => Target::ExternCrate,
|
||||
|
|
|
|||
|
|
@ -134,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||
self.instantiate_lang_item_trait_ref(
|
||||
lang_item,
|
||||
span,
|
||||
hir_id,
|
||||
args,
|
||||
param_ty,
|
||||
bounds,
|
||||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Outlives(lifetime) => {
|
||||
let region = self.ast_region_to_region(lifetime, None);
|
||||
bounds.push_region_bound(
|
||||
|
|
|
|||
|
|
@ -661,7 +661,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
|
|||
args.args[0].hir_id(),
|
||||
multispan,
|
||||
msg,
|
||||
|lint| lint,
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
Applicability::MachineApplicable,
|
||||
);
|
||||
self.maybe_lint_blanket_trait_impl(self_ty, lint);
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -477,7 +477,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
ty::Const::new_misc_error(tcx, ty).into()
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
(kind, arg) => span_bug!(
|
||||
self.span,
|
||||
"mismatched path argument for kind {kind:?}: found arg {arg:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -675,36 +678,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
)
|
||||
}
|
||||
|
||||
fn instantiate_poly_trait_ref_inner(
|
||||
/// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
|
||||
/// a full trait reference. The resulting trait reference is returned. This may also generate
|
||||
/// auxiliary bounds, which are added to `bounds`.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// poly_trait_ref = Iterator<Item = u32>
|
||||
/// self_ty = Foo
|
||||
/// ```
|
||||
///
|
||||
/// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
|
||||
///
|
||||
/// **A note on binders:** against our usual convention, there is an implied binder around
|
||||
/// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
|
||||
/// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
|
||||
/// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
|
||||
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
|
||||
/// however.
|
||||
#[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
|
||||
pub(crate) fn instantiate_poly_trait_ref(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
binding_span: Option<Span>,
|
||||
constness: ty::BoundConstness,
|
||||
polarity: ty::ImplPolarity,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
trait_ref_span: Span,
|
||||
trait_def_id: DefId,
|
||||
trait_segment: &hir::PathSegment<'_>,
|
||||
args: &GenericArgs<'_>,
|
||||
infer_args: bool,
|
||||
self_ty: Ty<'tcx>,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> GenericArgCountResult {
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
let trait_segment = trait_ref.path.segments.last().unwrap();
|
||||
let args = trait_segment.args();
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
|
||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
|
||||
|
||||
let (generic_args, arg_count) = self.create_args_for_ast_path(
|
||||
trait_ref_span,
|
||||
trait_ref.path.span,
|
||||
trait_def_id,
|
||||
&[],
|
||||
trait_segment,
|
||||
args,
|
||||
infer_args,
|
||||
trait_segment.infer_args,
|
||||
Some(self_ty),
|
||||
constness,
|
||||
);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
||||
|
|
@ -732,13 +756,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding(
|
||||
hir_id,
|
||||
trait_ref.hir_ref_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding_span.unwrap_or(binding.span),
|
||||
binding.span,
|
||||
constness,
|
||||
only_self_bounds,
|
||||
polarity,
|
||||
|
|
@ -749,102 +773,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
arg_count
|
||||
}
|
||||
|
||||
/// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
|
||||
/// a full trait reference. The resulting trait reference is returned. This may also generate
|
||||
/// auxiliary bounds, which are added to `bounds`.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// poly_trait_ref = Iterator<Item = u32>
|
||||
/// self_ty = Foo
|
||||
/// ```
|
||||
///
|
||||
/// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
|
||||
///
|
||||
/// **A note on binders:** against our usual convention, there is an implied bounder around
|
||||
/// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
|
||||
/// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
|
||||
/// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
|
||||
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
|
||||
/// however.
|
||||
#[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
|
||||
pub(crate) fn instantiate_poly_trait_ref(
|
||||
&self,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
constness: ty::BoundConstness,
|
||||
polarity: ty::ImplPolarity,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> GenericArgCountResult {
|
||||
let hir_id = trait_ref.hir_ref_id;
|
||||
let binding_span = None;
|
||||
let trait_ref_span = trait_ref.path.span;
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
let trait_segment = trait_ref.path.segments.last().unwrap();
|
||||
let args = trait_segment.args();
|
||||
let infer_args = trait_segment.infer_args;
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
|
||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
|
||||
|
||||
self.instantiate_poly_trait_ref_inner(
|
||||
hir_id,
|
||||
span,
|
||||
binding_span,
|
||||
constness,
|
||||
polarity,
|
||||
bounds,
|
||||
speculative,
|
||||
trait_ref_span,
|
||||
trait_def_id,
|
||||
trait_segment,
|
||||
args,
|
||||
infer_args,
|
||||
self_ty,
|
||||
only_self_bounds,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn instantiate_lang_item_trait_ref(
|
||||
&self,
|
||||
lang_item: hir::LangItem,
|
||||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
args: &GenericArgs<'_>,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) {
|
||||
let binding_span = Some(span);
|
||||
let constness = ty::BoundConstness::NotConst;
|
||||
let speculative = false;
|
||||
let trait_ref_span = span;
|
||||
let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
|
||||
let trait_segment = &hir::PathSegment::invalid();
|
||||
let infer_args = false;
|
||||
|
||||
self.instantiate_poly_trait_ref_inner(
|
||||
hir_id,
|
||||
span,
|
||||
binding_span,
|
||||
constness,
|
||||
ty::ImplPolarity::Positive,
|
||||
bounds,
|
||||
speculative,
|
||||
trait_ref_span,
|
||||
trait_def_id,
|
||||
trait_segment,
|
||||
args,
|
||||
infer_args,
|
||||
self_ty,
|
||||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
|
||||
fn ast_path_to_mono_trait_ref(
|
||||
&self,
|
||||
span: Span,
|
||||
|
|
@ -1506,8 +1434,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -1946,7 +1872,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
"s",
|
||||
),
|
||||
[only] => (only.to_string(), ""),
|
||||
[] => unreachable!(),
|
||||
[] => unreachable!("expected at least one generic to prohibit"),
|
||||
};
|
||||
let last_span = *arg_spans.last().unwrap();
|
||||
let span: MultiSpan = arg_spans.into();
|
||||
|
|
@ -2555,8 +2481,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len())
|
||||
{
|
||||
// Resolve our own lifetime parameters.
|
||||
let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
|
||||
let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
|
||||
let GenericParamDefKind::Lifetime { .. } = param.kind else {
|
||||
span_bug!(
|
||||
tcx.def_span(param.def_id),
|
||||
"only expected lifetime for opaque's own generics, got {:?}",
|
||||
param.kind
|
||||
);
|
||||
};
|
||||
let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else {
|
||||
bug!(
|
||||
"expected lifetime argument for param {param:?}, found {:?}",
|
||||
&lifetimes[i]
|
||||
)
|
||||
};
|
||||
self.ast_region_to_region(lifetime, None).into()
|
||||
} else {
|
||||
tcx.mk_param_from_def(param)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
| ty::ClauseKind::ConstArgHasType(..)
|
||||
| ty::ClauseKind::WellFormed(_)
|
||||
| ty::ClauseKind::ConstEvaluatable(_) => {
|
||||
bug!()
|
||||
span_bug!(span, "did not expect {pred} clause in object bounds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
|
|||
hir_id,
|
||||
span,
|
||||
"use of calling convention not supported on this target",
|
||||
|lint| lint,
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -190,7 +190,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
"static of uninhabited type",
|
||||
|lint| {
|
||||
lint
|
||||
.note("uninhabited statics cannot be initialized, and any access would be an immediate error")
|
||||
.note("uninhabited statics cannot be initialized, and any access would be an immediate error");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -1093,7 +1093,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
|||
"this {descr} contains `{field_ty}`, which {note}, \
|
||||
and makes it not a breaking change to become \
|
||||
non-zero-sized in the future."
|
||||
))
|
||||
));
|
||||
},
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ use super::potentially_plural_count;
|
|||
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
|
||||
use hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||
use rustc_errors::{
|
||||
pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed, MultiSpan,
|
||||
};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::intravisit;
|
||||
|
|
@ -50,13 +48,7 @@ pub(super) fn compare_impl_method<'tcx>(
|
|||
|
||||
let _: Result<_, ErrorGuaranteed> = try {
|
||||
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
|
||||
compare_method_predicate_entailment(
|
||||
tcx,
|
||||
impl_m,
|
||||
trait_m,
|
||||
impl_trait_ref,
|
||||
CheckImpliedWfMode::Check,
|
||||
)?;
|
||||
compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
|
||||
refine::check_refining_return_position_impl_trait_in_trait(
|
||||
tcx,
|
||||
impl_m,
|
||||
|
|
@ -170,7 +162,6 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
check_implied_wf: CheckImpliedWfMode,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let trait_to_impl_args = impl_trait_ref.args;
|
||||
|
||||
|
|
@ -317,7 +308,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
return Err(emitted);
|
||||
}
|
||||
|
||||
if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
|
||||
if !(impl_sig, trait_sig).references_error() {
|
||||
// Select obligations to make progress on inference before processing
|
||||
// the wf obligation below.
|
||||
// FIXME(-Znext-solver): Not needed when the hack below is removed.
|
||||
|
|
@ -333,8 +324,9 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
// trigger the lint. Instead, let's only consider type outlives and
|
||||
// region outlives obligations.
|
||||
//
|
||||
// FIXME(-Znext-solver): Try removing this hack again once
|
||||
// the new solver is stable.
|
||||
// FIXME(-Znext-solver): Try removing this hack again once the new
|
||||
// solver is stable. We should just be able to register a WF pred for
|
||||
// the fn sig.
|
||||
let mut wf_args: smallvec::SmallVec<[_; 4]> =
|
||||
unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
|
||||
// Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
|
||||
|
|
@ -357,7 +349,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
// We need to register Projection oblgiations too, because we may end up with
|
||||
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
|
||||
// If we only register the region outlives obligation, this leads to an unconstrained var.
|
||||
// See `implied_bounds_entailment_alias_var` test.
|
||||
// See `implied_bounds_entailment_alias_var.rs` test.
|
||||
ty::PredicateKind::Clause(
|
||||
ty::ClauseKind::RegionOutlives(..)
|
||||
| ty::ClauseKind::TypeOutlives(..)
|
||||
|
|
@ -378,26 +370,8 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
// version.
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
match check_implied_wf {
|
||||
CheckImpliedWfMode::Check => {
|
||||
let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
|
||||
return compare_method_predicate_entailment(
|
||||
tcx,
|
||||
impl_m,
|
||||
trait_m,
|
||||
impl_trait_ref,
|
||||
CheckImpliedWfMode::Skip,
|
||||
)
|
||||
.map(|()| {
|
||||
// If the skip-mode was successful, emit a lint.
|
||||
emit_implied_wf_lint(infcx.tcx, impl_m, impl_m_hir_id, vec![]);
|
||||
});
|
||||
}
|
||||
CheckImpliedWfMode::Skip => {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
}
|
||||
}
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
}
|
||||
|
||||
// Finally, resolve all regions. This catches wily misuses of
|
||||
|
|
@ -408,119 +382,14 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
);
|
||||
let errors = infcx.resolve_regions(&outlives_env);
|
||||
if !errors.is_empty() {
|
||||
// FIXME(compiler-errors): This can be simplified when IMPLIED_BOUNDS_ENTAILMENT
|
||||
// becomes a hard error (i.e. ideally we'd just call `resolve_regions_and_report_errors`
|
||||
let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
|
||||
match check_implied_wf {
|
||||
CheckImpliedWfMode::Check => {
|
||||
return compare_method_predicate_entailment(
|
||||
tcx,
|
||||
impl_m,
|
||||
trait_m,
|
||||
impl_trait_ref,
|
||||
CheckImpliedWfMode::Skip,
|
||||
)
|
||||
.map(|()| {
|
||||
let bad_args = extract_bad_args_for_implies_lint(
|
||||
tcx,
|
||||
&errors,
|
||||
(trait_m, trait_sig),
|
||||
// Unnormalized impl sig corresponds to the HIR types written
|
||||
(impl_m, unnormalized_impl_sig),
|
||||
impl_m_hir_id,
|
||||
);
|
||||
// If the skip-mode was successful, emit a lint.
|
||||
emit_implied_wf_lint(tcx, impl_m, impl_m_hir_id, bad_args);
|
||||
});
|
||||
}
|
||||
CheckImpliedWfMode::Skip => {
|
||||
if infcx.tainted_by_errors().is_none() {
|
||||
infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors);
|
||||
}
|
||||
return Err(tcx
|
||||
.sess
|
||||
.span_delayed_bug(rustc_span::DUMMY_SP, "error should have been emitted"));
|
||||
}
|
||||
}
|
||||
return Err(infcx
|
||||
.tainted_by_errors()
|
||||
.unwrap_or_else(|| infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn extract_bad_args_for_implies_lint<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
errors: &[infer::RegionResolutionError<'tcx>],
|
||||
(trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
|
||||
hir_id: hir::HirId,
|
||||
) -> Vec<(Span, Option<String>)> {
|
||||
let mut blame_generics = vec![];
|
||||
for error in errors {
|
||||
// Look for the subregion origin that contains an input/output type
|
||||
let origin = match error {
|
||||
infer::RegionResolutionError::ConcreteFailure(o, ..) => o,
|
||||
infer::RegionResolutionError::GenericBoundFailure(o, ..) => o,
|
||||
infer::RegionResolutionError::SubSupConflict(_, _, o, ..) => o,
|
||||
infer::RegionResolutionError::UpperBoundUniverseConflict(.., o, _) => o,
|
||||
};
|
||||
// Extract (possible) input/output types from origin
|
||||
match origin {
|
||||
infer::SubregionOrigin::Subtype(trace) => {
|
||||
if let Some((a, b)) = trace.values.ty() {
|
||||
blame_generics.extend([a, b]);
|
||||
}
|
||||
}
|
||||
infer::SubregionOrigin::RelateParamBound(_, ty, _) => blame_generics.push(*ty),
|
||||
infer::SubregionOrigin::ReferenceOutlivesReferent(ty, _) => blame_generics.push(*ty),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let fn_decl = tcx.hir().fn_decl_by_hir_id(hir_id).unwrap();
|
||||
let opt_ret_ty = match fn_decl.output {
|
||||
hir::FnRetTy::DefaultReturn(_) => None,
|
||||
hir::FnRetTy::Return(ty) => Some(ty),
|
||||
};
|
||||
|
||||
// Map late-bound regions from trait to impl, so the names are right.
|
||||
let mapping = std::iter::zip(
|
||||
tcx.fn_sig(trait_m.def_id).skip_binder().bound_vars(),
|
||||
tcx.fn_sig(impl_m.def_id).skip_binder().bound_vars(),
|
||||
)
|
||||
.filter_map(|(impl_bv, trait_bv)| {
|
||||
if let ty::BoundVariableKind::Region(impl_bv) = impl_bv
|
||||
&& let ty::BoundVariableKind::Region(trait_bv) = trait_bv
|
||||
{
|
||||
Some((impl_bv, trait_bv))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// For each arg, see if it was in the "blame" of any of the region errors.
|
||||
// If so, then try to produce a suggestion to replace the argument type with
|
||||
// one from the trait.
|
||||
let mut bad_args = vec![];
|
||||
for (idx, (ty, hir_ty)) in
|
||||
std::iter::zip(impl_sig.inputs_and_output, fn_decl.inputs.iter().chain(opt_ret_ty))
|
||||
.enumerate()
|
||||
{
|
||||
let expected_ty = trait_sig.inputs_and_output[idx]
|
||||
.fold_with(&mut RemapLateBound { tcx, mapping: &mapping });
|
||||
if blame_generics.iter().any(|blame| ty.contains(*blame)) {
|
||||
let expected_ty_sugg = expected_ty.to_string();
|
||||
bad_args.push((
|
||||
hir_ty.span,
|
||||
// Only suggest something if it actually changed.
|
||||
(expected_ty_sugg != ty.to_string()).then_some(expected_ty_sugg),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
bad_args
|
||||
}
|
||||
|
||||
struct RemapLateBound<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>,
|
||||
|
|
@ -544,53 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_implied_wf_lint<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: ty::AssocItem,
|
||||
hir_id: hir::HirId,
|
||||
bad_args: Vec<(Span, Option<String>)>,
|
||||
) {
|
||||
let span: MultiSpan = if bad_args.is_empty() {
|
||||
tcx.def_span(impl_m.def_id).into()
|
||||
} else {
|
||||
bad_args.iter().map(|(span, _)| *span).collect::<Vec<_>>().into()
|
||||
};
|
||||
tcx.struct_span_lint_hir(
|
||||
rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT,
|
||||
hir_id,
|
||||
span,
|
||||
"impl method assumes more implied bounds than the corresponding trait method",
|
||||
|lint| {
|
||||
let bad_args: Vec<_> =
|
||||
bad_args.into_iter().filter_map(|(span, sugg)| Some((span, sugg?))).collect();
|
||||
if !bad_args.is_empty() {
|
||||
lint.multipart_suggestion(
|
||||
format!(
|
||||
"replace {} type{} to make the impl signature compatible",
|
||||
pluralize!("this", bad_args.len()),
|
||||
pluralize!(bad_args.len())
|
||||
),
|
||||
bad_args,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum CheckImpliedWfMode {
|
||||
/// Checks implied well-formedness of the impl method. If it fails, we will
|
||||
/// re-check with `Skip`, and emit a lint if it succeeds.
|
||||
Check,
|
||||
/// Skips checking implied well-formedness of the impl method, but will emit
|
||||
/// a lint if the `compare_method_predicate_entailment` succeeded. This means that
|
||||
/// the reason that we had failed earlier during `Check` was due to the impl
|
||||
/// having stronger requirements than the trait.
|
||||
Skip,
|
||||
}
|
||||
|
||||
fn compare_asyncness<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: ty::AssocItem,
|
||||
|
|
@ -1086,8 +908,14 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
|||
_ => return Ok(region),
|
||||
}
|
||||
|
||||
let e = if let Some(region) = self.map.get(®ion) {
|
||||
if let ty::ReEarlyParam(e) = region.kind() { e } else { bug!() }
|
||||
let e = if let Some(id_region) = self.map.get(®ion) {
|
||||
if let ty::ReEarlyParam(e) = id_region.kind() {
|
||||
e
|
||||
} else {
|
||||
bug!(
|
||||
"expected to map region {region} to early-bound identity region, but got {id_region}"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let guar = match region.kind() {
|
||||
ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
|
||||
|
|
@ -1710,92 +1538,87 @@ fn compare_synthetic_generics<'tcx>(
|
|||
trait_m.name
|
||||
);
|
||||
err.span_label(trait_span, "declaration in trait here");
|
||||
match (impl_synthetic, trait_synthetic) {
|
||||
if impl_synthetic {
|
||||
// The case where the impl method uses `impl Trait` but the trait method uses
|
||||
// explicit generics
|
||||
(true, false) => {
|
||||
err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
|
||||
let _: Option<_> = try {
|
||||
// try taking the name from the trait impl
|
||||
// FIXME: this is obviously suboptimal since the name can already be used
|
||||
// as another generic argument
|
||||
let new_name = tcx.opt_item_name(trait_def_id)?;
|
||||
let trait_m = trait_m.def_id.as_local()?;
|
||||
let trait_m = tcx.hir().expect_trait_item(trait_m);
|
||||
err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
|
||||
let _: Option<_> = try {
|
||||
// try taking the name from the trait impl
|
||||
// FIXME: this is obviously suboptimal since the name can already be used
|
||||
// as another generic argument
|
||||
let new_name = tcx.opt_item_name(trait_def_id)?;
|
||||
let trait_m = trait_m.def_id.as_local()?;
|
||||
let trait_m = tcx.hir().expect_trait_item(trait_m);
|
||||
|
||||
let impl_m = impl_m.def_id.as_local()?;
|
||||
let impl_m = tcx.hir().expect_impl_item(impl_m);
|
||||
let impl_m = impl_m.def_id.as_local()?;
|
||||
let impl_m = tcx.hir().expect_impl_item(impl_m);
|
||||
|
||||
// in case there are no generics, take the spot between the function name
|
||||
// and the opening paren of the argument list
|
||||
let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
|
||||
// in case there are generics, just replace them
|
||||
let generics_span =
|
||||
impl_m.generics.span.substitute_dummy(new_generics_span);
|
||||
// replace with the generics from the trait
|
||||
let new_generics =
|
||||
tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
|
||||
// in case there are no generics, take the spot between the function name
|
||||
// and the opening paren of the argument list
|
||||
let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
|
||||
// in case there are generics, just replace them
|
||||
let generics_span = impl_m.generics.span.substitute_dummy(new_generics_span);
|
||||
// replace with the generics from the trait
|
||||
let new_generics =
|
||||
tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
|
||||
|
||||
err.multipart_suggestion(
|
||||
"try changing the `impl Trait` argument to a generic parameter",
|
||||
vec![
|
||||
// replace `impl Trait` with `T`
|
||||
(impl_span, new_name.to_string()),
|
||||
// replace impl method generics with trait method generics
|
||||
// This isn't quite right, as users might have changed the names
|
||||
// of the generics, but it works for the common case
|
||||
(generics_span, new_generics),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
};
|
||||
}
|
||||
err.multipart_suggestion(
|
||||
"try changing the `impl Trait` argument to a generic parameter",
|
||||
vec![
|
||||
// replace `impl Trait` with `T`
|
||||
(impl_span, new_name.to_string()),
|
||||
// replace impl method generics with trait method generics
|
||||
// This isn't quite right, as users might have changed the names
|
||||
// of the generics, but it works for the common case
|
||||
(generics_span, new_generics),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
};
|
||||
} else {
|
||||
// The case where the trait method uses `impl Trait`, but the impl method uses
|
||||
// explicit generics.
|
||||
(false, true) => {
|
||||
err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
|
||||
let _: Option<_> = try {
|
||||
let impl_m = impl_m.def_id.as_local()?;
|
||||
let impl_m = tcx.hir().expect_impl_item(impl_m);
|
||||
let (sig, _) = impl_m.expect_fn();
|
||||
let input_tys = sig.decl.inputs;
|
||||
err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
|
||||
let _: Option<_> = try {
|
||||
let impl_m = impl_m.def_id.as_local()?;
|
||||
let impl_m = tcx.hir().expect_impl_item(impl_m);
|
||||
let (sig, _) = impl_m.expect_fn();
|
||||
let input_tys = sig.decl.inputs;
|
||||
|
||||
struct Visitor(Option<Span>, hir::def_id::LocalDefId);
|
||||
impl<'v> intravisit::Visitor<'v> for Visitor {
|
||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
||||
intravisit::walk_ty(self, ty);
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
|
||||
&& let Res::Def(DefKind::TyParam, def_id) = path.res
|
||||
&& def_id == self.1.to_def_id()
|
||||
{
|
||||
self.0 = Some(ty.span);
|
||||
}
|
||||
struct Visitor(Option<Span>, hir::def_id::LocalDefId);
|
||||
impl<'v> intravisit::Visitor<'v> for Visitor {
|
||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
||||
intravisit::walk_ty(self, ty);
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
|
||||
&& let Res::Def(DefKind::TyParam, def_id) = path.res
|
||||
&& def_id == self.1.to_def_id()
|
||||
{
|
||||
self.0 = Some(ty.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = Visitor(None, impl_def_id);
|
||||
for ty in input_tys {
|
||||
intravisit::Visitor::visit_ty(&mut visitor, ty);
|
||||
}
|
||||
let span = visitor.0?;
|
||||
let mut visitor = Visitor(None, impl_def_id);
|
||||
for ty in input_tys {
|
||||
intravisit::Visitor::visit_ty(&mut visitor, ty);
|
||||
}
|
||||
let span = visitor.0?;
|
||||
|
||||
let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
|
||||
let bounds = bounds.first()?.span().to(bounds.last()?.span());
|
||||
let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
|
||||
let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
|
||||
let bounds = bounds.first()?.span().to(bounds.last()?.span());
|
||||
let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
|
||||
|
||||
err.multipart_suggestion(
|
||||
"try removing the generic parameter and using `impl Trait` instead",
|
||||
vec![
|
||||
// delete generic parameters
|
||||
(impl_m.generics.span, String::new()),
|
||||
// replace param usage with `impl Trait`
|
||||
(span, format!("impl {bounds}")),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
};
|
||||
}
|
||||
_ => unreachable!(),
|
||||
err.multipart_suggestion(
|
||||
"try removing the generic parameter and using `impl Trait` instead",
|
||||
vec![
|
||||
// delete generic parameters
|
||||
(impl_m.generics.span, String::new()),
|
||||
// replace param usage with `impl Trait`
|
||||
(span, format!("impl {bounds}")),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
};
|
||||
}
|
||||
error_found = Some(err.emit_unless(delay));
|
||||
}
|
||||
|
|
@ -1859,7 +1682,9 @@ fn compare_generic_param_kinds<'tcx>(
|
|||
// this is exhaustive so that anyone adding new generic param kinds knows
|
||||
// to make sure this error is reported for them.
|
||||
(Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false,
|
||||
(Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(),
|
||||
(Lifetime { .. }, _) | (_, Lifetime { .. }) => {
|
||||
bug!("lifetime params are expected to be filtered by `ty_const_params_of`")
|
||||
}
|
||||
} {
|
||||
let param_impl_span = tcx.def_span(param_impl.def_id);
|
||||
let param_trait_span = tcx.def_span(param_trait.def_id);
|
||||
|
|
@ -1883,7 +1708,10 @@ fn compare_generic_param_kinds<'tcx>(
|
|||
)
|
||||
}
|
||||
Type { .. } => format!("{prefix} type parameter"),
|
||||
Lifetime { .. } => unreachable!(),
|
||||
Lifetime { .. } => span_bug!(
|
||||
tcx.def_span(param.def_id),
|
||||
"lifetime params are expected to be filtered by `ty_const_params_of`"
|
||||
),
|
||||
};
|
||||
|
||||
let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap();
|
||||
|
|
@ -2187,7 +2015,10 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
..
|
||||
}) => ty.span,
|
||||
hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span,
|
||||
_ => bug!(),
|
||||
item => span_bug!(
|
||||
tcx.def_span(impl_ty_def_id),
|
||||
"cannot call `check_type_bounds` on item: {item:?}",
|
||||
),
|
||||
}
|
||||
};
|
||||
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?;
|
||||
|
|
|
|||
|
|
@ -262,7 +262,10 @@ fn report_mismatched_rpitit_signature<'tcx>(
|
|||
|
||||
if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
|
||||
let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
|
||||
bug!();
|
||||
span_bug!(
|
||||
tcx.def_span(trait_m_def_id),
|
||||
"expected return type of async fn in trait to be a AFIT projection"
|
||||
);
|
||||
};
|
||||
let Some(future_output_ty) = tcx
|
||||
.explicit_item_bounds(future_ty.def_id)
|
||||
|
|
@ -272,7 +275,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
|
|||
_ => None,
|
||||
})
|
||||
else {
|
||||
bug!()
|
||||
span_bug!(tcx.def_span(trait_m_def_id), "expected `Future` projection bound in AFIT");
|
||||
};
|
||||
return_ty = future_output_ty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,24 +92,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
|
||||
let mut error = false;
|
||||
let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);
|
||||
let main_fn_generics = tcx.generics_of(main_def_id);
|
||||
let main_fn_predicates = tcx.predicates_of(main_def_id);
|
||||
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
|
||||
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
|
||||
tcx.sess.emit_err(errors::MainFunctionGenericParameters {
|
||||
span: generics_param_span.unwrap_or(main_span),
|
||||
label_span: generics_param_span,
|
||||
});
|
||||
error = true;
|
||||
} else if !main_fn_predicates.predicates.is_empty() {
|
||||
// generics may bring in implicit predicates, so we skip this check if generics is present.
|
||||
let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
|
||||
tcx.sess.emit_err(errors::WhereClauseOnMain {
|
||||
span: generics_where_clauses_span.unwrap_or(main_span),
|
||||
generics_span: generics_where_clauses_span,
|
||||
});
|
||||
error = true;
|
||||
}
|
||||
|
||||
let main_asyncness = tcx.asyncness(main_def_id);
|
||||
if main_asyncness.is_async() {
|
||||
|
|
@ -142,10 +124,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
if let Some(term_did) = tcx.lang_items().termination() {
|
||||
let return_ty = main_fnsig.output();
|
||||
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
|
||||
if !return_ty.bound_vars().is_empty() {
|
||||
tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
|
||||
error = true;
|
||||
}
|
||||
let return_ty = return_ty.skip_binder();
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let cause = traits::ObligationCause::new(
|
||||
|
|
@ -180,7 +158,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
Abi::Rust,
|
||||
));
|
||||
|
||||
check_function_signature(
|
||||
if check_function_signature(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
main_span,
|
||||
|
|
@ -189,7 +167,28 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
),
|
||||
main_def_id,
|
||||
expected_sig,
|
||||
);
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let main_fn_generics = tcx.generics_of(main_def_id);
|
||||
let main_fn_predicates = tcx.predicates_of(main_def_id);
|
||||
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
|
||||
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
|
||||
tcx.sess.emit_err(errors::MainFunctionGenericParameters {
|
||||
span: generics_param_span.unwrap_or(main_span),
|
||||
label_span: generics_param_span,
|
||||
});
|
||||
} else if !main_fn_predicates.predicates.is_empty() {
|
||||
// generics may bring in implicit predicates, so we skip this check if generics is present.
|
||||
let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
|
||||
tcx.sess.emit_err(errors::WhereClauseOnMain {
|
||||
span: generics_where_clauses_span.unwrap_or(main_span),
|
||||
generics_span: generics_where_clauses_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||
|
|
@ -255,7 +254,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
|||
Abi::Rust,
|
||||
));
|
||||
|
||||
check_function_signature(
|
||||
let _ = check_function_signature(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
start_span,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ fn equate_intrinsic_type<'tcx>(
|
|||
&& gen_count_ok(own_counts.consts, n_cts, "const")
|
||||
{
|
||||
let it_def_id = it.owner_id.def_id;
|
||||
check_function_signature(
|
||||
let _ = check_function_signature(
|
||||
tcx,
|
||||
ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType),
|
||||
it_def_id.into(),
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
16 => InlineAsmType::I16,
|
||||
32 => InlineAsmType::I32,
|
||||
64 => InlineAsmType::I64,
|
||||
_ => unreachable!(),
|
||||
width => bug!("unsupported pointer width: {width}"),
|
||||
};
|
||||
|
||||
match *ty.kind() {
|
||||
|
|
@ -101,7 +101,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
16 => InlineAsmType::VecI16(size),
|
||||
32 => InlineAsmType::VecI32(size),
|
||||
64 => InlineAsmType::VecI64(size),
|
||||
_ => unreachable!(),
|
||||
width => bug!("unsupported pointer width: {width}"),
|
||||
})
|
||||
}
|
||||
ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
|
||||
|
|
@ -109,7 +109,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
ty::Infer(_) => unreachable!(),
|
||||
ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -136,8 +136,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args);
|
||||
let ty::Adt(ty, args) = ty.kind() else { unreachable!() };
|
||||
assert!(ty.is_manually_drop());
|
||||
// FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
|
||||
// If so, just get it from the args.
|
||||
let ty::Adt(ty, args) = ty.kind() else {
|
||||
unreachable!("expected first field of `MaybeUninit` to be an ADT")
|
||||
};
|
||||
assert!(
|
||||
ty.is_manually_drop(),
|
||||
"expected first field of `MaybeUnit` to be `ManuallyDrop`"
|
||||
);
|
||||
let fields = &ty.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
|
||||
self.get_asm_ty(ty)
|
||||
|
|
@ -269,7 +276,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
lint.help(format!(
|
||||
"or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
|
||||
));
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ use std::num::NonZeroU32;
|
|||
|
||||
use check::check_mod_item_types;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
|
|
@ -570,7 +571,26 @@ pub fn check_function_signature<'tcx>(
|
|||
mut cause: ObligationCause<'tcx>,
|
||||
fn_id: DefId,
|
||||
expected_sig: ty::PolyFnSig<'tcx>,
|
||||
) {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
fn extract_span_for_error_reporting<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
err: TypeError<'_>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
fn_id: LocalDefId,
|
||||
) -> rustc_span::Span {
|
||||
let mut args = {
|
||||
let node = tcx.hir().expect_owner(fn_id);
|
||||
let decl = node.fn_decl().unwrap_or_else(|| bug!("expected fn decl, found {:?}", node));
|
||||
decl.inputs.iter().map(|t| t.span).chain(std::iter::once(decl.output.span()))
|
||||
};
|
||||
|
||||
match err {
|
||||
TypeError::ArgumentMutability(i)
|
||||
| TypeError::ArgumentSorts(ExpectedFound { .. }, i) => args.nth(i).unwrap(),
|
||||
_ => cause.span(),
|
||||
}
|
||||
}
|
||||
|
||||
let local_id = fn_id.as_local().unwrap_or(CRATE_DEF_ID);
|
||||
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
|
|
@ -587,8 +607,7 @@ pub fn check_function_signature<'tcx>(
|
|||
Ok(()) => {
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return;
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
|
|
@ -610,30 +629,14 @@ pub fn check_function_signature<'tcx>(
|
|||
false,
|
||||
false,
|
||||
);
|
||||
diag.emit();
|
||||
return;
|
||||
return Err(diag.emit());
|
||||
}
|
||||
}
|
||||
|
||||
let outlives_env = OutlivesEnvironment::new(param_env);
|
||||
let _ = ocx.resolve_regions_and_report_errors(local_id, &outlives_env);
|
||||
|
||||
fn extract_span_for_error_reporting<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
err: TypeError<'_>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
fn_id: LocalDefId,
|
||||
) -> rustc_span::Span {
|
||||
let mut args = {
|
||||
let node = tcx.hir().expect_owner(fn_id);
|
||||
let decl = node.fn_decl().unwrap_or_else(|| bug!("expected fn decl, found {:?}", node));
|
||||
decl.inputs.iter().map(|t| t.span).chain(std::iter::once(decl.output.span()))
|
||||
};
|
||||
|
||||
match err {
|
||||
TypeError::ArgumentMutability(i)
|
||||
| TypeError::ArgumentSorts(ExpectedFound { .. }, i) => args.nth(i).unwrap(),
|
||||
_ => cause.span(),
|
||||
}
|
||||
if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &outlives_env) {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,11 +204,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
|||
res = Err(err.emit());
|
||||
}
|
||||
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
|
||||
match (tcx.impl_polarity(def_id), impl_.polarity) {
|
||||
(ty::ImplPolarity::Positive, _) => {
|
||||
match tcx.impl_polarity(def_id) {
|
||||
ty::ImplPolarity::Positive => {
|
||||
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
|
||||
}
|
||||
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
|
||||
ty::ImplPolarity::Negative => {
|
||||
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
|
||||
bug!("impl_polarity query disagrees with impl's polarity in AST");
|
||||
};
|
||||
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
||||
if let hir::Defaultness::Default { .. } = impl_.defaultness {
|
||||
let mut spans = vec![span];
|
||||
|
|
@ -222,10 +225,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
|||
.emit());
|
||||
}
|
||||
}
|
||||
(ty::ImplPolarity::Reservation, _) => {
|
||||
ty::ImplPolarity::Reservation => {
|
||||
// FIXME: what amount of WF checking do we need for reservation impls?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
res
|
||||
}
|
||||
|
|
@ -992,15 +994,6 @@ fn check_associated_item(
|
|||
})
|
||||
}
|
||||
|
||||
fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> {
|
||||
match kind {
|
||||
ItemKind::Struct(..) => Some(AdtKind::Struct),
|
||||
ItemKind::Union(..) => Some(AdtKind::Union),
|
||||
ItemKind::Enum(..) => Some(AdtKind::Enum),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
|
||||
fn check_type_defn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
@ -1068,9 +1061,14 @@ fn check_type_defn<'tcx>(
|
|||
hir_ty.span,
|
||||
wfcx.body_def_id,
|
||||
traits::FieldSized {
|
||||
adt_kind: match item_adt_kind(&item.kind) {
|
||||
Some(i) => i,
|
||||
None => bug!(),
|
||||
adt_kind: match &item.kind {
|
||||
ItemKind::Struct(..) => AdtKind::Struct,
|
||||
ItemKind::Union(..) => AdtKind::Union,
|
||||
ItemKind::Enum(..) => AdtKind::Enum,
|
||||
kind => span_bug!(
|
||||
item.span,
|
||||
"should be wfchecking an ADT, got {kind:?}"
|
||||
),
|
||||
},
|
||||
span: hir_ty.span,
|
||||
last,
|
||||
|
|
@ -1302,7 +1300,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
|||
| GenericParamDefKind::Const { has_default, .. } => {
|
||||
has_default && def.index >= generics.parent_count as u32
|
||||
}
|
||||
GenericParamDefKind::Lifetime => unreachable!(),
|
||||
GenericParamDefKind::Lifetime => {
|
||||
span_bug!(tcx.def_span(def.def_id), "lifetime params can have no default")
|
||||
}
|
||||
};
|
||||
|
||||
// Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
|
||||
|
|
@ -1607,15 +1607,10 @@ fn check_method_receiver<'tcx>(
|
|||
}
|
||||
|
||||
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
|
||||
struct_span_err!(
|
||||
tcx.sess.diagnostic(),
|
||||
span,
|
||||
E0307,
|
||||
"invalid `self` parameter type: {receiver_ty}"
|
||||
)
|
||||
.note("type of `self` must be `Self` or a type that dereferences to it")
|
||||
.help(HELP_FOR_SELF_TYPE)
|
||||
.emit()
|
||||
struct_span_err!(tcx.sess.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}")
|
||||
.note("type of `self` must be `Self` or a type that dereferences to it")
|
||||
.help(HELP_FOR_SELF_TYPE)
|
||||
.emit()
|
||||
}
|
||||
|
||||
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
|
||||
|
|
@ -1750,15 +1745,15 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
}
|
||||
}
|
||||
ItemKind::TyAlias(..) => {
|
||||
if tcx.type_alias_is_lazy(item.owner_id) {
|
||||
if tcx.type_of(item.owner_id).skip_binder().references_error() {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
bug!();
|
||||
assert!(
|
||||
tcx.type_alias_is_lazy(item.owner_id),
|
||||
"should not be computing variance of non-weak type alias"
|
||||
);
|
||||
if tcx.type_of(item.owner_id).skip_binder().references_error() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_ => bug!(),
|
||||
kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"),
|
||||
}
|
||||
|
||||
let ty_predicates = tcx.predicates_of(item.owner_id);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
|
|||
item.hir_id(),
|
||||
path.span,
|
||||
msg,
|
||||
|lint| lint,
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ fn lint_auto_trait_impl<'tcx>(
|
|||
impl_def_id: LocalDefId,
|
||||
) {
|
||||
if trait_ref.args.len() != 1 {
|
||||
tcx.sess.diagnostic().span_delayed_bug(
|
||||
tcx.sess.dcx().span_delayed_bug(
|
||||
tcx.def_span(impl_def_id),
|
||||
"auto traits cannot have generic parameters",
|
||||
);
|
||||
|
|
@ -522,7 +522,7 @@ fn lint_auto_trait_impl<'tcx>(
|
|||
format!(
|
||||
"try using the same sequence of generic parameters as the {self_descr} definition",
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue