commit
cfd7eaa8b7
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -260,13 +260,13 @@ jobs:
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: i686-gnu
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: i686-gnu-nopt
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: mingw-check
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: test-various
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
@ -275,16 +275,16 @@ jobs:
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: x86_64-gnu
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-stable
|
||||
env:
|
||||
IMAGE: x86_64-gnu
|
||||
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
- name: x86_64-gnu-aux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-debug
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
@ -309,7 +309,7 @@ jobs:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-nopt
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-tools
|
||||
env:
|
||||
|
@ -4090,6 +4090,7 @@ dependencies = [
|
||||
name = "rustc_smir"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_hir",
|
||||
"rustc_middle",
|
||||
"rustc_span",
|
||||
"tracing",
|
||||
|
@ -1589,7 +1589,6 @@ pub enum ClosureBinder {
|
||||
pub struct MacCall {
|
||||
pub path: Path,
|
||||
pub args: P<DelimArgs>,
|
||||
pub prior_type_ascription: Option<(Span, bool)>,
|
||||
}
|
||||
|
||||
impl MacCall {
|
||||
|
@ -631,7 +631,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||
}
|
||||
|
||||
pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
|
||||
let MacCall { path, args, prior_type_ascription: _ } = mac;
|
||||
let MacCall { path, args } = mac;
|
||||
vis.visit_path(path);
|
||||
visit_delim_args(args, vis);
|
||||
}
|
||||
|
@ -53,8 +53,6 @@ pub enum AssocOp {
|
||||
DotDot,
|
||||
/// `..=` range
|
||||
DotDotEq,
|
||||
/// `:`
|
||||
Colon,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
@ -96,7 +94,6 @@ impl AssocOp {
|
||||
token::DotDotEq => Some(DotDotEq),
|
||||
// DotDotDot is no longer supported, but we need some way to display the error
|
||||
token::DotDotDot => Some(DotDotEq),
|
||||
token::Colon => Some(Colon),
|
||||
// `<-` should probably be `< -`
|
||||
token::LArrow => Some(Less),
|
||||
_ if t.is_keyword(kw::As) => Some(As),
|
||||
@ -133,7 +130,7 @@ impl AssocOp {
|
||||
pub fn precedence(&self) -> usize {
|
||||
use AssocOp::*;
|
||||
match *self {
|
||||
As | Colon => 14,
|
||||
As => 14,
|
||||
Multiply | Divide | Modulus => 13,
|
||||
Add | Subtract => 12,
|
||||
ShiftLeft | ShiftRight => 11,
|
||||
@ -156,7 +153,7 @@ impl AssocOp {
|
||||
Assign | AssignOp(_) => Fixity::Right,
|
||||
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd
|
||||
| BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual
|
||||
| LAnd | LOr | Colon => Fixity::Left,
|
||||
| LAnd | LOr => Fixity::Left,
|
||||
DotDot | DotDotEq => Fixity::None,
|
||||
}
|
||||
}
|
||||
@ -166,8 +163,9 @@ impl AssocOp {
|
||||
match *self {
|
||||
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
|
||||
Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract
|
||||
| ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq
|
||||
| Colon => false,
|
||||
| ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +175,7 @@ impl AssocOp {
|
||||
Assign | AssignOp(_) => true,
|
||||
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply
|
||||
| Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor
|
||||
| BitOr | LAnd | LOr | DotDot | DotDotEq | Colon => false,
|
||||
| BitOr | LAnd | LOr | DotDot | DotDotEq => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +200,7 @@ impl AssocOp {
|
||||
BitOr => Some(BinOpKind::BitOr),
|
||||
LAnd => Some(BinOpKind::And),
|
||||
LOr => Some(BinOpKind::Or),
|
||||
Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None,
|
||||
Assign | AssignOp(_) | As | DotDot | DotDotEq => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,10 +221,9 @@ impl AssocOp {
|
||||
Greater | // `{ 42 } > 3`
|
||||
GreaterEqual | // `{ 42 } >= 3`
|
||||
AssignOp(_) | // `{ 42 } +=`
|
||||
As | // `{ 42 } as usize`
|
||||
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
|
||||
// NotEqual | // `{ 42 } != { 42 }` struct literals parser recovery.
|
||||
Colon, // `{ 42 }: usize`
|
||||
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.
|
||||
As // `{ 42 } as usize`
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -254,7 +251,6 @@ pub enum ExprPrecedence {
|
||||
Binary(BinOpKind),
|
||||
|
||||
Cast,
|
||||
Type,
|
||||
|
||||
Assign,
|
||||
AssignOp,
|
||||
@ -313,7 +309,6 @@ impl ExprPrecedence {
|
||||
// Binop-like expr kinds, handled by `AssocOp`.
|
||||
ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
|
||||
ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
|
||||
ExprPrecedence::Type => AssocOp::Colon.precedence() as i8,
|
||||
|
||||
ExprPrecedence::Assign |
|
||||
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,
|
||||
|
@ -136,7 +136,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
self.diagnostic().span_bug(
|
||||
p.span,
|
||||
&format!(
|
||||
format!(
|
||||
"lower_qpath: no final extension segment in {}..{}",
|
||||
proj_start,
|
||||
p.segments.len()
|
||||
|
@ -83,7 +83,7 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||
&self,
|
||||
const_extern_fn,
|
||||
span,
|
||||
&format!("`{}` as a `const fn` ABI is unstable", abi)
|
||||
format!("`{}` as a `const fn` ABI is unstable", abi)
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -104,7 +104,7 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
|
||||
self.sess.parse_sess.span_diagnostic.delay_span_bug(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"unrecognized ABI not caught in lowering: {}",
|
||||
symbol_unescaped.as_str()
|
||||
),
|
||||
|
@ -341,10 +341,16 @@ impl<'a> State<'a> {
|
||||
self.print_type(ty);
|
||||
}
|
||||
ast::ExprKind::Type(expr, ty) => {
|
||||
let prec = AssocOp::Colon.precedence() as i8;
|
||||
self.print_expr_maybe_paren(expr, prec);
|
||||
self.word_space(":");
|
||||
self.word("type_ascribe!(");
|
||||
self.ibox(0);
|
||||
self.print_expr(expr);
|
||||
|
||||
self.word(",");
|
||||
self.space_if_not_bol();
|
||||
self.print_type(ty);
|
||||
|
||||
self.end();
|
||||
self.word(")");
|
||||
}
|
||||
ast::ExprKind::Let(pat, scrutinee, _) => {
|
||||
self.print_let(pat, scrutinee);
|
||||
|
@ -623,7 +623,7 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F
|
||||
let (cfg, feature, has_feature) = gated_cfg;
|
||||
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
|
||||
let explain = format!("`cfg({cfg})` is experimental and subject to change");
|
||||
feature_err(sess, *feature, cfg_span, &explain).emit();
|
||||
feature_err(sess, *feature, cfg_span, explain).emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
} else if reinits > 1 {
|
||||
err.span_note(
|
||||
MultiSpan::from_spans(reinit_spans),
|
||||
&if reinits <= 3 {
|
||||
if reinits <= 3 {
|
||||
format!("these {reinits} reinitializations might get skipped")
|
||||
} else {
|
||||
format!(
|
||||
@ -253,7 +253,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// We have a `&mut` ref, we need to reborrow on each iteration (#62112).
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
&format!(
|
||||
format!(
|
||||
"consider creating a fresh reborrow of {} here",
|
||||
self.describe_place(moved_place)
|
||||
.map(|n| format!("`{n}`"))
|
||||
@ -304,7 +304,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
..
|
||||
} = use_spans
|
||||
{
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"{} occurs due to deref coercion to `{deref_target_ty}`",
|
||||
desired_action.as_noun(),
|
||||
));
|
||||
@ -586,7 +586,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// _ => {} // We don't want to point to this.
|
||||
// };
|
||||
// ```
|
||||
err.span_label(sp, &label);
|
||||
err.span_label(sp, label);
|
||||
shown = true;
|
||||
}
|
||||
}
|
||||
@ -1139,7 +1139,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
if union_type_name != "" {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"{} is a field of the union `{}`, so it overlaps the field {}",
|
||||
msg_place, union_type_name, msg_borrow,
|
||||
));
|
||||
@ -1238,14 +1238,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
err.span_help(
|
||||
inner_call_span,
|
||||
&format!(
|
||||
format!(
|
||||
"try adding a local storing this{}...",
|
||||
if use_span.is_some() { "" } else { " argument" }
|
||||
),
|
||||
);
|
||||
err.span_help(
|
||||
outer_call_span,
|
||||
&format!(
|
||||
format!(
|
||||
"...and then using that local {}",
|
||||
if use_span.is_some() { "here" } else { "as the argument to this call" }
|
||||
),
|
||||
@ -2281,7 +2281,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
sugg_span,
|
||||
&format!(
|
||||
format!(
|
||||
"to force the {} to take ownership of {} (and any \
|
||||
other referenced variables), use the `move` keyword",
|
||||
kind, captured_var
|
||||
@ -2293,7 +2293,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
match category {
|
||||
ConstraintCategory::Return(_) | ConstraintCategory::OpaqueType => {
|
||||
let msg = format!("{} is returned here", kind);
|
||||
err.span_note(constraint_span, &msg);
|
||||
err.span_note(constraint_span, msg);
|
||||
}
|
||||
ConstraintCategory::CallArgument(_) => {
|
||||
fr_name.highlight_region_name(&mut err);
|
||||
@ -2304,7 +2304,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
} else {
|
||||
let msg = format!("{scope} requires argument type to outlive `{fr_name}`");
|
||||
err.span_note(constraint_span, &msg);
|
||||
err.span_note(constraint_span, msg);
|
||||
}
|
||||
}
|
||||
_ => bug!(
|
||||
@ -2626,7 +2626,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
});
|
||||
if let Some(Ok(instance)) = deref_target {
|
||||
let deref_target_ty = instance.ty(tcx, self.param_env);
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"borrow occurs due to deref coercion to `{}`",
|
||||
deref_target_ty
|
||||
));
|
||||
@ -3180,7 +3180,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
||||
|
||||
diag.span_label(*return_span, format!("also has lifetime `{}`", region_name,));
|
||||
|
||||
diag.help(&format!(
|
||||
diag.help(format!(
|
||||
"use data from the highlighted arguments which match the `{}` lifetime of \
|
||||
the return type",
|
||||
region_name,
|
||||
|
@ -90,7 +90,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||
{
|
||||
err.span_label(
|
||||
pat.span,
|
||||
&format!("binding `{ident}` declared here"),
|
||||
format!("binding `{ident}` declared here"),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -323,7 +323,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
&msg,
|
||||
msg,
|
||||
format!(" + {suggestable_name}"),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
|
@ -1073,7 +1073,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if !is_loop_move {
|
||||
err.span_suggestion_verbose(
|
||||
move_span.shrink_to_lo(),
|
||||
&format!(
|
||||
format!(
|
||||
"consider creating a fresh reborrow of {} here",
|
||||
self.describe_place(moved_place.as_ref())
|
||||
.map(|n| format!("`{n}`"))
|
||||
|
@ -533,7 +533,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
suggestions.sort_unstable_by_key(|&(span, _, _)| span);
|
||||
suggestions.dedup_by_key(|&mut (span, _, _)| span);
|
||||
for (span, msg, suggestion) in suggestions {
|
||||
err.span_suggestion_verbose(span, &msg, suggestion, Applicability::MachineApplicable);
|
||||
err.span_suggestion_verbose(span, msg, suggestion, Applicability::MachineApplicable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -573,7 +573,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
if !is_trait_sig {
|
||||
err.span_suggestion_verbose(
|
||||
err_help_span,
|
||||
&format!(
|
||||
format!(
|
||||
"consider changing this to be a mutable {pointer_desc}"
|
||||
),
|
||||
suggested_code,
|
||||
@ -582,7 +582,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
} else if let Some(x) = local_trait {
|
||||
err.span_suggestion_verbose(
|
||||
x,
|
||||
&format!(
|
||||
format!(
|
||||
"consider changing that to be a mutable {pointer_desc}"
|
||||
),
|
||||
suggested_code,
|
||||
@ -636,14 +636,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!("consider {changing} this binding's type"),
|
||||
format!("consider {changing} this binding's type"),
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
err_label_span,
|
||||
&format!(
|
||||
format!(
|
||||
"consider changing this binding's type to be: `{message}`"
|
||||
),
|
||||
);
|
||||
@ -679,13 +679,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
match opt_source {
|
||||
Some(BorrowedContentSource::OverloadedDeref(ty)) => {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"trait `DerefMut` is required to modify through a dereference, \
|
||||
but it is not implemented for `{ty}`",
|
||||
));
|
||||
}
|
||||
Some(BorrowedContentSource::OverloadedIndex(ty)) => {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"trait `IndexMut` is required to modify indexed content, \
|
||||
but it is not implemented for `{ty}`",
|
||||
));
|
||||
@ -736,7 +736,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
// val[index] = rv;
|
||||
// ---------- place
|
||||
self.err.multipart_suggestions(
|
||||
&format!(
|
||||
format!(
|
||||
"to modify a `{}`, use `.get_mut()`, `.insert()` or the entry API",
|
||||
self.ty,
|
||||
),
|
||||
@ -788,7 +788,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
{
|
||||
// val[index].path(args..);
|
||||
self.err.multipart_suggestion(
|
||||
&format!("to modify a `{}` use `.get_mut()`", self.ty),
|
||||
format!("to modify a `{}` use `.get_mut()`", self.ty),
|
||||
vec![
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
@ -822,7 +822,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let mut v = V { assign_span, err, ty, suggested: false };
|
||||
v.visit_body(body);
|
||||
if !v.suggested {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API",
|
||||
));
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ impl OutlivesSuggestionBuilder {
|
||||
if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name)
|
||||
&& !matches!(outlived_fr_name.source, RegionNameSource::Static)
|
||||
{
|
||||
diag.help(&format!(
|
||||
diag.help(format!(
|
||||
"consider adding the following bound: `{fr_name}: {outlived_fr_name}`",
|
||||
));
|
||||
}
|
||||
@ -207,7 +207,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.diagnostic().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(" + "))
|
||||
@ -232,15 +232,15 @@ impl OutlivesSuggestionBuilder {
|
||||
match constraint {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect();
|
||||
diag.help(&format!("add bound `{a}: {}`", bs.join(" + ")));
|
||||
diag.help(format!("add bound `{a}: {}`", bs.join(" + ")));
|
||||
}
|
||||
SuggestedConstraint::Equal(a, b) => {
|
||||
diag.help(&format!(
|
||||
diag.help(format!(
|
||||
"`{a}` and `{b}` must be the same: replace one with the other",
|
||||
));
|
||||
}
|
||||
SuggestedConstraint::Static(a) => {
|
||||
diag.help(&format!("replace `{a}` with `'static`"));
|
||||
diag.help(format!("replace `{a}` with `'static`"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -533,8 +533,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
_ => panic!("Unexpected type {ty:?}"),
|
||||
};
|
||||
diag.note(&format!("requirement occurs because of {desc}",));
|
||||
diag.note(¬e);
|
||||
diag.note(format!("requirement occurs because of {desc}",));
|
||||
diag.note(note);
|
||||
diag.help("see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance");
|
||||
}
|
||||
}
|
||||
@ -863,7 +863,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
|
||||
diag.multipart_suggestion_verbose(
|
||||
&format!(
|
||||
format!(
|
||||
"to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"
|
||||
),
|
||||
spans_suggs,
|
||||
|
@ -622,7 +622,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
// programs, so we need to use delay_span_bug here. See #82126.
|
||||
self.infcx.tcx.sess.delay_span_bug(
|
||||
hir_arg.span(),
|
||||
&format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
|
||||
format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
|
||||
self.consume_operand(location, cond);
|
||||
use rustc_middle::mir::AssertKind;
|
||||
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||
if let AssertKind::BoundsCheck { len, index } = &**msg {
|
||||
self.consume_operand(location, len);
|
||||
self.consume_operand(location, index);
|
||||
}
|
||||
|
@ -738,7 +738,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
|
||||
self.consume_operand(loc, (cond, span), flow_state);
|
||||
use rustc_middle::mir::AssertKind;
|
||||
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||
if let AssertKind::BoundsCheck { len, index } = &**msg {
|
||||
self.consume_operand(loc, (len, span), flow_state);
|
||||
self.consume_operand(loc, (index, span), flow_state);
|
||||
}
|
||||
@ -2022,7 +2022,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// been emitted (#52262).
|
||||
self.infcx.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
|
||||
place, kind,
|
||||
),
|
||||
@ -2383,7 +2383,7 @@ mod error {
|
||||
}
|
||||
for (_, (mut diag, count)) in std::mem::take(&mut self.errors.buffered_mut_errors) {
|
||||
if count > 10 {
|
||||
diag.note(&format!("...and {} other attempted mutable borrows", count - 10));
|
||||
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
|
||||
}
|
||||
diag.buffer(&mut self.errors.buffered);
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ pub(super) fn dump_annotation<'tcx>(
|
||||
|
||||
regioncx.annotate(tcx, &mut err);
|
||||
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"number of external vids: {}",
|
||||
closure_region_requirements.num_external_vids
|
||||
));
|
||||
@ -421,7 +421,7 @@ pub(super) fn dump_annotation<'tcx>(
|
||||
};
|
||||
|
||||
if !opaque_type_values.is_empty() {
|
||||
err.note(&format!("Inferred opaque type values:\n{:#?}", opaque_type_values));
|
||||
err.note(format!("Inferred opaque type values:\n{:#?}", opaque_type_values));
|
||||
}
|
||||
|
||||
errors.buffer_non_error_diag(err);
|
||||
|
@ -399,7 +399,7 @@ fn check_opaque_type_parameter_valid(
|
||||
return Err(tcx
|
||||
.sess
|
||||
.struct_span_err(span, "non-defining opaque type use in defining scope")
|
||||
.span_note(spans, &format!("{} used multiple times", descr))
|
||||
.span_note(spans, format!("{} used multiple times", descr))
|
||||
.emit());
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
|
||||
.delay_span_bug(span, format!("failed to normalize {:?}", ty));
|
||||
TypeOpOutput {
|
||||
output: self.infcx.tcx.ty_error(guar),
|
||||
constraints: None,
|
||||
|
@ -106,7 +106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() {
|
||||
self.tcx().sess.delay_span_bug(
|
||||
body.span,
|
||||
&format!(
|
||||
format!(
|
||||
"Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})",
|
||||
body.yield_ty(),
|
||||
universal_regions.yield_ty,
|
||||
|
@ -236,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
if hidden_type.has_non_region_infer() {
|
||||
let reported = infcx.tcx.sess.delay_span_bug(
|
||||
decl.hidden_type.span,
|
||||
&format!("could not resolve {:#?}", hidden_type.ty.kind()),
|
||||
format!("could not resolve {:#?}", hidden_type.ty.kind()),
|
||||
);
|
||||
hidden_type.ty = infcx.tcx.ty_error(reported);
|
||||
}
|
||||
@ -1404,7 +1404,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
||||
}
|
||||
|
||||
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||
if let AssertKind::BoundsCheck { len, index } = &**msg {
|
||||
if len.ty(body, tcx) != tcx.types.usize {
|
||||
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
||||
match self.defining_ty {
|
||||
DefiningTy::Closure(def_id, substs) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"defining type: {} with closure substs {:#?}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
&substs[tcx.generics_of(def_id).parent_count..],
|
||||
@ -347,11 +347,11 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
// and other things that are not stable across tests!
|
||||
// So we just include the region-vid. Annoying.
|
||||
for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
|
||||
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
});
|
||||
}
|
||||
DefiningTy::Generator(def_id, substs, _) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"defining type: {} with generator substs {:#?}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
&substs[tcx.generics_of(def_id).parent_count..],
|
||||
@ -361,23 +361,23 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
// `r` but doing so is not stable across architectures
|
||||
// and so forth.
|
||||
for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
|
||||
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
});
|
||||
}
|
||||
DefiningTy::FnDef(def_id, substs) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"defining type: {}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
));
|
||||
}
|
||||
DefiningTy::Const(def_id, substs) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"defining constant type: {}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
));
|
||||
}
|
||||
DefiningTy::InlineConst(def_id, substs) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"defining inline constant type: {}",
|
||||
tcx.def_path_str_with_substs(def_id, substs),
|
||||
));
|
||||
|
@ -68,9 +68,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...
|
||||
let mut err = diag.create_err(errors::AsmExpectedComma { span: p.token.span });
|
||||
p.maybe_annotate_with_ascription(&mut err, false);
|
||||
return Err(err);
|
||||
return Err(diag.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());
|
||||
@ -555,7 +553,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
let mut e = ecx.struct_span_err(err_sp, msg);
|
||||
e.span_label(err_sp, err.label + " in asm template string");
|
||||
if let Some(note) = err.note {
|
||||
e.note(¬e);
|
||||
e.note(note);
|
||||
}
|
||||
if let Some((label, span)) = err.secondary_label {
|
||||
let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end));
|
||||
@ -602,7 +600,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
1 => format!("there is 1 {}argument", positional),
|
||||
x => format!("there are {} {}arguments", x, positional),
|
||||
};
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
|
||||
if named_pos.contains_key(&idx) {
|
||||
err.span_label(args.operands[idx].1, "named argument");
|
||||
@ -705,7 +703,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
let (sp, msg) = unused_operands.into_iter().next().unwrap();
|
||||
let mut err = ecx.struct_span_err(sp, msg);
|
||||
err.span_label(sp, msg);
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"if this argument is intentionally unused, \
|
||||
consider using it in an asm comment: `\"/*{} */\"`",
|
||||
help_str
|
||||
@ -720,7 +718,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
for (sp, msg) in unused_operands {
|
||||
err.span_label(sp, msg);
|
||||
}
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"if these arguments are intentionally unused, \
|
||||
consider using them in an asm comment: `\"/*{} */\"`",
|
||||
help_str
|
||||
|
@ -61,7 +61,6 @@ pub fn expand_assert<'cx>(
|
||||
delim: MacDelimiter::Parenthesis,
|
||||
tokens,
|
||||
}),
|
||||
prior_type_ascription: None,
|
||||
})),
|
||||
);
|
||||
expr_if_not(cx, call_site_span, cond_expr, then, None)
|
||||
|
@ -182,7 +182,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
||||
delim: MacDelimiter::Parenthesis,
|
||||
tokens: initial.into_iter().chain(captures).collect::<TokenStream>(),
|
||||
}),
|
||||
prior_type_ascription: None,
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
@ -63,7 +63,6 @@ fn expand<'cx>(
|
||||
delim: MacDelimiter::Parenthesis,
|
||||
tokens: tts,
|
||||
}),
|
||||
prior_type_ascription: None,
|
||||
})),
|
||||
),
|
||||
)
|
||||
|
@ -616,14 +616,14 @@ fn report_missing_placeholders(
|
||||
} else {
|
||||
diag.span_note(
|
||||
sp,
|
||||
&format!("format specifiers use curly braces, and {}", trn),
|
||||
format!("format specifiers use curly braces, and {}", trn),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if success {
|
||||
diag.help(&format!("`{}` should be written as `{}`", sub, trn));
|
||||
diag.help(format!("`{}` should be written as `{}`", sub, trn));
|
||||
} else {
|
||||
diag.note(&format!("`{}` should use curly braces, and {}", sub, trn));
|
||||
diag.note(format!("`{}` should use curly braces, and {}", sub, trn));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -777,7 +777,7 @@ fn report_invalid_references(
|
||||
has_precision_star = true;
|
||||
e.span_label(
|
||||
*span,
|
||||
&format!(
|
||||
format!(
|
||||
"this precision flag adds an extra required argument at position {}, which is why there {} expected",
|
||||
index,
|
||||
if num_placeholders == 1 {
|
||||
|
@ -194,7 +194,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
||||
};
|
||||
|
||||
self.handler
|
||||
.struct_span_err(attr.span, &msg)
|
||||
.struct_span_err(attr.span, msg)
|
||||
.span_label(prev_attr.span, "previous attribute here")
|
||||
.emit();
|
||||
|
||||
@ -219,7 +219,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.handler.span_err(attr.span, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -233,7 +233,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.handler.span_err(attr.span, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ pub fn expand_include<'cx>(
|
||||
if self.p.token != token::Eof {
|
||||
let token = pprust::token_to_string(&self.p.token);
|
||||
let msg = format!("expected item, found `{}`", token);
|
||||
self.p.struct_span_err(self.p.token.span, &msg).emit();
|
||||
self.p.struct_span_err(self.p.token.span, msg).emit();
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -88,10 +88,10 @@ pub(crate) fn import_function<'tcx>(
|
||||
let sig = get_function_sig(tcx, module.target_config().default_call_conv, inst);
|
||||
match module.declare_function(name, Linkage::Import, &sig) {
|
||||
Ok(func_id) => func_id,
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(format!(
|
||||
"attempt to declare `{name}` as function, but it was already declared as static"
|
||||
)),
|
||||
Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(&format!(
|
||||
Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(format!(
|
||||
"attempt to declare `{name}` with signature {new_sig:?}, \
|
||||
but it was already declared with signature {prev_sig:?}"
|
||||
)),
|
||||
@ -548,7 +548,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
if !matches!(fn_sig.abi(), Abi::C { .. }) {
|
||||
fx.tcx.sess.span_fatal(
|
||||
source_info.span,
|
||||
&format!("Variadic call for non-C abi {:?}", fn_sig.abi()),
|
||||
format!("Variadic call for non-C abi {:?}", fn_sig.abi()),
|
||||
);
|
||||
}
|
||||
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
||||
@ -560,7 +560,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
// FIXME set %al to upperbound on float args once floats are supported
|
||||
fx.tcx.sess.span_fatal(
|
||||
source_info.span,
|
||||
&format!("Non int ty {:?} for variadic call", ty),
|
||||
format!("Non int ty {:?} for variadic call", ty),
|
||||
);
|
||||
}
|
||||
AbiParam::new(ty)
|
||||
|
@ -220,13 +220,13 @@ pub(crate) fn verify_func(
|
||||
match cranelift_codegen::verify_function(&func, &flags) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
tcx.sess.err(&format!("{:?}", err));
|
||||
tcx.sess.err(format!("{:?}", err));
|
||||
let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error(
|
||||
&func,
|
||||
Some(Box::new(writer)),
|
||||
err,
|
||||
);
|
||||
tcx.sess.fatal(&format!("cranelift verify error:\n{}", pretty_error));
|
||||
tcx.sess.fatal(format!("cranelift verify error:\n{}", pretty_error));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -335,7 +335,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
||||
fx.bcx.switch_to_block(failure);
|
||||
fx.bcx.ins().nop();
|
||||
|
||||
match msg {
|
||||
match &**msg {
|
||||
AssertKind::BoundsCheck { ref len, ref index } => {
|
||||
let len = codegen_operand(fx, len).load_scalar(fx);
|
||||
let index = codegen_operand(fx, index).load_scalar(fx);
|
||||
|
@ -481,7 +481,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||
#[inline]
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
||||
if let layout::LayoutError::SizeOverflow(_) = err {
|
||||
self.0.sess.span_fatal(span, &err.to_string())
|
||||
self.0.sess.span_fatal(span, err.to_string())
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
||||
}
|
||||
@ -499,7 +499,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||
fn_abi_request: FnAbiRequest<'tcx>,
|
||||
) -> ! {
|
||||
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
|
||||
self.0.sess.span_fatal(span, &err.to_string())
|
||||
self.0.sess.span_fatal(span, err.to_string())
|
||||
} else {
|
||||
match fn_abi_request {
|
||||
FnAbiRequest::OfFnPtr { sig, extra_args } => {
|
||||
|
@ -65,7 +65,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).raise();
|
||||
handler.fatal(err).raise();
|
||||
} else {
|
||||
// The error was already emitted, but compilation continued. Raise a silent
|
||||
// fatal error.
|
||||
|
@ -308,7 +308,7 @@ fn data_id_for_static(
|
||||
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||
) {
|
||||
Ok(data_id) => data_id,
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(format!(
|
||||
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
|
||||
)),
|
||||
Err(err) => Err::<_, _>(err).unwrap(),
|
||||
@ -356,7 +356,7 @@ fn data_id_for_static(
|
||||
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||
) {
|
||||
Ok(data_id) => data_id,
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(format!(
|
||||
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
|
||||
)),
|
||||
Err(err) => Err::<_, _>(err).unwrap(),
|
||||
@ -404,7 +404,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
if let Some(names) = section_name.split_once(',') {
|
||||
names
|
||||
} else {
|
||||
tcx.sess.fatal(&format!(
|
||||
tcx.sess.fatal(format!(
|
||||
"#[link_section = \"{}\"] is not valid for macos target: must be segment and section separated by comma",
|
||||
section_name
|
||||
));
|
||||
@ -449,7 +449,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
GlobalAlloc::Static(def_id) => {
|
||||
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
|
||||
{
|
||||
tcx.sess.fatal(&format!(
|
||||
tcx.sess.fatal(format!(
|
||||
"Allocation {:?} contains reference to TLS value {:?}",
|
||||
alloc_id, def_id
|
||||
));
|
||||
|
@ -69,7 +69,7 @@ impl OngoingCodegen {
|
||||
|
||||
let module_codegen_result = match module_codegen_result {
|
||||
Ok(module_codegen_result) => module_codegen_result,
|
||||
Err(err) => sess.fatal(&err),
|
||||
Err(err) => sess.fatal(err),
|
||||
};
|
||||
let ModuleCodegenResult { module_regular, module_global_asm, existing_work_product } =
|
||||
module_codegen_result;
|
||||
@ -468,7 +468,7 @@ pub(crate) fn run_aot(
|
||||
let obj = create_compressed_metadata_file(tcx.sess, &metadata, &symbol_name);
|
||||
|
||||
if let Err(err) = std::fs::write(&tmp_file, obj) {
|
||||
tcx.sess.fatal(&format!("error writing metadata object file: {}", err));
|
||||
tcx.sess.fatal(format!("error writing metadata object file: {}", err));
|
||||
}
|
||||
|
||||
(metadata_cgu_name, tmp_file)
|
||||
|
@ -42,7 +42,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||
_ => {
|
||||
fx.tcx
|
||||
.sess
|
||||
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
|
||||
.warn(format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
|
||||
crate::trap::trap_unimplemented(fx, intrinsic);
|
||||
return;
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
||||
}
|
||||
*/
|
||||
_ => {
|
||||
fx.tcx.sess.warn(&format!(
|
||||
fx.tcx.sess.warn(format!(
|
||||
"unsupported AArch64 llvm intrinsic {}; replacing with trap",
|
||||
intrinsic
|
||||
));
|
||||
|
@ -138,10 +138,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
||||
llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b);
|
||||
}
|
||||
_ => {
|
||||
fx.tcx.sess.warn(&format!(
|
||||
"unsupported x86 llvm intrinsic {}; replacing with trap",
|
||||
intrinsic
|
||||
));
|
||||
fx.tcx
|
||||
.sess
|
||||
.warn(format!("unsupported x86 llvm intrinsic {}; replacing with trap", intrinsic));
|
||||
crate::trap::trap_unimplemented(fx, intrinsic);
|
||||
return;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ fn report_atomic_type_validation_error<'tcx>(
|
||||
) {
|
||||
fx.tcx.sess.span_err(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"`{}` intrinsic: expected basic integer or raw pointer type, found `{:?}`",
|
||||
intrinsic, ty
|
||||
),
|
||||
@ -1202,7 +1202,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
_ => {
|
||||
fx.tcx
|
||||
.sess
|
||||
.span_fatal(source_info.span, &format!("unsupported intrinsic {}", intrinsic));
|
||||
.span_fatal(source_info.span, format!("unsupported intrinsic {}", intrinsic));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ fn report_simd_type_validation_error(
|
||||
span: Span,
|
||||
ty: Ty<'_>,
|
||||
) {
|
||||
fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
|
||||
fx.tcx.sess.span_err(span, format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
|
||||
// Prevent verifier error
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
@ -150,7 +150,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
_ => {
|
||||
fx.tcx.sess.span_err(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"simd_shuffle index must be an array of `u32`, got `{}`",
|
||||
idx_ty,
|
||||
),
|
||||
@ -248,7 +248,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
if idx >= lane_count.into() {
|
||||
fx.tcx.sess.span_fatal(
|
||||
fx.mir.span,
|
||||
&format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count),
|
||||
format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count),
|
||||
);
|
||||
}
|
||||
|
||||
@ -296,7 +296,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
if idx >= lane_count.into() {
|
||||
fx.tcx.sess.span_fatal(
|
||||
fx.mir.span,
|
||||
&format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count),
|
||||
format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count),
|
||||
);
|
||||
}
|
||||
|
||||
@ -699,7 +699,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
_ => {
|
||||
fx.tcx.sess.span_fatal(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"invalid monomorphization of `simd_bitmask` intrinsic: \
|
||||
vector argument `{}`'s element type `{}`, expected integer element \
|
||||
type",
|
||||
@ -739,7 +739,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
_ => {
|
||||
fx.tcx.sess.span_fatal(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"invalid monomorphization of `simd_bitmask` intrinsic: \
|
||||
cannot return `{}`, expected `u{}` or `[u8; {}]`",
|
||||
ret.layout().ty,
|
||||
@ -875,7 +875,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
}
|
||||
|
||||
_ => {
|
||||
fx.tcx.sess.span_err(span, &format!("Unknown SIMD intrinsic {}", intrinsic));
|
||||
fx.tcx.sess.span_err(span, format!("Unknown SIMD intrinsic {}", intrinsic));
|
||||
// Prevent verifier error
|
||||
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
||||
let mut config = self.config.borrow_mut();
|
||||
if config.is_none() {
|
||||
let new_config = BackendConfig::from_opts(&sess.opts.cg.llvm_args)
|
||||
.unwrap_or_else(|err| sess.fatal(&err));
|
||||
.unwrap_or_else(|err| sess.fatal(err));
|
||||
*config = Some(new_config);
|
||||
}
|
||||
}
|
||||
@ -245,7 +245,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
||||
fn target_triple(sess: &Session) -> target_lexicon::Triple {
|
||||
match sess.target.llvm_target.parse() {
|
||||
Ok(triple) => triple,
|
||||
Err(err) => sess.fatal(&format!("target not recognized: {}", err)),
|
||||
Err(err) => sess.fatal(format!("target not recognized: {}", err)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,7 +307,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
|
||||
Some(value) => {
|
||||
let mut builder =
|
||||
cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
|
||||
sess.fatal(format!("can't compile for {}: {}", target_triple, err));
|
||||
});
|
||||
if let Err(_) = builder.enable(value) {
|
||||
sess.fatal("the specified target cpu isn't currently supported by Cranelift.");
|
||||
@ -317,7 +317,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
|
||||
None => {
|
||||
let mut builder =
|
||||
cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
|
||||
sess.fatal(format!("can't compile for {}: {}", target_triple, err));
|
||||
});
|
||||
if target_triple.architecture == target_lexicon::Architecture::X86_64 {
|
||||
// Don't use "haswell" as the default, as it implies `has_lzcnt`.
|
||||
@ -330,7 +330,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
|
||||
|
||||
match isa_builder.finish(flags) {
|
||||
Ok(target_isa) => target_isa,
|
||||
Err(err) => sess.fatal(&format!("failed to build TargetIsa: {}", err)),
|
||||
Err(err) => sess.fatal(format!("failed to build TargetIsa: {}", err)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
Ok(func_id) => func_id,
|
||||
Err(err) => {
|
||||
tcx.sess
|
||||
.fatal(&format!("entry symbol `{entry_name}` declared multiple times: {err}"));
|
||||
.fatal(format!("entry symbol `{entry_name}` declared multiple times: {err}"));
|
||||
}
|
||||
};
|
||||
|
||||
@ -171,7 +171,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
}
|
||||
|
||||
if let Err(err) = m.define_function(cmain_func_id, &mut ctx) {
|
||||
tcx.sess.fatal(&format!("entry symbol `{entry_name}` defined multiple times: {err}"));
|
||||
tcx.sess.fatal(format!("entry symbol `{entry_name}` defined multiple times: {err}"));
|
||||
}
|
||||
|
||||
unwind_context.add_function(cmain_func_id, &ctx, m.isa());
|
||||
|
@ -344,7 +344,7 @@ impl<'tcx> CPlace<'tcx> {
|
||||
if layout.size.bytes() >= u64::from(u32::MAX - 16) {
|
||||
fx.tcx
|
||||
.sess
|
||||
.fatal(&format!("values of type {} are too big to store on the stack", layout.ty));
|
||||
.fatal(format!("values of type {} are too big to store on the stack", layout.ty));
|
||||
}
|
||||
|
||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||
|
@ -40,7 +40,6 @@ use regex::Regex;
|
||||
use tempfile::Builder as TempFileBuilder;
|
||||
|
||||
use itertools::Itertools;
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::OnceCell;
|
||||
use std::collections::BTreeSet;
|
||||
use std::ffi::OsString;
|
||||
@ -54,7 +53,7 @@ use std::{env, fmt, fs, io, mem, str};
|
||||
pub fn ensure_removed(diag_handler: &Handler, 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));
|
||||
diag_handler.err(format!("failed to remove {}: {}", path.display(), e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -576,17 +575,17 @@ fn link_dwarf_object<'a>(
|
||||
|
||||
impl<Relocations> ThorinSession<Relocations> {
|
||||
fn alloc_mmap(&self, data: Mmap) -> &Mmap {
|
||||
(*self.arena_mmap.alloc(data)).borrow()
|
||||
&*self.arena_mmap.alloc(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Relocations> thorin::Session<Relocations> for ThorinSession<Relocations> {
|
||||
fn alloc_data(&self, data: Vec<u8>) -> &[u8] {
|
||||
(*self.arena_data.alloc(data)).borrow()
|
||||
&*self.arena_data.alloc(data)
|
||||
}
|
||||
|
||||
fn alloc_relocation(&self, data: Relocations) -> &Relocations {
|
||||
(*self.arena_relocations.alloc(data)).borrow()
|
||||
&*self.arena_relocations.alloc(data)
|
||||
}
|
||||
|
||||
fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> {
|
||||
@ -1406,7 +1405,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
|
||||
sess.emit_note(errors::StaticLibraryNativeArtifacts);
|
||||
// Prefix for greppability
|
||||
// Note: This must not be translated as tools are allowed to depend on this exact string.
|
||||
sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" ")));
|
||||
sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1631,7 @@ impl<'a> Linker for AixLinker<'a> {
|
||||
}
|
||||
};
|
||||
if let Err(e) = res {
|
||||
self.sess.fatal(&format!("failed to write export file: {}", e));
|
||||
self.sess.fatal(format!("failed to write export file: {}", e));
|
||||
}
|
||||
self.cmd.arg(format!("-bE:{}", path.to_str().unwrap()));
|
||||
}
|
||||
|
@ -1833,7 +1833,7 @@ impl SharedEmitterMain {
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
Ok(SharedEmitterMessage::Fatal(msg)) => {
|
||||
sess.fatal(&msg);
|
||||
sess.fatal(msg);
|
||||
}
|
||||
Err(_) => {
|
||||
break;
|
||||
|
@ -301,7 +301,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
if let Some(val) = attr.value_str() {
|
||||
if val.as_str().bytes().any(|b| b == 0) {
|
||||
let msg = format!("illegal null byte in link_section value: `{}`", &val);
|
||||
tcx.sess.span_err(attr.span, &msg);
|
||||
tcx.sess.span_err(attr.span, msg);
|
||||
} else {
|
||||
codegen_fn_attrs.link_section = Some(val);
|
||||
}
|
||||
@ -631,7 +631,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
|
||||
} else {
|
||||
let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
|
||||
tcx.sess
|
||||
.struct_span_err(attr.span, &msg)
|
||||
.struct_span_err(attr.span, msg)
|
||||
.note("the value may not exceed `u16::MAX`")
|
||||
.emit();
|
||||
None
|
||||
|
@ -94,7 +94,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
// Computing the layout can still fail here, e.g. if the target architecture
|
||||
// cannot represent the type. See https://github.com/rust-lang/rust/issues/94961.
|
||||
// FIXME: migrate once `rustc_middle::mir::interpret::InterpError` is translatable.
|
||||
tcx.sess.fatal(&format!("{}", e));
|
||||
tcx.sess.fatal(format!("{}", e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -370,7 +370,7 @@ pub fn from_target_feature(
|
||||
let Some(feature_gate) = supported_target_features.get(feature) else {
|
||||
let msg =
|
||||
format!("the feature named `{}` is not valid for this target", feature);
|
||||
let mut err = tcx.sess.struct_span_err(item.span(), &msg);
|
||||
let mut err = tcx.sess.struct_span_err(item.span(), msg);
|
||||
err.span_label(
|
||||
item.span(),
|
||||
format!("`{}` is not valid for this target", feature),
|
||||
@ -408,7 +408,7 @@ pub fn from_target_feature(
|
||||
&tcx.sess.parse_sess,
|
||||
feature_gate.unwrap(),
|
||||
item.span(),
|
||||
&format!("the target feature `{}` is currently unstable", feature),
|
||||
format!("the target feature `{}` is currently unstable", feature),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
@ -104,13 +104,13 @@ impl<'tcx> ConstEvalErr<'tcx> {
|
||||
// Add spans for the stacktrace. Don't print a single-line backtrace though.
|
||||
if self.stacktrace.len() > 1 {
|
||||
// Helper closure to print duplicated lines.
|
||||
let mut flush_last_line = |last_frame, times| {
|
||||
let mut flush_last_line = |last_frame: Option<(String, _)>, times| {
|
||||
if let Some((line, span)) = last_frame {
|
||||
err.span_note(span, &line);
|
||||
err.span_note(span, line.clone());
|
||||
// Don't print [... additional calls ...] if the number of lines is small
|
||||
if times < 3 {
|
||||
for _ in 0..times {
|
||||
err.span_note(span, &line);
|
||||
err.span_note(span, line.clone());
|
||||
}
|
||||
} else {
|
||||
err.span_note(
|
||||
|
@ -368,7 +368,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||
if matches!(err.error, InterpError::UndefinedBehavior(_)) {
|
||||
diag.note(NOTE_ON_UNDEFINED_BEHAVIOR_ERROR);
|
||||
}
|
||||
diag.note(&format!(
|
||||
diag.note(format!(
|
||||
"the raw bytes of the constant ({}",
|
||||
display_allocation(
|
||||
*ecx.tcx,
|
||||
|
@ -83,7 +83,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
|
||||
Some(span) => {
|
||||
tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id })
|
||||
}
|
||||
None => tcx.sess.struct_err(&msg),
|
||||
None => tcx.sess.struct_err(msg),
|
||||
};
|
||||
diag.emit();
|
||||
|
||||
|
@ -387,7 +387,7 @@ pub fn intern_const_alloc_recursive<
|
||||
Err(error) => {
|
||||
ecx.tcx.sess.delay_span_bug(
|
||||
ecx.tcx.span,
|
||||
&format!(
|
||||
format!(
|
||||
"error during interning should later cause validation failure: {}",
|
||||
error
|
||||
),
|
||||
|
@ -293,7 +293,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// FIXME: This should be a span_bug (#80742)
|
||||
self.tcx.sess.delay_span_bug(
|
||||
self.frame().current_span(),
|
||||
&format!("{null_op:?} MIR operator called for unsized type {ty}"),
|
||||
format!("{null_op:?} MIR operator called for unsized type {ty}"),
|
||||
);
|
||||
throw_inval!(SizeOfUnsizedType(ty));
|
||||
}
|
||||
|
@ -38,16 +38,14 @@ macro_rules! throw_validation_failure {
|
||||
msg.push_str(", but expected ");
|
||||
write!(&mut msg, $($expected_fmt)*).unwrap();
|
||||
)?
|
||||
let path = rustc_middle::ty::print::with_no_trimmed_paths!({
|
||||
let where_ = &$where;
|
||||
if !where_.is_empty() {
|
||||
let mut path = String::new();
|
||||
write_path(&mut path, where_);
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let where_ = &$where;
|
||||
let path = if !where_.is_empty() {
|
||||
let mut path = String::new();
|
||||
write_path(&mut path, where_);
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
throw_ub!(ValidationFailure { path, msg })
|
||||
}};
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_floating_point_arithmetic,
|
||||
span,
|
||||
&format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
|
||||
format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -211,13 +211,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
err.span_note(span, "function defined here, but it is not `const`");
|
||||
}
|
||||
FnPtr(..) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"function pointers need an RFC before allowed to be called in {}s",
|
||||
ccx.const_kind()
|
||||
));
|
||||
}
|
||||
Closure(..) => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"closures need an RFC before allowed to be called in {}s",
|
||||
ccx.const_kind()
|
||||
));
|
||||
@ -289,7 +289,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
ccx.const_kind()
|
||||
);
|
||||
|
||||
err.note(&format!("attempting to deref into `{}`", deref_target_ty));
|
||||
err.note(format!("attempting to deref into `{}`", deref_target_ty));
|
||||
|
||||
// Check first whether the source is accessible (issue #87060)
|
||||
if tcx.sess.source_map().is_span_accessible(deref_target) {
|
||||
@ -310,14 +310,14 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
}),
|
||||
};
|
||||
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"calls in {}s are limited to constant functions, \
|
||||
tuple structs and tuple variants",
|
||||
ccx.const_kind(),
|
||||
));
|
||||
|
||||
if let Some(feature) = feature && ccx.tcx.sess.is_nightly_build() {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable",
|
||||
feature,
|
||||
));
|
||||
@ -354,7 +354,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
||||
err.help("const-stable functions can only call other const-stable functions");
|
||||
} else if ccx.tcx.sess.is_nightly_build() {
|
||||
if let Some(feature) = feature {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable",
|
||||
feature
|
||||
));
|
||||
@ -637,7 +637,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_mut_refs,
|
||||
span,
|
||||
&format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
|
||||
format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -724,7 +724,7 @@ pub mod ty {
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_mut_refs,
|
||||
span,
|
||||
&format!("mutable references are not allowed in {}s", ccx.const_kind()),
|
||||
format!("mutable references are not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// occurred.
|
||||
self.tcx.sess.diagnostic().delay_span_bug(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||
self.body.source.instance,
|
||||
self.when,
|
||||
@ -1094,7 +1094,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
if self.body.source_scopes.get(scope).is_none() {
|
||||
self.tcx.sess.diagnostic().delay_span_bug(
|
||||
self.body.span,
|
||||
&format!(
|
||||
format!(
|
||||
"broken MIR in {:?} ({}):\ninvalid source scope {:?}",
|
||||
self.body.source.instance, self.when, scope,
|
||||
),
|
||||
|
@ -287,11 +287,19 @@ pub enum SubdiagnosticMessage {
|
||||
FluentAttr(FluentId),
|
||||
}
|
||||
|
||||
/// `From` impl that enables existing diagnostic calls to functions which now take
|
||||
/// `impl Into<SubdiagnosticMessage>` to continue to work as before.
|
||||
impl<S: Into<String>> From<S> for SubdiagnosticMessage {
|
||||
fn from(s: S) -> Self {
|
||||
SubdiagnosticMessage::Str(s.into())
|
||||
impl From<String> for SubdiagnosticMessage {
|
||||
fn from(s: String) -> Self {
|
||||
SubdiagnosticMessage::Str(s)
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a str> for SubdiagnosticMessage {
|
||||
fn from(s: &'a str) -> Self {
|
||||
SubdiagnosticMessage::Str(s.to_string())
|
||||
}
|
||||
}
|
||||
impl From<Cow<'static, str>> for SubdiagnosticMessage {
|
||||
fn from(s: Cow<'static, str>) -> Self {
|
||||
SubdiagnosticMessage::Str(s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,11 +360,19 @@ impl DiagnosticMessage {
|
||||
}
|
||||
}
|
||||
|
||||
/// `From` impl that enables existing diagnostic calls to functions which now take
|
||||
/// `impl Into<DiagnosticMessage>` to continue to work as before.
|
||||
impl<S: Into<String>> From<S> for DiagnosticMessage {
|
||||
fn from(s: S) -> Self {
|
||||
DiagnosticMessage::Str(s.into())
|
||||
impl From<String> for DiagnosticMessage {
|
||||
fn from(s: String) -> Self {
|
||||
DiagnosticMessage::Str(s)
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a str> for DiagnosticMessage {
|
||||
fn from(s: &'a str) -> Self {
|
||||
DiagnosticMessage::Str(s.to_string())
|
||||
}
|
||||
}
|
||||
impl From<Cow<'static, str>> for DiagnosticMessage {
|
||||
fn from(s: Cow<'static, str>) -> Self {
|
||||
DiagnosticMessage::Str(s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -791,7 +791,7 @@ macro_rules! struct_span_err {
|
||||
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
|
||||
$session.struct_span_err_with_code(
|
||||
$span,
|
||||
&format!($($message)*),
|
||||
format!($($message)*),
|
||||
$crate::error_code!($code),
|
||||
)
|
||||
})
|
||||
|
@ -601,7 +601,7 @@ impl Emitter for SilentEmitter {
|
||||
if d.level == Level::Fatal {
|
||||
let mut d = d.clone();
|
||||
if let Some(ref note) = self.fatal_note {
|
||||
d.note(note);
|
||||
d.note(note.clone());
|
||||
}
|
||||
self.fatal_handler.emit_diagnostic(&mut d);
|
||||
}
|
||||
|
@ -1462,10 +1462,10 @@ impl HandlerInner {
|
||||
DiagnosticMessage::Str(warnings),
|
||||
)),
|
||||
(_, 0) => {
|
||||
let _ = self.fatal(&errors);
|
||||
let _ = self.fatal(errors);
|
||||
}
|
||||
(_, _) => {
|
||||
let _ = self.fatal(&format!("{}; {}", &errors, &warnings));
|
||||
let _ = self.fatal(format!("{}; {}", &errors, &warnings));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1486,18 +1486,18 @@ impl HandlerInner {
|
||||
error_codes.sort();
|
||||
if error_codes.len() > 1 {
|
||||
let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
|
||||
self.failure(&format!(
|
||||
self.failure(format!(
|
||||
"Some errors have detailed explanations: {}{}",
|
||||
error_codes[..limit].join(", "),
|
||||
if error_codes.len() > 9 { "..." } else { "." }
|
||||
));
|
||||
self.failure(&format!(
|
||||
self.failure(format!(
|
||||
"For more information about an error, try \
|
||||
`rustc --explain {}`.",
|
||||
&error_codes[0]
|
||||
));
|
||||
} else {
|
||||
self.failure(&format!(
|
||||
self.failure(format!(
|
||||
"For more information about this error, try \
|
||||
`rustc --explain {}`.",
|
||||
&error_codes[0]
|
||||
@ -1663,7 +1663,7 @@ impl HandlerInner {
|
||||
if bug.level != Level::DelayedBug {
|
||||
// NOTE(eddyb) not panicking here because we're already producing
|
||||
// an ICE, and the more information the merrier.
|
||||
bug.note(&format!(
|
||||
bug.note(format!(
|
||||
"`flushed_delayed` got diagnostic with level {:?}, \
|
||||
instead of the expected `DelayedBug`",
|
||||
bug.level,
|
||||
@ -1732,7 +1732,7 @@ impl DelayedDiagnostic {
|
||||
}
|
||||
|
||||
fn decorate(mut self) -> Diagnostic {
|
||||
self.inner.note(&format!("delayed at {}", self.note));
|
||||
self.inner.note(format!("delayed at {}", self.note));
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
@ -1831,7 +1831,7 @@ pub fn add_elided_lifetime_in_path_suggestion(
|
||||
if incl_angl_brckt { format!("<{}>", anon_lts) } else { format!("{}, ", anon_lts) };
|
||||
diag.span_suggestion_verbose(
|
||||
insertion_span.shrink_to_hi(),
|
||||
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
|
||||
format!("indicate the anonymous lifetime{}", pluralize!(n)),
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -992,7 +992,6 @@ pub struct ExpansionData {
|
||||
pub depth: usize,
|
||||
pub module: Rc<ModuleData>,
|
||||
pub dir_ownership: DirOwnership,
|
||||
pub prior_type_ascription: Option<(Span, bool)>,
|
||||
/// Some parent node that is close to this macro call
|
||||
pub lint_node_id: NodeId,
|
||||
pub is_trailing_mac: bool,
|
||||
@ -1043,7 +1042,6 @@ impl<'a> ExtCtxt<'a> {
|
||||
depth: 0,
|
||||
module: Default::default(),
|
||||
dir_ownership: DirOwnership::Owned { relative: None },
|
||||
prior_type_ascription: None,
|
||||
lint_node_id: ast::CRATE_NODE_ID,
|
||||
is_trailing_mac: false,
|
||||
},
|
||||
@ -1148,7 +1146,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
for (span, notes) in self.expansions.iter() {
|
||||
let mut db = self.sess.parse_sess.create_note(errors::TraceMacro { span: *span });
|
||||
for note in notes {
|
||||
db.note(note);
|
||||
db.note(note.clone());
|
||||
}
|
||||
db.emit();
|
||||
}
|
||||
|
@ -657,8 +657,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
|
||||
}
|
||||
SyntaxExtensionKind::LegacyBang(expander) => {
|
||||
let prev = self.cx.current_expansion.prior_type_ascription;
|
||||
self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription;
|
||||
let tok_result = expander.expand(self.cx, span, mac.args.tokens.clone());
|
||||
let result = if let Some(result) = fragment_kind.make_from(tok_result) {
|
||||
result
|
||||
@ -666,7 +664,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
self.error_wrong_fragment_kind(fragment_kind, &mac, span);
|
||||
fragment_kind.dummy(span)
|
||||
};
|
||||
self.cx.current_expansion.prior_type_ascription = prev;
|
||||
result
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@ -800,7 +797,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
&self.cx.sess.parse_sess,
|
||||
sym::proc_macro_hygiene,
|
||||
span,
|
||||
&format!("custom attributes cannot be applied to {}", kind),
|
||||
format!("custom attributes cannot be applied to {}", kind),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
@ -250,8 +250,7 @@ fn expand_macro<'cx>(
|
||||
trace_macros_note(&mut cx.expansions, sp, msg);
|
||||
}
|
||||
|
||||
let mut p = Parser::new(sess, tts, false, None);
|
||||
p.last_type_ascription = cx.current_expansion.prior_type_ascription;
|
||||
let p = Parser::new(sess, tts, false, None);
|
||||
|
||||
if is_local {
|
||||
cx.resolver.record_macro_rule_usage(node_id, i);
|
||||
@ -475,7 +474,7 @@ pub fn compile_declarative_macro(
|
||||
|
||||
let s = parse_failure_msg(&token);
|
||||
let sp = token.span.substitute_dummy(def.span);
|
||||
let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
|
||||
let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, s);
|
||||
err.span_label(sp, msg);
|
||||
annotate_doc_comment(&mut err, sess.source_map(), sp);
|
||||
err.emit();
|
||||
@ -484,7 +483,7 @@ pub fn compile_declarative_macro(
|
||||
Error(sp, msg) => {
|
||||
sess.parse_sess
|
||||
.span_diagnostic
|
||||
.struct_span_err(sp.substitute_dummy(def.span), &msg)
|
||||
.struct_span_err(sp.substitute_dummy(def.span), msg)
|
||||
.emit();
|
||||
return dummy_syn_ext();
|
||||
}
|
||||
@ -556,7 +555,7 @@ 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));
|
||||
diag.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");
|
||||
@ -1165,7 +1164,7 @@ fn check_matcher_core<'tt>(
|
||||
let sp = next_token.span();
|
||||
let mut err = sess.span_diagnostic.struct_span_err(
|
||||
sp,
|
||||
&format!(
|
||||
format!(
|
||||
"`${name}:{frag}` {may_be} followed by `{next}`, which \
|
||||
is not allowed for `{frag}` fragments",
|
||||
name = name,
|
||||
@ -1197,13 +1196,13 @@ fn check_matcher_core<'tt>(
|
||||
match possible {
|
||||
&[] => {}
|
||||
&[t] => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"only {} is allowed after `{}` fragments",
|
||||
t, kind,
|
||||
));
|
||||
}
|
||||
ts => {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"{}{} or {}",
|
||||
msg,
|
||||
ts[..ts.len() - 1].to_vec().join(", "),
|
||||
|
@ -78,7 +78,7 @@ fn check_trailing_token<'sess>(
|
||||
if let Some(tt) = iter.next() {
|
||||
let mut diag = sess
|
||||
.span_diagnostic
|
||||
.struct_span_err(tt.span(), &format!("unexpected token: {}", pprust::tt_to_string(tt)));
|
||||
.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)
|
||||
} else {
|
||||
@ -137,11 +137,11 @@ fn parse_ident<'sess>(
|
||||
let token_str = pprust::token_to_string(token);
|
||||
let mut err = sess.span_diagnostic.struct_span_err(
|
||||
span,
|
||||
&format!("expected identifier, found `{}`", &token_str)
|
||||
format!("expected identifier, found `{}`", &token_str)
|
||||
);
|
||||
err.span_suggestion(
|
||||
token.span,
|
||||
&format!("try removing `{}`", &token_str),
|
||||
format!("try removing `{}`", &token_str),
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
@ -85,7 +85,7 @@ pub(super) fn parse(
|
||||
frag.name
|
||||
);
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(span, &msg)
|
||||
.struct_span_err(span, msg)
|
||||
.help(VALID_FRAGMENT_NAMES_MSG)
|
||||
.emit();
|
||||
token::NonterminalKind::Ident
|
||||
@ -195,7 +195,7 @@ fn parse_tree(
|
||||
_ => {
|
||||
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.span_diagnostic.span_err(delim_span.entire(), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -246,7 +246,7 @@ fn parse_tree(
|
||||
"expected identifier, found `{}`",
|
||||
pprust::token_to_string(&token),
|
||||
);
|
||||
sess.span_diagnostic.span_err(token.span, &msg);
|
||||
sess.span_diagnostic.span_err(token.span, msg);
|
||||
TokenTree::MetaVar(token.span, Ident::empty())
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ fn parse_sep_and_kleene_op(
|
||||
// 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)));
|
||||
.span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
|
||||
sess.span_diagnostic.span_note_without_error(
|
||||
token.span,
|
||||
"`$$` and meta-variable expressions are not allowed inside macro parameter definitions",
|
||||
|
@ -21,7 +21,6 @@ pub fn placeholder(
|
||||
delim: ast::MacDelimiter::Parenthesis,
|
||||
tokens: ast::tokenstream::TokenStream::new(Vec::new()),
|
||||
}),
|
||||
prior_type_ascription: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ impl base::AttrProcMacro for AttrProcMacro {
|
||||
|e| {
|
||||
let mut err = ecx.struct_span_err(span, "custom attribute panicked");
|
||||
if let Some(s) = e.as_str() {
|
||||
err.help(&format!("message: {}", s));
|
||||
err.help(format!("message: {}", s));
|
||||
}
|
||||
err.emit()
|
||||
},
|
||||
@ -148,7 +148,7 @@ impl MultiItemModifier for DeriveProcMacro {
|
||||
Err(e) => {
|
||||
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
|
||||
if let Some(s) = e.as_str() {
|
||||
err.help(&format!("message: {}", s));
|
||||
err.help(format!("message: {}", s));
|
||||
}
|
||||
err.emit();
|
||||
return ExpandResult::Ready(vec![]);
|
||||
|
@ -130,6 +130,8 @@ declare_features! (
|
||||
(accepted, copy_closures, "1.26.0", Some(44490), None),
|
||||
/// Allows `crate` in paths.
|
||||
(accepted, crate_in_paths, "1.30.0", Some(45477), None),
|
||||
/// Allows using `#[debugger_visualizer]` attribute.
|
||||
(accepted, debugger_visualizer, "CURRENT_RUSTC_VERSION", Some(95939), None),
|
||||
/// Allows rustc to inject a default alloc_error_handler
|
||||
(accepted, default_alloc_error_handler, "1.68.0", Some(66741), None),
|
||||
/// Allows using assigning a default type to type parameters in algebraic data type definitions.
|
||||
|
@ -363,8 +363,6 @@ declare_features! (
|
||||
(active, custom_inner_attributes, "1.30.0", Some(54726), None),
|
||||
/// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
|
||||
(active, custom_test_frameworks, "1.30.0", Some(50297), None),
|
||||
/// Allows using `#[debugger_visualizer]`.
|
||||
(active, debugger_visualizer, "1.62.0", Some(95939), None),
|
||||
/// Allows declarative macros 2.0 (`macro`).
|
||||
(active, decl_macro, "1.17.0", Some(39412), None),
|
||||
/// Allows default type parameters to influence type inference.
|
||||
|
@ -403,16 +403,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk
|
||||
),
|
||||
|
||||
// Debugging
|
||||
ungated!(
|
||||
debugger_visualizer, Normal,
|
||||
template!(List: r#"natvis_file = "...", gdb_script_file = "...""#), DuplicatesOk
|
||||
),
|
||||
|
||||
// ==========================================================================
|
||||
// Unstable attributes:
|
||||
// ==========================================================================
|
||||
|
||||
// RFC #3191: #[debugger_visualizer] support
|
||||
gated!(
|
||||
debugger_visualizer, Normal, template!(List: r#"natvis_file = "...", gdb_script_file = "...""#),
|
||||
DuplicatesOk, experimental!(debugger_visualizer)
|
||||
),
|
||||
|
||||
// Linking:
|
||||
gated!(
|
||||
naked, Normal, template!(Word), WarnFollowing, @only_local: true,
|
||||
|
@ -293,6 +293,8 @@ language_item_table! {
|
||||
|
||||
PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
Poll, sym::Poll, poll, Target::Enum, GenericRequirement::None;
|
||||
PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None;
|
||||
PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None;
|
||||
|
@ -35,6 +35,10 @@ hir_analysis_field_already_declared =
|
||||
|
||||
hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
|
||||
|
||||
hir_analysis_const_param_ty_impl_on_non_adt =
|
||||
the trait `ConstParamTy` may not be implemented for this type
|
||||
.label = type is not a structure or enumeration
|
||||
|
||||
hir_analysis_ambiguous_lifetime_bound =
|
||||
ambiguous lifetime bound, explicit lifetime bound required
|
||||
|
||||
|
@ -243,13 +243,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let note = format!("{title} is defined in an impl for the type `{impl_ty}`");
|
||||
|
||||
if let Some(span) = note_span {
|
||||
err.span_note(span, ¬e);
|
||||
err.span_note(span, note);
|
||||
} else {
|
||||
err.note(¬e);
|
||||
err.note(note);
|
||||
}
|
||||
}
|
||||
if candidates.len() > limit {
|
||||
err.note(&format!("and {} others", candidates.len() - limit));
|
||||
err.note(format!("and {} others", candidates.len() - limit));
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
"associated type `{name}` not found for `{self_ty}` in the current scope"
|
||||
);
|
||||
err.span_label(name.span, format!("associated item not found in `{self_ty}`"));
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"the associated type was found for\n{type_candidates}{additional_types}",
|
||||
));
|
||||
add_def_label(&mut err);
|
||||
@ -390,10 +390,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
name.span,
|
||||
&format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
|
||||
format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
|
||||
);
|
||||
if !bounds.is_empty() {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"the following trait bounds were not satisfied:\n{}",
|
||||
bounds.join("\n")
|
||||
));
|
||||
@ -409,7 +409,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
if !tcx.sess.source_map().is_span_accessible(span) {
|
||||
continue;
|
||||
}
|
||||
err.span_label(span, &msg);
|
||||
err.span_label(span, msg);
|
||||
}
|
||||
add_def_label(&mut err);
|
||||
err.emit()
|
||||
@ -589,7 +589,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
if !suggestions.is_empty() {
|
||||
err.multipart_suggestion(
|
||||
&format!("specify the associated type{}", pluralize!(types_count)),
|
||||
format!("specify the associated type{}", pluralize!(types_count)),
|
||||
suggestions,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
|
@ -112,7 +112,7 @@ fn generic_arg_mismatch_err(
|
||||
if let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) = body.value.kind
|
||||
{
|
||||
if let Res::Def(DefKind::Fn { .. }, id) = path.res {
|
||||
err.help(&format!("`{}` is a function item, not a type", tcx.item_name(id)));
|
||||
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
|
||||
err.help("function item types cannot be named directly");
|
||||
}
|
||||
}
|
||||
@ -130,7 +130,7 @@ fn generic_arg_mismatch_err(
|
||||
} else {
|
||||
(arg.descr(), param.kind.descr())
|
||||
};
|
||||
err.note(&format!("{} arguments must be provided before {} arguments", first, last));
|
||||
err.note(format!("{} arguments must be provided before {} arguments", first, last));
|
||||
if let Some(help) = help {
|
||||
err.help(help);
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ use std::slice;
|
||||
#[derive(Debug)]
|
||||
pub struct PathSeg(pub DefId, pub usize);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct OnlySelfBounds(pub bool);
|
||||
|
||||
pub trait AstConv<'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||
|
||||
@ -670,6 +673,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
args: &GenericArgs<'_>,
|
||||
infer_args: bool,
|
||||
self_ty: Ty<'tcx>,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> GenericArgCountResult {
|
||||
let (substs, arg_count) = self.create_substs_for_ast_path(
|
||||
trait_ref_span,
|
||||
@ -706,6 +710,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
&mut dup_bindings,
|
||||
binding_span.unwrap_or(binding.span),
|
||||
constness,
|
||||
only_self_bounds,
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
||||
}
|
||||
@ -741,6 +746,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
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;
|
||||
@ -766,6 +772,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
args,
|
||||
infer_args,
|
||||
self_ty,
|
||||
only_self_bounds,
|
||||
)
|
||||
}
|
||||
|
||||
@ -777,6 +784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
args: &GenericArgs<'_>,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) {
|
||||
let binding_span = Some(span);
|
||||
let constness = ty::BoundConstness::NotConst;
|
||||
@ -799,6 +807,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
args,
|
||||
infer_args,
|
||||
self_ty,
|
||||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
|
||||
@ -947,6 +956,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
ast_bounds: I,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) {
|
||||
for ast_bound in ast_bounds {
|
||||
match ast_bound {
|
||||
@ -964,11 +974,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
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,
|
||||
lang_item,
|
||||
span,
|
||||
hir_id,
|
||||
args,
|
||||
param_ty,
|
||||
bounds,
|
||||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Outlives(lifetime) => {
|
||||
@ -1006,8 +1023,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> Bounds<'tcx> {
|
||||
self.compute_bounds_inner(param_ty, ast_bounds)
|
||||
let mut bounds = Bounds::default();
|
||||
self.add_bounds(
|
||||
param_ty,
|
||||
ast_bounds.iter(),
|
||||
&mut bounds,
|
||||
ty::List::empty(),
|
||||
only_self_bounds,
|
||||
);
|
||||
debug!(?bounds);
|
||||
|
||||
bounds
|
||||
}
|
||||
|
||||
/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
|
||||
@ -1029,17 +1057,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
|
||||
self.compute_bounds_inner(param_ty, &result)
|
||||
}
|
||||
|
||||
fn compute_bounds_inner(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
) -> Bounds<'tcx> {
|
||||
let mut bounds = Bounds::default();
|
||||
|
||||
self.add_bounds(param_ty, ast_bounds.iter(), &mut bounds, ty::List::empty());
|
||||
self.add_bounds(
|
||||
param_ty,
|
||||
result.iter(),
|
||||
&mut bounds,
|
||||
ty::List::empty(),
|
||||
OnlySelfBounds(true),
|
||||
);
|
||||
debug!(?bounds);
|
||||
|
||||
bounds
|
||||
@ -1062,6 +1087,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
dup_bindings: &mut FxHashMap<DefId, Span>,
|
||||
path_span: Span,
|
||||
constness: ty::BoundConstness,
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
||||
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
||||
@ -1142,9 +1168,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
binding.span,
|
||||
&format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
||||
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
||||
)
|
||||
.span_label(binding.span, &format!("private {}", assoc_item.kind))
|
||||
.span_label(binding.span, format!("private {}", assoc_item.kind))
|
||||
.emit();
|
||||
}
|
||||
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
||||
@ -1316,11 +1342,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let expected = tcx.def_descr(assoc_item_def_id);
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
binding.span,
|
||||
&format!("expected {expected} bound, found {got}"),
|
||||
format!("expected {expected} bound, found {got}"),
|
||||
);
|
||||
err.span_note(
|
||||
tcx.def_span(assoc_item_def_id),
|
||||
&format!("{expected} defined here"),
|
||||
format!("{expected} defined here"),
|
||||
);
|
||||
|
||||
if let hir::def::DefKind::AssocConst = def_kind
|
||||
@ -1361,8 +1387,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
|
||||
self.add_bounds(param_ty, ast_bounds.iter(), bounds, projection_ty.bound_vars());
|
||||
//
|
||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
|
||||
// type bound into a trait predicate, since we only want to add predicates
|
||||
// for the `Self` type.
|
||||
if !only_self_bounds.0 {
|
||||
let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
|
||||
self.add_bounds(
|
||||
param_ty,
|
||||
ast_bounds.iter(),
|
||||
bounds,
|
||||
projection_ty.bound_vars(),
|
||||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -1403,6 +1441,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
dummy_self,
|
||||
&mut bounds,
|
||||
false,
|
||||
// FIXME: This should be `true`, but we don't really handle
|
||||
// associated type bounds or type aliases in objects in a way
|
||||
// that makes this meaningful, I think.
|
||||
OnlySelfBounds(false),
|
||||
) {
|
||||
potential_assoc_types.extend(cur_potential_assoc_types);
|
||||
}
|
||||
@ -1466,7 +1508,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
"additional use",
|
||||
);
|
||||
first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use");
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"consider creating a new trait with all of these as supertraits and using that \
|
||||
trait here instead: `trait NewTrait: {} {{}}`",
|
||||
regular_traits
|
||||
@ -1776,7 +1818,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
([], []) => {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a type named `Type` that implements a trait named \
|
||||
`Trait` with associated type `{name}`, you could use the \
|
||||
fully-qualified path",
|
||||
@ -1788,7 +1830,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
([], [trait_str]) => {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a type named `Example` that implemented `{trait_str}`, \
|
||||
you could use the fully-qualified path",
|
||||
),
|
||||
@ -1799,7 +1841,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
([], traits) => {
|
||||
err.span_suggestions(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a type named `Example` that implemented one of the \
|
||||
traits with associated type `{name}`, you could use the \
|
||||
fully-qualified path",
|
||||
@ -1814,7 +1856,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
([type_str], []) => {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a trait named `Example` with associated type `{name}` \
|
||||
implemented for `{type_str}`, you could use the fully-qualified path",
|
||||
),
|
||||
@ -1825,7 +1867,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
(types, []) => {
|
||||
err.span_suggestions(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a trait named `Example` with associated type `{name}` \
|
||||
implemented for one of the types, you could use the fully-qualified \
|
||||
path",
|
||||
@ -1991,7 +2033,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"associated type `{}` could derive from `{}`",
|
||||
ty_param_name,
|
||||
bound.print_only_trait_path(),
|
||||
@ -1999,7 +2041,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
if !where_bounds.is_empty() {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"consider introducing a new type parameter `T` and adding `where` constraints:\
|
||||
\n where\n T: {},\n{}",
|
||||
ty_param_name,
|
||||
@ -2067,14 +2109,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// work for the `enum`, instead of just looking if it takes *any*.
|
||||
err.span_suggestion_verbose(
|
||||
args_span,
|
||||
&format!("{type_name} doesn't have generic parameters"),
|
||||
format!("{type_name} doesn't have generic parameters"),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return;
|
||||
}
|
||||
let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
return;
|
||||
};
|
||||
let (qself_sugg_span, is_self) = if let hir::TyKind::Path(
|
||||
@ -2108,12 +2150,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
kw::SelfUpper == segment.ident.name,
|
||||
),
|
||||
_ => {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
return;
|
||||
};
|
||||
let suggestion = vec![
|
||||
@ -2128,7 +2170,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
(args_span, String::new()),
|
||||
];
|
||||
err.multipart_suggestion_verbose(
|
||||
&msg,
|
||||
msg,
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
@ -2180,7 +2222,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let reported = if variant_resolution.is_some() {
|
||||
// Variant in type position
|
||||
let msg = format!("expected type, found variant `{}`", assoc_ident);
|
||||
tcx.sess.span_err(span, &msg)
|
||||
tcx.sess.span_err(span, msg)
|
||||
} else if qself_ty.is_enum() {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
@ -2251,7 +2293,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// Assume that if it's not matched, there must be a const defined with the same name
|
||||
// but it was used in a type position.
|
||||
let msg = format!("found associated const `{assoc_ident}` when type was expected");
|
||||
let guar = tcx.sess.struct_span_err(span, &msg).emit();
|
||||
let guar = tcx.sess.struct_span_err(span, msg).emit();
|
||||
return Err(guar);
|
||||
};
|
||||
|
||||
@ -2271,7 +2313,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
also,
|
||||
tcx.def_kind_descr(kind, def_id)
|
||||
);
|
||||
lint.span_note(tcx.def_span(def_id), ¬e_msg);
|
||||
lint.span_note(tcx.def_span(def_id), note_msg);
|
||||
};
|
||||
|
||||
could_refer_to(DefKind::Variant, variant_def_id, "");
|
||||
@ -2468,9 +2510,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let msg = format!("{kind} `{name}` is private");
|
||||
let def_span = tcx.def_span(item);
|
||||
tcx.sess
|
||||
.struct_span_err_with_code(span, &msg, rustc_errors::error_code!(E0624))
|
||||
.span_label(span, &format!("private {kind}"))
|
||||
.span_label(def_span, &format!("{kind} defined here"))
|
||||
.struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624))
|
||||
.span_label(span, format!("private {kind}"))
|
||||
.span_label(def_span, format!("{kind} defined here"))
|
||||
.emit();
|
||||
}
|
||||
tcx.check_stability(item, Some(block), span, None);
|
||||
@ -2918,7 +2960,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
self.prohibit_generics(path.segments.iter(), |err| {
|
||||
if let Some(span) = tcx.def_ident_span(def_id) {
|
||||
let name = tcx.item_name(def_id);
|
||||
err.span_note(span, &format!("type parameter `{name}` defined here"));
|
||||
err.span_note(span, format!("type parameter `{name}` defined here"));
|
||||
}
|
||||
});
|
||||
|
||||
@ -2979,7 +3021,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let mut span: MultiSpan = vec![t_sp].into();
|
||||
span.push_span_label(
|
||||
i_sp,
|
||||
&format!("`Self` is on type `{type_name}` in this `impl`"),
|
||||
format!("`Self` is on type `{type_name}` in this `impl`"),
|
||||
);
|
||||
let mut postfix = "";
|
||||
if generics == 0 {
|
||||
@ -2987,11 +3029,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
span.push_span_label(
|
||||
t_sp,
|
||||
&format!("`Self` corresponds to this type{postfix}"),
|
||||
format!("`Self` corresponds to this type{postfix}"),
|
||||
);
|
||||
err.span_note(span, &msg);
|
||||
err.span_note(span, msg);
|
||||
} else {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
}
|
||||
for segment in path.segments {
|
||||
if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper {
|
||||
@ -3082,7 +3124,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
if let Some(args) = segment.args {
|
||||
err.span_suggestion_verbose(
|
||||
segment.ident.span.shrink_to_hi().to(args.span_ext),
|
||||
&format!("primitive type `{name}` doesn't have generic parameters"),
|
||||
format!("primitive type `{name}` doesn't have generic parameters"),
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
@ -3373,7 +3415,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
if !infer_replacements.is_empty() {
|
||||
diag.multipart_suggestion(
|
||||
&format!(
|
||||
format!(
|
||||
"try replacing `_` with the type{} in the corresponding trait method signature",
|
||||
rustc_errors::pluralize!(infer_replacements.len()),
|
||||
),
|
||||
|
@ -175,7 +175,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
}
|
||||
// Generic statics are rejected, but we still reach this case.
|
||||
Err(e) => {
|
||||
tcx.sess.delay_span_bug(span, &e.to_string());
|
||||
tcx.sess.delay_span_bug(span, e.to_string());
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -334,7 +334,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||
&tcx.sess.parse_sess,
|
||||
sym::impl_trait_projections,
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"`{}` return type cannot contain a projection or `Self` that references \
|
||||
lifetimes from a parent scope",
|
||||
if is_async { "async fn" } else { "impl Trait" },
|
||||
@ -428,7 +428,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
let ty_err = ty_err.to_string(tcx);
|
||||
tcx.sess.delay_span_bug(
|
||||
span,
|
||||
&format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
|
||||
format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -618,11 +618,11 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||
E0044,
|
||||
"foreign items may not have {kinds} parameters",
|
||||
)
|
||||
.span_label(item.span, &format!("can't have {kinds} parameters"))
|
||||
.span_label(item.span, format!("can't have {kinds} parameters"))
|
||||
.help(
|
||||
// FIXME: once we start storing spans for type arguments, turn this
|
||||
// into a suggestion.
|
||||
&format!(
|
||||
format!(
|
||||
"replace the {} parameters with concrete {}{}",
|
||||
kinds,
|
||||
kinds_pl,
|
||||
@ -985,10 +985,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
||||
|
||||
err.span_note(
|
||||
tcx.def_span(def_spans[0].0),
|
||||
&format!(
|
||||
"`{}` has a `#[repr(align)]` attribute",
|
||||
tcx.item_name(def_spans[0].0)
|
||||
),
|
||||
format!("`{}` has a `#[repr(align)]` attribute", tcx.item_name(def_spans[0].0)),
|
||||
);
|
||||
|
||||
if def_spans.len() > 2 {
|
||||
@ -997,7 +994,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
||||
let ident = tcx.item_name(*adt_def);
|
||||
err.span_note(
|
||||
*span,
|
||||
&if first {
|
||||
if first {
|
||||
format!(
|
||||
"`{}` contains a field of type `{}`",
|
||||
tcx.type_of(def.did()).subst_identity(),
|
||||
@ -1466,10 +1463,10 @@ fn opaque_type_cycle_error(
|
||||
let ty_span = tcx.def_span(def_id);
|
||||
if !seen.contains(&ty_span) {
|
||||
let descr = if ty.is_impl_trait() { "opaque " } else { "" };
|
||||
err.span_label(ty_span, &format!("returning this {descr}type `{ty}`"));
|
||||
err.span_label(ty_span, format!("returning this {descr}type `{ty}`"));
|
||||
seen.insert(ty_span);
|
||||
}
|
||||
err.span_label(sp, &format!("returning here with type `{ty}`"));
|
||||
err.span_label(sp, format!("returning here with type `{ty}`"));
|
||||
}
|
||||
|
||||
for closure_def_id in visitor.closures {
|
||||
|
@ -1273,7 +1273,7 @@ fn compare_number_of_generics<'tcx>(
|
||||
|
||||
let mut err = tcx.sess.struct_span_err_with_code(
|
||||
spans,
|
||||
&format!(
|
||||
format!(
|
||||
"{} `{}` has {} {kind} parameter{} but its trait \
|
||||
declaration has {} {kind} parameter{}",
|
||||
item_kind,
|
||||
|
@ -52,7 +52,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
|
||||
let span = tcx.def_span(drop_impl_did);
|
||||
let reported = tcx.sess.delay_span_bug(
|
||||
span,
|
||||
&format!("should have been rejected by coherence check: {dtor_self_type}"),
|
||||
format!("should have been rejected by coherence check: {dtor_self_type}"),
|
||||
);
|
||||
Err(reported)
|
||||
}
|
||||
@ -76,15 +76,15 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
||||
struct_span_err!(tcx.sess, drop_impl_span, E0366, "`Drop` impls cannot be specialized");
|
||||
match arg {
|
||||
ty::util::NotUniqueParam::DuplicateParam(arg) => {
|
||||
err.note(&format!("`{arg}` is mentioned multiple times"))
|
||||
err.note(format!("`{arg}` is mentioned multiple times"))
|
||||
}
|
||||
ty::util::NotUniqueParam::NotParam(arg) => {
|
||||
err.note(&format!("`{arg}` is not a generic parameter"))
|
||||
err.note(format!("`{arg}` is not a generic parameter"))
|
||||
}
|
||||
};
|
||||
err.span_note(
|
||||
item_span,
|
||||
&format!(
|
||||
format!(
|
||||
"use the same sequence of generic lifetime, type and const parameters \
|
||||
as the {self_descr} definition",
|
||||
),
|
||||
|
@ -547,14 +547,14 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
||||
Err(_) => {
|
||||
let msg =
|
||||
format!("unrecognized platform-specific intrinsic function: `{name}`");
|
||||
tcx.sess.struct_span_err(it.span, &msg).emit();
|
||||
tcx.sess.struct_span_err(it.span, msg).emit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let msg = format!("unrecognized platform-specific intrinsic function: `{name}`");
|
||||
tcx.sess.struct_span_err(it.span, &msg).emit();
|
||||
tcx.sess.struct_span_err(it.span, msg).emit();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -130,7 +130,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
_ => None,
|
||||
};
|
||||
let Some(asm_ty) = asm_ty else {
|
||||
let msg = &format!("cannot use value of type `{ty}` for inline assembly");
|
||||
let msg = format!("cannot use value of type `{ty}` for inline assembly");
|
||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||
err.note(
|
||||
"only integers, floats, SIMD vectors, pointers and function pointers \
|
||||
@ -145,7 +145,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
if !ty.is_copy_modulo_regions(self.tcx, self.param_env) {
|
||||
let msg = "arguments for inline assembly must be copyable";
|
||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||
err.note(&format!("`{ty}` does not implement the Copy trait"));
|
||||
err.note(format!("`{ty}` does not implement the Copy trait"));
|
||||
err.emit();
|
||||
}
|
||||
|
||||
@ -164,8 +164,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
|
||||
|
||||
let in_expr_ty = (self.get_operand_ty)(in_expr);
|
||||
err.span_label(in_expr.span, &format!("type `{in_expr_ty}`"));
|
||||
err.span_label(expr.span, &format!("type `{ty}`"));
|
||||
err.span_label(in_expr.span, format!("type `{in_expr_ty}`"));
|
||||
err.span_label(expr.span, format!("type `{ty}`"));
|
||||
err.note(
|
||||
"asm inout arguments must have the same type, \
|
||||
unless they are both pointers or integers of the same size",
|
||||
@ -184,17 +184,17 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
let reg_class = reg.reg_class();
|
||||
let supported_tys = reg_class.supported_types(asm_arch);
|
||||
let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else {
|
||||
let msg = &format!("type `{ty}` cannot be used with this register class");
|
||||
let msg = format!("type `{ty}` cannot be used with this register class");
|
||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||
let supported_tys: Vec<_> =
|
||||
supported_tys.iter().map(|(t, _)| t.to_string()).collect();
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"register class `{}` supports these types: {}",
|
||||
reg_class.name(),
|
||||
supported_tys.join(", "),
|
||||
));
|
||||
if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"consider using the `{}` register class instead",
|
||||
suggest.name()
|
||||
));
|
||||
@ -215,9 +215,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
// register class is usable at all.
|
||||
if let Some(feature) = feature {
|
||||
if !target_features.contains(feature) {
|
||||
let msg = &format!("`{}` target feature is not enabled", feature);
|
||||
let msg = format!("`{}` target feature is not enabled", feature);
|
||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"this is required to use type `{}` with register class `{}`",
|
||||
ty,
|
||||
reg_class.name(),
|
||||
@ -252,10 +252,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
"formatting may not be suitable for sub-register argument",
|
||||
|lint| {
|
||||
lint.span_label(expr.span, "for this argument");
|
||||
lint.help(&format!(
|
||||
lint.help(format!(
|
||||
"use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`",
|
||||
));
|
||||
lint.help(&format!(
|
||||
lint.help(format!(
|
||||
"or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
|
||||
));
|
||||
lint
|
||||
@ -301,7 +301,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
op.is_clobber(),
|
||||
) {
|
||||
let msg = format!("cannot use register `{}`: {}", reg.name(), msg);
|
||||
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
|
||||
self.tcx.sess.struct_span_err(*op_sp, msg).emit();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -340,7 +340,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
reg_class.name(),
|
||||
feature
|
||||
);
|
||||
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
|
||||
self.tcx.sess.struct_span_err(*op_sp, msg).emit();
|
||||
// register isn't enabled, don't do more checks
|
||||
continue;
|
||||
}
|
||||
@ -354,7 +354,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
.intersperse(", ")
|
||||
.collect::<String>(),
|
||||
);
|
||||
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
|
||||
self.tcx.sess.struct_span_err(*op_sp, msg).emit();
|
||||
// register isn't enabled, don't do more checks
|
||||
continue;
|
||||
}
|
||||
@ -436,7 +436,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
self.tcx.sess.struct_span_err(*op_sp, "invalid `sym` operand");
|
||||
err.span_label(
|
||||
self.tcx.def_span(anon_const.def_id),
|
||||
&format!("is {} `{}`", ty.kind().article(), ty),
|
||||
format!("is {} `{}`", ty.kind().article(), ty),
|
||||
);
|
||||
err.help("`sym` operands must refer to either a function or a static");
|
||||
err.emit();
|
||||
|
@ -445,7 +445,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||
let plural = pluralize!(unsatisfied_bounds.len());
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
gat_item_hir.span,
|
||||
&format!("missing required bound{} on `{}`", plural, gat_item_hir.ident),
|
||||
format!("missing required bound{} on `{}`", plural, gat_item_hir.ident),
|
||||
);
|
||||
|
||||
let suggestion = format!(
|
||||
@ -455,14 +455,14 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||
);
|
||||
err.span_suggestion(
|
||||
gat_item_hir.generics.tail_span_for_predicate_suggestion(),
|
||||
&format!("add the required where clause{plural}"),
|
||||
format!("add the required where clause{plural}"),
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
let bound =
|
||||
if unsatisfied_bounds.len() > 1 { "these bounds are" } else { "this bound is" };
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"{} currently required to ensure that impls have maximum flexibility",
|
||||
bound
|
||||
));
|
||||
@ -916,14 +916,14 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
||||
if is_ptr {
|
||||
tcx.sess.span_err(
|
||||
hir_ty.span,
|
||||
&format!(
|
||||
format!(
|
||||
"using {unsupported_type} as const generic parameters is forbidden",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
hir_ty.span,
|
||||
&format!(
|
||||
format!(
|
||||
"{unsupported_type} is forbidden as the type of a const generic parameter",
|
||||
),
|
||||
);
|
||||
@ -1029,7 +1029,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
||||
let ty = tcx.erase_regions(ty);
|
||||
if ty.has_infer() {
|
||||
tcx.sess
|
||||
.delay_span_bug(item.span, &format!("inference variables in {:?}", ty));
|
||||
.delay_span_bug(item.span, format!("inference variables in {:?}", ty));
|
||||
// Just treat unresolved type expression as if it needs drop.
|
||||
true
|
||||
} else {
|
||||
@ -1651,7 +1651,7 @@ fn check_method_receiver<'tcx>(
|
||||
&tcx.sess.parse_sess,
|
||||
sym::arbitrary_self_types,
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"`{receiver_ty}` cannot be used as the type of `self` without \
|
||||
the `arbitrary_self_types` feature",
|
||||
),
|
||||
@ -1874,10 +1874,10 @@ fn report_bivariance(
|
||||
} else {
|
||||
format!("consider removing `{param_name}` or referring to it in a field")
|
||||
};
|
||||
err.help(&msg);
|
||||
err.help(msg);
|
||||
|
||||
if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
|
||||
param_name
|
||||
));
|
||||
|
@ -1,9 +1,11 @@
|
||||
//! Check properties that are required by built-in traits and set
|
||||
//! up data structures required by type-checking/codegen.
|
||||
|
||||
use crate::errors::{CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem};
|
||||
use crate::errors::{
|
||||
ConstParamTyImplOnNonAdt, CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{struct_span_err, MultiSpan};
|
||||
use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
@ -14,9 +16,11 @@ use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::traits::misc::{
|
||||
type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason,
|
||||
type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy,
|
||||
ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason,
|
||||
};
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause};
|
||||
@ -27,6 +31,7 @@ pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) {
|
||||
Checker { tcx, trait_def_id }
|
||||
.check(lang_items.drop_trait(), visit_implementation_of_drop)
|
||||
.check(lang_items.copy_trait(), visit_implementation_of_copy)
|
||||
.check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty)
|
||||
.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)
|
||||
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn);
|
||||
}
|
||||
@ -83,110 +88,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) {
|
||||
Ok(()) => {}
|
||||
Err(CopyImplementationError::InfringingFields(fields)) => {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0204,
|
||||
"the trait `Copy` cannot be implemented for this type"
|
||||
);
|
||||
|
||||
// We'll try to suggest constraining type parameters to fulfill the requirements of
|
||||
// their `Copy` implementation.
|
||||
let mut errors: BTreeMap<_, Vec<_>> = Default::default();
|
||||
let mut bounds = vec![];
|
||||
|
||||
let mut seen_tys = FxHashSet::default();
|
||||
|
||||
for (field, ty, reason) in fields {
|
||||
// Only report an error once per type.
|
||||
if !seen_tys.insert(ty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let field_span = tcx.def_span(field.did);
|
||||
err.span_label(field_span, "this field does not implement `Copy`");
|
||||
|
||||
match reason {
|
||||
InfringingFieldsReason::Fulfill(fulfillment_errors) => {
|
||||
for error in fulfillment_errors {
|
||||
let error_predicate = error.obligation.predicate;
|
||||
// Only note if it's not the root obligation, otherwise it's trivial and
|
||||
// should be self-explanatory (i.e. a field literally doesn't implement Copy).
|
||||
|
||||
// FIXME: This error could be more descriptive, especially if the error_predicate
|
||||
// contains a foreign type or if it's a deeply nested type...
|
||||
if error_predicate != error.root_obligation.predicate {
|
||||
errors
|
||||
.entry((ty.to_string(), error_predicate.to_string()))
|
||||
.or_default()
|
||||
.push(error.obligation.cause.span);
|
||||
}
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(
|
||||
ty::TraitPredicate {
|
||||
trait_ref,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
..
|
||||
},
|
||||
)) = error_predicate.kind().skip_binder()
|
||||
{
|
||||
let ty = trait_ref.self_ty();
|
||||
if let ty::Param(_) = ty.kind() {
|
||||
bounds.push((
|
||||
format!("{ty}"),
|
||||
trait_ref.print_only_trait_path().to_string(),
|
||||
Some(trait_ref.def_id),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
InfringingFieldsReason::Regions(region_errors) => {
|
||||
for error in region_errors {
|
||||
let ty = ty.to_string();
|
||||
match error {
|
||||
RegionResolutionError::ConcreteFailure(origin, a, b) => {
|
||||
let predicate = format!("{b}: {a}");
|
||||
errors
|
||||
.entry((ty.clone(), predicate.clone()))
|
||||
.or_default()
|
||||
.push(origin.span());
|
||||
if let ty::RegionKind::ReEarlyBound(ebr) = *b && ebr.has_name() {
|
||||
bounds.push((b.to_string(), a.to_string(), None));
|
||||
}
|
||||
}
|
||||
RegionResolutionError::GenericBoundFailure(origin, a, b) => {
|
||||
let predicate = format!("{a}: {b}");
|
||||
errors
|
||||
.entry((ty.clone(), predicate.clone()))
|
||||
.or_default()
|
||||
.push(origin.span());
|
||||
if let infer::region_constraints::GenericKind::Param(_) = a {
|
||||
bounds.push((a.to_string(), b.to_string(), None));
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ((ty, error_predicate), spans) in errors {
|
||||
let span: MultiSpan = spans.into();
|
||||
err.span_note(
|
||||
span,
|
||||
&format!("the `Copy` impl for `{}` requires that `{}`", ty, error_predicate),
|
||||
);
|
||||
}
|
||||
suggest_constraining_type_params(
|
||||
tcx,
|
||||
tcx.hir().get_generics(impl_did).expect("impls always have generics"),
|
||||
&mut err,
|
||||
bounds.iter().map(|(param, constraint, def_id)| {
|
||||
(param.as_str(), constraint.as_str(), *def_id)
|
||||
}),
|
||||
None,
|
||||
);
|
||||
err.emit();
|
||||
infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span);
|
||||
}
|
||||
Err(CopyImplementationError::NotAnAdt) => {
|
||||
tcx.sess.emit_err(CopyImplOnNonAdt { span });
|
||||
@ -197,6 +99,29 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
let self_type = tcx.type_of(impl_did).subst_identity();
|
||||
assert!(!self_type.has_escaping_bound_vars());
|
||||
|
||||
let param_env = tcx.param_env(impl_did);
|
||||
|
||||
let span = match tcx.hir().expect_item(impl_did).expect_impl() {
|
||||
hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return,
|
||||
impl_ => impl_.self_ty.span,
|
||||
};
|
||||
|
||||
let cause = traits::ObligationCause::misc(span, impl_did);
|
||||
match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
|
||||
Ok(()) => {}
|
||||
Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
|
||||
infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span);
|
||||
}
|
||||
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
|
||||
tcx.sess.emit_err(ConstParamTyImplOnNonAdt { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", impl_did);
|
||||
|
||||
@ -288,7 +213,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||
for structs containing the field being coerced, \
|
||||
ZST fields with 1 byte alignment, and nothing else",
|
||||
)
|
||||
.note(&format!(
|
||||
.note(format!(
|
||||
"extra field `{}` of type `{}` is not allowed",
|
||||
field.name, ty_a,
|
||||
))
|
||||
@ -316,7 +241,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||
for a coercion between structures with a single field \
|
||||
being coerced",
|
||||
)
|
||||
.note(&format!(
|
||||
.note(format!(
|
||||
"currently, {} fields need coercions: {}",
|
||||
coerced_fields.len(),
|
||||
coerced_fields
|
||||
@ -373,7 +298,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
|
||||
|
||||
let unsize_trait = tcx.lang_items().require(LangItem::Unsize).unwrap_or_else(|err| {
|
||||
tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err.to_string()));
|
||||
tcx.sess.fatal(format!("`CoerceUnsized` implementation {}", err.to_string()));
|
||||
});
|
||||
|
||||
let source = tcx.type_of(impl_did).subst_identity();
|
||||
@ -544,7 +469,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||
"`CoerceUnsized` may only be implemented for \
|
||||
a coercion between structures with one field being coerced",
|
||||
)
|
||||
.note(&format!(
|
||||
.note(format!(
|
||||
"currently, {} fields need coercions: {}",
|
||||
diff_fields.len(),
|
||||
diff_fields
|
||||
@ -593,3 +518,119 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||
|
||||
CoerceUnsizedInfo { custom_kind: kind }
|
||||
}
|
||||
|
||||
fn infringing_fields_error(
|
||||
tcx: TyCtxt<'_>,
|
||||
fields: Vec<(&ty::FieldDef, Ty<'_>, InfringingFieldsReason<'_>)>,
|
||||
lang_item: LangItem,
|
||||
impl_did: LocalDefId,
|
||||
impl_span: Span,
|
||||
) -> ErrorGuaranteed {
|
||||
let trait_did = tcx.require_lang_item(lang_item, Some(impl_span));
|
||||
|
||||
let trait_name = tcx.def_path_str(trait_did);
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_span,
|
||||
E0204,
|
||||
"the trait `{trait_name}` cannot be implemented for this type"
|
||||
);
|
||||
|
||||
// We'll try to suggest constraining type parameters to fulfill the requirements of
|
||||
// their `Copy` implementation.
|
||||
let mut errors: BTreeMap<_, Vec<_>> = Default::default();
|
||||
let mut bounds = vec![];
|
||||
|
||||
let mut seen_tys = FxHashSet::default();
|
||||
|
||||
for (field, ty, reason) in fields {
|
||||
// Only report an error once per type.
|
||||
if !seen_tys.insert(ty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let field_span = tcx.def_span(field.did);
|
||||
err.span_label(field_span, format!("this field does not implement `{trait_name}`"));
|
||||
|
||||
match reason {
|
||||
InfringingFieldsReason::Fulfill(fulfillment_errors) => {
|
||||
for error in fulfillment_errors {
|
||||
let error_predicate = error.obligation.predicate;
|
||||
// Only note if it's not the root obligation, otherwise it's trivial and
|
||||
// should be self-explanatory (i.e. a field literally doesn't implement Copy).
|
||||
|
||||
// FIXME: This error could be more descriptive, especially if the error_predicate
|
||||
// contains a foreign type or if it's a deeply nested type...
|
||||
if error_predicate != error.root_obligation.predicate {
|
||||
errors
|
||||
.entry((ty.to_string(), error_predicate.to_string()))
|
||||
.or_default()
|
||||
.push(error.obligation.cause.span);
|
||||
}
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
..
|
||||
})) = error_predicate.kind().skip_binder()
|
||||
{
|
||||
let ty = trait_ref.self_ty();
|
||||
if let ty::Param(_) = ty.kind() {
|
||||
bounds.push((
|
||||
format!("{ty}"),
|
||||
trait_ref.print_only_trait_path().to_string(),
|
||||
Some(trait_ref.def_id),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
InfringingFieldsReason::Regions(region_errors) => {
|
||||
for error in region_errors {
|
||||
let ty = ty.to_string();
|
||||
match error {
|
||||
RegionResolutionError::ConcreteFailure(origin, a, b) => {
|
||||
let predicate = format!("{b}: {a}");
|
||||
errors
|
||||
.entry((ty.clone(), predicate.clone()))
|
||||
.or_default()
|
||||
.push(origin.span());
|
||||
if let ty::RegionKind::ReEarlyBound(ebr) = *b && ebr.has_name() {
|
||||
bounds.push((b.to_string(), a.to_string(), None));
|
||||
}
|
||||
}
|
||||
RegionResolutionError::GenericBoundFailure(origin, a, b) => {
|
||||
let predicate = format!("{a}: {b}");
|
||||
errors
|
||||
.entry((ty.clone(), predicate.clone()))
|
||||
.or_default()
|
||||
.push(origin.span());
|
||||
if let infer::region_constraints::GenericKind::Param(_) = a {
|
||||
bounds.push((a.to_string(), b.to_string(), None));
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ((ty, error_predicate), spans) in errors {
|
||||
let span: MultiSpan = spans.into();
|
||||
err.span_note(
|
||||
span,
|
||||
format!("the `{trait_name}` impl for `{ty}` requires that `{error_predicate}`"),
|
||||
);
|
||||
}
|
||||
suggest_constraining_type_params(
|
||||
tcx,
|
||||
tcx.hir().get_generics(impl_did).expect("impls always have generics"),
|
||||
&mut err,
|
||||
bounds
|
||||
.iter()
|
||||
.map(|(param, constraint, def_id)| (param.as_str(), constraint.as_str(), *def_id)),
|
||||
None,
|
||||
);
|
||||
|
||||
err.emit()
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
||||
);
|
||||
err.help("consider using an extension trait instead");
|
||||
if let ty::Ref(_, subty, _) = ty.kind() {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"you could also try moving the reference to \
|
||||
uses of `{}` (such as `self`) within the implementation",
|
||||
subty
|
||||
|
@ -372,10 +372,10 @@ fn emit_orphan_check_error<'tcx>(
|
||||
|
||||
if is_target_ty {
|
||||
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
||||
err.span_label(self_ty_span, &msg);
|
||||
err.span_label(self_ty_span, msg);
|
||||
} else {
|
||||
// Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
|
||||
err.span_label(trait_span, &msg);
|
||||
err.span_label(trait_span, msg);
|
||||
}
|
||||
}
|
||||
err.note("define and implement a trait or new type instead");
|
||||
@ -531,15 +531,15 @@ fn lint_auto_trait_impl<'tcx>(
|
||||
let self_descr = tcx.def_descr(self_type_did);
|
||||
match arg {
|
||||
ty::util::NotUniqueParam::DuplicateParam(arg) => {
|
||||
lint.note(&format!("`{}` is mentioned multiple times", arg));
|
||||
lint.note(format!("`{}` is mentioned multiple times", arg));
|
||||
}
|
||||
ty::util::NotUniqueParam::NotParam(arg) => {
|
||||
lint.note(&format!("`{}` is not a generic parameter", arg));
|
||||
lint.note(format!("`{}` is not a generic parameter", arg));
|
||||
}
|
||||
}
|
||||
lint.span_note(
|
||||
item_span,
|
||||
&format!(
|
||||
format!(
|
||||
"try using the same sequence of generic parameters as the {} definition",
|
||||
self_descr,
|
||||
),
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::ItemCtxt;
|
||||
use crate::astconv::AstConv;
|
||||
use crate::astconv::{AstConv, OnlySelfBounds};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
|
||||
);
|
||||
|
||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
|
||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
||||
|
||||
@ -67,7 +67,7 @@ fn opaque_type_bounds<'tcx>(
|
||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
||||
ty::print::with_no_queries!({
|
||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
|
||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
||||
debug!(?bounds);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::astconv::AstConv;
|
||||
use crate::astconv::{AstConv, OnlySelfBounds};
|
||||
use crate::bounds::Bounds;
|
||||
use crate::collect::ItemCtxt;
|
||||
use crate::constrained_generic_params as cgp;
|
||||
@ -14,9 +14,6 @@ use rustc_middle::ty::{GenericPredicates, ToPredicate};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct OnlySelfBounds(bool);
|
||||
|
||||
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
||||
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
|
||||
/// `Self: Trait` predicates for traits.
|
||||
@ -99,8 +96,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||
| ItemKind::Struct(_, generics)
|
||||
| ItemKind::Union(_, generics) => generics,
|
||||
|
||||
ItemKind::Trait(_, _, generics, ..) | ItemKind::TraitAlias(generics, _) => {
|
||||
is_trait = Some(ty::TraitRef::identity(tcx, def_id.to_def_id()));
|
||||
ItemKind::Trait(_, _, generics, self_bounds, ..)
|
||||
| ItemKind::TraitAlias(generics, self_bounds) => {
|
||||
is_trait = Some(self_bounds);
|
||||
generics
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics,
|
||||
@ -122,10 +120,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||
|
||||
// Below we'll consider the bounds on the type parameters (including `Self`)
|
||||
// and the explicit where-clauses, but to get the full set of predicates
|
||||
// on a trait we need to add in the supertrait bounds and bounds found on
|
||||
// associated types.
|
||||
if let Some(_trait_ref) = is_trait {
|
||||
predicates.extend(tcx.implied_predicates_of(def_id).predicates.iter().cloned());
|
||||
// on a trait we must also consider the bounds that follow the trait's name,
|
||||
// like `trait Foo: A + B + C`.
|
||||
if let Some(self_bounds) = is_trait {
|
||||
predicates.extend(
|
||||
icx.astconv()
|
||||
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
|
||||
.predicates(),
|
||||
);
|
||||
}
|
||||
|
||||
// In default impls, we can assume that the self type implements
|
||||
@ -225,7 +227,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||
}
|
||||
|
||||
let mut bounds = Bounds::default();
|
||||
icx.astconv().add_bounds(ty, bound_pred.bounds.iter(), &mut bounds, bound_vars);
|
||||
icx.astconv().add_bounds(
|
||||
ty,
|
||||
bound_pred.bounds.iter(),
|
||||
&mut bounds,
|
||||
bound_vars,
|
||||
OnlySelfBounds(false),
|
||||
);
|
||||
predicates.extend(bounds.predicates());
|
||||
}
|
||||
|
||||
@ -608,7 +616,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||
let (superbounds, where_bounds_that_match) = match filter {
|
||||
PredicateFilter::All => (
|
||||
// Convert the bounds that follow the colon (or equal in trait aliases)
|
||||
icx.astconv().compute_bounds(self_param_ty, bounds),
|
||||
icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false)),
|
||||
// Also include all where clause bounds
|
||||
icx.type_parameter_bounds_in_generics(
|
||||
generics,
|
||||
@ -620,7 +628,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||
),
|
||||
PredicateFilter::SelfOnly => (
|
||||
// Convert the bounds that follow the colon (or equal in trait aliases)
|
||||
icx.astconv().compute_bounds(self_param_ty, bounds),
|
||||
icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true)),
|
||||
// Include where clause bounds for `Self`
|
||||
icx.type_parameter_bounds_in_generics(
|
||||
generics,
|
||||
@ -774,32 +782,35 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||
only_self_bounds: OnlySelfBounds,
|
||||
assoc_name: Option<Ident>,
|
||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||
ast_generics
|
||||
.predicates
|
||||
.iter()
|
||||
.filter_map(|wp| match wp {
|
||||
hir::WherePredicate::BoundPredicate(bp) => Some(bp),
|
||||
_ => None,
|
||||
})
|
||||
.flat_map(|bp| {
|
||||
let bt = if bp.is_param_bound(param_def_id.to_def_id()) {
|
||||
Some(ty)
|
||||
} else if !only_self_bounds.0 {
|
||||
Some(self.to_ty(bp.bounded_ty))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let bvars = self.tcx.late_bound_vars(bp.hir_id);
|
||||
let mut bounds = Bounds::default();
|
||||
|
||||
bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter(
|
||||
|(_, b, _)| match assoc_name {
|
||||
Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
|
||||
None => true,
|
||||
},
|
||||
)
|
||||
})
|
||||
.flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars))
|
||||
.collect()
|
||||
for predicate in ast_generics.predicates {
|
||||
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
|
||||
ty
|
||||
} else if !only_self_bounds.0 {
|
||||
self.to_ty(predicate.bounded_ty)
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
|
||||
self.astconv().add_bounds(
|
||||
bound_ty,
|
||||
predicate.bounds.iter().filter(|bound| {
|
||||
assoc_name
|
||||
.map_or(true, |assoc_name| self.bound_defines_assoc_item(bound, assoc_name))
|
||||
}),
|
||||
&mut bounds,
|
||||
bound_vars,
|
||||
only_self_bounds,
|
||||
);
|
||||
}
|
||||
|
||||
bounds.predicates().collect()
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
@ -817,19 +828,3 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a specific `GenericBound` from the AST into a set of
|
||||
/// predicates that apply to the self type. A vector is returned
|
||||
/// because this can be anywhere from zero predicates (`T: ?Sized` adds no
|
||||
/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar`
|
||||
/// and `<T as Bar>::X == i32`).
|
||||
fn predicates_from_bound<'tcx>(
|
||||
astconv: &dyn AstConv<'tcx>,
|
||||
param_ty: Ty<'tcx>,
|
||||
bound: &'tcx hir::GenericBound<'tcx>,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||
let mut bounds = Bounds::default();
|
||||
astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
|
||||
bounds.predicates().collect()
|
||||
}
|
||||
|
@ -987,7 +987,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
lifetime.ident
|
||||
),
|
||||
|lint| {
|
||||
let help = &format!(
|
||||
let help = format!(
|
||||
"you can use the `'static` lifetime directly, in place of `{}`",
|
||||
lifetime.ident,
|
||||
);
|
||||
@ -1365,7 +1365,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||
|
||||
self.tcx.sess.delay_span_bug(
|
||||
lifetime_ref.ident.span,
|
||||
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
|
||||
format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -828,14 +828,14 @@ fn infer_placeholder_type<'a>(
|
||||
if let Some(ty) = ty.make_suggestable(tcx, false) {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("provide a type for the {item}", item = kind),
|
||||
format!("provide a type for the {item}", item = kind),
|
||||
format!("{colon} {ty}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
with_forced_trimmed_paths!(err.span_note(
|
||||
tcx.hir().body(body_id).value.span,
|
||||
&format!("however, the inferred type `{ty}` cannot be named"),
|
||||
format!("however, the inferred type `{ty}` cannot be named"),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -856,7 +856,7 @@ fn infer_placeholder_type<'a>(
|
||||
} else {
|
||||
with_forced_trimmed_paths!(diag.span_note(
|
||||
tcx.hir().body(body_id).value.span,
|
||||
&format!("however, the inferred type `{ty}` cannot be named"),
|
||||
format!("however, the inferred type `{ty}` cannot be named"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,14 @@ pub struct CopyImplOnNonAdt {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_const_param_ty_impl_on_non_adt)]
|
||||
pub struct ConstParamTyImplOnNonAdt {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_trait_object_declared_with_no_traits, code = "E0224")]
|
||||
pub struct TraitObjectDeclaredWithNoTraits {
|
||||
|
@ -76,7 +76,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
||||
// (#36836)
|
||||
tcx.sess.delay_span_bug(
|
||||
tcx.def_span(impl_def_id),
|
||||
&format!(
|
||||
format!(
|
||||
"potentially unconstrained type parameters weren't evaluated: {:?}",
|
||||
impl_self_ty,
|
||||
),
|
||||
|
@ -272,7 +272,7 @@ fn check_duplicate_params<'tcx>(
|
||||
if let (_, [duplicate, ..]) = base_params.partition_dedup() {
|
||||
let param = impl1_substs[duplicate.0 as usize];
|
||||
tcx.sess
|
||||
.struct_span_err(span, &format!("specializing impl repeats parameter `{}`", param))
|
||||
.struct_span_err(span, format!("specializing impl repeats parameter `{}`", param))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
@ -464,7 +464,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"cannot specialize on trait `{}`",
|
||||
tcx.def_path_str(trait_ref.def_id),
|
||||
),
|
||||
@ -479,7 +479,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
&format!("cannot specialize on associated type `{projection_ty} == {term}`",),
|
||||
format!("cannot specialize on associated type `{projection_ty} == {term}`",),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
@ -495,7 +495,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||
}
|
||||
_ => {
|
||||
tcx.sess
|
||||
.struct_span_err(span, &format!("cannot specialize on predicate `{}`", predicate))
|
||||
.struct_span_err(span, format!("cannot specialize on predicate `{}`", predicate))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode,
|
||||
|
||||
use std::ops::Not;
|
||||
|
||||
use astconv::AstConv;
|
||||
use astconv::{AstConv, OnlySelfBounds};
|
||||
use bounds::Bounds;
|
||||
|
||||
fluent_messages! { "../messages.ftl" }
|
||||
@ -531,6 +531,7 @@ pub fn hir_trait_to_predicates<'tcx>(
|
||||
self_ty,
|
||||
&mut bounds,
|
||||
true,
|
||||
OnlySelfBounds(false),
|
||||
);
|
||||
|
||||
bounds
|
||||
|
@ -61,7 +61,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
|
||||
|
||||
let span = tcx.def_span(item_def_id);
|
||||
let mut err = tcx.sess.struct_span_err(span, "rustc_outlives");
|
||||
for p in &pred {
|
||||
for p in pred {
|
||||
err.note(p);
|
||||
}
|
||||
err.emit();
|
||||
|
@ -48,7 +48,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
|
||||
&self,
|
||||
mut err: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"certain types, like `{}`, must be casted before passing them to a \
|
||||
variadic function, because of arcane ABI rules dictated by the C \
|
||||
standard",
|
||||
|
@ -480,7 +480,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
let span = self.path_segment.ident.span;
|
||||
let msg = self.create_error_message();
|
||||
|
||||
self.tcx.sess.struct_span_err_with_code(span, &msg, self.code())
|
||||
self.tcx.sess.struct_span_err_with_code(span, msg, self.code())
|
||||
}
|
||||
|
||||
/// Builds the `expected 1 type argument / supplied 2 type arguments` message.
|
||||
@ -602,7 +602,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
&msg,
|
||||
msg,
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
@ -625,7 +625,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix);
|
||||
debug!("sugg: {:?}", sugg);
|
||||
|
||||
err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders);
|
||||
err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
|
||||
}
|
||||
AngleBrackets::Implied => {
|
||||
// We never encounter missing lifetimes in situations in which lifetimes are elided
|
||||
@ -652,7 +652,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
&msg,
|
||||
msg,
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
@ -683,7 +683,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix);
|
||||
debug!("sugg: {:?}", sugg);
|
||||
|
||||
err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders);
|
||||
err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -885,7 +885,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
|
||||
err.span_suggestion(
|
||||
span_redundant_lt_args,
|
||||
&msg_lifetimes,
|
||||
msg_lifetimes,
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
@ -927,7 +927,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
|
||||
err.span_suggestion(
|
||||
span_redundant_type_or_const_args,
|
||||
&msg_types_or_consts,
|
||||
msg_types_or_consts,
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
@ -943,7 +943,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
|
||||
if !suggestions.is_empty() {
|
||||
err.multipart_suggestion_verbose(
|
||||
&format!(
|
||||
format!(
|
||||
"replace the generic bound{s} with the associated type{s}",
|
||||
s = pluralize!(unbound_types.len())
|
||||
),
|
||||
@ -969,7 +969,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
},
|
||||
);
|
||||
|
||||
err.span_suggestion(span, &msg, "", Applicability::MaybeIncorrect);
|
||||
err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
|
||||
} else if redundant_lifetime_args && redundant_type_or_const_args {
|
||||
remove_lifetime_args(err);
|
||||
remove_type_or_const_args(err);
|
||||
@ -1029,7 +1029,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
)
|
||||
};
|
||||
|
||||
err.span_note(spans, &msg);
|
||||
err.span_note(spans, msg);
|
||||
}
|
||||
|
||||
/// Add note if `impl Trait` is explicitly specified.
|
||||
|
@ -1407,10 +1407,16 @@ impl<'a> State<'a> {
|
||||
self.print_type(ty);
|
||||
}
|
||||
hir::ExprKind::Type(expr, ty) => {
|
||||
let prec = AssocOp::Colon.precedence() as i8;
|
||||
self.print_expr_maybe_paren(expr, prec);
|
||||
self.word_space(":");
|
||||
self.word("type_ascribe!(");
|
||||
self.ibox(0);
|
||||
self.print_expr(expr);
|
||||
|
||||
self.word(",");
|
||||
self.space_if_not_bol();
|
||||
self.print_type(ty);
|
||||
|
||||
self.end();
|
||||
self.word(")");
|
||||
}
|
||||
hir::ExprKind::DropTemps(init) => {
|
||||
// Print `{`:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user