mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Auto merge of #126528 - GuillaumeGomez:rollup-6zjs70e, r=GuillaumeGomez
Rollup of 9 pull requests Successful merges: - #126229 (Bump windows-bindgen to 0.57) - #126404 (Check that alias-relate terms are WF if reporting an error in alias-relate) - #126410 (smir: merge identical Constant and ConstOperand types) - #126478 (Migrate `run-make/codegen-options-parsing` to `rmake.rs`) - #126496 (Make proof tree probing and `Candidate`/`CandidateSource` generic over interner) - #126508 (Make uninitialized_error_reported a set of locals) - #126517 (Migrate `run-make/dep-graph` to `rmake.rs`) - #126525 (trait_selection: remove extra words) - #126526 (tests/ui/lint: Move 19 tests to new `non-snake-case` subdir) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
3cf924b934
@ -6385,9 +6385,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-bindgen"
|
||||
version = "0.56.0"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28e3ea6330cf17fdcdce8bf08d0549ce93769dca9bedc6c39c36c8c0e17db46"
|
||||
checksum = "1ccb96113d6277ba543c0f77e1c5494af8094bf9daf9b85acdc3f1b620e7c7b4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"rayon",
|
||||
@ -6408,9 +6408,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-metadata"
|
||||
version = "0.56.0"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3993f7827fff10c454e3a24847075598c7c08108304b8b07943c2c73d78f3b34"
|
||||
checksum = "8308d076825b9d9e5abc64f8113e96d02b2aeeba869b20fdd65c7e70cda13dfc"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
|
@ -100,12 +100,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
move_site_vec.iter().map(|move_site| move_site.moi).collect();
|
||||
|
||||
if move_out_indices.is_empty() {
|
||||
let root_place = PlaceRef { projection: &[], ..used_place };
|
||||
let root_local = used_place.local;
|
||||
|
||||
if !self.uninitialized_error_reported.insert(root_place) {
|
||||
if !self.uninitialized_error_reported.insert(root_local) {
|
||||
debug!(
|
||||
"report_use_of_moved_or_uninitialized place: error about {:?} suppressed",
|
||||
root_place
|
||||
root_local
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
|
||||
fn_self_span_reported: FxIndexSet<Span>,
|
||||
/// This field keeps track of errors reported in the checking of uninitialized variables,
|
||||
/// so that we don't report seemingly duplicate errors.
|
||||
uninitialized_error_reported: FxIndexSet<PlaceRef<'tcx>>,
|
||||
uninitialized_error_reported: FxIndexSet<Local>,
|
||||
/// This field keeps track of all the local variables that are declared mut and are mutated.
|
||||
/// Used for the warning issued by an unused mutable local variable.
|
||||
used_mut: FxIndexSet<Local>,
|
||||
|
@ -113,7 +113,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
|
||||
let const_ = constant.const_;
|
||||
constant.const_ = self.renumber_regions(const_, || RegionCtxt::Location(location));
|
||||
debug!("constant: {:#?}", constant);
|
||||
|
@ -301,10 +301,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
self.sanitize_place(place, location, context);
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
|
||||
debug!(?constant, ?location, "visit_constant");
|
||||
fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
|
||||
debug!(?constant, ?location, "visit_const_operand");
|
||||
|
||||
self.super_constant(constant, location);
|
||||
self.super_const_operand(constant, location);
|
||||
let ty = self.sanitize_type(constant, constant.const_.ty());
|
||||
|
||||
self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
|
||||
|
@ -471,6 +471,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
|
||||
{
|
||||
self.resolve_vars_if_possible(value)
|
||||
}
|
||||
|
||||
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
|
||||
self.probe(|_| probe())
|
||||
}
|
||||
}
|
||||
|
||||
/// See the `error_reporting` module for more details.
|
||||
|
@ -1287,7 +1287,7 @@ fn use_verbose(ty: Ty<'_>, fn_def: bool) -> bool {
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||
fn visit_constant(&mut self, constant: &ConstOperand<'tcx>, _location: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, _location: Location) {
|
||||
let ConstOperand { span, user_ty, const_ } = constant;
|
||||
if use_verbose(const_.ty(), true) {
|
||||
self.push("mir::ConstOperand");
|
||||
@ -1415,7 +1415,7 @@ pub fn write_allocations<'tcx>(
|
||||
struct CollectAllocIds(BTreeSet<AllocId>);
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for CollectAllocIds {
|
||||
fn visit_constant(&mut self, c: &ConstOperand<'tcx>, _: Location) {
|
||||
fn visit_const_operand(&mut self, c: &ConstOperand<'tcx>, _: Location) {
|
||||
match c.const_ {
|
||||
Const::Ty(_, _) | Const::Unevaluated(..) => {}
|
||||
Const::Val(val, _) => {
|
||||
|
@ -184,12 +184,12 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
/// This is called for every constant in the MIR body and every `required_consts`
|
||||
/// (i.e., including consts that have been dead-code-eliminated).
|
||||
fn visit_constant(
|
||||
fn visit_const_operand(
|
||||
&mut self,
|
||||
constant: & $($mutability)? ConstOperand<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
self.super_constant(constant, location);
|
||||
self.super_const_operand(constant, location);
|
||||
}
|
||||
|
||||
fn visit_ty_const(
|
||||
@ -597,7 +597,7 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
InlineAsmOperand::Const { value }
|
||||
| InlineAsmOperand::SymFn { value } => {
|
||||
self.visit_constant(value, location);
|
||||
self.visit_const_operand(value, location);
|
||||
}
|
||||
InlineAsmOperand::Out { place: None, .. }
|
||||
| InlineAsmOperand::SymStatic { def_id: _ }
|
||||
@ -788,7 +788,7 @@ macro_rules! make_mir_visitor {
|
||||
);
|
||||
}
|
||||
Operand::Constant(constant) => {
|
||||
self.visit_constant(constant, location);
|
||||
self.visit_const_operand(constant, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -867,7 +867,7 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
match value {
|
||||
VarDebugInfoContents::Const(c) => self.visit_constant(c, location),
|
||||
VarDebugInfoContents::Const(c) => self.visit_const_operand(c, location),
|
||||
VarDebugInfoContents::Place(place) =>
|
||||
self.visit_place(
|
||||
place,
|
||||
@ -882,7 +882,7 @@ macro_rules! make_mir_visitor {
|
||||
_scope: $(& $mutability)? SourceScope
|
||||
) {}
|
||||
|
||||
fn super_constant(
|
||||
fn super_const_operand(
|
||||
&mut self,
|
||||
constant: & $($mutability)? ConstOperand<'tcx>,
|
||||
location: Location
|
||||
@ -1057,7 +1057,7 @@ macro_rules! super_body {
|
||||
|
||||
for const_ in &$($mutability)? $body.required_consts {
|
||||
let location = Location::START;
|
||||
$self.visit_constant(const_, location);
|
||||
$self.visit_const_operand(const_, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -706,9 +706,9 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
self.super_operand(operand, location);
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
|
||||
trace!("visit_constant: {:?}", constant);
|
||||
self.super_constant(constant, location);
|
||||
fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
|
||||
trace!("visit_const_operand: {:?}", constant);
|
||||
self.super_const_operand(constant, location);
|
||||
self.eval_constant(constant);
|
||||
}
|
||||
|
||||
|
@ -956,7 +956,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _location: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &mut ConstOperand<'tcx>, _location: Location) {
|
||||
if constant.const_.is_required_const() {
|
||||
self.promoted.required_consts.push(*constant);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
|
||||
fn visit_constant(&mut self, constant: &ConstOperand<'tcx>, _: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, _: Location) {
|
||||
if constant.const_.is_required_const() {
|
||||
self.required_consts.push(*constant);
|
||||
}
|
||||
|
@ -49,14 +49,14 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) {
|
||||
// We have to use `try_normalize_erasing_regions` here, since it's
|
||||
// possible that we visit impossible-to-satisfy where clauses here,
|
||||
// see #91745
|
||||
if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) {
|
||||
constant.const_ = c;
|
||||
}
|
||||
self.super_constant(constant, location);
|
||||
self.super_const_operand(constant, location);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -799,7 +799,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
||||
/// This does not walk the MIR of the constant as that is not needed for codegen, all we need is
|
||||
/// to ensure that the constant evaluates successfully and walk the result.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_constant(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) {
|
||||
fn visit_const_operand(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) {
|
||||
// No `super_constant` as we don't care about `visit_ty`/`visit_ty_const`.
|
||||
let Some(val) = self.eval_constant(constant) else { return };
|
||||
collect_const_value(self.tcx, val, self.used_items);
|
||||
|
@ -261,7 +261,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
|
||||
self.super_local_decl(local, local_decl);
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, ct: &mir::ConstOperand<'tcx>, location: Location) {
|
||||
fn visit_const_operand(&mut self, ct: &mir::ConstOperand<'tcx>, location: Location) {
|
||||
match ct.const_ {
|
||||
mir::Const::Ty(_, c) => {
|
||||
c.visit_with(self);
|
||||
|
@ -52,7 +52,11 @@ impl<'tcx> BodyBuilder<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
|
||||
fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
|
||||
fn visit_const_operand(
|
||||
&mut self,
|
||||
constant: &mut mir::ConstOperand<'tcx>,
|
||||
location: mir::Location,
|
||||
) {
|
||||
let const_ = constant.const_;
|
||||
let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), constant.span) {
|
||||
Ok(v) => v,
|
||||
@ -63,7 +67,7 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
|
||||
};
|
||||
let ty = constant.ty();
|
||||
constant.const_ = mir::Const::Val(val, ty);
|
||||
self.super_constant(constant, location);
|
||||
self.super_const_operand(constant, location);
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
|
@ -328,13 +328,13 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
|
||||
type T = stable_mir::mir::Constant;
|
||||
type T = stable_mir::mir::ConstOperand;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
stable_mir::mir::Constant {
|
||||
stable_mir::mir::ConstOperand {
|
||||
span: self.span.stable(tables),
|
||||
user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
|
||||
literal: self.const_.stable(tables),
|
||||
const_: self.const_.stable(tables),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
//! Code shared by trait and projection goals for candidate assembly.
|
||||
|
||||
use derivative::Derivative;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::traits::solve::inspect::ProbeKind;
|
||||
use rustc_middle::traits::solve::{
|
||||
CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult,
|
||||
};
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause, QueryResult};
|
||||
use rustc_middle::traits::BuiltinImplSource;
|
||||
use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{fast_reject, TypeFoldable};
|
||||
use rustc_middle::ty::{TypeVisitableExt, Upcast};
|
||||
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
||||
use std::fmt::Debug;
|
||||
use rustc_type_ir::solve::{CandidateSource, CanonicalResponse};
|
||||
use rustc_type_ir::Interner;
|
||||
|
||||
use crate::solve::GoalSource;
|
||||
use crate::solve::{EvalCtxt, SolverMode};
|
||||
@ -26,10 +26,11 @@ pub(super) mod structural_traits;
|
||||
///
|
||||
/// It consists of both the `source`, which describes how that goal would be proven,
|
||||
/// and the `result` when using the given `source`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct Candidate<'tcx> {
|
||||
pub(super) source: CandidateSource<'tcx>,
|
||||
pub(super) result: CanonicalResponse<'tcx>,
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug(bound = ""), Clone(bound = ""))]
|
||||
pub(super) struct Candidate<I: Interner> {
|
||||
pub(super) source: CandidateSource<I>,
|
||||
pub(super) result: CanonicalResponse<I>,
|
||||
}
|
||||
|
||||
/// Methods used to assemble candidates for either trait or projection goals.
|
||||
@ -50,22 +51,22 @@ pub(super) trait GoalKind<'tcx>:
|
||||
/// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
source: CandidateSource<'tcx>,
|
||||
source: CandidateSource<TyCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Clause<'tcx>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// Consider a clause, which consists of a "assumption" and some "requirements",
|
||||
/// to satisfy a goal. If the requirements hold, then attempt to satisfy our
|
||||
/// goal by equating it with the assumption.
|
||||
fn probe_and_consider_implied_clause(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
parent_source: CandidateSource<'tcx>,
|
||||
parent_source: CandidateSource<TyCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Clause<'tcx>,
|
||||
requirements: impl IntoIterator<Item = (GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, parent_source, goal, assumption, |ecx| {
|
||||
for (nested_source, goal) in requirements {
|
||||
ecx.add_goal(nested_source, goal);
|
||||
@ -79,10 +80,10 @@ pub(super) trait GoalKind<'tcx>:
|
||||
/// since they're not implied by the well-formedness of the object type.
|
||||
fn probe_and_consider_object_bound_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
source: CandidateSource<'tcx>,
|
||||
source: CandidateSource<TyCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Clause<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
|
||||
let tcx = ecx.interner();
|
||||
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
|
||||
@ -105,7 +106,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// If the predicate contained an error, we want to avoid emitting unnecessary trait
|
||||
/// errors but still want to emit errors for other trait goals. We have some special
|
||||
@ -116,7 +117,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_error_guaranteed_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A type implements an `auto trait` if its components do as well.
|
||||
///
|
||||
@ -125,13 +126,13 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_auto_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A trait alias holds if the RHS traits and `where` clauses hold.
|
||||
fn consider_trait_alias_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A type is `Sized` if its tail component is `Sized`.
|
||||
///
|
||||
@ -140,7 +141,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_sized_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`.
|
||||
///
|
||||
@ -149,20 +150,20 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_copy_clone_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A type is `PointerLike` if we can compute its layout, and that layout
|
||||
/// matches the layout of `usize`.
|
||||
fn consider_builtin_pointer_like_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A type is a `FnPtr` if it is of `FnPtr` type.
|
||||
fn consider_builtin_fn_ptr_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
|
||||
/// family of traits where `A` is given by the signature of the type.
|
||||
@ -170,7 +171,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// An async closure is known to implement the `AsyncFn<A>` family of traits
|
||||
/// where `A` is given by the signature of the type.
|
||||
@ -178,7 +179,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which
|
||||
/// is used internally to delay computation for async closures until after
|
||||
@ -186,13 +187,13 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// `Tuple` is implemented if the `Self` type is a tuple.
|
||||
fn consider_builtin_tuple_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// `Pointee` is always implemented.
|
||||
///
|
||||
@ -202,7 +203,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_pointee_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A coroutine (that comes from an `async` desugaring) is known to implement
|
||||
/// `Future<Output = O>`, where `O` is given by the coroutine's return type
|
||||
@ -210,7 +211,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_future_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A coroutine (that comes from a `gen` desugaring) is known to implement
|
||||
/// `Iterator<Item = O>`, where `O` is given by the generator's yield type
|
||||
@ -218,19 +219,19 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A coroutine (that comes from a `gen` desugaring) is known to implement
|
||||
/// `FusedIterator`
|
||||
fn consider_builtin_fused_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
fn consider_builtin_async_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to
|
||||
/// implement `Coroutine<R, Yield = Y, Return = O>`, given the resume, yield,
|
||||
@ -238,27 +239,27 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_builtin_coroutine_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
fn consider_builtin_discriminant_kind_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
fn consider_builtin_async_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
fn consider_builtin_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
fn consider_builtin_transmute_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution>;
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;
|
||||
|
||||
/// Consider (possibly several) candidates to upcast or unsize a type to another
|
||||
/// type, excluding the coercion of a sized type into a `dyn Trait`.
|
||||
@ -270,14 +271,14 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_structural_builtin_unsize_candidates(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Vec<Candidate<'tcx>>;
|
||||
) -> Vec<Candidate<TyCtxt<'tcx>>>;
|
||||
}
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
) -> Vec<Candidate<TyCtxt<'tcx>>> {
|
||||
let Ok(normalized_self_ty) =
|
||||
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
|
||||
else {
|
||||
@ -324,7 +325,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
pub(super) fn forced_ambiguity(
|
||||
&mut self,
|
||||
cause: MaybeCause,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
// This may fail if `try_evaluate_added_goals` overflows because it
|
||||
// fails to reach a fixpoint but ends up getting an error after
|
||||
// running for some additional step.
|
||||
@ -340,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_non_blanket_impl_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
@ -456,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_blanket_impl_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
|
||||
@ -479,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_builtin_impl_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let trait_def_id = goal.predicate.trait_def_id(tcx);
|
||||
@ -552,7 +553,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_param_env_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
||||
candidates.extend(G::probe_and_consider_implied_clause(
|
||||
@ -569,7 +570,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_alias_bound_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
|
||||
ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates);
|
||||
@ -589,7 +590,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
&mut self,
|
||||
self_ty: Ty<'tcx>,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let (kind, alias_ty) = match *self_ty.kind() {
|
||||
ty::Bool
|
||||
@ -673,7 +674,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object {
|
||||
@ -764,7 +765,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn assemble_coherence_unknowable_candidates<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
|
||||
@ -793,7 +794,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn discard_impls_shadowed_by_env<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
|
||||
@ -841,7 +842,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub(super) fn merge_candidates(
|
||||
&mut self,
|
||||
candidates: Vec<Candidate<'tcx>>,
|
||||
candidates: Vec<Candidate<TyCtxt<'tcx>>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
// First try merging all candidates. This is complete and fully sound.
|
||||
let responses = candidates.iter().map(|c| c.result).collect::<Vec<_>>();
|
||||
|
@ -1,27 +1,29 @@
|
||||
use crate::solve::assembly::Candidate;
|
||||
|
||||
use super::EvalCtxt;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::traits::BuiltinImplSource;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::{inspect, CandidateSource, QueryResult};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_next_trait_solver::solve::{
|
||||
inspect, BuiltinImplSource, CandidateSource, NoSolution, QueryResult,
|
||||
};
|
||||
use rustc_type_ir::{InferCtxtLike, Interner};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub(in crate::solve) struct ProbeCtxt<'me, 'a, 'tcx, F, T> {
|
||||
ecx: &'me mut EvalCtxt<'a, InferCtxt<'tcx>>,
|
||||
pub(in crate::solve) struct ProbeCtxt<'me, 'a, Infcx, I, F, T>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
ecx: &'me mut EvalCtxt<'a, Infcx, I>,
|
||||
probe_kind: F,
|
||||
_result: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'tcx, F, T> ProbeCtxt<'_, '_, 'tcx, F, T>
|
||||
impl<Infcx, I, F, T> ProbeCtxt<'_, '_, Infcx, I, F, T>
|
||||
where
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<I>,
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(in crate::solve) fn enter(
|
||||
self,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> T,
|
||||
) -> T {
|
||||
pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> T) -> T {
|
||||
let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self;
|
||||
|
||||
let infcx = outer_ecx.infcx;
|
||||
@ -38,7 +40,7 @@ where
|
||||
tainted: outer_ecx.tainted,
|
||||
inspect: outer_ecx.inspect.take_and_enter_probe(),
|
||||
};
|
||||
let r = nested_ecx.infcx.probe(|_| {
|
||||
let r = nested_ecx.infcx.probe(|| {
|
||||
let r = f(&mut nested_ecx);
|
||||
nested_ecx.inspect.probe_final_state(infcx, max_input_universe);
|
||||
r
|
||||
@ -52,30 +54,43 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, 'tcx, F> {
|
||||
cx: ProbeCtxt<'me, 'a, 'tcx, F, QueryResult<'tcx>>,
|
||||
source: CandidateSource<'tcx>,
|
||||
pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, Infcx, I, F>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
cx: ProbeCtxt<'me, 'a, Infcx, I, F, QueryResult<I>>,
|
||||
source: CandidateSource<I>,
|
||||
}
|
||||
|
||||
impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F>
|
||||
impl<Infcx, I, F> TraitProbeCtxt<'_, '_, Infcx, I, F>
|
||||
where
|
||||
F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
F: FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>,
|
||||
{
|
||||
#[instrument(level = "debug", skip_all, fields(source = ?self.source))]
|
||||
pub(in crate::solve) fn enter(
|
||||
self,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
self.cx.enter(|ecx| f(ecx)).map(|result| Candidate { source: self.source, result })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||
impl<'a, Infcx, I> EvalCtxt<'a, Infcx, I>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// `probe_kind` is only called when proof tree building is enabled so it can be
|
||||
/// as expensive as necessary to output the desired information.
|
||||
pub(in crate::solve) fn probe<F, T>(&mut self, probe_kind: F) -> ProbeCtxt<'_, 'a, 'tcx, F, T>
|
||||
pub(in crate::solve) fn probe<F, T>(
|
||||
&mut self,
|
||||
probe_kind: F,
|
||||
) -> ProbeCtxt<'_, 'a, Infcx, I, F, T>
|
||||
where
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<I>,
|
||||
{
|
||||
ProbeCtxt { ecx: self, probe_kind, _result: PhantomData }
|
||||
}
|
||||
@ -83,28 +98,20 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||
pub(in crate::solve) fn probe_builtin_trait_candidate(
|
||||
&mut self,
|
||||
source: BuiltinImplSource,
|
||||
) -> TraitProbeCtxt<
|
||||
'_,
|
||||
'a,
|
||||
'tcx,
|
||||
impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
> {
|
||||
) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>>
|
||||
{
|
||||
self.probe_trait_candidate(CandidateSource::BuiltinImpl(source))
|
||||
}
|
||||
|
||||
pub(in crate::solve) fn probe_trait_candidate(
|
||||
&mut self,
|
||||
source: CandidateSource<'tcx>,
|
||||
) -> TraitProbeCtxt<
|
||||
'_,
|
||||
'a,
|
||||
'tcx,
|
||||
impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
> {
|
||||
source: CandidateSource<I>,
|
||||
) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>>
|
||||
{
|
||||
TraitProbeCtxt {
|
||||
cx: ProbeCtxt {
|
||||
ecx: self,
|
||||
probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::TraitCandidate {
|
||||
probe_kind: move |result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
|
||||
source,
|
||||
result: *result,
|
||||
},
|
||||
|
@ -515,6 +515,32 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
||||
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
|
||||
}
|
||||
|
||||
// alias-relate may fail because the lhs or rhs can't be normalized,
|
||||
// and therefore is treated as rigid.
|
||||
if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred_kind.no_bound_vars() {
|
||||
if let Some(obligation) = goal
|
||||
.infcx()
|
||||
.visit_proof_tree_at_depth(
|
||||
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(lhs.into())),
|
||||
goal.depth() + 1,
|
||||
self,
|
||||
)
|
||||
.break_value()
|
||||
{
|
||||
return ControlFlow::Break(obligation);
|
||||
} else if let Some(obligation) = goal
|
||||
.infcx()
|
||||
.visit_proof_tree_at_depth(
|
||||
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(rhs.into())),
|
||||
goal.depth() + 1,
|
||||
self,
|
||||
)
|
||||
.break_value()
|
||||
{
|
||||
return ControlFlow::Break(obligation);
|
||||
}
|
||||
}
|
||||
|
||||
ControlFlow::Break(self.obligation.clone())
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +278,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
self.source
|
||||
}
|
||||
|
||||
pub fn depth(&self) -> usize {
|
||||
self.depth
|
||||
}
|
||||
|
||||
fn candidates_recur(
|
||||
&'a self,
|
||||
candidates: &mut Vec<InspectCandidate<'a, 'tcx>>,
|
||||
@ -435,9 +439,18 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
visitor: &mut V,
|
||||
) -> V::Result {
|
||||
self.visit_proof_tree_at_depth(goal, 0, visitor)
|
||||
}
|
||||
|
||||
fn visit_proof_tree_at_depth<V: ProofTreeVisitor<'tcx>>(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
depth: usize,
|
||||
visitor: &mut V,
|
||||
) -> V::Result {
|
||||
let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
|
||||
let proof_tree = proof_tree.unwrap();
|
||||
visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None, GoalSource::Misc))
|
||||
visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc))
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Clause<'tcx>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if let Some(projection_pred) = assumption.as_projection_clause() {
|
||||
if projection_pred.projection_def_id() == goal.predicate.def_id() {
|
||||
let tcx = ecx.interner();
|
||||
@ -140,7 +140,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, NormalizesTo<'tcx>>,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
|
||||
let goal_trait_ref = goal.predicate.alias.trait_ref(tcx);
|
||||
@ -267,14 +267,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_error_guaranteed_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
Err(NoSolution)
|
||||
}
|
||||
|
||||
fn consider_auto_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
ecx.interner().dcx().span_delayed_bug(
|
||||
ecx.interner().def_span(goal.predicate.def_id()),
|
||||
"associated types not allowed on auto traits",
|
||||
@ -285,35 +285,35 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_trait_alias_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("trait aliases do not have associated types: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_sized_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`Sized` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_copy_clone_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_pointer_like_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`PointerLike` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_fn_ptr_trait_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`FnPtr` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let tupled_inputs_and_output =
|
||||
match structural_traits::extract_tupled_inputs_and_output_from_callable(
|
||||
@ -364,7 +364,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
|
||||
let env_region = match goal_kind {
|
||||
@ -454,7 +454,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let [
|
||||
closure_fn_kind_ty,
|
||||
goal_kind_ty,
|
||||
@ -501,14 +501,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_tuple_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`Tuple` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_pointee_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
assert_eq!(metadata_def_id, goal.predicate.def_id());
|
||||
@ -590,7 +590,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_future_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let ty::Coroutine(def_id, args) = *self_ty.kind() else {
|
||||
return Err(NoSolution);
|
||||
@ -626,7 +626,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let ty::Coroutine(def_id, args) = *self_ty.kind() else {
|
||||
return Err(NoSolution);
|
||||
@ -662,14 +662,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_fused_iterator_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`FusedIterator` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_async_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let ty::Coroutine(def_id, args) = *self_ty.kind() else {
|
||||
return Err(NoSolution);
|
||||
@ -705,7 +705,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_coroutine_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let ty::Coroutine(def_id, args) = *self_ty.kind() else {
|
||||
return Err(NoSolution);
|
||||
@ -752,14 +752,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_structural_builtin_unsize_candidates(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
) -> Vec<Candidate<TyCtxt<'tcx>>> {
|
||||
bug!("`Unsize` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_discriminant_kind_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let discriminant_ty = match *self_ty.kind() {
|
||||
ty::Bool
|
||||
@ -811,7 +811,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_async_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let async_destructor_ty = match *self_ty.kind() {
|
||||
ty::Bool
|
||||
@ -864,14 +864,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn consider_builtin_destruct_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`Destruct` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_transmute_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
bug!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, TraitPredicate<'tcx>>,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
|
||||
let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
|
||||
@ -94,7 +94,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_error_guaranteed_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
// FIXME: don't need to enter a probe here.
|
||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
|
||||
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
|
||||
@ -106,7 +106,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Clause<'tcx>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if let Some(trait_clause) = assumption.as_trait_clause() {
|
||||
if trait_clause.def_id() == goal.predicate.def_id()
|
||||
&& trait_clause.polarity() == goal.predicate.polarity
|
||||
@ -131,7 +131,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_auto_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -174,7 +174,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_trait_alias_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -197,7 +197,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_sized_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -212,7 +212,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_copy_clone_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -227,7 +227,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_pointer_like_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -257,7 +257,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_fn_ptr_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
match goal.predicate.polarity {
|
||||
// impl FnPtr for FnPtr {}
|
||||
@ -289,7 +289,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -330,7 +330,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -380,7 +380,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else {
|
||||
bug!();
|
||||
};
|
||||
@ -407,7 +407,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_tuple_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -423,7 +423,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_pointee_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -435,7 +435,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_future_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -461,7 +461,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -487,7 +487,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_fused_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -511,7 +511,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_async_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -537,7 +537,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_coroutine_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -569,7 +569,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_discriminant_kind_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -582,7 +582,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_async_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -595,7 +595,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -611,7 +611,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_builtin_transmute_candidate(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
@ -652,7 +652,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn consider_structural_builtin_unsize_candidates(
|
||||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
) -> Vec<Candidate<TyCtxt<'tcx>>> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return vec![];
|
||||
}
|
||||
@ -738,7 +738,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
a_region: ty::Region<'tcx>,
|
||||
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
b_region: ty::Region<'tcx>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
) -> Vec<Candidate<TyCtxt<'tcx>>> {
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (a_ty, _b_ty), .. } = goal;
|
||||
|
||||
@ -784,7 +784,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
|
||||
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
b_region: ty::Region<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (a_ty, _), .. } = goal;
|
||||
|
||||
@ -825,7 +825,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
b_region: ty::Region<'tcx>,
|
||||
upcast_principal: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let param_env = goal.param_env;
|
||||
|
||||
// We may upcast to auto traits that are either explicitly listed in
|
||||
@ -928,7 +928,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
|
||||
a_elem_ty: Ty<'tcx>,
|
||||
b_elem_ty: Ty<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
self.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
|
||||
self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
|
||||
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
|
||||
@ -953,7 +953,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
def: ty::AdtDef<'tcx>,
|
||||
a_args: ty::GenericArgsRef<'tcx>,
|
||||
b_args: ty::GenericArgsRef<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (_a_ty, b_ty), .. } = goal;
|
||||
|
||||
@ -1014,7 +1014,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
|
||||
a_tys: &'tcx ty::List<Ty<'tcx>>,
|
||||
b_tys: &'tcx ty::List<Ty<'tcx>>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (_a_ty, b_ty), .. } = goal;
|
||||
|
||||
@ -1049,7 +1049,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn disqualify_auto_trait_candidate_due_to_possible_impl(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, TraitPredicate<'tcx>>,
|
||||
) -> Option<Result<Candidate<'tcx>, NoSolution>> {
|
||||
) -> Option<Result<Candidate<TyCtxt<'tcx>>, NoSolution>> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
match *self_ty.kind() {
|
||||
// Stall int and float vars until they are resolved to a concrete
|
||||
@ -1154,7 +1154,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
&EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
Ty<'tcx>,
|
||||
) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
self.probe_trait_candidate(source).enter(|ecx| {
|
||||
ecx.add_goals(
|
||||
GoalSource::ImplWhereBound,
|
||||
|
@ -769,8 +769,8 @@ pub struct UncoveredTyParams<'tcx, T> {
|
||||
/// add "non-blanket" impls without breaking negative reasoning in dependent
|
||||
/// crates. This is the "rebalancing coherence" (RFC 1023) restriction.
|
||||
///
|
||||
/// For that, we only a allow crate to perform negative reasoning on
|
||||
/// non-local-non-`#[fundamental]` only if there's a local key parameter as per (2).
|
||||
/// For that, we only allow a crate to perform negative reasoning on
|
||||
/// non-local-non-`#[fundamental]` if there's a local key parameter as per (2).
|
||||
///
|
||||
/// Because we never perform negative reasoning generically (coherence does
|
||||
/// not involve type parameters), this can be interpreted as doing the full
|
||||
|
@ -72,4 +72,6 @@ pub trait InferCtxtLike: Sized {
|
||||
fn resolve_vars_if_possible<T>(&self, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<Self::Interner>;
|
||||
|
||||
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
|
||||
}
|
||||
|
@ -637,7 +637,7 @@ pub enum AggregateKind {
|
||||
pub enum Operand {
|
||||
Copy(Place),
|
||||
Move(Place),
|
||||
Constant(Constant),
|
||||
Constant(ConstOperand),
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
@ -653,6 +653,13 @@ impl From<Local> for Place {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct ConstOperand {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
pub const_: MirConst,
|
||||
}
|
||||
|
||||
/// Debug information pertaining to a user variable.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct VarDebugInfo {
|
||||
@ -714,13 +721,6 @@ pub enum VarDebugInfoContents {
|
||||
Const(ConstOperand),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct ConstOperand {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
pub const_: MirConst,
|
||||
}
|
||||
|
||||
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
|
||||
// is so it can be used for both Places (for which the projection elements are of type
|
||||
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
|
||||
@ -829,13 +829,6 @@ pub type FieldIdx = usize;
|
||||
|
||||
type UserTypeAnnotationIndex = usize;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Constant {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
pub literal: MirConst,
|
||||
}
|
||||
|
||||
/// The possible branch sites of a [TerminatorKind::SwitchInt].
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct SwitchTargets {
|
||||
@ -1001,9 +994,9 @@ impl Operand {
|
||||
}
|
||||
}
|
||||
|
||||
impl Constant {
|
||||
impl ConstOperand {
|
||||
pub fn ty(&self) -> Ty {
|
||||
self.literal.ty()
|
||||
self.const_.ty()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ fn pretty_operand(operand: &Operand) -> String {
|
||||
Operand::Move(mv) => {
|
||||
format!("move {:?}", mv)
|
||||
}
|
||||
Operand::Constant(cnst) => pretty_mir_const(&cnst.literal),
|
||||
Operand::Constant(cnst) => pretty_mir_const(&cnst.const_),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,8 +108,8 @@ pub trait MirVisitor {
|
||||
self.super_ty(ty)
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, constant: &Constant, location: Location) {
|
||||
self.super_constant(constant, location)
|
||||
fn visit_const_operand(&mut self, constant: &ConstOperand, location: Location) {
|
||||
self.super_const_operand(constant, location)
|
||||
}
|
||||
|
||||
fn visit_mir_const(&mut self, constant: &MirConst, location: Location) {
|
||||
@ -366,7 +366,7 @@ pub trait MirVisitor {
|
||||
self.visit_place(place, PlaceContext::NON_MUTATING, location)
|
||||
}
|
||||
Operand::Constant(constant) => {
|
||||
self.visit_constant(constant, location);
|
||||
self.visit_const_operand(constant, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,10 +380,10 @@ pub trait MirVisitor {
|
||||
let _ = ty;
|
||||
}
|
||||
|
||||
fn super_constant(&mut self, constant: &Constant, location: Location) {
|
||||
let Constant { span, user_ty: _, literal } = constant;
|
||||
fn super_const_operand(&mut self, constant: &ConstOperand, location: Location) {
|
||||
let ConstOperand { span, user_ty: _, const_ } = constant;
|
||||
self.visit_span(span);
|
||||
self.visit_mir_const(literal, location);
|
||||
self.visit_mir_const(const_, location);
|
||||
}
|
||||
|
||||
fn super_mir_const(&mut self, constant: &MirConst, location: Location) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,4 +4,4 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies.windows-bindgen]
|
||||
version = "0.56.0"
|
||||
version = "0.57.0"
|
||||
|
@ -11,7 +11,6 @@ run-make/c-unwind-abi-catch-panic/Makefile
|
||||
run-make/cat-and-grep-sanity-check/Makefile
|
||||
run-make/cdylib-dylib-linkage/Makefile
|
||||
run-make/cdylib-fewer-symbols/Makefile
|
||||
run-make/codegen-options-parsing/Makefile
|
||||
run-make/comment-section/Makefile
|
||||
run-make/compiler-lookup-paths-2/Makefile
|
||||
run-make/compiler-lookup-paths/Makefile
|
||||
@ -25,7 +24,6 @@ run-make/cross-lang-lto-upstream-rlibs/Makefile
|
||||
run-make/cross-lang-lto/Makefile
|
||||
run-make/debug-assertions/Makefile
|
||||
run-make/debugger-visualizer-dep-info/Makefile
|
||||
run-make/dep-graph/Makefile
|
||||
run-make/dep-info-doesnt-run-much/Makefile
|
||||
run-make/dep-info-spaces/Makefile
|
||||
run-make/dep-info/Makefile
|
||||
|
@ -2760,7 +2760,6 @@ ui/lint/issue-1866.rs
|
||||
ui/lint/issue-19102.rs
|
||||
ui/lint/issue-20343.rs
|
||||
ui/lint/issue-30302.rs
|
||||
ui/lint/issue-31924-non-snake-ffi.rs
|
||||
ui/lint/issue-34798.rs
|
||||
ui/lint/issue-35075.rs
|
||||
ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
|
||||
@ -2769,7 +2768,6 @@ ui/lint/issue-54099-camel-case-underscore-types.rs
|
||||
ui/lint/issue-57410-1.rs
|
||||
ui/lint/issue-57410.rs
|
||||
ui/lint/issue-63364.rs
|
||||
ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs
|
||||
ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
|
||||
ui/lint/issue-79546-fuel-ice.rs
|
||||
ui/lint/issue-79744.rs
|
||||
@ -2777,7 +2775,6 @@ ui/lint/issue-80988.rs
|
||||
ui/lint/issue-81218.rs
|
||||
ui/lint/issue-83477.rs
|
||||
ui/lint/issue-87274-paren-parent.rs
|
||||
ui/lint/issue-89469.rs
|
||||
ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs
|
||||
ui/lint/issue-97094.rs
|
||||
ui/lint/issue-99387.rs
|
||||
|
@ -1,34 +0,0 @@
|
||||
# This test intentionally feeds invalid inputs to codegen and checks if the error message outputs contain specific helpful indications.
|
||||
|
||||
# ignore-cross-compile
|
||||
include ../tools.mk
|
||||
|
||||
all:
|
||||
#Option taking a number
|
||||
$(RUSTC) -C codegen-units dummy.rs 2>&1 | \
|
||||
$(CGREP) 'codegen option `codegen-units` requires a number'
|
||||
$(RUSTC) -C codegen-units= dummy.rs 2>&1 | \
|
||||
$(CGREP) 'incorrect value `` for codegen option `codegen-units` - a number was expected'
|
||||
$(RUSTC) -C codegen-units=foo dummy.rs 2>&1 | \
|
||||
$(CGREP) 'incorrect value `foo` for codegen option `codegen-units` - a number was expected'
|
||||
$(RUSTC) -C codegen-units=1 dummy.rs
|
||||
#Option taking a string
|
||||
$(RUSTC) -C extra-filename dummy.rs 2>&1 | \
|
||||
$(CGREP) 'codegen option `extra-filename` requires a string'
|
||||
$(RUSTC) -C extra-filename= dummy.rs 2>&1
|
||||
$(RUSTC) -C extra-filename=foo dummy.rs 2>&1
|
||||
#Option taking no argument
|
||||
$(RUSTC) -C lto= dummy.rs 2>&1 | \
|
||||
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
|
||||
$(RUSTC) -C lto=1 dummy.rs 2>&1 | \
|
||||
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
|
||||
$(RUSTC) -C lto=foo dummy.rs 2>&1 | \
|
||||
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
|
||||
$(RUSTC) -C lto dummy.rs
|
||||
|
||||
# Should not link dead code...
|
||||
$(RUSTC) --print link-args dummy.rs 2>&1 | \
|
||||
$(CGREP) -e '--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF'
|
||||
# ... unless you specifically ask to keep it
|
||||
$(RUSTC) --print link-args -C link-dead-code dummy.rs 2>&1 | \
|
||||
$(CGREP) -ve '--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF'
|
56
tests/run-make/codegen-options-parsing/rmake.rs
Normal file
56
tests/run-make/codegen-options-parsing/rmake.rs
Normal file
@ -0,0 +1,56 @@
|
||||
// This test intentionally feeds invalid inputs to codegen and checks if the error message outputs
|
||||
// contain specific helpful indications.
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::regex::Regex;
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
// Option taking a number.
|
||||
rustc()
|
||||
.input("dummy.rs")
|
||||
.arg("-Ccodegen-units")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("codegen option `codegen-units` requires a number");
|
||||
rustc().input("dummy.rs").arg("-Ccodegen-units=").run_fail().assert_stderr_contains(
|
||||
"incorrect value `` for codegen option `codegen-units` - a number was expected",
|
||||
);
|
||||
rustc().input("dummy.rs").arg("-Ccodegen-units=foo").run_fail().assert_stderr_contains(
|
||||
"incorrect value `foo` for codegen option `codegen-units` - a number was expected",
|
||||
);
|
||||
rustc().input("dummy.rs").arg("-Ccodegen-units=1").run();
|
||||
|
||||
// Option taking a string.
|
||||
rustc()
|
||||
.input("dummy.rs")
|
||||
.arg("-Cextra-filename")
|
||||
.run_fail()
|
||||
.assert_stderr_contains("codegen option `extra-filename` requires a string");
|
||||
rustc().input("dummy.rs").arg("-Cextra-filename=").run();
|
||||
rustc().input("dummy.rs").arg("-Cextra-filename=foo").run();
|
||||
|
||||
// Option taking no argument.
|
||||
rustc().input("dummy.rs").arg("-Clto=").run_fail().assert_stderr_contains(
|
||||
"codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
|
||||
`fat`, or omitted",
|
||||
);
|
||||
rustc().input("dummy.rs").arg("-Clto=1").run_fail().assert_stderr_contains(
|
||||
"codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
|
||||
`fat`, or omitted",
|
||||
);
|
||||
rustc().input("dummy.rs").arg("-Clto=foo").run_fail().assert_stderr_contains(
|
||||
"codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
|
||||
`fat`, or omitted",
|
||||
);
|
||||
rustc().input("dummy.rs").arg("-Clto").run();
|
||||
|
||||
let regex = Regex::new("--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF").unwrap();
|
||||
// Should not link dead code...
|
||||
let stdout = rustc().input("dummy.rs").print("link-args").run().stdout_utf8();
|
||||
assert!(regex.is_match(&stdout));
|
||||
// ... unless you specifically ask to keep it
|
||||
let stdout =
|
||||
rustc().input("dummy.rs").print("link-args").arg("-Clink-dead-code").run().stdout_utf8();
|
||||
assert!(!regex.is_match(&stdout));
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# ignore-cross-compile
|
||||
|
||||
# Just verify that we successfully run and produce dep graphs when requested.
|
||||
|
||||
all:
|
||||
RUST_DEP_GRAPH=$(TMPDIR)/dep-graph $(RUSTC) \
|
||||
-Cincremental=$(TMPDIR)/incr \
|
||||
-Zquery-dep-graph -Zdump-dep-graph foo.rs
|
||||
test -f $(TMPDIR)/dep-graph.txt
|
||||
test -f $(TMPDIR)/dep-graph.dot
|
18
tests/run-make/dep-graph/rmake.rs
Normal file
18
tests/run-make/dep-graph/rmake.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Just verify that we successfully run and produce dep graphs when requested.
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{path, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
.input("foo.rs")
|
||||
.incremental(path("incr"))
|
||||
.arg("-Zquery-dep-graph")
|
||||
.arg("-Zdump-dep-graph")
|
||||
.env("RUST_DEP_GRAPH", path("dep-graph"))
|
||||
.run();
|
||||
|
||||
assert!(path("dep-graph.txt").is_file());
|
||||
assert!(path("dep-graph.dot").is_file());
|
||||
}
|
@ -21,7 +21,7 @@ extern crate stable_mir;
|
||||
use rustc_smir::rustc_internal;
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
use stable_mir::mir::mono::Instance;
|
||||
use stable_mir::mir::{Body, Constant, Operand, Rvalue, StatementKind, TerminatorKind};
|
||||
use stable_mir::mir::{Body, ConstOperand, Operand, Rvalue, StatementKind, TerminatorKind};
|
||||
use stable_mir::ty::{ConstantKind, MirConst};
|
||||
use stable_mir::{CrateDef, CrateItems, ItemKind};
|
||||
use std::convert::TryFrom;
|
||||
@ -72,7 +72,7 @@ fn check_msg(body: &Body, expected: &str) {
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
let ConstantKind::Allocated(alloc) = msg_const.literal.kind() else {
|
||||
let ConstantKind::Allocated(alloc) = msg_const.const_.kind() else {
|
||||
unreachable!()
|
||||
};
|
||||
assert_eq!(alloc.provenance.ptrs.len(), 1);
|
||||
@ -96,8 +96,8 @@ fn change_panic_msg(mut body: Body, new_msg: &str) -> Body {
|
||||
match &mut bb.terminator.kind {
|
||||
TerminatorKind::Call { args, .. } => {
|
||||
let new_const = MirConst::from_str(new_msg);
|
||||
args[0] = Operand::Constant(Constant {
|
||||
literal: new_const,
|
||||
args[0] = Operand::Constant(ConstOperand {
|
||||
const_: new_const,
|
||||
span: bb.terminator.span,
|
||||
user_ty: None,
|
||||
});
|
||||
|
@ -31,18 +31,6 @@ help: consider further restricting `Self`
|
||||
LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
|
||||
| +++++++++++++++++++++++++
|
||||
|
||||
error[E0271]: type mismatch resolving `<Self as Deref>::Target == str`
|
||||
--> $DIR/defaults-unsound-62211-1.rs:24:96
|
||||
|
|
||||
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
|
||||
| ^^^^ types differ
|
||||
|
|
||||
note: required by a bound in `UncheckedCopy::Output`
|
||||
--> $DIR/defaults-unsound-62211-1.rs:24:31
|
||||
|
|
||||
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
|
||||
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
|
||||
|
||||
error[E0277]: the trait bound `Self: Deref` is not satisfied
|
||||
--> $DIR/defaults-unsound-62211-1.rs:24:96
|
||||
|
|
||||
@ -50,10 +38,10 @@ LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + Fro
|
||||
| ^^^^ the trait `Deref` is not implemented for `Self`
|
||||
|
|
||||
note: required by a bound in `UncheckedCopy::Output`
|
||||
--> $DIR/defaults-unsound-62211-1.rs:24:25
|
||||
--> $DIR/defaults-unsound-62211-1.rs:24:31
|
||||
|
|
||||
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
|
||||
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | trait UncheckedCopy: Sized + Deref {
|
||||
@ -75,7 +63,6 @@ help: consider further restricting `Self`
|
||||
LL | trait UncheckedCopy: Sized + Copy {
|
||||
| ++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -26,7 +26,6 @@ trait UncheckedCopy: Sized {
|
||||
//~| ERROR the trait bound `Self: Deref` is not satisfied
|
||||
//~| ERROR cannot add-assign `&'static str` to `Self`
|
||||
//~| ERROR `Self` doesn't implement `std::fmt::Display`
|
||||
//[next]~| ERROR type mismatch resolving `<Self as Deref>::Target == str`
|
||||
|
||||
// We said the Output type was Copy, so we can Copy it freely!
|
||||
fn unchecked_copy(other: &Self::Output) -> Self::Output {
|
||||
|
@ -31,18 +31,6 @@ help: consider further restricting `Self`
|
||||
LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
|
||||
| +++++++++++++++++++++++++
|
||||
|
||||
error[E0271]: type mismatch resolving `<Self as Deref>::Target == str`
|
||||
--> $DIR/defaults-unsound-62211-2.rs:24:96
|
||||
|
|
||||
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
|
||||
| ^^^^ types differ
|
||||
|
|
||||
note: required by a bound in `UncheckedCopy::Output`
|
||||
--> $DIR/defaults-unsound-62211-2.rs:24:31
|
||||
|
|
||||
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
|
||||
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
|
||||
|
||||
error[E0277]: the trait bound `Self: Deref` is not satisfied
|
||||
--> $DIR/defaults-unsound-62211-2.rs:24:96
|
||||
|
|
||||
@ -50,10 +38,10 @@ LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + Fro
|
||||
| ^^^^ the trait `Deref` is not implemented for `Self`
|
||||
|
|
||||
note: required by a bound in `UncheckedCopy::Output`
|
||||
--> $DIR/defaults-unsound-62211-2.rs:24:25
|
||||
--> $DIR/defaults-unsound-62211-2.rs:24:31
|
||||
|
|
||||
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
|
||||
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | trait UncheckedCopy: Sized + Deref {
|
||||
@ -75,7 +63,6 @@ help: consider further restricting `Self`
|
||||
LL | trait UncheckedCopy: Sized + Copy {
|
||||
| ++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -26,7 +26,6 @@ trait UncheckedCopy: Sized {
|
||||
//~| ERROR the trait bound `Self: Deref` is not satisfied
|
||||
//~| ERROR cannot add-assign `&'static str` to `Self`
|
||||
//~| ERROR `Self` doesn't implement `std::fmt::Display`
|
||||
//[next]~| ERROR type mismatch resolving `<Self as Deref>::Target == str`
|
||||
|
||||
// We said the Output type was Copy, so we can Copy it freely!
|
||||
fn unchecked_copy(other: &Self::Output) -> Self::Output {
|
||||
|
@ -1,15 +1,3 @@
|
||||
error[E0271]: type mismatch resolving `<<T as SubEncoder>::ActualSize as Add>::Output == <T as SubEncoder>::ActualSize`
|
||||
--> $DIR/issue-54108.rs:23:17
|
||||
|
|
||||
LL | type Size = <Self as SubEncoder>::ActualSize;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
|
||||
|
|
||||
note: required by a bound in `Encoder::Size`
|
||||
--> $DIR/issue-54108.rs:8:20
|
||||
|
|
||||
LL | type Size: Add<Output = Self::Size>;
|
||||
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
|
||||
|
||||
error[E0277]: cannot add `<T as SubEncoder>::ActualSize` to `<T as SubEncoder>::ActualSize`
|
||||
--> $DIR/issue-54108.rs:23:17
|
||||
|
|
||||
@ -18,16 +6,15 @@ LL | type Size = <Self as SubEncoder>::ActualSize;
|
||||
|
|
||||
= help: the trait `Add` is not implemented for `<T as SubEncoder>::ActualSize`
|
||||
note: required by a bound in `Encoder::Size`
|
||||
--> $DIR/issue-54108.rs:8:16
|
||||
--> $DIR/issue-54108.rs:8:20
|
||||
|
|
||||
LL | type Size: Add<Output = Self::Size>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
|
||||
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
|
||||
help: consider further restricting the associated type
|
||||
|
|
||||
LL | T: SubEncoder, <T as SubEncoder>::ActualSize: Add
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -22,7 +22,6 @@ where
|
||||
{
|
||||
type Size = <Self as SubEncoder>::ActualSize;
|
||||
//~^ ERROR: cannot add `<T as SubEncoder>::ActualSize` to `<T as SubEncoder>::ActualSize`
|
||||
//[next]~| ERROR type mismatch resolving `<<T as SubEncoder>::ActualSize as Add>::Output == <T as SubEncoder>::ActualSize`
|
||||
|
||||
fn foo(&self) -> Self::Size {
|
||||
self.bar() + self.bar()
|
||||
|
@ -1,29 +1,29 @@
|
||||
error: structure field `lowerCamelCaseName` should have a snake case name
|
||||
--> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:7:9
|
||||
--> $DIR/no-snake-case-warning-for-field-puns-issue-66362.rs:7:9
|
||||
|
|
||||
LL | lowerCamelCaseName: bool,
|
||||
| ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9
|
||||
--> $DIR/no-snake-case-warning-for-field-puns-issue-66362.rs:1:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: variable `lowerCamelCaseBinding` should have a snake case name
|
||||
--> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:20:38
|
||||
--> $DIR/no-snake-case-warning-for-field-puns-issue-66362.rs:20:38
|
||||
|
|
||||
LL | Foo::Good { snake_case_name: lowerCamelCaseBinding } => { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_binding`
|
||||
|
||||
error: variable `anotherLowerCamelCaseBinding` should have a snake case name
|
||||
--> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:24:41
|
||||
--> $DIR/no-snake-case-warning-for-field-puns-issue-66362.rs:24:41
|
||||
|
|
||||
LL | if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `another_lower_camel_case_binding`
|
||||
|
||||
error: variable `yetAnotherLowerCamelCaseBinding` should have a snake case name
|
||||
--> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:27:43
|
||||
--> $DIR/no-snake-case-warning-for-field-puns-issue-66362.rs:27:43
|
||||
|
|
||||
LL | if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `yet_another_lower_camel_case_binding`
|
@ -6,8 +6,6 @@ LL | needs_coroutine(
|
||||
LL | #[coroutine]
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | yield ();
|
||||
LL | | },
|
||||
| |_________^ the trait `Coroutine<A>` is not implemented for `{coroutine@$DIR/coroutine.rs:20:9: 20:11}`
|
||||
@ -18,47 +16,6 @@ note: required by a bound in `needs_coroutine`
|
||||
LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine`
|
||||
|
||||
error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Yield == B`
|
||||
--> $DIR/coroutine.rs:20:9
|
||||
|
|
||||
LL | needs_coroutine(
|
||||
| --------------- required by a bound introduced by this call
|
||||
LL | #[coroutine]
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | yield ();
|
||||
LL | | },
|
||||
| |_________^ types differ
|
||||
|
|
||||
note: required by a bound in `needs_coroutine`
|
||||
--> $DIR/coroutine.rs:14:41
|
||||
|
|
||||
LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
|
||||
| ^^^^^^^^^ required by this bound in `needs_coroutine`
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Return == C`
|
||||
--> $DIR/coroutine.rs:20:9
|
||||
|
|
||||
LL | needs_coroutine(
|
||||
| --------------- required by a bound introduced by this call
|
||||
LL | #[coroutine]
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | yield ();
|
||||
LL | | },
|
||||
| |_________^ types differ
|
||||
|
|
||||
note: required by a bound in `needs_coroutine`
|
||||
--> $DIR/coroutine.rs:14:52
|
||||
|
|
||||
LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
|
||||
| ^^^^^^^^^^ required by this bound in `needs_coroutine`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -19,8 +19,6 @@ fn main() {
|
||||
#[coroutine]
|
||||
|| {
|
||||
//[fail]~^ ERROR Coroutine<A>` is not satisfied
|
||||
//[fail]~| ERROR as Coroutine<A>>::Yield == B`
|
||||
//[fail]~| ERROR as Coroutine<A>>::Return == C`
|
||||
yield ();
|
||||
},
|
||||
);
|
||||
|
@ -19,14 +19,10 @@ fn main() {
|
||||
require_fn(f as fn() -> i32);
|
||||
require_fn(f as unsafe fn() -> i32);
|
||||
//~^ ERROR: expected a `Fn()` closure, found `unsafe fn() -> i32`
|
||||
//~| ERROR: type mismatch resolving `<unsafe fn() -> i32 as FnOnce<()>>::Output == i32`
|
||||
require_fn(g);
|
||||
//~^ ERROR: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}`
|
||||
//~| ERROR: type mismatch resolving `<extern "C" fn() -> i32 {g} as FnOnce<()>>::Output == i32`
|
||||
require_fn(g as extern "C" fn() -> i32);
|
||||
//~^ ERROR: expected a `Fn()` closure, found `extern "C" fn() -> i32`
|
||||
//~| ERROR: type mismatch resolving `<extern "C" fn() -> i32 as FnOnce<()>>::Output == i32`
|
||||
require_fn(h);
|
||||
//~^ ERROR: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}`
|
||||
//~| ERROR: type mismatch resolving `<unsafe fn() -> i32 {h} as FnOnce<()>>::Output == i32`
|
||||
}
|
||||
|
@ -15,22 +15,8 @@ note: required by a bound in `require_fn`
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0271]: type mismatch resolving `<unsafe fn() -> i32 as FnOnce<()>>::Output == i32`
|
||||
--> $DIR/fn-trait.rs:20:16
|
||||
|
|
||||
LL | require_fn(f as unsafe fn() -> i32);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `require_fn`
|
||||
--> $DIR/fn-trait.rs:3:31
|
||||
|
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}`
|
||||
--> $DIR/fn-trait.rs:23:16
|
||||
--> $DIR/fn-trait.rs:22:16
|
||||
|
|
||||
LL | require_fn(g);
|
||||
| ---------- ^ expected an `Fn()` closure, found `extern "C" fn() -> i32 {g}`
|
||||
@ -45,22 +31,8 @@ note: required by a bound in `require_fn`
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0271]: type mismatch resolving `<extern "C" fn() -> i32 {g} as FnOnce<()>>::Output == i32`
|
||||
--> $DIR/fn-trait.rs:23:16
|
||||
|
|
||||
LL | require_fn(g);
|
||||
| ---------- ^ types differ
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `require_fn`
|
||||
--> $DIR/fn-trait.rs:3:31
|
||||
|
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32`
|
||||
--> $DIR/fn-trait.rs:26:16
|
||||
--> $DIR/fn-trait.rs:24:16
|
||||
|
|
||||
LL | require_fn(g as extern "C" fn() -> i32);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn()` closure, found `extern "C" fn() -> i32`
|
||||
@ -75,22 +47,8 @@ note: required by a bound in `require_fn`
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0271]: type mismatch resolving `<extern "C" fn() -> i32 as FnOnce<()>>::Output == i32`
|
||||
--> $DIR/fn-trait.rs:26:16
|
||||
|
|
||||
LL | require_fn(g as extern "C" fn() -> i32);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `require_fn`
|
||||
--> $DIR/fn-trait.rs:3:31
|
||||
|
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}`
|
||||
--> $DIR/fn-trait.rs:29:16
|
||||
--> $DIR/fn-trait.rs:26:16
|
||||
|
|
||||
LL | require_fn(h);
|
||||
| ---------- ^ call the function in a closure: `|| unsafe { /* code */ }`
|
||||
@ -106,21 +64,6 @@ note: required by a bound in `require_fn`
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `require_fn`
|
||||
|
||||
error[E0271]: type mismatch resolving `<unsafe fn() -> i32 {h} as FnOnce<()>>::Output == i32`
|
||||
--> $DIR/fn-trait.rs:29:16
|
||||
|
|
||||
LL | require_fn(h);
|
||||
| ---------- ^ types differ
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `require_fn`
|
||||
--> $DIR/fn-trait.rs:3:31
|
||||
|
|
||||
LL | fn require_fn(_: impl Fn() -> i32) {}
|
||||
| ^^^ required by this bound in `require_fn`
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user