mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Auto merge of #112817 - compiler-errors:rollup-0eqomra, r=compiler-errors
Rollup of 8 pull requests Successful merges: - #112232 (Better error for non const `PartialEq` call generated by `match`) - #112499 (Fix python linting errors) - #112596 (Suggest correct signature on missing fn returning RPITIT/AFIT) - #112606 (Alter `Display` for `Ipv6Addr` for IPv4-compatible addresses) - #112781 (Don't consider TAIT normalizable to hidden ty if it would result in impossible item bounds) - #112787 (Add gha problem matcher) - #112799 (Clean up "doc(hidden)" check) - #112803 (Format the examples directory of cg_clif) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d7dcadc597
@ -14,7 +14,7 @@ use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::{
|
||||
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
|
||||
self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
|
||||
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
|
||||
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
|
||||
};
|
||||
@ -2579,7 +2579,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diagnostic) {
|
||||
let tcx = self.infcx.tcx;
|
||||
if let (
|
||||
Some(Terminator { kind: TerminatorKind::Call { from_hir_call: false, .. }, .. }),
|
||||
Some(Terminator {
|
||||
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
|
||||
..
|
||||
}),
|
||||
Some((method_did, method_substs)),
|
||||
) = (
|
||||
&self.body[loan.reserve_location.block].terminator,
|
||||
|
@ -6,8 +6,8 @@ use rustc_hir::intravisit::Visitor;
|
||||
use rustc_index::IndexSlice;
|
||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_middle::mir::{
|
||||
Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place,
|
||||
Rvalue, Statement, StatementKind, TerminatorKind,
|
||||
Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
|
||||
Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
|
||||
};
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::{self, RegionVid, TyCtxt};
|
||||
@ -494,7 +494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
} else if self.was_captured_by_trait_object(borrow) {
|
||||
LaterUseKind::TraitCapture
|
||||
} else if location.statement_index == block.statements.len() {
|
||||
if let TerminatorKind::Call { func, from_hir_call: true, .. } =
|
||||
if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
|
||||
&block.terminator().kind
|
||||
{
|
||||
// Just point to the function, to reduce the chance of overlapping spans.
|
||||
|
@ -13,8 +13,9 @@ use rustc_index::IndexSlice;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::{
|
||||
AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place,
|
||||
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
|
||||
AggregateKind, CallSource, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location,
|
||||
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
|
||||
TerminatorKind,
|
||||
};
|
||||
use rustc_middle::ty::print::Print;
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
@ -414,7 +415,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if !is_terminator {
|
||||
continue;
|
||||
} else if let Some(Terminator {
|
||||
kind: TerminatorKind::Call { func, from_hir_call: false, .. },
|
||||
kind:
|
||||
TerminatorKind::Call {
|
||||
func,
|
||||
call_source: CallSource::OverloadedOperator,
|
||||
..
|
||||
},
|
||||
..
|
||||
}) = &bbd.terminator
|
||||
{
|
||||
@ -839,7 +845,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
debug!("move_spans: target_temp = {:?}", target_temp);
|
||||
|
||||
if let Some(Terminator {
|
||||
kind: TerminatorKind::Call { fn_span, from_hir_call, .. }, ..
|
||||
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
||||
}) = &self.body[location.block].terminator
|
||||
{
|
||||
let Some((method_did, method_substs)) =
|
||||
@ -859,7 +865,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
method_did,
|
||||
method_substs,
|
||||
*fn_span,
|
||||
*from_hir_call,
|
||||
call_source.from_hir_call(),
|
||||
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
|
||||
);
|
||||
|
||||
|
@ -128,7 +128,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
destination,
|
||||
target: _,
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
self.consume_operand(location, func);
|
||||
|
@ -710,7 +710,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
|
||||
destination,
|
||||
target: _,
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
self.consume_operand(loc, (func, span), flow_state);
|
||||
|
@ -1065,7 +1065,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
)?;
|
||||
|
||||
ocx.infcx.add_item_bounds_for_hidden_type(
|
||||
opaque_type_key,
|
||||
opaque_type_key.def_id.to_def_id(),
|
||||
opaque_type_key.substs,
|
||||
cause,
|
||||
param_env,
|
||||
hidden_ty.ty,
|
||||
@ -1370,7 +1371,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
// FIXME: check the values
|
||||
}
|
||||
TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => {
|
||||
TerminatorKind::Call { func, args, destination, call_source, target, .. } => {
|
||||
self.check_operand(func, term_location);
|
||||
for arg in args {
|
||||
self.check_operand(arg, term_location);
|
||||
@ -1446,7 +1447,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
.add_element(region_vid, term_location);
|
||||
}
|
||||
|
||||
self.check_call_inputs(body, term, &sig, args, term_location, *from_hir_call);
|
||||
self.check_call_inputs(body, term, &sig, args, term_location, *call_source);
|
||||
}
|
||||
TerminatorKind::Assert { cond, msg, .. } => {
|
||||
self.check_operand(cond, term_location);
|
||||
@ -1573,7 +1574,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
args: &[Operand<'tcx>],
|
||||
term_location: Location,
|
||||
from_hir_call: bool,
|
||||
call_source: CallSource,
|
||||
) {
|
||||
debug!("check_call_inputs({:?}, {:?})", sig, args);
|
||||
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
|
||||
@ -1591,7 +1592,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let op_arg_ty = op_arg.ty(body, self.tcx());
|
||||
|
||||
let op_arg_ty = self.normalize(op_arg_ty, term_location);
|
||||
let category = if from_hir_call {
|
||||
let category = if call_source.from_hir_call() {
|
||||
ConstraintCategory::CallArgument(self.infcx.tcx.erase_regions(func_ty))
|
||||
} else {
|
||||
ConstraintCategory::Boring
|
||||
|
@ -421,7 +421,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
||||
target,
|
||||
fn_span,
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
} => {
|
||||
fx.tcx.prof.generic_activity("codegen call").run(|| {
|
||||
crate::abi::codegen_terminator_call(
|
||||
|
@ -3,7 +3,6 @@ import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
from os import walk
|
||||
|
||||
|
||||
def run_command(command, cwd=None):
|
||||
@ -180,7 +179,7 @@ def update_intrinsics(llvm_path, llvmint, llvmint2):
|
||||
intrinsics[arch].sort(key=lambda x: (x[0], x[2]))
|
||||
out.write(' // {}\n'.format(arch))
|
||||
for entry in intrinsics[arch]:
|
||||
if entry[2] == True: # if it is a duplicate
|
||||
if entry[2] is True: # if it is a duplicate
|
||||
out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(entry[0], entry[1]))
|
||||
elif "_round_mask" in entry[1]:
|
||||
out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(entry[0], entry[1]))
|
||||
|
@ -1280,7 +1280,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
destination,
|
||||
target,
|
||||
unwind,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span,
|
||||
} => self.codegen_call_terminator(
|
||||
helper,
|
||||
|
@ -210,6 +210,9 @@ const_eval_long_running =
|
||||
.label = the const evaluator is currently interpreting this expression
|
||||
.help = the constant being evaluated
|
||||
|
||||
const_eval_match_eq_non_const = cannot match on `{$ty}` in {const_eval_const_context}s
|
||||
.note = `{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
|
||||
const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
|
||||
|
||||
const_eval_memory_access_test = memory access failed
|
||||
|
@ -271,6 +271,18 @@ pub struct RawBytesNote {
|
||||
pub bytes: String,
|
||||
}
|
||||
|
||||
// FIXME(fee1-dead) do not use stringly typed `ConstContext`
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_match_eq_non_const, code = "E0015")]
|
||||
#[note]
|
||||
pub struct NonConstMatchEq<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_for_loop_into_iter_non_const, code = "E0015")]
|
||||
pub struct NonConstForLoopIntoIter<'tcx> {
|
||||
|
@ -62,7 +62,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
destination,
|
||||
target,
|
||||
unwind,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
let old_stack = self.frame_idx();
|
||||
|
@ -702,7 +702,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
self.super_terminator(terminator, location);
|
||||
|
||||
match &terminator.kind {
|
||||
TerminatorKind::Call { func, args, fn_span, from_hir_call, .. } => {
|
||||
TerminatorKind::Call { func, args, fn_span, call_source, .. } => {
|
||||
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
|
||||
let caller = self.def_id();
|
||||
|
||||
@ -755,7 +755,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
call_source: *call_source,
|
||||
feature: Some(sym::const_trait_impl),
|
||||
});
|
||||
return;
|
||||
@ -797,7 +797,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
});
|
||||
|
||||
@ -823,7 +823,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
});
|
||||
return;
|
||||
@ -866,7 +866,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
});
|
||||
return;
|
||||
@ -926,7 +926,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
callee,
|
||||
substs,
|
||||
span: *fn_span,
|
||||
from_hir_call: *from_hir_call,
|
||||
call_source: *call_source,
|
||||
feature: None,
|
||||
});
|
||||
return;
|
||||
|
@ -7,7 +7,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::{self, CallSource};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
|
||||
@ -100,7 +100,7 @@ pub struct FnCallNonConst<'tcx> {
|
||||
pub callee: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
pub span: Span,
|
||||
pub from_hir_call: bool,
|
||||
pub call_source: CallSource,
|
||||
pub feature: Option<Symbol>,
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
_: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let FnCallNonConst { caller, callee, substs, span, from_hir_call, feature } = *self;
|
||||
let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self;
|
||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||
|
||||
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
||||
@ -157,7 +157,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
let call_kind = call_kind(tcx, ccx.param_env, callee, substs, span, from_hir_call, None);
|
||||
let call_kind =
|
||||
call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None);
|
||||
|
||||
debug!(?call_kind);
|
||||
|
||||
@ -219,48 +220,59 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
err
|
||||
}
|
||||
CallKind::Operator { trait_id, self_ty, .. } => {
|
||||
let mut sugg = None;
|
||||
let mut err = if let CallSource::MatchCmp = call_source {
|
||||
tcx.sess.create_err(errors::NonConstMatchEq {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
ty: self_ty,
|
||||
})
|
||||
} else {
|
||||
let mut sugg = None;
|
||||
|
||||
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
|
||||
match (substs[0].unpack(), substs[1].unpack()) {
|
||||
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
|
||||
if self_ty == rhs_ty
|
||||
&& self_ty.is_ref()
|
||||
&& self_ty.peel_refs().is_primitive() =>
|
||||
{
|
||||
let mut num_refs = 0;
|
||||
let mut tmp_ty = self_ty;
|
||||
while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
|
||||
num_refs += 1;
|
||||
tmp_ty = *inner_ty;
|
||||
}
|
||||
let deref = "*".repeat(num_refs);
|
||||
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
|
||||
match (substs[0].unpack(), substs[1].unpack()) {
|
||||
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
|
||||
if self_ty == rhs_ty
|
||||
&& self_ty.is_ref()
|
||||
&& self_ty.peel_refs().is_primitive() =>
|
||||
{
|
||||
let mut num_refs = 0;
|
||||
let mut tmp_ty = self_ty;
|
||||
while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
|
||||
num_refs += 1;
|
||||
tmp_ty = *inner_ty;
|
||||
}
|
||||
let deref = "*".repeat(num_refs);
|
||||
|
||||
if let Ok(call_str) = ccx.tcx.sess.source_map().span_to_snippet(span) {
|
||||
if let Some(eq_idx) = call_str.find("==") {
|
||||
if let Some(rhs_idx) =
|
||||
call_str[(eq_idx + 2)..].find(|c: char| !c.is_whitespace())
|
||||
{
|
||||
let rhs_pos =
|
||||
span.lo() + BytePos::from_usize(eq_idx + 2 + rhs_idx);
|
||||
let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
|
||||
sugg = Some(errors::ConsiderDereferencing {
|
||||
deref,
|
||||
span: span.shrink_to_lo(),
|
||||
rhs_span,
|
||||
});
|
||||
if let Ok(call_str) =
|
||||
ccx.tcx.sess.source_map().span_to_snippet(span)
|
||||
{
|
||||
if let Some(eq_idx) = call_str.find("==") {
|
||||
if let Some(rhs_idx) = call_str[(eq_idx + 2)..]
|
||||
.find(|c: char| !c.is_whitespace())
|
||||
{
|
||||
let rhs_pos = span.lo()
|
||||
+ BytePos::from_usize(eq_idx + 2 + rhs_idx);
|
||||
let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
|
||||
sugg = Some(errors::ConsiderDereferencing {
|
||||
deref,
|
||||
span: span.shrink_to_lo(),
|
||||
rhs_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let mut err = tcx.sess.create_err(errors::NonConstOperator {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
sugg,
|
||||
});
|
||||
tcx.sess.create_err(errors::NonConstOperator {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
sugg,
|
||||
})
|
||||
};
|
||||
|
||||
diag_trait(&mut err, self_ty, trait_id);
|
||||
err
|
||||
}
|
||||
|
@ -797,7 +797,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
};
|
||||
|
||||
match terminator.kind {
|
||||
TerminatorKind::Call { mut func, mut args, from_hir_call, fn_span, .. } => {
|
||||
TerminatorKind::Call {
|
||||
mut func, mut args, call_source: desugar, fn_span, ..
|
||||
} => {
|
||||
self.visit_operand(&mut func, loc);
|
||||
for arg in &mut args {
|
||||
self.visit_operand(arg, loc);
|
||||
@ -813,7 +815,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
unwind: UnwindAction::Continue,
|
||||
destination: Place::from(new_temp),
|
||||
target: Some(new_target),
|
||||
from_hir_call,
|
||||
call_source: desugar,
|
||||
fn_span,
|
||||
},
|
||||
source_info: SourceInfo::outermost(terminator.source_info.span),
|
||||
|
@ -403,7 +403,32 @@ fn fn_sig_suggestion<'tcx>(
|
||||
.flatten()
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ");
|
||||
let output = sig.output();
|
||||
let mut output = sig.output();
|
||||
|
||||
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
||||
output = if let ty::Alias(_, alias_ty) = *output.kind() {
|
||||
tcx.explicit_item_bounds(alias_ty.def_id)
|
||||
.subst_iter_copied(tcx, alias_ty.substs)
|
||||
.find_map(|(bound, _)| {
|
||||
bound.to_opt_poly_projection_pred()?.no_bound_vars()?.term.ty()
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
span_bug!(
|
||||
ident.span,
|
||||
"expected async fn to have `impl Future` output, but it returns {output}"
|
||||
)
|
||||
})
|
||||
} else {
|
||||
span_bug!(
|
||||
ident.span,
|
||||
"expected async fn to have `impl Future` output, but it returns {output}"
|
||||
)
|
||||
};
|
||||
"async "
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
|
||||
|
||||
let unsafety = sig.unsafety.prefix_str();
|
||||
@ -414,7 +439,9 @@ fn fn_sig_suggestion<'tcx>(
|
||||
// lifetimes between the `impl` and the `trait`, but this should be good enough to
|
||||
// fill in a significant portion of the missing code, and other subsequent
|
||||
// suggestions can help the user fix the code.
|
||||
format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}")
|
||||
format!(
|
||||
"{unsafety}{asyncness}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}"
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
|
||||
|
@ -536,7 +536,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
)?;
|
||||
|
||||
self.add_item_bounds_for_hidden_type(
|
||||
opaque_type_key,
|
||||
opaque_type_key.def_id.to_def_id(),
|
||||
opaque_type_key.substs,
|
||||
cause,
|
||||
param_env,
|
||||
hidden_ty,
|
||||
@ -598,7 +599,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
|
||||
pub fn add_item_bounds_for_hidden_type(
|
||||
&self,
|
||||
OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
@ -631,7 +633,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// Replace all other mentions of the same opaque type with the hidden type,
|
||||
// as the bounds must hold on the hidden type after all.
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. })
|
||||
if def_id.to_def_id() == def_id2 && substs == substs2 =>
|
||||
if def_id == def_id2 && substs == substs2 =>
|
||||
{
|
||||
hidden_ty
|
||||
}
|
||||
@ -640,7 +642,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
ty::Alias(
|
||||
ty::Projection,
|
||||
ty::AliasTy { def_id: def_id2, substs: substs2, .. },
|
||||
) if def_id.to_def_id() == def_id2 && substs == substs2 => hidden_ty,
|
||||
) if def_id == def_id2 && substs == substs2 => hidden_ty,
|
||||
_ => ty,
|
||||
},
|
||||
lt_op: |lt| lt,
|
||||
|
@ -512,6 +512,31 @@ pub struct CopyNonOverlapping<'tcx> {
|
||||
pub count: Operand<'tcx>,
|
||||
}
|
||||
|
||||
/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics
|
||||
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub enum CallSource {
|
||||
/// This came from something such as `a > b` or `a + b`. In THIR, if `from_hir_call`
|
||||
/// is false then this is the desugaring.
|
||||
OverloadedOperator,
|
||||
/// This was from comparison generated by a match, used by const-eval for better errors
|
||||
/// when the comparison cannot be done in compile time.
|
||||
///
|
||||
/// (see <https://github.com/rust-lang/rust/issues/90237>)
|
||||
MatchCmp,
|
||||
/// Other types of desugaring that did not come from the HIR, but we don't care about
|
||||
/// for diagnostics (yet).
|
||||
Misc,
|
||||
/// Normal function call, no special source
|
||||
Normal,
|
||||
}
|
||||
|
||||
impl CallSource {
|
||||
pub fn from_hir_call(self) -> bool {
|
||||
matches!(self, CallSource::Normal)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Terminators
|
||||
|
||||
@ -638,11 +663,10 @@ pub enum TerminatorKind<'tcx> {
|
||||
target: Option<BasicBlock>,
|
||||
/// Action to be taken if the call unwinds.
|
||||
unwind: UnwindAction,
|
||||
/// `true` if this is from a call in HIR rather than from an overloaded
|
||||
/// operator. True for overloaded function call.
|
||||
from_hir_call: bool,
|
||||
/// Where this call came from in HIR/THIR.
|
||||
call_source: CallSource,
|
||||
/// This `Span` is the span of the function, without the dot and receiver
|
||||
/// (e.g. `foo(a, b)` in `x.foo(a, b)`
|
||||
/// e.g. `foo(a, b)` in `x.foo(a, b)`
|
||||
fn_span: Span,
|
||||
},
|
||||
|
||||
|
@ -519,7 +519,7 @@ macro_rules! make_mir_visitor {
|
||||
destination,
|
||||
target: _,
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _
|
||||
} => {
|
||||
self.visit_operand(func, location);
|
||||
|
@ -128,7 +128,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
destination,
|
||||
target: Some(target),
|
||||
unwind: UnwindAction::Continue,
|
||||
from_hir_call: *from_hir_call,
|
||||
call_source: if *from_hir_call { CallSource::Normal } else {
|
||||
CallSource::OverloadedOperator
|
||||
},
|
||||
fn_span: *fn_span,
|
||||
})
|
||||
},
|
||||
|
@ -173,7 +173,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
destination: storage,
|
||||
target: Some(success),
|
||||
unwind: UnwindAction::Continue,
|
||||
from_hir_call: false,
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: expr_span,
|
||||
},
|
||||
);
|
||||
|
@ -277,7 +277,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
.ty
|
||||
.is_inhabited_from(this.tcx, this.parent_module, this.param_env)
|
||||
.then_some(success),
|
||||
from_hir_call,
|
||||
call_source: if from_hir_call {
|
||||
CallSource::Normal
|
||||
} else {
|
||||
CallSource::OverloadedOperator
|
||||
},
|
||||
fn_span,
|
||||
},
|
||||
);
|
||||
|
@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
destination: ref_str,
|
||||
target: Some(eq_block),
|
||||
unwind: UnwindAction::Continue,
|
||||
from_hir_call: false,
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: source_info.span
|
||||
}
|
||||
);
|
||||
@ -496,7 +496,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
destination: eq_result,
|
||||
target: Some(eq_block),
|
||||
unwind: UnwindAction::Continue,
|
||||
from_hir_call: false,
|
||||
call_source: CallSource::MatchCmp,
|
||||
fn_span: source_info.span,
|
||||
},
|
||||
);
|
||||
|
@ -654,7 +654,7 @@ where
|
||||
destination: unit_temp,
|
||||
target: Some(succ),
|
||||
unwind: unwind.into_action(),
|
||||
from_hir_call: true,
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: self.source_info.span,
|
||||
},
|
||||
source_info: self.source_info,
|
||||
|
@ -502,15 +502,7 @@ impl Direction for Forward {
|
||||
propagate(target, exit_state);
|
||||
}
|
||||
|
||||
Call {
|
||||
unwind,
|
||||
destination,
|
||||
target,
|
||||
func: _,
|
||||
args: _,
|
||||
from_hir_call: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
Call { unwind, destination, target, func: _, args: _, call_source: _, fn_span: _ } => {
|
||||
if let UnwindAction::Cleanup(unwind) = unwind {
|
||||
propagate(unwind, exit_state);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
|
||||
destination: dummy_place.clone(),
|
||||
target: Some(mir::START_BLOCK),
|
||||
unwind: mir::UnwindAction::Continue,
|
||||
from_hir_call: false,
|
||||
call_source: mir::CallSource::Misc,
|
||||
fn_span: DUMMY_SP,
|
||||
},
|
||||
);
|
||||
@ -54,7 +54,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
|
||||
destination: dummy_place.clone(),
|
||||
target: Some(mir::START_BLOCK),
|
||||
unwind: mir::UnwindAction::Continue,
|
||||
from_hir_call: false,
|
||||
call_source: mir::CallSource::Misc,
|
||||
fn_span: DUMMY_SP,
|
||||
},
|
||||
);
|
||||
|
@ -399,7 +399,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
destination,
|
||||
target,
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
self.gather_operand(func);
|
||||
|
@ -140,7 +140,7 @@ impl<'tcx> MockBlocks<'tcx> {
|
||||
destination: self.dummy_place.clone(),
|
||||
target: Some(TEMP_BLOCK),
|
||||
unwind: UnwindAction::Continue,
|
||||
from_hir_call: false,
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: DUMMY_SP,
|
||||
},
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
|
||||
destination: _,
|
||||
target: _,
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _,
|
||||
} = &terminator.kind
|
||||
{
|
||||
|
@ -1692,7 +1692,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
|
||||
destination,
|
||||
target: Some(_),
|
||||
unwind: _,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
self.check_assigned_place(*destination, |this| {
|
||||
|
@ -30,8 +30,8 @@ use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{
|
||||
traversal, AnalysisPhase, Body, ClearCrossCrate, ConstQualifs, Constant, LocalDecl, MirPass,
|
||||
MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||
traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstQualifs, Constant, LocalDecl,
|
||||
MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||
Statement, StatementKind, TerminatorKind, START_BLOCK,
|
||||
};
|
||||
use rustc_middle::query::Providers;
|
||||
@ -189,7 +189,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
|
||||
};
|
||||
method(place)
|
||||
}).collect();
|
||||
terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, from_hir_call: false, fn_span };
|
||||
terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, call_source: CallSource::Misc, fn_span };
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ fn lower_slice_len_call<'tcx>(
|
||||
args,
|
||||
destination,
|
||||
target: Some(bb),
|
||||
from_hir_call: true,
|
||||
call_source: CallSource::Normal,
|
||||
..
|
||||
} => {
|
||||
// some heuristics for fast rejection
|
||||
|
@ -500,7 +500,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
|
||||
destination: dest,
|
||||
target: Some(next),
|
||||
unwind: UnwindAction::Cleanup(cleanup),
|
||||
from_hir_call: true,
|
||||
call_source: CallSource::Normal,
|
||||
fn_span: self.span,
|
||||
},
|
||||
false,
|
||||
@ -789,7 +789,7 @@ fn build_call_shim<'tcx>(
|
||||
} else {
|
||||
UnwindAction::Continue
|
||||
},
|
||||
from_hir_call: true,
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: span,
|
||||
},
|
||||
false,
|
||||
|
@ -351,7 +351,7 @@ impl<'tcx> Stable for mir::Terminator<'tcx> {
|
||||
target: target.as_usize(),
|
||||
unwind: unwind.stable(),
|
||||
},
|
||||
Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => {
|
||||
Call { func, args, destination, target, unwind, call_source: _, fn_span: _ } => {
|
||||
Terminator::Call {
|
||||
func: func.stable(),
|
||||
args: args.iter().map(|arg| arg.stable()).collect(),
|
||||
|
@ -835,13 +835,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
|
||||
pub(super) fn add_item_bounds_for_hidden_type(
|
||||
&mut self,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
opaque_def_id: DefId,
|
||||
opaque_substs: ty::SubstsRef<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
) {
|
||||
let mut obligations = Vec::new();
|
||||
self.infcx.add_item_bounds_for_hidden_type(
|
||||
opaque_type_key,
|
||||
opaque_def_id,
|
||||
opaque_substs,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
hidden_ty,
|
||||
@ -872,7 +874,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
ecx.eq(param_env, a, b)?;
|
||||
}
|
||||
ecx.eq(param_env, candidate_ty, ty)?;
|
||||
ecx.add_item_bounds_for_hidden_type(candidate_key, param_env, candidate_ty);
|
||||
ecx.add_item_bounds_for_hidden_type(
|
||||
candidate_key.def_id.to_def_id(),
|
||||
candidate_key.substs,
|
||||
param_env,
|
||||
candidate_ty,
|
||||
);
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
},
|
||||
|r| CandidateKind::Candidate { name: "opaque type storage".into(), result: *r },
|
||||
|
@ -20,8 +20,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
let Some(opaque_ty_def_id) = opaque_ty.def_id.as_local() else {
|
||||
return Err(NoSolution);
|
||||
};
|
||||
let opaque_ty =
|
||||
ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
|
||||
// FIXME: at some point we should call queries without defining
|
||||
// new opaque types but having the existing opaque type definitions.
|
||||
// This will require moving this below "Prefer opaques registered already".
|
||||
@ -41,7 +39,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
Ok(()) => {}
|
||||
}
|
||||
// Prefer opaques registered already.
|
||||
let matches = self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected);
|
||||
let opaque_type_key =
|
||||
ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
|
||||
let matches =
|
||||
self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
|
||||
if !matches.is_empty() {
|
||||
if let Some(response) = self.try_merge_responses(&matches) {
|
||||
return Ok(response);
|
||||
@ -50,11 +51,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
// Otherwise, define a new opaque type
|
||||
self.insert_hidden_type(opaque_ty, goal.param_env, expected)?;
|
||||
self.add_item_bounds_for_hidden_type(opaque_ty, goal.param_env, expected);
|
||||
self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
|
||||
self.add_item_bounds_for_hidden_type(
|
||||
opaque_ty.def_id,
|
||||
opaque_ty.substs,
|
||||
goal.param_env,
|
||||
expected,
|
||||
);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
(Reveal::UserFacing, SolverMode::Coherence) => {
|
||||
// An impossible opaque type bound is the only way this goal will fail
|
||||
// e.g. assigning `impl Copy := NotCopy`
|
||||
self.add_item_bounds_for_hidden_type(
|
||||
opaque_ty.def_id,
|
||||
opaque_ty.substs,
|
||||
goal.param_env,
|
||||
expected,
|
||||
);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||
}
|
||||
(Reveal::All, _) => {
|
||||
|
@ -1770,14 +1770,8 @@ impl fmt::Display for Ipv6Addr {
|
||||
f.write_str("::")
|
||||
} else if self.is_loopback() {
|
||||
f.write_str("::1")
|
||||
} else if let Some(ipv4) = self.to_ipv4() {
|
||||
match segments[5] {
|
||||
// IPv4 Compatible address
|
||||
0 => write!(f, "::{}", ipv4),
|
||||
// IPv4 Mapped address
|
||||
0xffff => write!(f, "::ffff:{}", ipv4),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else if let Some(ipv4) = self.to_ipv4_mapped() {
|
||||
write!(f, "::ffff:{}", ipv4)
|
||||
} else {
|
||||
#[derive(Copy, Clone, Default)]
|
||||
struct Span {
|
||||
|
@ -119,7 +119,7 @@ def print_singletons(uppers, lowers, uppersname, lowersname):
|
||||
print("#[rustfmt::skip]")
|
||||
print("const {}: &[u8] = &[".format(lowersname))
|
||||
for i in range(0, len(lowers), 8):
|
||||
print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
|
||||
print(" {}".format(" ".join("{:#04x},".format(x) for x in lowers[i:i+8])))
|
||||
print("];")
|
||||
|
||||
def print_normal(normal, normalname):
|
||||
|
@ -139,7 +139,7 @@ fn ipv6_addr_to_string() {
|
||||
|
||||
// ipv4-compatible address
|
||||
let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280);
|
||||
assert_eq!(a1.to_string(), "::192.0.2.128");
|
||||
assert_eq!(a1.to_string(), "::c000:280");
|
||||
|
||||
// v6 address with no zero segments
|
||||
assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(), "8:9:a:b:c:d:e:f");
|
||||
@ -316,7 +316,7 @@ fn ip_properties() {
|
||||
|
||||
check!("::", unspec);
|
||||
check!("::1", loopback);
|
||||
check!("::0.0.0.2", global);
|
||||
check!("::2", global);
|
||||
check!("1::", global);
|
||||
check!("fc00::");
|
||||
check!("fdff:ffff::");
|
||||
@ -607,7 +607,7 @@ fn ipv6_properties() {
|
||||
|
||||
check!("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], loopback);
|
||||
|
||||
check!("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], global | unicast_global);
|
||||
check!("::2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], global | unicast_global);
|
||||
|
||||
check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global);
|
||||
|
||||
|
@ -34,7 +34,7 @@ fn ipv6_socket_addr_to_string() {
|
||||
// IPv4-compatible address.
|
||||
assert_eq!(
|
||||
SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280), 8080, 0, 0).to_string(),
|
||||
"[::192.0.2.128]:8080"
|
||||
"[::c000:280]:8080"
|
||||
);
|
||||
|
||||
// IPv6 address with no zero segments.
|
||||
|
@ -85,7 +85,7 @@ fn ipv6_socket_addr_to_string() {
|
||||
// IPv4-compatible address.
|
||||
assert_eq!(
|
||||
SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280), 8080, 0, 0).to_string(),
|
||||
"[::192.0.2.128]:8080"
|
||||
"[::c000:280]:8080"
|
||||
);
|
||||
|
||||
// IPv6 address with no zero segments.
|
||||
|
@ -38,6 +38,5 @@ ignore = [
|
||||
|
||||
# these are ignored by a standard cargo fmt run
|
||||
"compiler/rustc_codegen_cranelift/y.rs", # running rustfmt breaks this file
|
||||
"compiler/rustc_codegen_cranelift/example",
|
||||
"compiler/rustc_codegen_cranelift/scripts",
|
||||
]
|
||||
|
@ -620,7 +620,7 @@ class RustBuild(object):
|
||||
# The latter one does not exist on NixOS when using tmpfs as root.
|
||||
try:
|
||||
with open("/etc/os-release", "r") as f:
|
||||
if not any(l.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for l in f):
|
||||
if not any(ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for ln in f):
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
@ -872,7 +872,7 @@ class RustBuild(object):
|
||||
}
|
||||
for var_name, toml_key in var_data.items():
|
||||
toml_val = self.get_toml(toml_key, build_section)
|
||||
if toml_val != None:
|
||||
if toml_val is not None:
|
||||
env["{}_{}".format(var_name, host_triple_sanitized)] = toml_val
|
||||
|
||||
# preserve existing RUSTFLAGS
|
||||
|
@ -9,7 +9,7 @@ rust_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
rust_dir = os.path.dirname(rust_dir)
|
||||
rust_dir = os.path.dirname(rust_dir)
|
||||
sys.path.append(os.path.join(rust_dir, "src", "bootstrap"))
|
||||
import bootstrap
|
||||
import bootstrap # noqa: E402
|
||||
|
||||
|
||||
class Option(object):
|
||||
@ -319,7 +319,7 @@ def apply_args(known_args, option_checking, config):
|
||||
for key in known_args:
|
||||
# The `set` option is special and can be passed a bunch of times
|
||||
if key == 'set':
|
||||
for option, value in known_args[key]:
|
||||
for _option, value in known_args[key]:
|
||||
keyval = value.split('=', 1)
|
||||
if len(keyval) == 1 or keyval[1] == "true":
|
||||
value = True
|
||||
@ -401,7 +401,7 @@ def parse_example_config(known_args, config):
|
||||
top_level_keys = []
|
||||
|
||||
for line in open(rust_dir + '/config.example.toml').read().split("\n"):
|
||||
if cur_section == None:
|
||||
if cur_section is None:
|
||||
if line.count('=') == 1:
|
||||
top_level_key = line.split('=')[0]
|
||||
top_level_key = top_level_key.strip(' #')
|
||||
@ -523,8 +523,8 @@ def write_uncommented(target, f):
|
||||
block.append(line)
|
||||
if len(line) == 0:
|
||||
if not is_comment:
|
||||
for l in block:
|
||||
f.write(l + "\n")
|
||||
for ln in block:
|
||||
f.write(ln + "\n")
|
||||
block = []
|
||||
is_comment = True
|
||||
continue
|
||||
|
0
src/ci/cpu-usage-over-time.py
Normal file → Executable file
0
src/ci/cpu-usage-over-time.py
Normal file → Executable file
0
src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py
Normal file → Executable file
0
src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py
Normal file → Executable file
@ -2,6 +2,14 @@
|
||||
# Simpler reimplementation of Android's sdkmanager
|
||||
# Extra features of this implementation are pinning and mirroring
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
# These URLs are the Google repositories containing the list of available
|
||||
# packages and their versions. The list has been generated by listing the URLs
|
||||
# fetched while executing `tools/bin/sdkmanager --list`
|
||||
@ -27,15 +35,6 @@ MIRROR_BUCKET = "rust-lang-ci-mirrors"
|
||||
MIRROR_BUCKET_REGION = "us-west-1"
|
||||
MIRROR_BASE_DIR = "rustc/android/"
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import urllib.request
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
class Package:
|
||||
def __init__(self, path, url, sha1, deps=None):
|
||||
if deps is None:
|
||||
|
@ -519,8 +519,8 @@ class TestEnvironment:
|
||||
env_vars += f'\n "{var_name}={var_value}",'
|
||||
|
||||
# Default to no backtrace for test suite
|
||||
if os.getenv("RUST_BACKTRACE") == None:
|
||||
env_vars += f'\n "RUST_BACKTRACE=0",'
|
||||
if os.getenv("RUST_BACKTRACE") is None:
|
||||
env_vars += '\n "RUST_BACKTRACE=0",'
|
||||
|
||||
# Use /tmp as the test temporary directory
|
||||
env_vars += f'\n "RUST_TEST_TMPDIR=/tmp",'
|
||||
|
@ -10,6 +10,46 @@
|
||||
"message": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "cargo-common",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(warning|warn|error)(\\[(\\S*)\\])?: (.*)$",
|
||||
"severity": 1,
|
||||
"message": 4,
|
||||
"code": 3
|
||||
},
|
||||
{
|
||||
"regexp": "^\\s+-->\\s(\\S+):(\\d+):(\\d+)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "compiler-panic",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "error: internal compiler error: (.*):(\\d+):(\\d+): (.*)$",
|
||||
"message": 4,
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "cargo-fmt",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(Diff in (\\S+)) at line (\\d+):",
|
||||
"message": 1,
|
||||
"file": 2,
|
||||
"line": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
4
src/ci/stage-build.py
Normal file → Executable file
4
src/ci/stage-build.py
Normal file → Executable file
@ -440,7 +440,7 @@ def retry_action(action, name: str, max_fails: int = 5):
|
||||
try:
|
||||
action()
|
||||
return
|
||||
except:
|
||||
except BaseException: # also catch ctrl+c/sysexit
|
||||
LOGGER.error(f"Action `{name}` has failed\n{traceback.format_exc()}")
|
||||
|
||||
raise Exception(f"Action `{name}` has failed after {max_fails} attempts")
|
||||
@ -818,7 +818,7 @@ def run_tests(pipeline: Pipeline):
|
||||
# Extract rustc, libstd, cargo and src archives to create the optimized sysroot
|
||||
rustc_dir = extract_dist_dir(f"rustc-nightly-{PGO_HOST}") / "rustc"
|
||||
libstd_dir = extract_dist_dir(f"rust-std-nightly-{PGO_HOST}") / f"rust-std-{PGO_HOST}"
|
||||
cargo_dir = extract_dist_dir(f"cargo-nightly-{PGO_HOST}") / f"cargo"
|
||||
cargo_dir = extract_dist_dir(f"cargo-nightly-{PGO_HOST}") / "cargo"
|
||||
extracted_src_dir = extract_dist_dir("rust-src-nightly") / "rust-src"
|
||||
|
||||
# We need to manually copy libstd to the extracted rustc sysroot
|
||||
|
4
src/etc/dec2flt_table.py
Normal file → Executable file
4
src/etc/dec2flt_table.py
Normal file → Executable file
@ -14,8 +14,7 @@ Adapted from Daniel Lemire's fast_float ``table_generation.py``,
|
||||
available here: <https://github.com/fastfloat/fast_float/blob/main/script/table_generation.py>.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from math import ceil, floor, log, log2
|
||||
from fractions import Fraction
|
||||
from math import ceil, floor, log
|
||||
from collections import deque
|
||||
|
||||
HEADER = """
|
||||
@ -97,7 +96,6 @@ def print_proper_powers(min_exp, max_exp, bias):
|
||||
print('#[rustfmt::skip]')
|
||||
typ = '[(u64, u64); N_POWERS_OF_FIVE]'
|
||||
print('pub static POWER_OF_FIVE_128: {} = ['.format(typ))
|
||||
lo_mask = (1 << 64) - 1
|
||||
for c, exp in powers:
|
||||
hi = '0x{:x}'.format(c // (1 << 64))
|
||||
lo = '0x{:x}'.format(c % (1 << 64))
|
||||
|
@ -4,6 +4,7 @@ from os import path
|
||||
self_dir = path.dirname(path.realpath(__file__))
|
||||
sys.path.append(self_dir)
|
||||
|
||||
# ruff: noqa: E402
|
||||
import gdb
|
||||
import gdb_lookup
|
||||
|
||||
|
@ -102,7 +102,9 @@ for (trait, supers, errs) in [('Clone', [], 1),
|
||||
traits[trait] = (ALL, supers, errs)
|
||||
|
||||
for (trait, (types, super_traits, error_count)) in traits.items():
|
||||
mk = lambda ty: create_test_case(ty, trait, super_traits, error_count)
|
||||
def mk(ty, t=trait, st=super_traits, ec=error_count):
|
||||
return create_test_case(ty, t, st, ec)
|
||||
|
||||
if types & ENUM:
|
||||
write_file(trait + '-enum', mk(ENUM_TUPLE))
|
||||
write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT))
|
||||
|
8
src/etc/htmldocck.py
Normal file → Executable file
8
src/etc/htmldocck.py
Normal file → Executable file
@ -144,7 +144,7 @@ VOID_ELEMENTS = {'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'ke
|
||||
|
||||
# Python 2 -> 3 compatibility
|
||||
try:
|
||||
unichr
|
||||
unichr # noqa: B018 FIXME: py2
|
||||
except NameError:
|
||||
unichr = chr
|
||||
|
||||
@ -348,7 +348,9 @@ class CachedFiles(object):
|
||||
try:
|
||||
tree = ET.fromstringlist(f.readlines(), CustomHTMLParser())
|
||||
except Exception as e:
|
||||
raise RuntimeError('Cannot parse an HTML file {!r}: {}'.format(path, e))
|
||||
raise RuntimeError( # noqa: B904 FIXME: py2
|
||||
'Cannot parse an HTML file {!r}: {}'.format(path, e)
|
||||
)
|
||||
self.trees[path] = tree
|
||||
return self.trees[path]
|
||||
|
||||
@ -422,7 +424,7 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text):
|
||||
if bless:
|
||||
expected_str = None
|
||||
else:
|
||||
raise FailedCheck('No saved snapshot value')
|
||||
raise FailedCheck('No saved snapshot value') # noqa: B904 FIXME: py2
|
||||
|
||||
if not normalize_to_text:
|
||||
actual_str = ET.tostring(actual_tree).decode('utf-8')
|
||||
|
@ -124,7 +124,7 @@ def start_breakpoint_listener(target):
|
||||
breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
|
||||
print_debug("breakpoint added, id = " + str(breakpoint.id))
|
||||
new_breakpoints.append(breakpoint.id)
|
||||
except:
|
||||
except BaseException: # explicitly catch ctrl+c/sysexit
|
||||
print_debug("breakpoint listener shutting down")
|
||||
|
||||
# Start the listener and let it run as a daemon
|
||||
|
@ -1,6 +1,6 @@
|
||||
import sys
|
||||
|
||||
from lldb import SBValue, SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLong, \
|
||||
from lldb import SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLong, \
|
||||
eBasicTypeUnsignedChar
|
||||
|
||||
# from lldb.formatters import Logger
|
||||
|
0
src/etc/test-float-parse/runtests.py
Normal file → Executable file
0
src/etc/test-float-parse/runtests.py
Normal file → Executable file
@ -54,7 +54,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
||||
let mut inserted = FxHashSet::default();
|
||||
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
|
||||
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
|
||||
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||
if let Some(name) = item.name && !item.is_doc_hidden() {
|
||||
inserted.insert((item.type_(), name));
|
||||
}
|
||||
item
|
||||
@ -64,7 +64,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
||||
return None;
|
||||
}
|
||||
let item = clean_doc_module(x, cx);
|
||||
if item.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||
if item.is_doc_hidden() {
|
||||
// Hidden modules are stripped at a later stage.
|
||||
// If a hidden module has the same name as a visible one, we want
|
||||
// to keep both of them around.
|
||||
@ -85,7 +85,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
||||
}
|
||||
let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
|
||||
for item in &v {
|
||||
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||
if let Some(name) = item.name && !item.is_doc_hidden() {
|
||||
inserted.insert((item.type_(), name));
|
||||
}
|
||||
}
|
||||
|
@ -783,6 +783,10 @@ impl Item {
|
||||
}
|
||||
attrs
|
||||
}
|
||||
|
||||
pub fn is_doc_hidden(&self) -> bool {
|
||||
self.attrs.is_doc_hidden()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -1129,6 +1133,10 @@ impl Attributes {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_doc_hidden(&self) -> bool {
|
||||
self.has_doc_flag(sym::hidden)
|
||||
}
|
||||
|
||||
pub(crate) fn from_ast(attrs: &[ast::Attribute]) -> Attributes {
|
||||
Attributes::from_ast_iter(attrs.iter().map(|attr| (attr, None)), false)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use rustc_span::symbol::sym;
|
||||
use std::mem;
|
||||
|
||||
use crate::clean;
|
||||
use crate::clean::{Item, ItemIdSet, NestedAttributesExt};
|
||||
use crate::clean::{Item, ItemIdSet};
|
||||
use crate::core::DocContext;
|
||||
use crate::fold::{strip_item, DocFolder};
|
||||
use crate::passes::{ImplStripper, Pass};
|
||||
@ -85,7 +85,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> {
|
||||
|
||||
impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
let has_doc_hidden = i.attrs.lists(sym::doc).has_word(sym::hidden);
|
||||
let has_doc_hidden = i.is_doc_hidden();
|
||||
let is_impl_or_exported_macro = match *i.kind {
|
||||
clean::ImplItem(..) => true,
|
||||
// If the macro has the `#[macro_export]` attribute, it means it's accessible at the
|
||||
|
@ -1,10 +1,9 @@
|
||||
//! A collection of utility functions for the `strip_*` passes.
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::{TyCtxt, Visibility};
|
||||
use rustc_span::symbol::sym;
|
||||
use std::mem;
|
||||
|
||||
use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt};
|
||||
use crate::clean::{self, Item, ItemId, ItemIdSet};
|
||||
use crate::fold::{strip_item, DocFolder};
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::visit_lib::RustdocEffectiveVisibilities;
|
||||
@ -163,7 +162,7 @@ impl<'a> ImplStripper<'a, '_> {
|
||||
// If the "for" item is exported and the impl block isn't `#[doc(hidden)]`, then we
|
||||
// need to keep it.
|
||||
self.cache.effective_visibilities.is_exported(self.tcx, for_def_id)
|
||||
&& !item.attrs.lists(sym::doc).has_word(sym::hidden)
|
||||
&& !item.is_doc_hidden()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -240,7 +239,7 @@ impl<'tcx> ImportStripper<'tcx> {
|
||||
// FIXME: This should be handled the same way as for HTML output.
|
||||
imp.imported_item_is_doc_hidden(self.tcx)
|
||||
} else {
|
||||
i.attrs.lists(sym::doc).has_word(sym::hidden)
|
||||
i.is_doc_hidden()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -249,7 +248,7 @@ impl<'tcx> DocFolder for ImportStripper<'tcx> {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
match *i.kind {
|
||||
clean::ImportItem(imp) if self.import_should_be_hidden(&i, &imp) => None,
|
||||
clean::ImportItem(_) if i.attrs.lists(sym::doc).has_word(sym::hidden) => None,
|
||||
clean::ImportItem(_) if i.is_doc_hidden() => None,
|
||||
clean::ExternCrateItem { .. } | clean::ImportItem(..)
|
||||
if i.visibility(self.tcx) != Some(Visibility::Public) =>
|
||||
{
|
||||
|
@ -317,7 +317,7 @@ fn check_terminator<'tcx>(
|
||||
TerminatorKind::Call {
|
||||
func,
|
||||
args,
|
||||
from_hir_call: _,
|
||||
call_source: _,
|
||||
destination: _,
|
||||
target: _,
|
||||
unwind: _,
|
||||
|
@ -5,7 +5,11 @@ Assumes the `MIRI_SYSROOT` env var to be set appropriately,
|
||||
and the working directory to contain the cargo-miri-test project.
|
||||
'''
|
||||
|
||||
import sys, subprocess, os, re, difflib
|
||||
import difflib
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
CGREEN = '\33[32m'
|
||||
CBOLD = '\33[1m'
|
||||
@ -46,7 +50,9 @@ def check_output(actual, path, name):
|
||||
print(f"--- END diff {name} ---")
|
||||
return False
|
||||
|
||||
def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}):
|
||||
def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env=None):
|
||||
if env is None:
|
||||
env = {}
|
||||
print("Testing {}...".format(name))
|
||||
## Call `cargo miri`, capture all output
|
||||
p_env = os.environ.copy()
|
||||
@ -64,13 +70,15 @@ def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}):
|
||||
|
||||
stdout_matches = check_output(stdout, stdout_ref, "stdout")
|
||||
stderr_matches = check_output(stderr, stderr_ref, "stderr")
|
||||
|
||||
|
||||
if p.returncode == 0 and stdout_matches and stderr_matches:
|
||||
# All good!
|
||||
return
|
||||
fail("exit code was {}".format(p.returncode))
|
||||
|
||||
def test_no_rebuild(name, cmd, env={}):
|
||||
def test_no_rebuild(name, cmd, env=None):
|
||||
if env is None:
|
||||
env = {}
|
||||
print("Testing {}...".format(name))
|
||||
p_env = os.environ.copy()
|
||||
p_env.update(env)
|
||||
@ -84,13 +92,13 @@ def test_no_rebuild(name, cmd, env={}):
|
||||
stdout = stdout.decode("UTF-8")
|
||||
stderr = stderr.decode("UTF-8")
|
||||
if p.returncode != 0:
|
||||
fail("rebuild failed");
|
||||
fail("rebuild failed")
|
||||
# Also check for 'Running' as a sanity check.
|
||||
if stderr.count(" Compiling ") > 0 or stderr.count(" Running ") == 0:
|
||||
print("--- BEGIN stderr ---")
|
||||
print(stderr, end="")
|
||||
print("--- END stderr ---")
|
||||
fail("Something was being rebuilt when it should not be (or we got no output)");
|
||||
fail("Something was being rebuilt when it should not be (or we got no output)")
|
||||
|
||||
def test_cargo_miri_run():
|
||||
test("`cargo miri run` (no isolation)",
|
||||
|
@ -22,7 +22,7 @@ except ImportError:
|
||||
import urllib.request as urllib2
|
||||
from urllib.error import HTTPError
|
||||
try:
|
||||
import typing
|
||||
import typing # noqa: F401 FIXME: py2
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@ -152,8 +152,8 @@ def update_latest(
|
||||
latest = json.load(f, object_pairs_hook=collections.OrderedDict)
|
||||
|
||||
current_status = {
|
||||
os: read_current_status(current_commit, 'history/' + os + '.tsv')
|
||||
for os in ['windows', 'linux']
|
||||
os_: read_current_status(current_commit, 'history/' + os_ + '.tsv')
|
||||
for os_ in ['windows', 'linux']
|
||||
}
|
||||
|
||||
slug = 'rust-lang/rust'
|
||||
@ -170,10 +170,10 @@ def update_latest(
|
||||
changed = False
|
||||
create_issue_for_status = None # set to the status that caused the issue
|
||||
|
||||
for os, s in current_status.items():
|
||||
old = status[os]
|
||||
for os_, s in current_status.items():
|
||||
old = status[os_]
|
||||
new = s.get(tool, old)
|
||||
status[os] = new
|
||||
status[os_] = new
|
||||
maintainers = ' '.join('@'+name for name in MAINTAINERS.get(tool, ()))
|
||||
# comparing the strings, but they are ordered appropriately:
|
||||
# "test-pass" > "test-fail" > "build-fail"
|
||||
@ -181,12 +181,12 @@ def update_latest(
|
||||
# things got fixed or at least the status quo improved
|
||||
changed = True
|
||||
message += '🎉 {} on {}: {} → {} (cc {}).\n' \
|
||||
.format(tool, os, old, new, maintainers)
|
||||
.format(tool, os_, old, new, maintainers)
|
||||
elif new < old:
|
||||
# tests or builds are failing and were not failing before
|
||||
changed = True
|
||||
title = '💔 {} on {}: {} → {}' \
|
||||
.format(tool, os, old, new)
|
||||
.format(tool, os_, old, new)
|
||||
message += '{} (cc {}).\n' \
|
||||
.format(title, maintainers)
|
||||
# See if we need to create an issue.
|
||||
|
0
tests/run-make/coverage-reports/sort_subviews.py
Normal file → Executable file
0
tests/run-make/coverage-reports/sort_subviews.py
Normal file → Executable file
@ -7,6 +7,6 @@ import xml.etree.ElementTree as ET
|
||||
for line in sys.stdin:
|
||||
try:
|
||||
ET.fromstring(line)
|
||||
except ET.ParseError as pe:
|
||||
except ET.ParseError:
|
||||
print("Invalid xml: %r" % line)
|
||||
raise
|
||||
|
@ -6,7 +6,7 @@ import json
|
||||
|
||||
|
||||
def find_redirect_map_file(folder, errors):
|
||||
for root, dirs, files in os.walk(folder):
|
||||
for root, _dirs, files in os.walk(folder):
|
||||
for name in files:
|
||||
if not name.endswith("redirect-map.json"):
|
||||
continue
|
||||
|
@ -46,7 +46,7 @@ def check_lib(lib):
|
||||
'--target', os.environ['TARGET'],
|
||||
'--extern', '{}={}'.format(lib['name'], lib['path'])],
|
||||
to_input=('extern crate {};'.format(lib['name'])).encode('utf-8'))
|
||||
if not 'use of unstable library feature' in '{}{}'.format(stdout, stderr):
|
||||
if 'use of unstable library feature' not in '{}{}'.format(stdout, stderr):
|
||||
print('crate {} "{}" is not unstable'.format(lib['name'], lib['path']))
|
||||
print('{}{}'.format(stdout, stderr))
|
||||
print('')
|
||||
|
22
tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
Normal file
22
tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
Normal file
@ -0,0 +1,22 @@
|
||||
// edition:2021
|
||||
// run-rustfix
|
||||
|
||||
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
||||
|
||||
trait Trait {
|
||||
async fn foo();
|
||||
|
||||
async fn bar() -> i32;
|
||||
|
||||
fn test(&self) -> impl Sized + '_;
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl Trait for S {fn test(&self) -> impl Sized + '_ { todo!() }
|
||||
async fn bar() -> i32 { todo!() }
|
||||
async fn foo() { todo!() }
|
||||
}
|
||||
//~^ ERROR not all trait items implemented
|
||||
|
||||
fn main() {}
|
19
tests/ui/impl-trait/in-trait/suggest-missing-item.rs
Normal file
19
tests/ui/impl-trait/in-trait/suggest-missing-item.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// edition:2021
|
||||
// run-rustfix
|
||||
|
||||
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
||||
|
||||
trait Trait {
|
||||
async fn foo();
|
||||
|
||||
async fn bar() -> i32;
|
||||
|
||||
fn test(&self) -> impl Sized + '_;
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl Trait for S {}
|
||||
//~^ ERROR not all trait items implemented
|
||||
|
||||
fn main() {}
|
18
tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
Normal file
18
tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test`
|
||||
--> $DIR/suggest-missing-item.rs:16:1
|
||||
|
|
||||
LL | async fn foo();
|
||||
| --------------- `foo` from trait
|
||||
LL |
|
||||
LL | async fn bar() -> i32;
|
||||
| ---------------------- `bar` from trait
|
||||
LL |
|
||||
LL | fn test(&self) -> impl Sized + '_;
|
||||
| ---------------------------------- `test` from trait
|
||||
...
|
||||
LL | impl Trait for S {}
|
||||
| ^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `test` in implementation
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0046`.
|
@ -0,0 +1,26 @@
|
||||
error[E0277]: can't compare `str` with `str` in const contexts
|
||||
--> $DIR/match-non-const-eq.rs:6:9
|
||||
|
|
||||
LL | "a" => (),
|
||||
| ^^^ no implementation for `str == str`
|
||||
|
|
||||
= help: the trait `~const PartialEq` is not implemented for `str`
|
||||
note: the trait `PartialEq` is implemented for `str`, but that implementation is not `const`
|
||||
--> $DIR/match-non-const-eq.rs:6:9
|
||||
|
|
||||
LL | "a" => (),
|
||||
| ^^^
|
||||
|
||||
error[E0015]: cannot match on `str` in constant functions
|
||||
--> $DIR/match-non-const-eq.rs:6:9
|
||||
|
|
||||
LL | "a" => (),
|
||||
| ^^^
|
||||
|
|
||||
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
@ -0,0 +1,12 @@
|
||||
// revisions: stock gated
|
||||
#![cfg_attr(gated, feature(const_trait_impl))]
|
||||
|
||||
const fn foo(input: &'static str) {
|
||||
match input {
|
||||
"a" => (), //[gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||
//~^ ERROR cannot match on `str` in constant functions
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,13 @@
|
||||
error[E0015]: cannot match on `str` in constant functions
|
||||
--> $DIR/match-non-const-eq.rs:6:9
|
||||
|
|
||||
LL | "a" => (),
|
||||
| ^^^
|
||||
|
|
||||
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,6 +1,8 @@
|
||||
// Regression test for issue #76202
|
||||
// Tests that we don't ICE when we have a trait impl on a TAIT.
|
||||
|
||||
// revisions: current next
|
||||
//[next] compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
Loading…
Reference in New Issue
Block a user