authorbors <bors@rust-lang.org> 2025-08-10 14:17:41 UTC
committerbors <bors@rust-lang.org> 2025-08-10 14:17:41 UTC
log18eeac04fc5c2a4c4a8020dbdf1c652077ad0e4e
tree3bb0db94131d71006af1bfd0151bb9d530cf1315
parent7f7b8ef27d86c865a7ab20c7c42f50811c6a914d
parent934cb10f1b21be3a855951fb9b1f38094946aac8

Auto merge of #145210 - Zalathar:rollup-dm4reb2, r=Zalathar

Rollup of 17 pull requests Successful merges: - rust-lang/rust#141624 (unstable-book: Add stubs for environment variables; document some of the important ones) - rust-lang/rust#143093 (Simplify polonius location-sensitive analysis) - rust-lang/rust#144402 (Stabilize loongarch32 inline asm) - rust-lang/rust#144403 (`tests/ui/issues/`: The Issues Strike Back [4/N]) - rust-lang/rust#144739 (Use new public libtest `ERROR_EXIT_CODE` constant in rustdoc) - rust-lang/rust#145089 (Improve error output when a command fails in bootstrap) - rust-lang/rust#145112 ([win][arm64ec] Partial fix for raw-dylib-link-ordinal on Arm64EC) - rust-lang/rust#145129 ([win][arm64ec] Add `/machine:arm64ec` when linking LLVM as Arm64EC) - rust-lang/rust#145130 (improve "Documentation problem" issue template.) - rust-lang/rust#145135 (Stabilize `duration_constructors_lite` feature) - rust-lang/rust#145145 (some `derive_more` refactors) - rust-lang/rust#145147 (rename `TraitRef::from_method` to `from_assoc`) - rust-lang/rust#145156 (Override custom Cargo `build-dir` in bootstrap) - rust-lang/rust#145160 (Change days-threshold to 28 in [behind-upstream]) - rust-lang/rust#145162 (`{BTree,Hash}Map`: add "`Entry` API" section heading) - rust-lang/rust#145187 (Fix an unstable feature comment that wasn't a doc comment) - rust-lang/rust#145191 (`suggest_borrow_generic_arg`: use the correct generic args) r? `@ghost` `@rustbot` modify labels: rollup

191 files changed, 2532 insertions(+), 1681 deletions(-)

.github/ISSUE_TEMPLATE/documentation.yaml+6-6
......@@ -1,5 +1,5 @@
11name: Documentation problem
2description: Create a report for a documentation problem.
2description: Report an issue with documentation content.
33labels: ["A-docs"]
44body:
55 - type: markdown
......@@ -19,20 +19,20 @@ body:
1919 - [The Rustonomicon](https://github.com/rust-lang/nomicon/issues)
2020 - [The Embedded Book](https://github.com/rust-embedded/book/issues)
2121
22 All other documentation issues should be filed here.
22 Or, if you find an issue related to rustdoc (e.g. doctest, rustdoc UI), please use the rustdoc issue template instead.
2323
24 Or, if you find an issue related to rustdoc (e.g. doctest, rustdoc UI), please use the bug report or blank issue template instead.
24 All other documentation issues should be filed here.
2525
2626 - type: textarea
2727 id: location
2828 attributes:
29 label: Location
29 label: Location (URL)
3030 validations:
31 required: true
31 required: true
3232
3333 - type: textarea
3434 id: summary
3535 attributes:
3636 label: Summary
3737 validations:
38 required: true
\ No newline at end of file
38 required: true
compiler/rustc_ast_lowering/src/asm.rs+1
......@@ -48,6 +48,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
4848 | asm::InlineAsmArch::Arm64EC
4949 | asm::InlineAsmArch::RiscV32
5050 | asm::InlineAsmArch::RiscV64
51 | asm::InlineAsmArch::LoongArch32
5152 | asm::InlineAsmArch::LoongArch64
5253 | asm::InlineAsmArch::S390x
5354 );
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs+22-7
......@@ -410,18 +410,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
410410 }
411411 let typeck = self.infcx.tcx.typeck(self.mir_def_id());
412412 let parent = self.infcx.tcx.parent_hir_node(expr.hir_id);
413 let (def_id, call_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
413 let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
414414 && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
415415 {
416416 let def_id = typeck.type_dependent_def_id(parent_expr.hir_id);
417 (def_id, Some(parent_expr.hir_id), args, 1)
417 (def_id, args, 1)
418418 } else if let hir::Node::Expr(parent_expr) = parent
419419 && let hir::ExprKind::Call(call, args) = parent_expr.kind
420420 && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
421421 {
422 (Some(*def_id), Some(call.hir_id), args, 0)
422 (Some(*def_id), args, 0)
423423 } else {
424 (None, None, &[][..], 0)
424 (None, &[][..], 0)
425425 };
426426 let ty = place.ty(self.body, self.infcx.tcx).ty;
427427
......@@ -459,11 +459,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
459459 // If the moved place is used generically by the callee and a reference to it
460460 // would still satisfy any bounds on its type, suggest borrowing.
461461 if let Some(&param) = arg_param
462 && let Some(generic_args) = call_id.and_then(|id| typeck.node_args_opt(id))
462 && let hir::Node::Expr(call_expr) = parent
463463 && let Some(ref_mutability) = self.suggest_borrow_generic_arg(
464464 err,
465 typeck,
466 call_expr,
465467 def_id,
466 generic_args,
467468 param,
468469 moved_place,
469470 pos + offset,
......@@ -627,8 +628,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
627628 fn suggest_borrow_generic_arg(
628629 &self,
629630 err: &mut Diag<'_>,
631 typeck: &ty::TypeckResults<'tcx>,
632 call_expr: &hir::Expr<'tcx>,
630633 callee_did: DefId,
631 generic_args: ty::GenericArgsRef<'tcx>,
632634 param: ty::ParamTy,
633635 moved_place: PlaceRef<'tcx>,
634636 moved_arg_pos: usize,
......@@ -639,6 +641,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
639641 let sig = tcx.fn_sig(callee_did).instantiate_identity().skip_binder();
640642 let clauses = tcx.predicates_of(callee_did);
641643
644 let generic_args = match call_expr.kind {
645 // For method calls, generic arguments are attached to the call node.
646 hir::ExprKind::MethodCall(..) => typeck.node_args_opt(call_expr.hir_id)?,
647 // For normal calls, generic arguments are in the callee's type.
648 // This diagnostic is only run for `FnDef` callees.
649 hir::ExprKind::Call(callee, _)
650 if let &ty::FnDef(_, args) = typeck.node_type(callee.hir_id).kind() =>
651 {
652 args
653 }
654 _ => return None,
655 };
656
642657 // First, is there at least one method on one of `param`'s trait bounds?
643658 // This keeps us from suggesting borrowing the argument to `mem::drop`, e.g.
644659 if !clauses.instantiate_identity(tcx).predicates.iter().any(|clause| {
compiler/rustc_borrowck/src/polonius/constraints.rs+1-3
......@@ -7,9 +7,7 @@ use rustc_mir_dataflow::points::PointIndex;
77///
88/// This models two sources of constraints:
99/// - constraints that traverse the subsets between regions at a given point, `a@p: b@p`. These
10/// depend on typeck constraints generated via assignments, calls, etc. (In practice there are
11/// subtleties where a statement's effect only starts being visible at the successor point, via
12/// the "result" of that statement).
10/// depend on typeck constraints generated via assignments, calls, etc.
1311/// - constraints that traverse the CFG via the same region, `a@p: a@q`, where `p` is a predecessor
1412/// of `q`. These depend on the liveness of the regions at these points, as well as their
1513/// variance.
compiler/rustc_borrowck/src/polonius/liveness_constraints.rs+2-10
......@@ -105,22 +105,14 @@ fn propagate_loans_between_points(
105105 });
106106 }
107107
108 let Some(current_live_regions) = live_regions.row(current_point) else {
109 // There are no constraints to add: there are no live regions at the current point.
110 return;
111 };
112108 let Some(next_live_regions) = live_regions.row(next_point) else {
113109 // There are no constraints to add: there are no live regions at the next point.
114110 return;
115111 };
116112
117113 for region in next_live_regions.iter() {
118 if !current_live_regions.contains(region) {
119 continue;
120 }
121
122 // `region` is indeed live at both points, add a constraint between them, according to
123 // variance.
114 // `region` could be live at the current point, and is live at the next point: add a
115 // constraint between them, according to variance.
124116 if let Some(&direction) = live_region_variances.get(&region) {
125117 add_liveness_constraint(
126118 region,
compiler/rustc_borrowck/src/polonius/loan_liveness.rs+22-169
......@@ -1,27 +1,18 @@
1use std::collections::{BTreeMap, BTreeSet};
2
31use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
4use rustc_middle::mir::visit::Visitor;
5use rustc_middle::mir::{
6 Body, Local, Location, Place, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
7};
8use rustc_middle::ty::{RegionVid, TyCtxt};
2use rustc_middle::ty::RegionVid;
93use rustc_mir_dataflow::points::PointIndex;
104
115use super::{LiveLoans, LocalizedOutlivesConstraintSet};
6use crate::BorrowSet;
127use crate::constraints::OutlivesConstraint;
13use crate::dataflow::BorrowIndex;
148use crate::region_infer::values::LivenessValues;
159use crate::type_check::Locations;
16use crate::{BorrowSet, PlaceConflictBias, places_conflict};
1710
18/// Compute loan reachability, stop at kills, and trace loan liveness throughout the CFG, by
11/// Compute loan reachability to approximately trace loan liveness throughout the CFG, by
1912/// traversing the full graph of constraints that combines:
2013/// - the localized constraints (the physical edges),
2114/// - with the constraints that hold at all points (the logical edges).
2215pub(super) fn compute_loan_liveness<'tcx>(
23 tcx: TyCtxt<'tcx>,
24 body: &Body<'tcx>,
2516 liveness: &LivenessValues,
2617 outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>,
2718 borrow_set: &BorrowSet<'tcx>,
......@@ -29,11 +20,6 @@ pub(super) fn compute_loan_liveness<'tcx>(
2920) -> LiveLoans {
3021 let mut live_loans = LiveLoans::new(borrow_set.len());
3122
32 // FIXME: it may be preferable for kills to be encoded in the edges themselves, to simplify and
33 // likely make traversal (and constraint generation) more efficient. We also display kills on
34 // edges when visualizing the constraint graph anyways.
35 let kills = collect_kills(body, tcx, borrow_set);
36
3723 // Create the full graph with the physical edges we've localized earlier, and the logical edges
3824 // of constraints that hold at all points.
3925 let logical_constraints =
......@@ -59,15 +45,15 @@ pub(super) fn compute_loan_liveness<'tcx>(
5945 continue;
6046 }
6147
62 // Record the loan as being live on entry to this point.
63 live_loans.insert(node.point, loan_idx);
64
65 // Here, we have a conundrum. There's currently a weakness in our theory, in that
66 // we're using a single notion of reachability to represent what used to be _two_
67 // different transitive closures. It didn't seem impactful when coming up with the
68 // single-graph and reachability through space (regions) + time (CFG) concepts, but in
69 // practice the combination of time-traveling with kills is more impactful than
70 // initially anticipated.
48 // Record the loan as being live on entry to this point if it reaches a live region
49 // there.
50 //
51 // This is an approximation of liveness (which is the thing we want), in that we're
52 // using a single notion of reachability to represent what used to be _two_ different
53 // transitive closures. It didn't seem impactful when coming up with the single-graph
54 // and reachability through space (regions) + time (CFG) concepts, but in practice the
55 // combination of time-traveling with kills is more impactful than initially
56 // anticipated.
7157 //
7258 // Kills should prevent a loan from reaching its successor points in the CFG, but not
7359 // while time-traveling: we're not actually at that CFG point, but looking for
......@@ -92,40 +78,20 @@ pub(super) fn compute_loan_liveness<'tcx>(
9278 // two-step traversal described above: only kills encountered on exit via a backward
9379 // edge are ignored.
9480 //
95 // In our test suite, there are a couple of cases where kills are encountered while
96 // time-traveling, however as far as we can tell, always in cases where they would be
97 // unreachable. We have reason to believe that this is a property of the single-graph
98 // approach (but haven't proved it yet):
99 // - reachable kills while time-traveling would also be encountered via regular
100 // traversal
101 // - it makes _some_ sense to ignore unreachable kills, but subtleties around dead code
102 // in general need to be better thought through (like they were for NLLs).
103 // - ignoring kills is a conservative approximation: the loan is still live and could
104 // cause false positive errors at another place access. Soundness issues in this
105 // domain should look more like the absence of reachability instead.
106 //
107 // This is enough in practice to pass tests, and therefore is what we have implemented
108 // for now.
81 // This version of the analysis, however, is enough in practice to pass the tests that
82 // we care about and NLLs reject, without regressions on crater, and is an actionable
83 // subset of the full analysis. It also naturally points to areas of improvement that we
84 // wish to explore later, namely handling kills appropriately during traversal, instead
85 // of continuing traversal to all the reachable nodes.
10986 //
110 // FIXME: all of the above. Analyze potential unsoundness, possibly in concert with a
111 // borrowck implementation in a-mir-formality, fuzzing, or manually crafting
112 // counter-examples.
87 // FIXME: analyze potential unsoundness, possibly in concert with a borrowck
88 // implementation in a-mir-formality, fuzzing, or manually crafting counter-examples.
11389
114 // Continuing traversal will depend on whether the loan is killed at this point, and
115 // whether we're time-traveling.
116 let current_location = liveness.location_from_point(node.point);
117 let is_loan_killed =
118 kills.get(&current_location).is_some_and(|kills| kills.contains(&loan_idx));
90 if liveness.is_live_at(node.region, liveness.location_from_point(node.point)) {
91 live_loans.insert(node.point, loan_idx);
92 }
11993
12094 for succ in graph.outgoing_edges(node) {
121 // If the loan is killed at this point, it is killed _on exit_. But only during
122 // forward traversal.
123 if is_loan_killed {
124 let destination = liveness.location_from_point(succ.point);
125 if current_location.is_predecessor_of(destination, body) {
126 continue;
127 }
128 }
12995 stack.push(succ);
13096 }
13197 }
......@@ -192,116 +158,3 @@ impl LocalizedConstraintGraph {
192158 physical_edges.chain(materialized_edges)
193159 }
194160}
195
196/// Traverses the MIR and collects kills.
197fn collect_kills<'tcx>(
198 body: &Body<'tcx>,
199 tcx: TyCtxt<'tcx>,
200 borrow_set: &BorrowSet<'tcx>,
201) -> BTreeMap<Location, BTreeSet<BorrowIndex>> {
202 let mut collector = KillsCollector { borrow_set, tcx, body, kills: BTreeMap::default() };
203 for (block, data) in body.basic_blocks.iter_enumerated() {
204 collector.visit_basic_block_data(block, data);
205 }
206 collector.kills
207}
208
209struct KillsCollector<'a, 'tcx> {
210 body: &'a Body<'tcx>,
211 tcx: TyCtxt<'tcx>,
212 borrow_set: &'a BorrowSet<'tcx>,
213
214 /// The set of loans killed at each location.
215 kills: BTreeMap<Location, BTreeSet<BorrowIndex>>,
216}
217
218// This visitor has a similar structure to the `Borrows` dataflow computation with respect to kills,
219// and the datalog polonius fact generation for the `loan_killed_at` relation.
220impl<'tcx> KillsCollector<'_, 'tcx> {
221 /// Records the borrows on the specified place as `killed`. For example, when assigning to a
222 /// local, or on a call's return destination.
223 fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
224 // For the reasons described in graph traversal, we also filter out kills
225 // unreachable from the loan's introduction point, as they would stop traversal when
226 // e.g. checking for reachability in the subset graph through invariance constraints
227 // higher up.
228 let filter_unreachable_kills = |loan| {
229 let introduction = self.borrow_set[loan].reserve_location;
230 let reachable = introduction.is_predecessor_of(location, self.body);
231 reachable
232 };
233
234 let other_borrows_of_local = self
235 .borrow_set
236 .local_map
237 .get(&place.local)
238 .into_iter()
239 .flat_map(|bs| bs.iter())
240 .copied();
241
242 // If the borrowed place is a local with no projections, all other borrows of this
243 // local must conflict. This is purely an optimization so we don't have to call
244 // `places_conflict` for every borrow.
245 if place.projection.is_empty() {
246 if !self.body.local_decls[place.local].is_ref_to_static() {
247 self.kills
248 .entry(location)
249 .or_default()
250 .extend(other_borrows_of_local.filter(|&loan| filter_unreachable_kills(loan)));
251 }
252 return;
253 }
254
255 // By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given
256 // pair of array indices are not equal, so that when `places_conflict` returns true, we
257 // will be assured that two places being compared definitely denotes the same sets of
258 // locations.
259 let definitely_conflicting_borrows = other_borrows_of_local
260 .filter(|&i| {
261 places_conflict(
262 self.tcx,
263 self.body,
264 self.borrow_set[i].borrowed_place,
265 place,
266 PlaceConflictBias::NoOverlap,
267 )
268 })
269 .filter(|&loan| filter_unreachable_kills(loan));
270
271 self.kills.entry(location).or_default().extend(definitely_conflicting_borrows);
272 }
273
274 /// Records the borrows on the specified local as `killed`.
275 fn record_killed_borrows_for_local(&mut self, local: Local, location: Location) {
276 if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
277 self.kills.entry(location).or_default().extend(borrow_indices.iter());
278 }
279 }
280}
281
282impl<'tcx> Visitor<'tcx> for KillsCollector<'_, 'tcx> {
283 fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
284 // Make sure there are no remaining borrows for locals that have gone out of scope.
285 if let StatementKind::StorageDead(local) = statement.kind {
286 self.record_killed_borrows_for_local(local, location);
287 }
288
289 self.super_statement(statement, location);
290 }
291
292 fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
293 // When we see `X = ...`, then kill borrows of `(*X).foo` and so forth.
294 self.record_killed_borrows_for_place(*place, location);
295 self.super_assign(place, rvalue, location);
296 }
297
298 fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
299 // A `Call` terminator's return value can be a local which has borrows, so we need to record
300 // those as killed as well.
301 if let TerminatorKind::Call { destination, .. } = terminator.kind {
302 self.record_killed_borrows_for_place(destination, location);
303 }
304
305 self.super_terminator(terminator, location);
306 }
307}
compiler/rustc_borrowck/src/polonius/mod.rs+2-4
......@@ -146,8 +146,8 @@ impl PoloniusContext {
146146 /// - converting NLL typeck constraints to be localized
147147 /// - encoding liveness constraints
148148 ///
149 /// Then, this graph is traversed, and combined with kills, reachability is recorded as loan
150 /// liveness, to be used by the loan scope and active loans computations.
149 /// Then, this graph is traversed, reachability is recorded as loan liveness, to be used by the
150 /// loan scope and active loans computations.
151151 ///
152152 /// The constraint data will be used to compute errors and diagnostics.
153153 pub(crate) fn compute_loan_liveness<'tcx>(
......@@ -182,8 +182,6 @@ impl PoloniusContext {
182182 // Now that we have a complete graph, we can compute reachability to trace the liveness of
183183 // loans for the next step in the chain, the NLL loan scope and active loans computations.
184184 let live_loans = compute_loan_liveness(
185 tcx,
186 body,
187185 regioncx.liveness_constraints(),
188186 regioncx.outlives_constraints(),
189187 borrow_set,
compiler/rustc_borrowck/src/polonius/typeck_constraints.rs+4-15
......@@ -47,9 +47,7 @@ pub(super) fn convert_typeck_constraints<'tcx>(
4747 tcx,
4848 body,
4949 stmt,
50 liveness,
5150 &outlives_constraint,
52 location,
5351 point,
5452 universal_regions,
5553 )
......@@ -78,9 +76,7 @@ fn localize_statement_constraint<'tcx>(
7876 tcx: TyCtxt<'tcx>,
7977 body: &Body<'tcx>,
8078 stmt: &Statement<'tcx>,
81 liveness: &LivenessValues,
8279 outlives_constraint: &OutlivesConstraint<'tcx>,
83 current_location: Location,
8480 current_point: PointIndex,
8581 universal_regions: &UniversalRegions<'tcx>,
8682) -> LocalizedOutlivesConstraint {
......@@ -98,8 +94,8 @@ fn localize_statement_constraint<'tcx>(
9894 // - and that should be impossible in MIR
9995 //
10096 // When we have a more complete implementation in the future, tested with crater, etc,
101 // we can relax this to a debug assert instead, or remove it.
102 assert!(
97 // we can remove this assertion. It's a debug assert because it can be expensive.
98 debug_assert!(
10399 {
104100 let mut lhs_regions = FxHashSet::default();
105101 tcx.for_each_free_region(lhs, |region| {
......@@ -119,16 +115,8 @@ fn localize_statement_constraint<'tcx>(
119115 "there should be no common regions between the LHS and RHS of an assignment"
120116 );
121117
122 // As mentioned earlier, we should be tracking these better upstream but: we want to
123 // relate the types on entry to the type of the place on exit. That is, outlives
124 // constraints on the RHS are on entry, and outlives constraints to/from the LHS are on
125 // exit (i.e. on entry to the successor location).
126118 let lhs_ty = body.local_decls[lhs.local].ty;
127 let successor_location = Location {
128 block: current_location.block,
129 statement_index: current_location.statement_index + 1,
130 };
131 let successor_point = liveness.point_from_location(successor_location);
119 let successor_point = current_point;
132120 compute_constraint_direction(
133121 tcx,
134122 outlives_constraint,
......@@ -195,6 +183,7 @@ fn localize_terminator_constraint<'tcx>(
195183 }
196184 }
197185}
186
198187/// For a given outlives constraint and CFG edge, returns the localized constraint with the
199188/// appropriate `from`-`to` direction. This is computed according to whether the constraint flows to
200189/// or from a free region in the given `value`, some kind of result for an effectful operation, like
compiler/rustc_const_eval/src/check_consts/ops.rs+1-1
......@@ -142,7 +142,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
142142 |err, self_ty, trait_id| {
143143 // FIXME(const_trait_impl): Do we need any of this on the non-const codepath?
144144
145 let trait_ref = TraitRef::from_method(tcx, trait_id, self.args);
145 let trait_ref = TraitRef::from_assoc(tcx, trait_id, self.args);
146146
147147 match self_ty.kind() {
148148 Param(param_ty) => {
compiler/rustc_const_eval/src/interpret/call.rs+1-1
......@@ -732,7 +732,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
732732 let tcx = *self.tcx;
733733
734734 let trait_def_id = tcx.trait_of_assoc(def_id).unwrap();
735 let virtual_trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, virtual_instance.args);
735 let virtual_trait_ref = ty::TraitRef::from_assoc(tcx, trait_def_id, virtual_instance.args);
736736 let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
737737 let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
738738
compiler/rustc_feature/src/unstable.rs+1-1
......@@ -545,7 +545,7 @@ declare_features! (
545545 (incomplete, inherent_associated_types, "1.52.0", Some(8995)),
546546 /// Allows using `pointer` and `reference` in intra-doc links
547547 (unstable, intra_doc_pointers, "1.51.0", Some(80896)),
548 // Allows setting the threshold for the `large_assignments` lint.
548 /// Allows setting the threshold for the `large_assignments` lint.
549549 (unstable, large_assignments, "1.52.0", Some(83518)),
550550 /// Allow to have type alias types for inter-crate use.
551551 (incomplete, lazy_type_alias, "1.72.0", Some(112792)),
compiler/rustc_middle/src/ty/context.rs+2-5
......@@ -290,11 +290,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
290290 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
291291 let trait_def_id = self.parent(def_id);
292292 debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
293 let trait_generics = self.generics_of(trait_def_id);
294 (
295 ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)),
296 &args[trait_generics.count()..],
297 )
293 let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
294 (trait_ref, &args[trait_ref.args.len()..])
298295 }
299296
300297 fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
compiler/rustc_middle/src/ty/generic_args.rs+3
......@@ -585,6 +585,9 @@ impl<'tcx> GenericArgs<'tcx> {
585585 tcx.mk_args_from_iter(target_args.iter().chain(self.iter().skip(defs.count())))
586586 }
587587
588 /// Truncates this list of generic args to have at most the number of args in `generics`.
589 ///
590 /// You might be looking for [`TraitRef::from_assoc`](super::TraitRef::from_assoc).
588591 pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> GenericArgsRef<'tcx> {
589592 tcx.mk_args(&self[..generics.count()])
590593 }
compiler/rustc_next_trait_solver/src/solve/inspect/build.rs+12-4
......@@ -68,7 +68,7 @@ impl<I: Interner> From<WipCanonicalGoalEvaluationStep<I>> for DebugSolver<I> {
6868 }
6969}
7070
71#[derive_where(PartialEq, Eq, Debug; I: Interner)]
71#[derive_where(PartialEq, Debug; I: Interner)]
7272struct WipGoalEvaluation<I: Interner> {
7373 pub uncanonicalized_goal: Goal<I, I::Predicate>,
7474 pub orig_values: Vec<I::GenericArg>,
......@@ -78,6 +78,8 @@ struct WipGoalEvaluation<I: Interner> {
7878 pub result: Option<QueryResult<I>>,
7979}
8080
81impl<I: Interner> Eq for WipGoalEvaluation<I> {}
82
8183impl<I: Interner> WipGoalEvaluation<I> {
8284 fn finalize(self) -> inspect::GoalEvaluation<I> {
8385 inspect::GoalEvaluation {
......@@ -98,7 +100,7 @@ impl<I: Interner> WipGoalEvaluation<I> {
98100/// This only exists during proof tree building and does not have
99101/// a corresponding struct in `inspect`. We need this to track a
100102/// bunch of metadata about the current evaluation.
101#[derive_where(PartialEq, Eq, Debug; I: Interner)]
103#[derive_where(PartialEq, Debug; I: Interner)]
102104struct WipCanonicalGoalEvaluationStep<I: Interner> {
103105 /// Unlike `EvalCtxt::var_values`, we append a new
104106 /// generic arg here whenever we create a new inference
......@@ -111,6 +113,8 @@ struct WipCanonicalGoalEvaluationStep<I: Interner> {
111113 evaluation: WipProbe<I>,
112114}
113115
116impl<I: Interner> Eq for WipCanonicalGoalEvaluationStep<I> {}
117
114118impl<I: Interner> WipCanonicalGoalEvaluationStep<I> {
115119 fn current_evaluation_scope(&mut self) -> &mut WipProbe<I> {
116120 let mut current = &mut self.evaluation;
......@@ -132,7 +136,7 @@ impl<I: Interner> WipCanonicalGoalEvaluationStep<I> {
132136 }
133137}
134138
135#[derive_where(PartialEq, Eq, Debug; I: Interner)]
139#[derive_where(PartialEq, Debug; I: Interner)]
136140struct WipProbe<I: Interner> {
137141 initial_num_var_values: usize,
138142 steps: Vec<WipProbeStep<I>>,
......@@ -140,6 +144,8 @@ struct WipProbe<I: Interner> {
140144 final_state: Option<inspect::CanonicalState<I, ()>>,
141145}
142146
147impl<I: Interner> Eq for WipProbe<I> {}
148
143149impl<I: Interner> WipProbe<I> {
144150 fn finalize(self) -> inspect::Probe<I> {
145151 inspect::Probe {
......@@ -150,7 +156,7 @@ impl<I: Interner> WipProbe<I> {
150156 }
151157}
152158
153#[derive_where(PartialEq, Eq, Debug; I: Interner)]
159#[derive_where(PartialEq, Debug; I: Interner)]
154160enum WipProbeStep<I: Interner> {
155161 AddGoal(GoalSource, inspect::CanonicalState<I, Goal<I, I::Predicate>>),
156162 NestedProbe(WipProbe<I>),
......@@ -158,6 +164,8 @@ enum WipProbeStep<I: Interner> {
158164 RecordImplArgs { impl_args: inspect::CanonicalState<I, I::GenericArgs> },
159165}
160166
167impl<I: Interner> Eq for WipProbeStep<I> {}
168
161169impl<I: Interner> WipProbeStep<I> {
162170 fn finalize(self) -> inspect::ProbeStep<I> {
163171 match self {
compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs+2-2
......@@ -342,7 +342,7 @@ pub(crate) fn transform_instance<'tcx>(
342342 let upcast_ty = match tcx.trait_of_assoc(def_id) {
343343 Some(trait_id) => trait_object_ty(
344344 tcx,
345 ty::Binder::dummy(ty::TraitRef::from_method(tcx, trait_id, instance.args)),
345 ty::Binder::dummy(ty::TraitRef::from_assoc(tcx, trait_id, instance.args)),
346346 ),
347347 // drop_in_place won't have a defining trait, skip the upcast
348348 None => instance.args.type_at(0),
......@@ -481,7 +481,7 @@ fn implemented_method<'tcx>(
481481 trait_method = trait_method_bound;
482482 method_id = instance.def_id();
483483 trait_id = tcx.trait_of_assoc(method_id)?;
484 trait_ref = ty::EarlyBinder::bind(TraitRef::from_method(tcx, trait_id, instance.args));
484 trait_ref = ty::EarlyBinder::bind(TraitRef::from_assoc(tcx, trait_id, instance.args));
485485 trait_id
486486 } else {
487487 return None;
compiler/rustc_trait_selection/src/traits/mod.rs+1-1
......@@ -763,7 +763,7 @@ fn instantiate_and_check_impossible_predicates<'tcx>(
763763 // Specifically check trait fulfillment to avoid an error when trying to resolve
764764 // associated items.
765765 if let Some(trait_def_id) = tcx.trait_of_assoc(key.0) {
766 let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, key.1);
766 let trait_ref = ty::TraitRef::from_assoc(tcx, trait_def_id, key.1);
767767 predicates.push(trait_ref.upcast(tcx));
768768 }
769769
compiler/rustc_ty_utils/src/instance.rs+2-2
......@@ -109,7 +109,7 @@ fn resolve_associated_item<'tcx>(
109109) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
110110 debug!(?trait_item_id, ?typing_env, ?trait_id, ?rcvr_args, "resolve_associated_item");
111111
112 let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args);
112 let trait_ref = ty::TraitRef::from_assoc(tcx, trait_id, rcvr_args);
113113
114114 let input = typing_env.as_query_input(trait_ref);
115115 let vtbl = match tcx.codegen_select_candidate(input) {
......@@ -238,7 +238,7 @@ fn resolve_associated_item<'tcx>(
238238 Some(ty::Instance::new_raw(leaf_def.item.def_id, args))
239239 }
240240 traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => {
241 let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args);
241 let trait_ref = ty::TraitRef::from_assoc(tcx, trait_id, rcvr_args);
242242 if trait_ref.has_non_region_infer() || trait_ref.has_non_region_param() {
243243 // We only resolve totally substituted vtable entries.
244244 None
compiler/rustc_type_ir/src/binder.rs+7-14
......@@ -1,5 +1,3 @@
1use std::fmt::Debug;
2use std::hash::Hash;
31use std::marker::PhantomData;
42use std::ops::{ControlFlow, Deref};
53
......@@ -23,18 +21,16 @@ use crate::{self as ty, Interner};
2321/// for more details.
2422///
2523/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
26#[derive_where(Clone; I: Interner, T: Clone)]
24#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, T)]
2725#[derive_where(Copy; I: Interner, T: Copy)]
28#[derive_where(Hash; I: Interner, T: Hash)]
29#[derive_where(PartialEq; I: Interner, T: PartialEq)]
30#[derive_where(Eq; I: Interner, T: Eq)]
31#[derive_where(Debug; I: Interner, T: Debug)]
3226#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
3327pub struct Binder<I: Interner, T> {
3428 value: T,
3529 bound_vars: I::BoundVarKinds,
3630}
3731
32impl<I: Interner, T: Eq> Eq for Binder<I, T> {}
33
3834// FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't
3935// understand how to turn `T` to `T::Lifted` in the output `type Lifted`.
4036impl<I: Interner, U: Interner, T> Lift<U> for Binder<I, T>
......@@ -356,14 +352,9 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
356352/// `instantiate`.
357353///
358354/// See <https://rustc-dev-guide.rust-lang.org/ty_module/early_binder.html> for more details.
359#[derive_where(Clone; I: Interner, T: Clone)]
360#[derive_where(Copy; I: Interner, T: Copy)]
361#[derive_where(PartialEq; I: Interner, T: PartialEq)]
362#[derive_where(Eq; I: Interner, T: Eq)]
363#[derive_where(Ord; I: Interner, T: Ord)]
355#[derive_where(Clone, PartialEq, Ord, Hash, Debug; I: Interner, T)]
364356#[derive_where(PartialOrd; I: Interner, T: Ord)]
365#[derive_where(Hash; I: Interner, T: Hash)]
366#[derive_where(Debug; I: Interner, T: Debug)]
357#[derive_where(Copy; I: Interner, T: Copy)]
367358#[cfg_attr(
368359 feature = "nightly",
369360 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -374,6 +365,8 @@ pub struct EarlyBinder<I: Interner, T> {
374365 _tcx: PhantomData<fn() -> I>,
375366}
376367
368impl<I: Interner, T: Eq> Eq for EarlyBinder<I, T> {}
369
377370/// For early binders, you should first call `instantiate` before using any visitors.
378371#[cfg(feature = "nightly")]
379372impl<I: Interner, T> !TypeFoldable<I> for ty::EarlyBinder<I, T> {}
compiler/rustc_type_ir/src/canonical.rs+12-12
......@@ -11,11 +11,7 @@ use crate::data_structures::HashMap;
1111use crate::inherent::*;
1212use crate::{self as ty, Interner, TypingMode, UniverseIndex};
1313
14#[derive_where(Clone; I: Interner, V: Clone)]
15#[derive_where(Hash; I: Interner, V: Hash)]
16#[derive_where(PartialEq; I: Interner, V: PartialEq)]
17#[derive_where(Eq; I: Interner, V: Eq)]
18#[derive_where(Debug; I: Interner, V: fmt::Debug)]
14#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, V)]
1915#[derive_where(Copy; I: Interner, V: Copy)]
2016#[cfg_attr(
2117 feature = "nightly",
......@@ -26,14 +22,12 @@ pub struct CanonicalQueryInput<I: Interner, V> {
2622 pub typing_mode: TypingMode<I>,
2723}
2824
25impl<I: Interner, V: Eq> Eq for CanonicalQueryInput<I, V> {}
26
2927/// A "canonicalized" type `V` is one where all free inference
3028/// variables have been rewritten to "canonical vars". These are
3129/// numbered starting from 0 in order of first appearance.
32#[derive_where(Clone; I: Interner, V: Clone)]
33#[derive_where(Hash; I: Interner, V: Hash)]
34#[derive_where(PartialEq; I: Interner, V: PartialEq)]
35#[derive_where(Eq; I: Interner, V: Eq)]
36#[derive_where(Debug; I: Interner, V: fmt::Debug)]
30#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, V)]
3731#[derive_where(Copy; I: Interner, V: Copy)]
3832#[cfg_attr(
3933 feature = "nightly",
......@@ -45,6 +39,8 @@ pub struct Canonical<I: Interner, V> {
4539 pub variables: I::CanonicalVarKinds,
4640}
4741
42impl<I: Interner, V: Eq> Eq for Canonical<I, V> {}
43
4844impl<I: Interner, V> Canonical<I, V> {
4945 /// Allows you to map the `value` of a canonical while keeping the
5046 /// same set of bound variables.
......@@ -89,7 +85,7 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
8985/// canonical value. This is sufficient information for code to create
9086/// a copy of the canonical value in some other inference context,
9187/// with fresh inference variables replacing the canonical values.
92#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
88#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
9389#[cfg_attr(
9490 feature = "nightly",
9591 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
......@@ -116,6 +112,8 @@ pub enum CanonicalVarKind<I: Interner> {
116112 PlaceholderConst(I::PlaceholderConst),
117113}
118114
115impl<I: Interner> Eq for CanonicalVarKind<I> {}
116
119117impl<I: Interner> CanonicalVarKind<I> {
120118 pub fn universe(self) -> UniverseIndex {
121119 match self {
......@@ -223,7 +221,7 @@ pub enum CanonicalTyVarKind {
223221/// vectors with the original values that were replaced by canonical
224222/// variables. You will need to supply it later to instantiate the
225223/// canonicalized query response.
226#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
224#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
227225#[cfg_attr(
228226 feature = "nightly",
229227 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -233,6 +231,8 @@ pub struct CanonicalVarValues<I: Interner> {
233231 pub var_values: I::GenericArgs,
234232}
235233
234impl<I: Interner> Eq for CanonicalVarValues<I> {}
235
236236impl<I: Interner> CanonicalVarValues<I> {
237237 pub fn is_identity(&self) -> bool {
238238 self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() {
compiler/rustc_type_ir/src/const_kind.rs+6-2
......@@ -10,7 +10,7 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen
1010use crate::{self as ty, DebruijnIndex, Interner};
1111
1212/// Represents a constant in Rust.
13#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
13#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
1414#[cfg_attr(
1515 feature = "nightly",
1616 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -45,6 +45,8 @@ pub enum ConstKind<I: Interner> {
4545 Expr(I::ExprConst),
4646}
4747
48impl<I: Interner> Eq for ConstKind<I> {}
49
4850impl<I: Interner> fmt::Debug for ConstKind<I> {
4951 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5052 use ConstKind::*;
......@@ -63,7 +65,7 @@ impl<I: Interner> fmt::Debug for ConstKind<I> {
6365}
6466
6567/// An unevaluated (potentially generic) constant used in the type-system.
66#[derive_where(Clone, Copy, Debug, Hash, PartialEq, Eq; I: Interner)]
68#[derive_where(Clone, Copy, Debug, Hash, PartialEq; I: Interner)]
6769#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
6870#[cfg_attr(
6971 feature = "nightly",
......@@ -74,6 +76,8 @@ pub struct UnevaluatedConst<I: Interner> {
7476 pub args: I::GenericArgs,
7577}
7678
79impl<I: Interner> Eq for UnevaluatedConst<I> {}
80
7781impl<I: Interner> UnevaluatedConst<I> {
7882 #[inline]
7983 pub fn new(def: I::DefId, args: I::GenericArgs) -> UnevaluatedConst<I> {
compiler/rustc_type_ir/src/error.rs+3-1
......@@ -18,7 +18,7 @@ impl<T> ExpectedFound<T> {
1818}
1919
2020// Data structures used in type unification
21#[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)]
21#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
2222#[derive(TypeVisitable_Generic)]
2323#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
2424pub enum TypeError<I: Interner> {
......@@ -58,6 +58,8 @@ pub enum TypeError<I: Interner> {
5858 TargetFeatureCast(I::DefId),
5959}
6060
61impl<I: Interner> Eq for TypeError<I> {}
62
6163impl<I: Interner> TypeError<I> {
6264 pub fn involves_regions(self) -> bool {
6365 match self {
compiler/rustc_type_ir/src/generic_arg.rs+6-2
......@@ -4,7 +4,7 @@ use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContex
44
55use crate::Interner;
66
7#[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)]
7#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
88#[cfg_attr(
99 feature = "nightly",
1010 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
......@@ -15,7 +15,9 @@ pub enum GenericArgKind<I: Interner> {
1515 Const(I::Const),
1616}
1717
18#[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)]
18impl<I: Interner> Eq for GenericArgKind<I> {}
19
20#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
1921#[cfg_attr(
2022 feature = "nightly",
2123 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
......@@ -24,3 +26,5 @@ pub enum TermKind<I: Interner> {
2426 Ty(I::Ty),
2527 Const(I::Const),
2628}
29
30impl<I: Interner> Eq for TermKind<I> {}
compiler/rustc_type_ir/src/infer_ctxt.rs+3-1
......@@ -18,7 +18,7 @@ use crate::{self as ty, Interner};
1818///
1919/// If neither of these functions are available, feel free to reach out to
2020/// t-types for help.
21#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
21#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
2222#[cfg_attr(
2323 feature = "nightly",
2424 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -90,6 +90,8 @@ pub enum TypingMode<I: Interner> {
9090 PostAnalysis,
9191}
9292
93impl<I: Interner> Eq for TypingMode<I> {}
94
9395impl<I: Interner> TypingMode<I> {
9496 /// Analysis outside of a body does not define any opaque types.
9597 pub fn non_body_analysis() -> TypingMode<I> {
compiler/rustc_type_ir/src/opaque_ty.rs+3-1
......@@ -6,7 +6,7 @@ use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
66use crate::inherent::*;
77use crate::{self as ty, Interner};
88
9#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
9#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
1010#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
1111#[cfg_attr(
1212 feature = "nightly",
......@@ -17,6 +17,8 @@ pub struct OpaqueTypeKey<I: Interner> {
1717 pub args: I::GenericArgs,
1818}
1919
20impl<I: Interner> Eq for OpaqueTypeKey<I> {}
21
2022impl<I: Interner> OpaqueTypeKey<I> {
2123 pub fn iter_captured_args(self, cx: I) -> impl Iterator<Item = (usize, I::GenericArg)> {
2224 let variances = cx.variances_of(self.def_id.into());
compiler/rustc_type_ir/src/pattern.rs+3-1
......@@ -5,7 +5,7 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen
55
66use crate::Interner;
77
8#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
8#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
99#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1010#[cfg_attr(
1111 feature = "nightly",
......@@ -15,3 +15,5 @@ pub enum PatternKind<I: Interner> {
1515 Range { start: I::Const, end: I::Const },
1616 Or(I::PatList),
1717}
18
19impl<I: Interner> Eq for PatternKind<I> {}
compiler/rustc_type_ir/src/predicate.rs+37-17
......@@ -15,12 +15,8 @@ use crate::visit::TypeVisitableExt as _;
1515use crate::{self as ty, Interner};
1616
1717/// `A: 'region`
18#[derive_where(Clone; I: Interner, A: Clone)]
18#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)]
1919#[derive_where(Copy; I: Interner, A: Copy)]
20#[derive_where(Hash; I: Interner, A: Hash)]
21#[derive_where(PartialEq; I: Interner, A: PartialEq)]
22#[derive_where(Eq; I: Interner, A: Eq)]
23#[derive_where(Debug; I: Interner, A: fmt::Debug)]
2420#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
2521#[cfg_attr(
2622 feature = "nightly",
......@@ -28,6 +24,8 @@ use crate::{self as ty, Interner};
2824)]
2925pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
3026
27impl<I: Interner, A: Eq> Eq for OutlivesPredicate<I, A> {}
28
3129// FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't
3230// understand how to turn `A` to `A::Lifted` in the output `type Lifted`.
3331impl<I: Interner, U: Interner, A> Lift<U> for OutlivesPredicate<I, A>
......@@ -53,7 +51,7 @@ where
5351///
5452/// Trait references also appear in object types like `Foo<U>`, but in
5553/// that case the `Self` parameter is absent from the generic parameters.
56#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
54#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
5755#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
5856#[cfg_attr(
5957 feature = "nightly",
......@@ -67,6 +65,8 @@ pub struct TraitRef<I: Interner> {
6765 _use_trait_ref_new_instead: (),
6866}
6967
68impl<I: Interner> Eq for TraitRef<I> {}
69
7070impl<I: Interner> TraitRef<I> {
7171 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
7272 interner.debug_assert_args_compatible(trait_def_id, args);
......@@ -82,7 +82,7 @@ impl<I: Interner> TraitRef<I> {
8282 Self::new_from_args(interner, trait_def_id, args)
8383 }
8484
85 pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
85 pub fn from_assoc(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
8686 let generics = interner.generics_of(trait_id);
8787 TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
8888 }
......@@ -128,7 +128,7 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
128128 }
129129}
130130
131#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
131#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
132132#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
133133#[cfg_attr(
134134 feature = "nightly",
......@@ -145,6 +145,8 @@ pub struct TraitPredicate<I: Interner> {
145145 pub polarity: PredicatePolarity,
146146}
147147
148impl<I: Interner> Eq for TraitPredicate<I> {}
149
148150impl<I: Interner> TraitPredicate<I> {
149151 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
150152 Self {
......@@ -271,7 +273,7 @@ impl fmt::Display for PredicatePolarity {
271273 }
272274}
273275
274#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
276#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
275277#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
276278#[cfg_attr(
277279 feature = "nightly",
......@@ -286,6 +288,8 @@ pub enum ExistentialPredicate<I: Interner> {
286288 AutoTrait(I::DefId),
287289}
288290
291impl<I: Interner> Eq for ExistentialPredicate<I> {}
292
289293impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
290294 /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
291295 /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
......@@ -319,7 +323,7 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
319323/// ```
320324/// The generic parameters don't include the erased `Self`, only trait
321325/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
322#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
326#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
323327#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
324328#[cfg_attr(
325329 feature = "nightly",
......@@ -333,6 +337,8 @@ pub struct ExistentialTraitRef<I: Interner> {
333337 _use_existential_trait_ref_new_instead: (),
334338}
335339
340impl<I: Interner> Eq for ExistentialTraitRef<I> {}
341
336342impl<I: Interner> ExistentialTraitRef<I> {
337343 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
338344 interner.debug_assert_existential_args_compatible(trait_def_id, args);
......@@ -386,7 +392,7 @@ impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
386392}
387393
388394/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
389#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
395#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
390396#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
391397#[cfg_attr(
392398 feature = "nightly",
......@@ -402,6 +408,8 @@ pub struct ExistentialProjection<I: Interner> {
402408 use_existential_projection_new_instead: (),
403409}
404410
411impl<I: Interner> Eq for ExistentialProjection<I> {}
412
405413impl<I: Interner> ExistentialProjection<I> {
406414 pub fn new_from_args(
407415 interner: I,
......@@ -542,7 +550,7 @@ impl From<ty::AliasTyKind> for AliasTermKind {
542550/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
543551/// * For an inherent projection, this would be `Ty::N<...>`.
544552/// * For an opaque type, there is no explicit syntax.
545#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
553#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
546554#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
547555#[cfg_attr(
548556 feature = "nightly",
......@@ -578,6 +586,8 @@ pub struct AliasTerm<I: Interner> {
578586 _use_alias_term_new_instead: (),
579587}
580588
589impl<I: Interner> Eq for AliasTerm<I> {}
590
581591impl<I: Interner> AliasTerm<I> {
582592 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
583593 interner.debug_assert_args_compatible(def_id, args);
......@@ -752,7 +762,7 @@ impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
752762/// equality between arbitrary types. Processing an instance of
753763/// Form #2 eventually yields one of these `ProjectionPredicate`
754764/// instances to normalize the LHS.
755#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
765#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
756766#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
757767#[cfg_attr(
758768 feature = "nightly",
......@@ -763,6 +773,8 @@ pub struct ProjectionPredicate<I: Interner> {
763773 pub term: I::Term,
764774}
765775
776impl<I: Interner> Eq for ProjectionPredicate<I> {}
777
766778impl<I: Interner> ProjectionPredicate<I> {
767779 pub fn self_ty(self) -> I::Ty {
768780 self.projection_term.self_ty()
......@@ -813,7 +825,7 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
813825
814826/// Used by the new solver to normalize an alias. This always expects the `term` to
815827/// be an unconstrained inference variable which is used as the output.
816#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
828#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
817829#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
818830#[cfg_attr(
819831 feature = "nightly",
......@@ -824,6 +836,8 @@ pub struct NormalizesTo<I: Interner> {
824836 pub term: I::Term,
825837}
826838
839impl<I: Interner> Eq for NormalizesTo<I> {}
840
827841impl<I: Interner> NormalizesTo<I> {
828842 pub fn self_ty(self) -> I::Ty {
829843 self.alias.self_ty()
......@@ -848,7 +862,7 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> {
848862 }
849863}
850864
851#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
865#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
852866#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
853867#[cfg_attr(
854868 feature = "nightly",
......@@ -859,6 +873,8 @@ pub struct HostEffectPredicate<I: Interner> {
859873 pub constness: BoundConstness,
860874}
861875
876impl<I: Interner> Eq for HostEffectPredicate<I> {}
877
862878impl<I: Interner> HostEffectPredicate<I> {
863879 pub fn self_ty(self) -> I::Ty {
864880 self.trait_ref.self_ty()
......@@ -892,7 +908,7 @@ impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
892908/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
893909/// whether the `a` type is the type that we should label as "expected" when
894910/// presenting user diagnostics.
895#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
911#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
896912#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
897913#[cfg_attr(
898914 feature = "nightly",
......@@ -904,8 +920,10 @@ pub struct SubtypePredicate<I: Interner> {
904920 pub b: I::Ty,
905921}
906922
923impl<I: Interner> Eq for SubtypePredicate<I> {}
924
907925/// Encodes that we have to coerce *from* the `a` type to the `b` type.
908#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
926#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
909927#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
910928#[cfg_attr(
911929 feature = "nightly",
......@@ -916,6 +934,8 @@ pub struct CoercePredicate<I: Interner> {
916934 pub b: I::Ty,
917935}
918936
937impl<I: Interner> Eq for CoercePredicate<I> {}
938
919939#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
920940#[cfg_attr(
921941 feature = "nightly",
compiler/rustc_type_ir/src/predicate_kind.rs+6-2
......@@ -9,7 +9,7 @@ use crate::{self as ty, Interner};
99
1010/// A clause is something that can appear in where bounds or be inferred
1111/// by implied bounds.
12#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
12#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
1313#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
1414#[cfg_attr(
1515 feature = "nightly",
......@@ -55,7 +55,9 @@ pub enum ClauseKind<I: Interner> {
5555 ),
5656}
5757
58#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
58impl<I: Interner> Eq for ClauseKind<I> {}
59
60#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
5961#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
6062#[cfg_attr(
6163 feature = "nightly",
......@@ -109,6 +111,8 @@ pub enum PredicateKind<I: Interner> {
109111 AliasRelate(I::Term, I::Term, AliasRelationDirection),
110112}
111113
114impl<I: Interner> Eq for PredicateKind<I> {}
115
112116#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
113117#[cfg_attr(
114118 feature = "nightly",
compiler/rustc_type_ir/src/region_kind.rs+3-1
......@@ -125,7 +125,7 @@ rustc_index::newtype_index! {
125125/// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
126126/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
127127/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
128#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
128#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
129129#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
130130pub enum RegionKind<I: Interner> {
131131 /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.
......@@ -177,6 +177,8 @@ pub enum RegionKind<I: Interner> {
177177 ReError(I::ErrorGuaranteed),
178178}
179179
180impl<I: Interner> Eq for RegionKind<I> {}
181
180182impl<I: Interner> fmt::Debug for RegionKind<I> {
181183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182184 match self {
compiler/rustc_type_ir/src/relate.rs+3-1
......@@ -33,7 +33,7 @@ pub enum StructurallyRelateAliases {
3333/// a miscompilation or unsoundness.
3434///
3535/// When in doubt, use `VarianceDiagInfo::default()`
36#[derive_where(Clone, Copy, PartialEq, Eq, Debug, Default; I: Interner)]
36#[derive_where(Clone, Copy, PartialEq, Debug, Default; I: Interner)]
3737pub enum VarianceDiagInfo<I: Interner> {
3838 /// No additional information - this is the default.
3939 /// We will not add any additional information to error messages.
......@@ -51,6 +51,8 @@ pub enum VarianceDiagInfo<I: Interner> {
5151 },
5252}
5353
54impl<I: Interner> Eq for VarianceDiagInfo<I> {}
55
5456impl<I: Interner> VarianceDiagInfo<I> {
5557 /// Mirrors `Variance::xform` - used to 'combine' the existing
5658 /// and new `VarianceDiagInfo`s when our variance changes.
compiler/rustc_type_ir/src/solve/inspect.rs+18-13
......@@ -17,9 +17,6 @@
1717//!
1818//! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
1919
20use std::fmt::Debug;
21use std::hash::Hash;
22
2320use derive_where::derive_where;
2421use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
2522
......@@ -32,25 +29,23 @@ use crate::{Canonical, CanonicalVarValues, Interner};
3229/// This is only ever used as [CanonicalState]. Any type information in proof
3330/// trees used mechanically has to be canonicalized as we otherwise leak
3431/// inference variables from a nested `InferCtxt`.
35#[derive_where(Clone; I: Interner, T: Clone)]
32#[derive_where(Clone, PartialEq, Hash, Debug; I: Interner, T)]
3633#[derive_where(Copy; I: Interner, T: Copy)]
37#[derive_where(PartialEq; I: Interner, T: PartialEq)]
38#[derive_where(Eq; I: Interner, T: Eq)]
39#[derive_where(Hash; I: Interner, T: Hash)]
40#[derive_where(Debug; I: Interner, T: Debug)]
4134#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
4235pub struct State<I: Interner, T> {
4336 pub var_values: CanonicalVarValues<I>,
4437 pub data: T,
4538}
4639
40impl<I: Interner, T: Eq> Eq for State<I, T> {}
41
4742pub type CanonicalState<I, T> = Canonical<I, State<I, T>>;
4843
4944/// When evaluating a goal we also store the original values
5045/// for the `CanonicalVarValues` of the canonicalized goal.
5146/// We use this to map any [CanonicalState] from the local `InferCtxt`
5247/// of the solver query to the `InferCtxt` of the caller.
53#[derive_where(PartialEq, Eq, Hash; I: Interner)]
48#[derive_where(PartialEq, Hash; I: Interner)]
5449pub struct GoalEvaluation<I: Interner> {
5550 pub uncanonicalized_goal: Goal<I, I::Predicate>,
5651 pub orig_values: Vec<I::GenericArg>,
......@@ -58,7 +53,9 @@ pub struct GoalEvaluation<I: Interner> {
5853 pub result: QueryResult<I>,
5954}
6055
61#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
56impl<I: Interner> Eq for GoalEvaluation<I> {}
57
58#[derive_where(PartialEq, Hash, Debug; I: Interner)]
6259pub enum GoalEvaluationKind<I: Interner> {
6360 Overflow,
6461 Evaluation {
......@@ -67,10 +64,12 @@ pub enum GoalEvaluationKind<I: Interner> {
6764 },
6865}
6966
67impl<I: Interner> Eq for GoalEvaluationKind<I> {}
68
7069/// A self-contained computation during trait solving. This either
7170/// corresponds to a `EvalCtxt::probe(_X)` call or the root evaluation
7271/// of a goal.
73#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
72#[derive_where(PartialEq, Hash, Debug; I: Interner)]
7473pub struct Probe<I: Interner> {
7574 /// What happened inside of this probe in chronological order.
7675 pub steps: Vec<ProbeStep<I>>,
......@@ -78,7 +77,9 @@ pub struct Probe<I: Interner> {
7877 pub final_state: CanonicalState<I, ()>,
7978}
8079
81#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
80impl<I: Interner> Eq for Probe<I> {}
81
82#[derive_where(PartialEq, Hash, Debug; I: Interner)]
8283pub enum ProbeStep<I: Interner> {
8384 /// We added a goal to the `EvalCtxt` which will get proven
8485 /// the next time `EvalCtxt::try_evaluate_added_goals` is called.
......@@ -97,10 +98,12 @@ pub enum ProbeStep<I: Interner> {
9798 MakeCanonicalResponse { shallow_certainty: Certainty },
9899}
99100
101impl<I: Interner> Eq for ProbeStep<I> {}
102
100103/// What kind of probe we're in. In case the probe represents a candidate, or
101104/// the final result of the current goal - via [ProbeKind::Root] - we also
102105/// store the [QueryResult].
103#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
106#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
104107#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
105108pub enum ProbeKind<I: Interner> {
106109 /// The root inference context while proving a goal.
......@@ -125,3 +128,5 @@ pub enum ProbeKind<I: Interner> {
125128 /// Checking that a rigid alias is well-formed.
126129 RigidAlias { result: QueryResult<I> },
127130}
131
132impl<I: Interner> Eq for ProbeKind<I> {}
compiler/rustc_type_ir/src/solve/mod.rs+21-16
......@@ -1,6 +1,5 @@
11pub mod inspect;
22
3use std::fmt;
43use std::hash::Hash;
54
65use derive_where::derive_where;
......@@ -32,12 +31,8 @@ pub struct NoSolution;
3231///
3332/// Most of the time the `param_env` contains the `where`-bounds of the function
3433/// we're currently typechecking while the `predicate` is some trait bound.
35#[derive_where(Clone; I: Interner, P: Clone)]
34#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, P)]
3635#[derive_where(Copy; I: Interner, P: Copy)]
37#[derive_where(Hash; I: Interner, P: Hash)]
38#[derive_where(PartialEq; I: Interner, P: PartialEq)]
39#[derive_where(Eq; I: Interner, P: Eq)]
40#[derive_where(Debug; I: Interner, P: fmt::Debug)]
4136#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
4237#[cfg_attr(
4338 feature = "nightly",
......@@ -48,6 +43,8 @@ pub struct Goal<I: Interner, P> {
4843 pub predicate: P,
4944}
5045
46impl<I: Interner, P: Eq> Eq for Goal<I, P> {}
47
5148impl<I: Interner, P> Goal<I, P> {
5249 pub fn new(cx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> {
5350 Goal { param_env, predicate: predicate.upcast(cx) }
......@@ -98,12 +95,8 @@ pub enum GoalSource {
9895 NormalizeGoal(PathKind),
9996}
10097
101#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
98#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal<I, P>)]
10299#[derive_where(Copy; I: Interner, Goal<I, P>: Copy)]
103#[derive_where(Hash; I: Interner, Goal<I, P>: Hash)]
104#[derive_where(PartialEq; I: Interner, Goal<I, P>: PartialEq)]
105#[derive_where(Eq; I: Interner, Goal<I, P>: Eq)]
106#[derive_where(Debug; I: Interner, Goal<I, P>: fmt::Debug)]
107100#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
108101#[cfg_attr(
109102 feature = "nightly",
......@@ -114,8 +107,10 @@ pub struct QueryInput<I: Interner, P> {
114107 pub predefined_opaques_in_body: I::PredefinedOpaques,
115108}
116109
110impl<I: Interner, P: Eq> Eq for QueryInput<I, P> {}
111
117112/// Opaques that are defined in the inference context before a query is called.
118#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
113#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
119114#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
120115#[cfg_attr(
121116 feature = "nightly",
......@@ -125,8 +120,10 @@ pub struct PredefinedOpaquesData<I: Interner> {
125120 pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
126121}
127122
123impl<I: Interner> Eq for PredefinedOpaquesData<I> {}
124
128125/// Possible ways the given goal can be proven.
129#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
126#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
130127pub enum CandidateSource<I: Interner> {
131128 /// A user written impl.
132129 ///
......@@ -189,6 +186,8 @@ pub enum CandidateSource<I: Interner> {
189186 CoherenceUnknowable,
190187}
191188
189impl<I: Interner> Eq for CandidateSource<I> {}
190
192191#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
193192pub enum ParamEnvSource {
194193 /// Preferred eagerly.
......@@ -217,7 +216,7 @@ pub enum BuiltinImplSource {
217216 TraitUpcasting(usize),
218217}
219218
220#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
219#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
221220#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
222221#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
223222pub struct Response<I: Interner> {
......@@ -227,8 +226,10 @@ pub struct Response<I: Interner> {
227226 pub external_constraints: I::ExternalConstraints,
228227}
229228
229impl<I: Interner> Eq for Response<I> {}
230
230231/// Additional constraints returned on success.
231#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
232#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
232233#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
233234#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
234235pub struct ExternalConstraintsData<I: Interner> {
......@@ -237,6 +238,8 @@ pub struct ExternalConstraintsData<I: Interner> {
237238 pub normalization_nested_goals: NestedNormalizationGoals<I>,
238239}
239240
241impl<I: Interner> Eq for ExternalConstraintsData<I> {}
242
240243impl<I: Interner> ExternalConstraintsData<I> {
241244 pub fn is_empty(&self) -> bool {
242245 self.region_constraints.is_empty()
......@@ -245,11 +248,13 @@ impl<I: Interner> ExternalConstraintsData<I> {
245248 }
246249}
247250
248#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
251#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
249252#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
250253#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
251254pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
252255
256impl<I: Interner> Eq for NestedNormalizationGoals<I> {}
257
253258impl<I: Interner> NestedNormalizationGoals<I> {
254259 pub fn empty() -> Self {
255260 NestedNormalizationGoals(vec![])
compiler/rustc_type_ir/src/ty_kind.rs+24-8
......@@ -69,7 +69,7 @@ impl AliasTyKind {
6969/// Types written by the user start out as `hir::TyKind` and get
7070/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
7171#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
72#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
72#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
7373#[cfg_attr(
7474 feature = "nightly",
7575 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -268,6 +268,8 @@ pub enum TyKind<I: Interner> {
268268 Error(I::ErrorGuaranteed),
269269}
270270
271impl<I: Interner> Eq for TyKind<I> {}
272
271273impl<I: Interner> TyKind<I> {
272274 pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
273275 match self {
......@@ -404,7 +406,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
404406/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
405407/// * For an inherent projection, this would be `Ty::N<...>`.
406408/// * For an opaque type, there is no explicit syntax.
407#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
409#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
408410#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
409411#[cfg_attr(
410412 feature = "nightly",
......@@ -440,6 +442,8 @@ pub struct AliasTy<I: Interner> {
440442 pub(crate) _use_alias_ty_new_instead: (),
441443}
442444
445impl<I: Interner> Eq for AliasTy<I> {}
446
443447impl<I: Interner> AliasTy<I> {
444448 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
445449 interner.debug_assert_args_compatible(def_id, args);
......@@ -720,7 +724,7 @@ impl fmt::Debug for InferTy {
720724 }
721725}
722726
723#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
727#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
724728#[cfg_attr(
725729 feature = "nightly",
726730 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -731,7 +735,9 @@ pub struct TypeAndMut<I: Interner> {
731735 pub mutbl: Mutability,
732736}
733737
734#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
738impl<I: Interner> Eq for TypeAndMut<I> {}
739
740#[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)]
735741#[cfg_attr(
736742 feature = "nightly",
737743 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -748,6 +754,8 @@ pub struct FnSig<I: Interner> {
748754 pub abi: I::Abi,
749755}
750756
757impl<I: Interner> Eq for FnSig<I> {}
758
751759impl<I: Interner> FnSig<I> {
752760 pub fn inputs(self) -> I::FnInputTys {
753761 self.inputs_and_output.inputs()
......@@ -845,11 +853,13 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
845853
846854// FIXME: this is a distinct type because we need to define `Encode`/`Decode`
847855// impls in this crate for `Binder<I, I::Ty>`.
848#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
856#[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)]
849857#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
850858#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
851859pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
852860
861impl<I: Interner> Eq for UnsafeBinderInner<I> {}
862
853863impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
854864 fn from(value: ty::Binder<I, I::Ty>) -> Self {
855865 UnsafeBinderInner(value)
......@@ -906,7 +916,7 @@ where
906916}
907917
908918// This is just a `FnSig` without the `FnHeader` fields.
909#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
919#[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)]
910920#[cfg_attr(
911921 feature = "nightly",
912922 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -916,6 +926,8 @@ pub struct FnSigTys<I: Interner> {
916926 pub inputs_and_output: I::Tys,
917927}
918928
929impl<I: Interner> Eq for FnSigTys<I> {}
930
919931impl<I: Interner> FnSigTys<I> {
920932 pub fn inputs(self) -> I::FnInputTys {
921933 self.inputs_and_output.inputs()
......@@ -958,7 +970,7 @@ impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
958970 }
959971}
960972
961#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
973#[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)]
962974#[cfg_attr(
963975 feature = "nightly",
964976 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -970,7 +982,9 @@ pub struct FnHeader<I: Interner> {
970982 pub abi: I::Abi,
971983}
972984
973#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
985impl<I: Interner> Eq for FnHeader<I> {}
986
987#[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)]
974988#[cfg_attr(
975989 feature = "nightly",
976990 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
......@@ -980,3 +994,5 @@ pub struct CoroutineWitnessTypes<I: Interner> {
980994 pub types: I::Tys,
981995 pub assumptions: I::RegionAssumptions,
982996}
997
998impl<I: Interner> Eq for CoroutineWitnessTypes<I> {}
compiler/rustc_type_ir/src/ty_kind/closure.rs+14-5
......@@ -101,7 +101,7 @@ use crate::{self as ty, Interner};
101101/// `yield` inside the coroutine.
102102/// * `GR`: The "return type", which is the type of value returned upon
103103/// completion of the coroutine.
104#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
104#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
105105#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
106106pub struct ClosureArgs<I: Interner> {
107107 /// Lifetime and type parameters from the enclosing function,
......@@ -112,6 +112,8 @@ pub struct ClosureArgs<I: Interner> {
112112 pub args: I::GenericArgs,
113113}
114114
115impl<I: Interner> Eq for ClosureArgs<I> {}
116
115117/// Struct returned by `split()`.
116118pub struct ClosureArgsParts<I: Interner> {
117119 /// This is the args of the typeck root.
......@@ -203,12 +205,14 @@ impl<I: Interner> ClosureArgs<I> {
203205 }
204206}
205207
206#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
208#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
207209#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
208210pub struct CoroutineClosureArgs<I: Interner> {
209211 pub args: I::GenericArgs,
210212}
211213
214impl<I: Interner> Eq for CoroutineClosureArgs<I> {}
215
212216/// See docs for explanation of how each argument is used.
213217///
214218/// See [`CoroutineClosureSignature`] for how these arguments are put together
......@@ -348,7 +352,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
348352 }
349353}
350354
351#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
355#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
352356#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
353357pub struct CoroutineClosureSignature<I: Interner> {
354358 pub tupled_inputs_ty: I::Ty,
......@@ -371,6 +375,8 @@ pub struct CoroutineClosureSignature<I: Interner> {
371375 pub abi: I::Abi,
372376}
373377
378impl<I: Interner> Eq for CoroutineClosureSignature<I> {}
379
374380impl<I: Interner> CoroutineClosureSignature<I> {
375381 /// Construct a coroutine from the closure signature. Since a coroutine signature
376382 /// is agnostic to the type of generator that is returned (by-ref/by-move),
......@@ -541,7 +547,7 @@ impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
541547 }
542548}
543549
544#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
550#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
545551#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
546552pub struct GenSig<I: Interner> {
547553 pub resume_ty: I::Ty,
......@@ -549,13 +555,16 @@ pub struct GenSig<I: Interner> {
549555 pub return_ty: I::Ty,
550556}
551557
558impl<I: Interner> Eq for GenSig<I> {}
552559/// Similar to `ClosureArgs`; see the above documentation for more.
553#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
560#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
554561#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
555562pub struct CoroutineArgs<I: Interner> {
556563 pub args: I::GenericArgs,
557564}
558565
566impl<I: Interner> Eq for CoroutineArgs<I> {}
567
559568pub struct CoroutineArgsParts<I: Interner> {
560569 /// This is the args of the typeck root.
561570 pub parent_args: I::GenericArgsSlice,
library/alloc/src/collections/btree/map.rs+2
......@@ -135,6 +135,8 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
135135/// ]);
136136/// ```
137137///
138/// ## `Entry` API
139///
138140/// `BTreeMap` implements an [`Entry API`], which allows for complex
139141/// methods of getting, setting, updating and removing keys and their values:
140142///
library/core/src/time.rs+4-4
......@@ -373,7 +373,6 @@ impl Duration {
373373 /// # Examples
374374 ///
375375 /// ```
376 /// #![feature(duration_constructors_lite)]
377376 /// use std::time::Duration;
378377 ///
379378 /// let duration = Duration::from_hours(6);
......@@ -381,7 +380,8 @@ impl Duration {
381380 /// assert_eq!(6 * 60 * 60, duration.as_secs());
382381 /// assert_eq!(0, duration.subsec_nanos());
383382 /// ```
384 #[unstable(feature = "duration_constructors_lite", issue = "140881")]
383 #[stable(feature = "duration_constructors_lite", since = "CURRENT_RUSTC_VERSION")]
384 #[rustc_const_stable(feature = "duration_constructors_lite", since = "CURRENT_RUSTC_VERSION")]
385385 #[must_use]
386386 #[inline]
387387 pub const fn from_hours(hours: u64) -> Duration {
......@@ -401,7 +401,6 @@ impl Duration {
401401 /// # Examples
402402 ///
403403 /// ```
404 /// #![feature(duration_constructors_lite)]
405404 /// use std::time::Duration;
406405 ///
407406 /// let duration = Duration::from_mins(10);
......@@ -409,7 +408,8 @@ impl Duration {
409408 /// assert_eq!(10 * 60, duration.as_secs());
410409 /// assert_eq!(0, duration.subsec_nanos());
411410 /// ```
412 #[unstable(feature = "duration_constructors_lite", issue = "140881")]
411 #[stable(feature = "duration_constructors_lite", since = "CURRENT_RUSTC_VERSION")]
412 #[rustc_const_stable(feature = "duration_constructors_lite", since = "CURRENT_RUSTC_VERSION")]
413413 #[must_use]
414414 #[inline]
415415 pub const fn from_mins(mins: u64) -> Duration {
library/coretests/tests/lib.rs-1
......@@ -36,7 +36,6 @@
3636#![feature(drop_guard)]
3737#![feature(duration_constants)]
3838#![feature(duration_constructors)]
39#![feature(duration_constructors_lite)]
4039#![feature(error_generic_member_access)]
4140#![feature(exact_div)]
4241#![feature(exact_size_is_empty)]
library/std/src/collections/hash/map.rs+4
......@@ -135,6 +135,8 @@ use crate::ops::Index;
135135/// ]);
136136/// ```
137137///
138/// ## `Entry` API
139///
138140/// `HashMap` implements an [`Entry` API](#method.entry), which allows
139141/// for complex methods of getting, setting, updating and removing keys and
140142/// their values:
......@@ -167,6 +169,8 @@ use crate::ops::Index;
167169/// player_stats.entry("mana").and_modify(|mana| *mana += 200).or_insert(100);
168170/// ```
169171///
172/// ## Usage with custom key types
173///
170174/// The easiest way to use `HashMap` with a custom key type is to derive [`Eq`] and [`Hash`].
171175/// We must also derive [`PartialEq`].
172176///
src/bootstrap/src/core/build_steps/llvm.rs+7
......@@ -421,6 +421,13 @@ impl Step for Llvm {
421421 ldflags.shared.push(" -latomic");
422422 }
423423
424 if target.starts_with("arm64ec") {
425 // MSVC linker requires the -machine:arm64ec flag to be passed to
426 // know it's linking as Arm64EC (vs Arm64X).
427 ldflags.exe.push(" -machine:arm64ec");
428 ldflags.shared.push(" -machine:arm64ec");
429 }
430
424431 if target.is_msvc() {
425432 cfg.define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreaded");
426433 cfg.static_crt(true);
src/bootstrap/src/core/builder/cargo.rs+9
......@@ -433,6 +433,15 @@ impl Builder<'_> {
433433 let out_dir = self.stage_out(compiler, mode);
434434 cargo.env("CARGO_TARGET_DIR", &out_dir);
435435
436 // Bootstrap makes a lot of assumptions about the artifacts produced in the target
437 // directory. If users override the "build directory" using `build-dir`
438 // (https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-dir), then
439 // bootstrap couldn't find these artifacts. So we forcefully override that option to our
440 // target directory here.
441 // In the future, we could attempt to read the build-dir location from Cargo and actually
442 // respect it.
443 cargo.env("CARGO_BUILD_BUILD_DIR", &out_dir);
444
436445 // Found with `rg "init_env_logger\("`. If anyone uses `init_env_logger`
437446 // from out of tree it shouldn't matter, since x.py is only used for
438447 // building in-tree.
src/bootstrap/src/utils/exec.rs+83-82
......@@ -80,11 +80,21 @@ impl CommandFingerprint {
8080 /// Helper method to format both Command and BootstrapCommand as a short execution line,
8181 /// without all the other details (e.g. environment variables).
8282 pub fn format_short_cmd(&self) -> String {
83 let program = Path::new(&self.program);
84 let mut line = vec![program.file_name().unwrap().to_str().unwrap().to_owned()];
85 line.extend(self.args.iter().map(|arg| arg.to_string_lossy().into_owned()));
86 line.extend(self.cwd.iter().map(|p| p.to_string_lossy().into_owned()));
87 line.join(" ")
83 use std::fmt::Write;
84
85 let mut cmd = self.program.to_string_lossy().to_string();
86 for arg in &self.args {
87 let arg = arg.to_string_lossy();
88 if arg.contains(' ') {
89 write!(cmd, " '{arg}'").unwrap();
90 } else {
91 write!(cmd, " {arg}").unwrap();
92 }
93 }
94 if let Some(cwd) = &self.cwd {
95 write!(cmd, " [workdir={}]", cwd.to_string_lossy()).unwrap();
96 }
97 cmd
8898 }
8999}
90100
......@@ -434,8 +444,8 @@ impl From<Command> for BootstrapCommand {
434444enum CommandStatus {
435445 /// The command has started and finished with some status.
436446 Finished(ExitStatus),
437 /// It was not even possible to start the command.
438 DidNotStart,
447 /// It was not even possible to start the command or wait for it to finish.
448 DidNotStartOrFinish,
439449}
440450
441451/// Create a new BootstrapCommand. This is a helper function to make command creation
......@@ -456,9 +466,9 @@ pub struct CommandOutput {
456466
457467impl CommandOutput {
458468 #[must_use]
459 pub fn did_not_start(stdout: OutputMode, stderr: OutputMode) -> Self {
469 pub fn not_finished(stdout: OutputMode, stderr: OutputMode) -> Self {
460470 Self {
461 status: CommandStatus::DidNotStart,
471 status: CommandStatus::DidNotStartOrFinish,
462472 stdout: match stdout {
463473 OutputMode::Print => None,
464474 OutputMode::Capture => Some(vec![]),
......@@ -489,7 +499,7 @@ impl CommandOutput {
489499 pub fn is_success(&self) -> bool {
490500 match self.status {
491501 CommandStatus::Finished(status) => status.success(),
492 CommandStatus::DidNotStart => false,
502 CommandStatus::DidNotStartOrFinish => false,
493503 }
494504 }
495505
......@@ -501,7 +511,7 @@ impl CommandOutput {
501511 pub fn status(&self) -> Option<ExitStatus> {
502512 match self.status {
503513 CommandStatus::Finished(status) => Some(status),
504 CommandStatus::DidNotStart => None,
514 CommandStatus::DidNotStartOrFinish => None,
505515 }
506516 }
507517
......@@ -745,25 +755,11 @@ impl ExecutionContext {
745755 self.start(command, stdout, stderr).wait_for_output(self)
746756 }
747757
748 fn fail(&self, message: &str, output: CommandOutput) -> ! {
749 if self.is_verbose() {
750 println!("{message}");
751 } else {
752 let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
753 // If the command captures output, the user would not see any indication that
754 // it has failed. In this case, print a more verbose error, since to provide more
755 // context.
756 if stdout.is_some() || stderr.is_some() {
757 if let Some(stdout) = output.stdout_if_present().take_if(|s| !s.trim().is_empty()) {
758 println!("STDOUT:\n{stdout}\n");
759 }
760 if let Some(stderr) = output.stderr_if_present().take_if(|s| !s.trim().is_empty()) {
761 println!("STDERR:\n{stderr}\n");
762 }
763 println!("Command has failed. Rerun with -v to see more details.");
764 } else {
765 println!("Command has failed. Rerun with -v to see more details.");
766 }
758 fn fail(&self, message: &str) -> ! {
759 println!("{message}");
760
761 if !self.is_verbose() {
762 println!("Command has failed. Rerun with -v to see more details.");
767763 }
768764 exit!(1);
769765 }
......@@ -856,7 +852,7 @@ impl<'a> DeferredCommand<'a> {
856852 && command.should_cache
857853 {
858854 exec_ctx.command_cache.insert(fingerprint.clone(), output.clone());
859 exec_ctx.profiler.record_execution(fingerprint.clone(), start_time);
855 exec_ctx.profiler.record_execution(fingerprint, start_time);
860856 }
861857
862858 output
......@@ -872,6 +868,8 @@ impl<'a> DeferredCommand<'a> {
872868 executed_at: &'a std::panic::Location<'a>,
873869 exec_ctx: &ExecutionContext,
874870 ) -> CommandOutput {
871 use std::fmt::Write;
872
875873 command.mark_as_executed();
876874
877875 let process = match process.take() {
......@@ -881,79 +879,82 @@ impl<'a> DeferredCommand<'a> {
881879
882880 let created_at = command.get_created_location();
883881
884 let mut message = String::new();
882 #[allow(clippy::enum_variant_names)]
883 enum FailureReason {
884 FailedAtRuntime(ExitStatus),
885 FailedToFinish(std::io::Error),
886 FailedToStart(std::io::Error),
887 }
885888
886 let output = match process {
889 let (output, fail_reason) = match process {
887890 Ok(child) => match child.wait_with_output() {
888 Ok(result) if result.status.success() => {
891 Ok(output) if output.status.success() => {
889892 // Successful execution
890 CommandOutput::from_output(result, stdout, stderr)
893 (CommandOutput::from_output(output, stdout, stderr), None)
891894 }
892 Ok(result) => {
893 // Command ran but failed
894 use std::fmt::Write;
895
896 writeln!(
897 message,
898 r#"
899Command {command:?} did not execute successfully.
900Expected success, got {}
901Created at: {created_at}
902Executed at: {executed_at}"#,
903 result.status,
895 Ok(output) => {
896 // Command started, but then it failed
897 let status = output.status;
898 (
899 CommandOutput::from_output(output, stdout, stderr),
900 Some(FailureReason::FailedAtRuntime(status)),
904901 )
905 .unwrap();
906
907 let output = CommandOutput::from_output(result, stdout, stderr);
908
909 if stdout.captures() {
910 writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap();
911 }
912 if stderr.captures() {
913 writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap();
914 }
915
916 output
917902 }
918903 Err(e) => {
919904 // Failed to wait for output
920 use std::fmt::Write;
921
922 writeln!(
923 message,
924 "\n\nCommand {command:?} did not execute successfully.\
925 \nIt was not possible to execute the command: {e:?}"
905 (
906 CommandOutput::not_finished(stdout, stderr),
907 Some(FailureReason::FailedToFinish(e)),
926908 )
927 .unwrap();
928
929 CommandOutput::did_not_start(stdout, stderr)
930909 }
931910 },
932911 Err(e) => {
933912 // Failed to spawn the command
934 use std::fmt::Write;
935
936 writeln!(
937 message,
938 "\n\nCommand {command:?} did not execute successfully.\
939 \nIt was not possible to execute the command: {e:?}"
940 )
941 .unwrap();
942
943 CommandOutput::did_not_start(stdout, stderr)
913 (CommandOutput::not_finished(stdout, stderr), Some(FailureReason::FailedToStart(e)))
944914 }
945915 };
946916
947 if !output.is_success() {
917 if let Some(fail_reason) = fail_reason {
918 let mut error_message = String::new();
919 let command_str = if exec_ctx.is_verbose() {
920 format!("{command:?}")
921 } else {
922 command.fingerprint().format_short_cmd()
923 };
924 let action = match fail_reason {
925 FailureReason::FailedAtRuntime(e) => {
926 format!("failed with exit code {}", e.code().unwrap_or(1))
927 }
928 FailureReason::FailedToFinish(e) => {
929 format!("failed to finish: {e:?}")
930 }
931 FailureReason::FailedToStart(e) => {
932 format!("failed to start: {e:?}")
933 }
934 };
935 writeln!(
936 error_message,
937 r#"Command `{command_str}` {action}
938Created at: {created_at}
939Executed at: {executed_at}"#,
940 )
941 .unwrap();
942 if stdout.captures() {
943 writeln!(error_message, "\n--- STDOUT vvv\n{}", output.stdout().trim()).unwrap();
944 }
945 if stderr.captures() {
946 writeln!(error_message, "\n--- STDERR vvv\n{}", output.stderr().trim()).unwrap();
947 }
948
948949 match command.failure_behavior {
949950 BehaviorOnFailure::DelayFail => {
950951 if exec_ctx.fail_fast {
951 exec_ctx.fail(&message, output);
952 exec_ctx.fail(&error_message);
952953 }
953 exec_ctx.add_to_delay_failure(message);
954 exec_ctx.add_to_delay_failure(error_message);
954955 }
955956 BehaviorOnFailure::Exit => {
956 exec_ctx.fail(&message, output);
957 exec_ctx.fail(&error_message);
957958 }
958959 BehaviorOnFailure::Ignore => {
959960 // If failures are allowed, either the error has been printed already
src/doc/unstable-book/src/compiler-environment-variables/COLORTERM.md created+5
......@@ -0,0 +1,5 @@
1# `COLORTERM`
2
3This environment variable is used by [`-Zterminal-urls`] to detect if URLs are supported by the terminal emulator.
4
5[`-Zterminal-urls`]: ../compiler-flags/terminal-urls.html
src/doc/unstable-book/src/compiler-environment-variables/QNX_TARGET.md created+11
......@@ -0,0 +1,11 @@
1# `QNX_TARGET`
2
3----
4
5This environment variable is mandatory when linking on `nto-qnx*_iosock` platforms. It is used to determine an `-L` path to pass to the QNX linker.
6
7You should [set this variable] by running `source qnxsdp-env.sh`.
8See [the QNX docs] for more background information.
9
10[set this variable]: https://www.qnx.com/developers/docs/qsc/com.qnx.doc.qsc.inst_larg_org/topic/build_server_developer_steps.html
11[the QNX docs]: https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html.
src/doc/unstable-book/src/compiler-environment-variables/SDKROOT.md created+6
......@@ -0,0 +1,6 @@
1# `SDKROOT`
2
3This environment variable is used on Apple targets.
4It is passed through to the linker (currently either as `-isysroot` or `-syslibroot`).
5
6Note that this variable is not always respected. When the SDKROOT is clearly wrong (e.g. when the platform of the SDK does not match the `--target` used by rustc), this is ignored and rustc does its own detection.
src/doc/unstable-book/src/compiler-environment-variables/TERM.md created+5
......@@ -0,0 +1,5 @@
1# `TERM`
2
3This environment variable is used by [`-Zterminal-urls`] to detect if URLs are supported by the terminal emulator.
4
5[`-Zterminal-urls`]: ../compiler-flags/terminal-urls.html
src/doc/unstable-book/src/compiler-flags/terminal-urls.md created+13
......@@ -0,0 +1,13 @@
1# `-Z terminal-urls`
2
3The tracking feature for this issue is [#125586]
4
5[#125586]: https://github.com/rust-lang/rust/issues/125586
6
7---
8
9This flag takes either a boolean or the string "auto".
10
11When enabled, use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output.
12Use "auto" to try and autodetect whether the terminal emulator supports hyperlinks.
13Currently, "auto" only enables hyperlinks if `COLORTERM=truecolor` and `TERM=xterm-256color`.
src/doc/unstable-book/src/language-features/asm-experimental-arch.md-5
......@@ -19,7 +19,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
1919- M68k
2020- CSKY
2121- SPARC
22- LoongArch32
2322
2423## Register classes
2524
......@@ -54,8 +53,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
5453| CSKY | `freg` | `f[0-31]` | `f` |
5554| SPARC | `reg` | `r[2-29]` | `r` |
5655| SPARC | `yreg` | `y` | Only clobbers |
57| LoongArch32 | `reg` | `$r1`, `$r[4-20]`, `$r[23,30]` | `r` |
58| LoongArch32 | `freg` | `$f[0-31]` | `f` |
5956
6057> **Notes**:
6158> - NVPTX doesn't have a fixed register set, so named registers are not supported.
......@@ -94,8 +91,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
9491| CSKY | `freg` | None | `f32`, |
9592| SPARC | `reg` | None | `i8`, `i16`, `i32`, `i64` (SPARC64 only) |
9693| SPARC | `yreg` | N/A | Only clobbers |
97| LoongArch32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
98| LoongArch32 | `freg` | None | `f32`, `f64` |
9994
10095## Register aliases
10196
src/doc/unstable-book/src/library-features/duration-constructors-lite.md deleted-11
......@@ -1,11 +0,0 @@
1# `duration_constructors_lite`
2
3The tracking issue for this feature is: [#140881]
4
5[#140881]: https://github.com/rust-lang/rust/issues/140881
6
7------------------------
8
9Add the methods `from_mins`, `from_hours` to `Duration`.
10
11For `from_days` and `from_weeks` see [`duration_constructors`](https://github.com/rust-lang/rust/issues/120301).
src/doc/unstable-book/src/library-features/duration-constructors.md-1
......@@ -7,4 +7,3 @@ The tracking issue for this feature is: [#120301]
77------------------------
88
99Add the methods `from_days` and `from_weeks` to `Duration`.
10For `from_mins` and `from_hours` see [duration-constructors-lite.md](./duration-constructors-lite.md)
src/librustdoc/doctest.rs+1-3
......@@ -409,9 +409,7 @@ pub(crate) fn run_tests(
409409 // We ensure temp dir destructor is called.
410410 std::mem::drop(temp_dir);
411411 times.display_times();
412 // FIXME(GuillaumeGomez): Uncomment the next line once #144297 has been merged.
413 // std::process::exit(test::ERROR_EXIT_CODE);
414 std::process::exit(101);
412 std::process::exit(test::ERROR_EXIT_CODE);
415413 }
416414}
417415
src/tools/compiletest/src/runtest.rs+1-1
......@@ -1766,7 +1766,7 @@ impl<'test> TestCx<'test> {
17661766
17671767 match self.config.compare_mode {
17681768 Some(CompareMode::Polonius) => {
1769 rustc.args(&["-Zpolonius"]);
1769 rustc.args(&["-Zpolonius=next"]);
17701770 }
17711771 Some(CompareMode::NextSolver) => {
17721772 rustc.args(&["-Znext-solver"]);
src/tools/tidy/src/features.rs+35
......@@ -9,6 +9,7 @@
99//! * All unstable lang features have tests to ensure they are actually unstable.
1010//! * Language features in a group are sorted by feature name.
1111
12use std::collections::BTreeSet;
1213use std::collections::hash_map::{Entry, HashMap};
1314use std::ffi::OsStr;
1415use std::num::NonZeroU32;
......@@ -21,6 +22,7 @@ use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many};
2122mod tests;
2223
2324mod version;
25use regex::Regex;
2426use version::Version;
2527
2628const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start";
......@@ -623,3 +625,36 @@ fn map_lib_features(
623625 },
624626 );
625627}
628
629fn should_document(var: &str) -> bool {
630 if var.starts_with("RUSTC_") || var.starts_with("RUST_") || var.starts_with("UNSTABLE_RUSTDOC_")
631 {
632 return true;
633 }
634 ["SDKROOT", "QNX_TARGET", "COLORTERM", "TERM"].contains(&var)
635}
636
637pub fn collect_env_vars(compiler: &Path) -> BTreeSet<String> {
638 let env_var_regex: Regex = Regex::new(r#"env::var(_os)?\("([^"]+)"#).unwrap();
639
640 let mut vars = BTreeSet::new();
641 walk(
642 compiler,
643 // skip build scripts, tests, and non-rust files
644 |path, _is_dir| {
645 filter_dirs(path)
646 || filter_not_rust(path)
647 || path.ends_with("build.rs")
648 || path.ends_with("tests.rs")
649 },
650 &mut |_entry, contents| {
651 for env_var in env_var_regex.captures_iter(contents).map(|c| c.get(2).unwrap().as_str())
652 {
653 if should_document(env_var) {
654 vars.insert(env_var.to_owned());
655 }
656 }
657 },
658 );
659 vars
660}
src/tools/tidy/src/unstable_book.rs+2
......@@ -6,6 +6,8 @@ use crate::features::{CollectedFeatures, Features, Status};
66
77pub const PATH_STR: &str = "doc/unstable-book";
88
9pub const ENV_VARS_DIR: &str = "src/compiler-environment-variables";
10
911pub const COMPILER_FLAGS_DIR: &str = "src/compiler-flags";
1012
1113pub const LANG_FEATURES_DIR: &str = "src/language-features";
src/tools/unstable-book-gen/src/main.rs+23-6
......@@ -5,11 +5,11 @@ use std::env;
55use std::fs::{self, write};
66use std::path::Path;
77
8use tidy::features::{Features, collect_lang_features, collect_lib_features};
8use tidy::features::{Features, collect_env_vars, collect_lang_features, collect_lib_features};
99use tidy::t;
1010use tidy::unstable_book::{
11 LANG_FEATURES_DIR, LIB_FEATURES_DIR, PATH_STR, collect_unstable_book_section_file_names,
12 collect_unstable_feature_names,
11 ENV_VARS_DIR, LANG_FEATURES_DIR, LIB_FEATURES_DIR, PATH_STR,
12 collect_unstable_book_section_file_names, collect_unstable_feature_names,
1313};
1414
1515fn generate_stub_issue(path: &Path, name: &str, issue: u32, description: &str) {
......@@ -27,6 +27,11 @@ fn generate_stub_no_issue(path: &Path, name: &str, description: &str) {
2727 t!(write(path, content), path);
2828}
2929
30fn generate_stub_env_var(path: &Path, name: &str) {
31 let content = format!(include_str!("stub-env-var.md"), name = name);
32 t!(write(path, content), path);
33}
34
3035fn set_to_summary_str(set: &BTreeSet<String>, dir: &str) -> String {
3136 set.iter()
3237 .map(|ref n| format!(" - [{}]({}/{}.md)", n.replace('-', "_"), dir, n))
......@@ -59,7 +64,7 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur
5964 t!(write(&summary_path, content), summary_path);
6065}
6166
62fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) {
67fn generate_feature_files(src: &Path, out: &Path, features: &Features) {
6368 let unstable_features = collect_unstable_feature_names(features);
6469 let unstable_section_file_names = collect_unstable_book_section_file_names(src);
6570 t!(fs::create_dir_all(&out));
......@@ -83,6 +88,16 @@ fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) {
8388 }
8489}
8590
91fn generate_env_files(src: &Path, out: &Path, env_vars: &BTreeSet<String>) {
92 let env_var_file_names = collect_unstable_book_section_file_names(src);
93 t!(fs::create_dir_all(&out));
94 for env_var in env_vars - &env_var_file_names {
95 let file_name = format!("{env_var}.md");
96 let out_file_path = out.join(&file_name);
97 generate_stub_env_var(&out_file_path, &env_var);
98 }
99}
100
86101fn copy_recursive(from: &Path, to: &Path) {
87102 for entry in t!(fs::read_dir(from)) {
88103 let e = t!(entry);
......@@ -112,21 +127,23 @@ fn main() {
112127 .into_iter()
113128 .filter(|&(ref name, _)| !lang_features.contains_key(name))
114129 .collect();
130 let env_vars = collect_env_vars(compiler_path);
115131
116132 let doc_src_path = src_path.join(PATH_STR);
117133
118134 t!(fs::create_dir_all(&dest_path));
119135
120 generate_unstable_book_files(
136 generate_feature_files(
121137 &doc_src_path.join(LANG_FEATURES_DIR),
122138 &dest_path.join(LANG_FEATURES_DIR),
123139 &lang_features,
124140 );
125 generate_unstable_book_files(
141 generate_feature_files(
126142 &doc_src_path.join(LIB_FEATURES_DIR),
127143 &dest_path.join(LIB_FEATURES_DIR),
128144 &lib_features,
129145 );
146 generate_env_files(&doc_src_path.join(ENV_VARS_DIR), &dest_path.join(ENV_VARS_DIR), &env_vars);
130147
131148 copy_recursive(&doc_src_path, &dest_path);
132149
src/tools/unstable-book-gen/src/stub-env-var.md created+9
......@@ -0,0 +1,9 @@
1# `{name}`
2
3Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.
4
5See [the code][github search] for more information.
6
7[github search]: https://github.com/search?q=repo%3Arust-lang%2Frust+%22{name}%22+path%3Acompiler&type=code
8
9------------------------
tests/assembly-llvm/asm/loongarch-type.rs+31-20
......@@ -1,8 +1,15 @@
11//@ add-core-stubs
2//@ revisions: loongarch32 loongarch64
3
24//@ assembly-output: emit-asm
3//@ compile-flags: --target loongarch64-unknown-linux-gnu
5
6//@[loongarch32] compile-flags: --target loongarch32-unknown-none
7//@[loongarch32] needs-llvm-components: loongarch
8
9//@[loongarch64] compile-flags: --target loongarch64-unknown-none
10//@[loongarch64] needs-llvm-components: loongarch
11
412//@ compile-flags: -Zmerge-functions=disabled
5//@ needs-llvm-components: loongarch
613
714#![feature(no_core, f16)]
815#![crate_type = "rlib"]
......@@ -22,7 +29,7 @@ extern "C" {
2229// CHECK-LABEL: sym_fn:
2330// CHECK: #APP
2431// CHECK: pcalau12i $t0, %got_pc_hi20(extern_func)
25// CHECK: ld.d $t0, $t0, %got_pc_lo12(extern_func)
32// CHECK: ld.{{[wd]}} $t0, $t0, %got_pc_lo12(extern_func)
2633// CHECK: #NO_APP
2734#[no_mangle]
2835pub unsafe fn sym_fn() {
......@@ -32,7 +39,7 @@ pub unsafe fn sym_fn() {
3239// CHECK-LABEL: sym_static:
3340// CHECK: #APP
3441// CHECK: pcalau12i $t0, %got_pc_hi20(extern_static)
35// CHECK: ld.d $t0, $t0, %got_pc_lo12(extern_static)
42// CHECK: ld.{{[wd]}} $t0, $t0, %got_pc_lo12(extern_static)
3643// CHECK: #NO_APP
3744#[no_mangle]
3845pub unsafe fn sym_static() {
......@@ -87,16 +94,18 @@ check!(reg_i32, i32, reg, "move");
8794// CHECK: #NO_APP
8895check!(reg_f32, f32, reg, "move");
8996
90// CHECK-LABEL: reg_i64:
91// CHECK: #APP
92// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}}
93// CHECK: #NO_APP
97// loongarch64-LABEL: reg_i64:
98// loongarch64: #APP
99// loongarch64: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}}
100// loongarch64: #NO_APP
101#[cfg(loongarch64)]
94102check!(reg_i64, i64, reg, "move");
95103
96// CHECK-LABEL: reg_f64:
97// CHECK: #APP
98// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}}
99// CHECK: #NO_APP
104// loongarch64-LABEL: reg_f64:
105// loongarch64: #APP
106// loongarch64: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}}
107// loongarch64: #NO_APP
108#[cfg(loongarch64)]
100109check!(reg_f64, f64, reg, "move");
101110
102111// CHECK-LABEL: reg_ptr:
......@@ -153,16 +162,18 @@ check_reg!(r4_i32, i32, "$r4", "move");
153162// CHECK: #NO_APP
154163check_reg!(r4_f32, f32, "$r4", "move");
155164
156// CHECK-LABEL: r4_i64:
157// CHECK: #APP
158// CHECK: move $a0, $a0
159// CHECK: #NO_APP
165// loongarch64-LABEL: r4_i64:
166// loongarch64: #APP
167// loongarch64: move $a0, $a0
168// loongarch64: #NO_APP
169#[cfg(loongarch64)]
160170check_reg!(r4_i64, i64, "$r4", "move");
161171
162// CHECK-LABEL: r4_f64:
163// CHECK: #APP
164// CHECK: move $a0, $a0
165// CHECK: #NO_APP
172// loongarch64-LABEL: r4_f64:
173// loongarch64: #APP
174// loongarch64: move $a0, $a0
175// loongarch64: #NO_APP
176#[cfg(loongarch64)]
166177check_reg!(r4_f64, f64, "$r4", "move");
167178
168179// CHECK-LABEL: r4_ptr:
tests/crashes/135646.rs deleted-7
......@@ -1,7 +0,0 @@
1//@ known-bug: #135646
2//@ compile-flags: -Zpolonius=next
3//@ edition: 2024
4
5fn main() {
6 &{ [1, 2, 3][4] };
7}
tests/run-make/raw-dylib-link-ordinal/exporter.def+1-1
......@@ -1,5 +1,5 @@
11LIBRARY exporter
22EXPORTS
33 exported_function @13 NONAME
4 exported_variable @5 NONAME
4 exported_variable @5 NONAME DATA
55 print_exported_variable @9 NONAME
tests/run-make/raw-dylib-link-ordinal/rmake.rs+2-1
......@@ -11,7 +11,7 @@
1111
1212//@ only-windows
1313
14use run_make_support::{cc, diff, is_windows_msvc, run, rustc};
14use run_make_support::{cc, diff, extra_c_flags, is_windows_msvc, run, rustc};
1515
1616// NOTE: build_native_dynamic lib is not used, as the special `def` files
1717// must be passed to the CC compiler.
......@@ -24,6 +24,7 @@ fn main() {
2424 cc().input("exporter.obj")
2525 .arg("exporter.def")
2626 .args(&["-link", "-dll", "-noimplib", "-out:exporter.dll"])
27 .args(extra_c_flags())
2728 .run();
2829 } else {
2930 cc().arg("-v").arg("-c").out_exe("exporter.obj").input("exporter.c").run();
tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr created+38
......@@ -0,0 +1,38 @@
1error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:27:18
3 |
4LL | asm!("", out("$r0") _);
5 | ^^^^^^^^^^^^
6
7error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:29:18
9 |
10LL | asm!("", out("$tp") _);
11 | ^^^^^^^^^^^^
12
13error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:31:18
15 |
16LL | asm!("", out("$sp") _);
17 | ^^^^^^^^^^^^
18
19error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:33:18
21 |
22LL | asm!("", out("$r21") _);
23 | ^^^^^^^^^^^^^
24
25error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:35:18
27 |
28LL | asm!("", out("$fp") _);
29 | ^^^^^^^^^^^^
30
31error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:37:18
33 |
34LL | asm!("", out("$r31") _);
35 | ^^^^^^^^^^^^^
36
37error: aborting due to 6 previous errors
38
tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr created+62
......@@ -0,0 +1,62 @@
1error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:27:18
3 |
4LL | asm!("", out("$r0") _);
5 | ^^^^^^^^^^^^
6
7error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:29:18
9 |
10LL | asm!("", out("$tp") _);
11 | ^^^^^^^^^^^^
12
13error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:31:18
15 |
16LL | asm!("", out("$sp") _);
17 | ^^^^^^^^^^^^
18
19error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:33:18
21 |
22LL | asm!("", out("$r21") _);
23 | ^^^^^^^^^^^^^
24
25error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:35:18
27 |
28LL | asm!("", out("$fp") _);
29 | ^^^^^^^^^^^^
30
31error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:37:18
33 |
34LL | asm!("", out("$r31") _);
35 | ^^^^^^^^^^^^^
36
37error: register class `freg` requires at least one of the following target features: d, f
38 --> $DIR/bad-reg.rs:41:26
39 |
40LL | asm!("/* {} */", in(freg) f);
41 | ^^^^^^^^^^
42
43error: register class `freg` requires at least one of the following target features: d, f
44 --> $DIR/bad-reg.rs:43:26
45 |
46LL | asm!("/* {} */", out(freg) _);
47 | ^^^^^^^^^^^
48
49error: register class `freg` requires at least one of the following target features: d, f
50 --> $DIR/bad-reg.rs:45:26
51 |
52LL | asm!("/* {} */", in(freg) d);
53 | ^^^^^^^^^^
54
55error: register class `freg` requires at least one of the following target features: d, f
56 --> $DIR/bad-reg.rs:47:26
57 |
58LL | asm!("/* {} */", out(freg) d);
59 | ^^^^^^^^^^^
60
61error: aborting due to 10 previous errors
62
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr+6-6
......@@ -1,35 +1,35 @@
11error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:22:18
2 --> $DIR/bad-reg.rs:27:18
33 |
44LL | asm!("", out("$r0") _);
55 | ^^^^^^^^^^^^
66
77error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:24:18
8 --> $DIR/bad-reg.rs:29:18
99 |
1010LL | asm!("", out("$tp") _);
1111 | ^^^^^^^^^^^^
1212
1313error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:26:18
14 --> $DIR/bad-reg.rs:31:18
1515 |
1616LL | asm!("", out("$sp") _);
1717 | ^^^^^^^^^^^^
1818
1919error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:28:18
20 --> $DIR/bad-reg.rs:33:18
2121 |
2222LL | asm!("", out("$r21") _);
2323 | ^^^^^^^^^^^^^
2424
2525error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:30:18
26 --> $DIR/bad-reg.rs:35:18
2727 |
2828LL | asm!("", out("$fp") _);
2929 | ^^^^^^^^^^^^
3030
3131error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:32:18
32 --> $DIR/bad-reg.rs:37:18
3333 |
3434LL | asm!("", out("$r31") _);
3535 | ^^^^^^^^^^^^^
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr+10-10
......@@ -1,59 +1,59 @@
11error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:22:18
2 --> $DIR/bad-reg.rs:27:18
33 |
44LL | asm!("", out("$r0") _);
55 | ^^^^^^^^^^^^
66
77error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:24:18
8 --> $DIR/bad-reg.rs:29:18
99 |
1010LL | asm!("", out("$tp") _);
1111 | ^^^^^^^^^^^^
1212
1313error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:26:18
14 --> $DIR/bad-reg.rs:31:18
1515 |
1616LL | asm!("", out("$sp") _);
1717 | ^^^^^^^^^^^^
1818
1919error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:28:18
20 --> $DIR/bad-reg.rs:33:18
2121 |
2222LL | asm!("", out("$r21") _);
2323 | ^^^^^^^^^^^^^
2424
2525error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:30:18
26 --> $DIR/bad-reg.rs:35:18
2727 |
2828LL | asm!("", out("$fp") _);
2929 | ^^^^^^^^^^^^
3030
3131error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:32:18
32 --> $DIR/bad-reg.rs:37:18
3333 |
3434LL | asm!("", out("$r31") _);
3535 | ^^^^^^^^^^^^^
3636
3737error: register class `freg` requires at least one of the following target features: d, f
38 --> $DIR/bad-reg.rs:36:26
38 --> $DIR/bad-reg.rs:41:26
3939 |
4040LL | asm!("/* {} */", in(freg) f);
4141 | ^^^^^^^^^^
4242
4343error: register class `freg` requires at least one of the following target features: d, f
44 --> $DIR/bad-reg.rs:38:26
44 --> $DIR/bad-reg.rs:43:26
4545 |
4646LL | asm!("/* {} */", out(freg) _);
4747 | ^^^^^^^^^^^
4848
4949error: register class `freg` requires at least one of the following target features: d, f
50 --> $DIR/bad-reg.rs:40:26
50 --> $DIR/bad-reg.rs:45:26
5151 |
5252LL | asm!("/* {} */", in(freg) d);
5353 | ^^^^^^^^^^
5454
5555error: register class `freg` requires at least one of the following target features: d, f
56 --> $DIR/bad-reg.rs:42:26
56 --> $DIR/bad-reg.rs:47:26
5757 |
5858LL | asm!("/* {} */", out(freg) d);
5959 | ^^^^^^^^^^^
tests/ui/asm/loongarch/bad-reg.rs+10-5
......@@ -1,6 +1,11 @@
11//@ add-core-stubs
22//@ needs-asm-support
3//@ revisions: loongarch64_lp64d loongarch64_lp64s
3//@ revisions: loongarch32_ilp32d loongarch32_ilp32s loongarch64_lp64d loongarch64_lp64s
4//@ min-llvm-version: 20
5//@[loongarch32_ilp32d] compile-flags: --target loongarch32-unknown-none
6//@[loongarch32_ilp32d] needs-llvm-components: loongarch
7//@[loongarch32_ilp32s] compile-flags: --target loongarch32-unknown-none-softfloat
8//@[loongarch32_ilp32s] needs-llvm-components: loongarch
49//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
510//@[loongarch64_lp64d] needs-llvm-components: loongarch
611//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
......@@ -34,12 +39,12 @@ fn f() {
3439
3540 asm!("", out("$f0") _); // ok
3641 asm!("/* {} */", in(freg) f);
37 //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
42 //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
3843 asm!("/* {} */", out(freg) _);
39 //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
44 //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
4045 asm!("/* {} */", in(freg) d);
41 //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
46 //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
4247 asm!("/* {} */", out(freg) d);
43 //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
48 //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
4449 }
4550}
tests/ui/borrowck/array-slice-coercion-mismatch-15783.rs created+18
......@@ -0,0 +1,18 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15783
2
3//@ dont-require-annotations: NOTE
4
5pub fn foo(params: Option<&[&str]>) -> usize {
6 params.unwrap().first().unwrap().len()
7}
8
9fn main() {
10 let name = "Foo";
11 let x = Some(&[name]);
12 let msg = foo(x);
13 //~^ ERROR mismatched types
14 //~| NOTE expected enum `Option<&[&str]>`
15 //~| NOTE found enum `Option<&[&str; 1]>`
16 //~| NOTE expected `Option<&[&str]>`, found `Option<&[&str; 1]>`
17 assert_eq!(msg, 3);
18}
tests/ui/borrowck/array-slice-coercion-mismatch-15783.stderr created+19
......@@ -0,0 +1,19 @@
1error[E0308]: mismatched types
2 --> $DIR/array-slice-coercion-mismatch-15783.rs:12:19
3 |
4LL | let msg = foo(x);
5 | --- ^ expected `Option<&[&str]>`, found `Option<&[&str; 1]>`
6 | |
7 | arguments to this function are incorrect
8 |
9 = note: expected enum `Option<&[&str]>`
10 found enum `Option<&[&str; 1]>`
11note: function defined here
12 --> $DIR/array-slice-coercion-mismatch-15783.rs:5:8
13 |
14LL | pub fn foo(params: Option<&[&str]>) -> usize {
15 | ^^^ -----------------------
16
17error: aborting due to 1 previous error
18
19For more information about this error, try `rustc --explain E0308`.
tests/ui/closures/unused-closure-ice-16256.rs created+8
......@@ -0,0 +1,8 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16256
2
3//@ run-pass
4
5fn main() {
6 let mut buf = Vec::new();
7 |c: u8| buf.push(c); //~ WARN unused closure that must be used
8}
tests/ui/closures/unused-closure-ice-16256.stderr created+11
......@@ -0,0 +1,11 @@
1warning: unused closure that must be used
2 --> $DIR/unused-closure-ice-16256.rs:7:5
3 |
4LL | |c: u8| buf.push(c);
5 | ^^^^^^^^^^^^^^^^^^^
6 |
7 = note: closures are lazy and do nothing unless called
8 = note: `#[warn(unused_must_use)]` on by default
9
10warning: 1 warning emitted
11
tests/ui/codegen/nested-enum-match-optimization-15793.rs created+29
......@@ -0,0 +1,29 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15793
2
3//@ run-pass
4#![allow(dead_code)]
5
6enum NestedEnum {
7 First,
8 Second,
9 Third
10}
11enum Enum {
12 Variant1(bool),
13 Variant2(NestedEnum)
14}
15
16#[inline(never)]
17fn foo(x: Enum) -> isize {
18 match x {
19 Enum::Variant1(true) => 1,
20 Enum::Variant1(false) => 2,
21 Enum::Variant2(NestedEnum::Second) => 3,
22 Enum::Variant2(NestedEnum::Third) => 4,
23 Enum::Variant2(NestedEnum::First) => 5
24 }
25}
26
27fn main() {
28 assert_eq!(foo(Enum::Variant2(NestedEnum::Third)), 4);
29}
tests/ui/derives/derive-partial-ord-discriminant-64bit.rs created+40
......@@ -0,0 +1,40 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15523
2
3//@ run-pass
4// Issue 15523: derive(PartialOrd) should use the provided
5// discriminant values for the derived ordering.
6//
7// This test is checking corner cases that arise when you have
8// 64-bit values in the variants.
9
10#[derive(PartialEq, PartialOrd)]
11#[repr(u64)]
12enum Eu64 {
13 Pos2 = 2,
14 PosMax = !0,
15 Pos1 = 1,
16}
17
18#[derive(PartialEq, PartialOrd)]
19#[repr(i64)]
20enum Ei64 {
21 Pos2 = 2,
22 Neg1 = -1,
23 NegMin = 1 << 63,
24 PosMax = !(1 << 63),
25 Pos1 = 1,
26}
27
28fn main() {
29 assert!(Eu64::Pos2 > Eu64::Pos1);
30 assert!(Eu64::Pos2 < Eu64::PosMax);
31 assert!(Eu64::Pos1 < Eu64::PosMax);
32
33 assert!(Ei64::Pos2 > Ei64::Pos1);
34 assert!(Ei64::Pos2 > Ei64::Neg1);
35 assert!(Ei64::Pos1 > Ei64::Neg1);
36 assert!(Ei64::Pos2 > Ei64::NegMin);
37 assert!(Ei64::Pos1 > Ei64::NegMin);
38 assert!(Ei64::Pos2 < Ei64::PosMax);
39 assert!(Ei64::Pos1 < Ei64::PosMax);
40}
tests/ui/derives/derive-partial-ord-discriminant.rs created+44
......@@ -0,0 +1,44 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15523
2
3//@ run-pass
4// Issue 15523: derive(PartialOrd) should use the provided
5// discriminant values for the derived ordering.
6//
7// This is checking the basic functionality.
8
9#[derive(PartialEq, PartialOrd)]
10enum E1 {
11 Pos2 = 2,
12 Neg1 = -1,
13 Pos1 = 1,
14}
15
16#[derive(PartialEq, PartialOrd)]
17#[repr(u8)]
18enum E2 {
19 Pos2 = 2,
20 PosMax = !0 as u8,
21 Pos1 = 1,
22}
23
24#[derive(PartialEq, PartialOrd)]
25#[repr(i8)]
26enum E3 {
27 Pos2 = 2,
28 Neg1 = -1_i8,
29 Pos1 = 1,
30}
31
32fn main() {
33 assert!(E1::Pos2 > E1::Pos1);
34 assert!(E1::Pos1 > E1::Neg1);
35 assert!(E1::Pos2 > E1::Neg1);
36
37 assert!(E2::Pos2 > E2::Pos1);
38 assert!(E2::Pos1 < E2::PosMax);
39 assert!(E2::Pos2 < E2::PosMax);
40
41 assert!(E3::Pos2 > E3::Pos1);
42 assert!(E3::Pos1 > E3::Neg1);
43 assert!(E3::Pos2 > E3::Neg1);
44}
tests/ui/drop/dropck-normalize-errors.nll.stderr created+76
......@@ -0,0 +1,76 @@
1error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>`
2 --> $DIR/dropck-normalize-errors.rs:19:28
3 |
4LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
5 | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
6 |
7help: this trait has no implementations, consider adding one
8 --> $DIR/dropck-normalize-errors.rs:11:1
9 |
10LL | trait NonImplementedTrait {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^
12note: required because it appears within the type `BDecoder`
13 --> $DIR/dropck-normalize-errors.rs:30:12
14 |
15LL | pub struct BDecoder {
16 | ^^^^^^^^
17note: required because it appears within the type `ADecoder<'a>`
18 --> $DIR/dropck-normalize-errors.rs:16:12
19 |
20LL | pub struct ADecoder<'a> {
21 | ^^^^^^^^
22 = note: the return type of a function must have a statically known size
23
24error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder`
25 --> $DIR/dropck-normalize-errors.rs:27:20
26 |
27LL | type Decoder = BDecoder;
28 | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
29 |
30help: this trait has no implementations, consider adding one
31 --> $DIR/dropck-normalize-errors.rs:11:1
32 |
33LL | trait NonImplementedTrait {
34 | ^^^^^^^^^^^^^^^^^^^^^^^^^
35note: required because it appears within the type `BDecoder`
36 --> $DIR/dropck-normalize-errors.rs:30:12
37 |
38LL | pub struct BDecoder {
39 | ^^^^^^^^
40note: required by a bound in `Decode::Decoder`
41 --> $DIR/dropck-normalize-errors.rs:8:5
42 |
43LL | type Decoder;
44 | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder`
45help: consider relaxing the implicit `Sized` restriction
46 |
47LL | type Decoder: ?Sized;
48 | ++++++++
49
50error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
51 --> $DIR/dropck-normalize-errors.rs:31:22
52 |
53LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc,
54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
55 |
56help: this trait has no implementations, consider adding one
57 --> $DIR/dropck-normalize-errors.rs:11:1
58 |
59LL | trait NonImplementedTrait {
60 | ^^^^^^^^^^^^^^^^^^^^^^^^^
61
62error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
63 --> $DIR/dropck-normalize-errors.rs:19:28
64 |
65LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
66 | ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
67 |
68help: this trait has no implementations, consider adding one
69 --> $DIR/dropck-normalize-errors.rs:11:1
70 |
71LL | trait NonImplementedTrait {
72 | ^^^^^^^^^^^^^^^^^^^^^^^^^
73
74error: aborting due to 4 previous errors
75
76For more information about this error, try `rustc --explain E0277`.
tests/ui/drop/dropck-normalize-errors.polonius.stderr created+64
......@@ -0,0 +1,64 @@
1error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>`
2 --> $DIR/dropck-normalize-errors.rs:19:28
3 |
4LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
5 | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
6 |
7help: this trait has no implementations, consider adding one
8 --> $DIR/dropck-normalize-errors.rs:11:1
9 |
10LL | trait NonImplementedTrait {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^
12note: required because it appears within the type `BDecoder`
13 --> $DIR/dropck-normalize-errors.rs:30:12
14 |
15LL | pub struct BDecoder {
16 | ^^^^^^^^
17note: required because it appears within the type `ADecoder<'a>`
18 --> $DIR/dropck-normalize-errors.rs:16:12
19 |
20LL | pub struct ADecoder<'a> {
21 | ^^^^^^^^
22 = note: the return type of a function must have a statically known size
23
24error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder`
25 --> $DIR/dropck-normalize-errors.rs:27:20
26 |
27LL | type Decoder = BDecoder;
28 | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
29 |
30help: this trait has no implementations, consider adding one
31 --> $DIR/dropck-normalize-errors.rs:11:1
32 |
33LL | trait NonImplementedTrait {
34 | ^^^^^^^^^^^^^^^^^^^^^^^^^
35note: required because it appears within the type `BDecoder`
36 --> $DIR/dropck-normalize-errors.rs:30:12
37 |
38LL | pub struct BDecoder {
39 | ^^^^^^^^
40note: required by a bound in `Decode::Decoder`
41 --> $DIR/dropck-normalize-errors.rs:8:5
42 |
43LL | type Decoder;
44 | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder`
45help: consider relaxing the implicit `Sized` restriction
46 |
47LL | type Decoder: ?Sized;
48 | ++++++++
49
50error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
51 --> $DIR/dropck-normalize-errors.rs:31:22
52 |
53LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc,
54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
55 |
56help: this trait has no implementations, consider adding one
57 --> $DIR/dropck-normalize-errors.rs:11:1
58 |
59LL | trait NonImplementedTrait {
60 | ^^^^^^^^^^^^^^^^^^^^^^^^^
61
62error: aborting due to 3 previous errors
63
64For more information about this error, try `rustc --explain E0277`.
tests/ui/drop/dropck-normalize-errors.rs+5-1
......@@ -1,5 +1,9 @@
11// Test that we don't ICE when computing the drop types for
22
3//@ ignore-compare-mode-polonius (explicit revisions)
4//@ revisions: nll polonius
5//@ [polonius] compile-flags: -Zpolonius=next
6
37trait Decode<'a> {
48 type Decoder;
59}
......@@ -14,7 +18,7 @@ pub struct ADecoder<'a> {
1418}
1519fn make_a_decoder<'a>() -> ADecoder<'a> {
1620 //~^ ERROR the trait bound
17 //~| ERROR the trait bound
21 //[nll]~| ERROR the trait bound
1822 panic!()
1923}
2024
tests/ui/drop/dropck-normalize-errors.stderr deleted-76
......@@ -1,76 +0,0 @@
1error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>`
2 --> $DIR/dropck-normalize-errors.rs:15:28
3 |
4LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
5 | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
6 |
7help: this trait has no implementations, consider adding one
8 --> $DIR/dropck-normalize-errors.rs:7:1
9 |
10LL | trait NonImplementedTrait {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^
12note: required because it appears within the type `BDecoder`
13 --> $DIR/dropck-normalize-errors.rs:26:12
14 |
15LL | pub struct BDecoder {
16 | ^^^^^^^^
17note: required because it appears within the type `ADecoder<'a>`
18 --> $DIR/dropck-normalize-errors.rs:12:12
19 |
20LL | pub struct ADecoder<'a> {
21 | ^^^^^^^^
22 = note: the return type of a function must have a statically known size
23
24error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder`
25 --> $DIR/dropck-normalize-errors.rs:23:20
26 |
27LL | type Decoder = BDecoder;
28 | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
29 |
30help: this trait has no implementations, consider adding one
31 --> $DIR/dropck-normalize-errors.rs:7:1
32 |
33LL | trait NonImplementedTrait {
34 | ^^^^^^^^^^^^^^^^^^^^^^^^^
35note: required because it appears within the type `BDecoder`
36 --> $DIR/dropck-normalize-errors.rs:26:12
37 |
38LL | pub struct BDecoder {
39 | ^^^^^^^^
40note: required by a bound in `Decode::Decoder`
41 --> $DIR/dropck-normalize-errors.rs:4:5
42 |
43LL | type Decoder;
44 | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder`
45help: consider relaxing the implicit `Sized` restriction
46 |
47LL | type Decoder: ?Sized;
48 | ++++++++
49
50error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
51 --> $DIR/dropck-normalize-errors.rs:27:22
52 |
53LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc,
54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
55 |
56help: this trait has no implementations, consider adding one
57 --> $DIR/dropck-normalize-errors.rs:7:1
58 |
59LL | trait NonImplementedTrait {
60 | ^^^^^^^^^^^^^^^^^^^^^^^^^
61
62error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
63 --> $DIR/dropck-normalize-errors.rs:15:28
64 |
65LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
66 | ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
67 |
68help: this trait has no implementations, consider adding one
69 --> $DIR/dropck-normalize-errors.rs:7:1
70 |
71LL | trait NonImplementedTrait {
72 | ^^^^^^^^^^^^^^^^^^^^^^^^^
73
74error: aborting due to 4 previous errors
75
76For more information about this error, try `rustc --explain E0277`.
tests/ui/drop/enum-drop-impl-15063.rs created+14
......@@ -0,0 +1,14 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15063
2
3//@ run-pass
4#![allow(dead_code)]
5#![allow(unused_variables)]
6enum Two { A, B}
7impl Drop for Two {
8 fn drop(&mut self) {
9 println!("Dropping!");
10 }
11}
12fn main() {
13 let k = Two::A;
14}
tests/ui/drop/generic-drop-trait-bound-15858.rs created+37
......@@ -0,0 +1,37 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15858
2
3//@ run-pass
4// FIXME(static_mut_refs): this could use an atomic
5#![allow(static_mut_refs)]
6static mut DROP_RAN: bool = false;
7
8trait Bar {
9 fn do_something(&mut self); //~ WARN method `do_something` is never used
10}
11
12struct BarImpl;
13
14impl Bar for BarImpl {
15 fn do_something(&mut self) {}
16}
17
18
19struct Foo<B: Bar>(#[allow(dead_code)] B);
20
21impl<B: Bar> Drop for Foo<B> {
22 fn drop(&mut self) {
23 unsafe {
24 DROP_RAN = true;
25 }
26 }
27}
28
29
30fn main() {
31 {
32 let _x: Foo<BarImpl> = Foo(BarImpl);
33 }
34 unsafe {
35 assert_eq!(DROP_RAN, true);
36 }
37}
tests/ui/drop/generic-drop-trait-bound-15858.stderr created+12
......@@ -0,0 +1,12 @@
1warning: method `do_something` is never used
2 --> $DIR/generic-drop-trait-bound-15858.rs:9:8
3 |
4LL | trait Bar {
5 | --- method in this trait
6LL | fn do_something(&mut self);
7 | ^^^^^^^^^^^^
8 |
9 = note: `#[warn(dead_code)]` on by default
10
11warning: 1 warning emitted
12
tests/ui/drop/nested-return-drop-order.rs created+90
......@@ -0,0 +1,90 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15763
2
3//@ run-pass
4#![allow(unreachable_code)]
5
6#[derive(PartialEq, Debug)]
7struct Bar {
8 x: isize
9}
10impl Drop for Bar {
11 fn drop(&mut self) {
12 assert_eq!(self.x, 22);
13 }
14}
15
16#[derive(PartialEq, Debug)]
17struct Foo {
18 x: Bar,
19 a: isize
20}
21
22fn foo() -> Result<Foo, isize> {
23 return Ok(Foo {
24 x: Bar { x: 22 },
25 a: return Err(32)
26 });
27}
28
29fn baz() -> Result<Foo, isize> {
30 Ok(Foo {
31 x: Bar { x: 22 },
32 a: return Err(32)
33 })
34}
35
36// explicit immediate return
37fn aa() -> isize {
38 return 3;
39}
40
41// implicit immediate return
42fn bb() -> isize {
43 3
44}
45
46// implicit outptr return
47fn cc() -> Result<isize, isize> {
48 Ok(3)
49}
50
51// explicit outptr return
52fn dd() -> Result<isize, isize> {
53 return Ok(3);
54}
55
56trait A {
57 fn aaa(&self) -> isize {
58 3
59 }
60 fn bbb(&self) -> isize {
61 return 3;
62 }
63 fn ccc(&self) -> Result<isize, isize> {
64 Ok(3)
65 }
66 fn ddd(&self) -> Result<isize, isize> {
67 return Ok(3);
68 }
69}
70
71impl A for isize {}
72
73fn main() {
74 assert_eq!(foo(), Err(32));
75 assert_eq!(baz(), Err(32));
76
77 assert_eq!(aa(), 3);
78 assert_eq!(bb(), 3);
79 assert_eq!(cc().unwrap(), 3);
80 assert_eq!(dd().unwrap(), 3);
81
82 let i = Box::new(32isize) as Box<dyn A>;
83 assert_eq!(i.aaa(), 3);
84 let i = Box::new(32isize) as Box<dyn A>;
85 assert_eq!(i.bbb(), 3);
86 let i = Box::new(32isize) as Box<dyn A>;
87 assert_eq!(i.ccc().unwrap(), 3);
88 let i = Box::new(32isize) as Box<dyn A>;
89 assert_eq!(i.ddd().unwrap(), 3);
90}
tests/ui/drop/same-alloca-reassigned-match-binding-16151.rs created+34
......@@ -0,0 +1,34 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16151
2
3//@ run-pass
4
5// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6#![allow(static_mut_refs)]
7
8use std::mem;
9
10static mut DROP_COUNT: usize = 0;
11
12struct Fragment;
13
14impl Drop for Fragment {
15 fn drop(&mut self) {
16 unsafe {
17 DROP_COUNT += 1;
18 }
19 }
20}
21
22fn main() {
23 {
24 let mut fragments = vec![Fragment, Fragment, Fragment];
25 let _new_fragments: Vec<Fragment> = mem::replace(&mut fragments, vec![])
26 .into_iter()
27 .skip_while(|_fragment| {
28 true
29 }).collect();
30 }
31 unsafe {
32 assert_eq!(DROP_COUNT, 3);
33 }
34}
tests/ui/drop/struct-field-drop-order.rs created+69
......@@ -0,0 +1,69 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16492
2
3//@ run-pass
4#![allow(non_snake_case)]
5
6use std::rc::Rc;
7use std::cell::Cell;
8
9struct Field {
10 number: usize,
11 state: Rc<Cell<usize>>
12}
13
14impl Field {
15 fn new(number: usize, state: Rc<Cell<usize>>) -> Field {
16 Field {
17 number: number,
18 state: state
19 }
20 }
21}
22
23impl Drop for Field {
24 fn drop(&mut self) {
25 println!("Dropping field {}", self.number);
26 assert_eq!(self.state.get(), self.number);
27 self.state.set(self.state.get()+1);
28 }
29}
30
31struct NoDropImpl {
32 _one: Field,
33 _two: Field,
34 _three: Field
35}
36
37struct HasDropImpl {
38 _one: Field,
39 _two: Field,
40 _three: Field
41}
42
43impl Drop for HasDropImpl {
44 fn drop(&mut self) {
45 println!("HasDropImpl.drop()");
46 assert_eq!(self._one.state.get(), 0);
47 self._one.state.set(1);
48 }
49}
50
51pub fn main() {
52 let state = Rc::new(Cell::new(1));
53 let noImpl = NoDropImpl {
54 _one: Field::new(1, state.clone()),
55 _two: Field::new(2, state.clone()),
56 _three: Field::new(3, state.clone())
57 };
58 drop(noImpl);
59 assert_eq!(state.get(), 4);
60
61 state.set(0);
62 let hasImpl = HasDropImpl {
63 _one: Field::new(1, state.clone()),
64 _two: Field::new(2, state.clone()),
65 _three: Field::new(3, state.clone())
66 };
67 drop(hasImpl);
68 assert_eq!(state.get(), 4);
69}
tests/ui/extern/empty-struct-extern-fn-16441.rs created+13
......@@ -0,0 +1,13 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16441
2
3//@ run-pass
4#![allow(dead_code)]
5
6struct Empty;
7
8// This used to cause an ICE
9#[allow(improper_ctypes_definitions)]
10extern "C" fn ice(_a: Empty) {}
11
12fn main() {
13}
tests/ui/fn/fn-traits-call-once-signature-15094.rs created+29
......@@ -0,0 +1,29 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15094
2
3#![feature(fn_traits, unboxed_closures)]
4
5use std::{fmt, ops};
6
7struct Debuger<T> {
8 x: T
9}
10
11impl<T: fmt::Debug> ops::FnOnce<(),> for Debuger<T> {
12 type Output = ();
13 fn call_once(self, _args: ()) {
14 //~^ ERROR `call_once` has an incompatible type for trait
15 //~| NOTE expected signature `extern "rust-call" fn
16 //~| NOTE found signature `fn
17 //~| NOTE expected "rust-call" fn, found "Rust" fn
18 println!("{:?}", self.x);
19 }
20}
21
22fn make_shower<T>(x: T) -> Debuger<T> {
23 Debuger { x: x }
24}
25
26pub fn main() {
27 let show3 = make_shower(3);
28 show3();
29}
tests/ui/fn/fn-traits-call-once-signature-15094.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0053]: method `call_once` has an incompatible type for trait
2 --> $DIR/fn-traits-call-once-signature-15094.rs:13:5
3 |
4LL | fn call_once(self, _args: ()) {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "Rust" fn
6 |
7 = note: expected signature `extern "rust-call" fn(Debuger<_>, ())`
8 found signature `fn(Debuger<_>, ())`
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0053`.
tests/ui/imports/enum-variant-import-path-15774.rs created+27
......@@ -0,0 +1,27 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15774
2
3//@ edition: 2015
4//@ run-pass
5
6#![deny(warnings)]
7#![allow(unused_imports)]
8
9pub enum Foo { A }
10mod bar {
11 pub fn normal(x: ::Foo) {
12 use Foo::A;
13 match x {
14 A => {}
15 }
16 }
17 pub fn wrong(x: ::Foo) {
18 match x {
19 ::Foo::A => {}
20 }
21 }
22}
23
24pub fn main() {
25 bar::normal(Foo::A);
26 bar::wrong(Foo::A);
27}
tests/ui/inference/iterator-sum-array-15673.rs created+11
......@@ -0,0 +1,11 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15673
2
3//@ run-pass
4#![allow(stable_features)]
5
6#![feature(iter_arith)]
7
8fn main() {
9 let x: [u64; 3] = [1, 2, 3];
10 assert_eq!(6, (0..3).map(|i| x[i]).sum::<u64>());
11}
tests/ui/inference/return-block-type-inference-15965.rs created+9
......@@ -0,0 +1,9 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15965
2
3fn main() {
4 return
5 { return () }
6//~^ ERROR type annotations needed [E0282]
7 ()
8 ;
9}
tests/ui/inference/return-block-type-inference-15965.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0282]: type annotations needed
2 --> $DIR/return-block-type-inference-15965.rs:5:9
3 |
4LL | / { return () }
5LL | |
6LL | | ()
7 | |______^ cannot infer type
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0282`.
tests/ui/issues/issue-15034.rs deleted-22
......@@ -1,22 +0,0 @@
1pub struct Lexer<'a> {
2 input: &'a str,
3}
4
5impl<'a> Lexer<'a> {
6 pub fn new(input: &'a str) -> Lexer<'a> {
7 Lexer { input: input }
8 }
9}
10
11struct Parser<'a> {
12 lexer: &'a mut Lexer<'a>,
13}
14
15impl<'a> Parser<'a> {
16 pub fn new(lexer: &'a mut Lexer) -> Parser<'a> {
17 Parser { lexer: lexer }
18 //~^ ERROR explicit lifetime required in the type of `lexer` [E0621]
19 }
20}
21
22fn main() {}
tests/ui/issues/issue-15034.stderr deleted-14
......@@ -1,14 +0,0 @@
1error[E0621]: explicit lifetime required in the type of `lexer`
2 --> $DIR/issue-15034.rs:17:9
3 |
4LL | Parser { lexer: lexer }
5 | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
6 |
7help: add explicit lifetime `'a` to the type of `lexer`
8 |
9LL | pub fn new(lexer: &'a mut Lexer<'a>) -> Parser<'a> {
10 | ++++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0621`.
tests/ui/issues/issue-15043.rs deleted-13
......@@ -1,13 +0,0 @@
1//@ run-pass
2
3#![allow(warnings)]
4
5struct S<T>(T);
6
7static s1: S<S<usize>>=S(S(0));
8static s2: S<usize>=S(0);
9
10fn main() {
11 let foo: S<S<usize>>=S(S(0));
12 let foo: S<usize>=S(0);
13}
tests/ui/issues/issue-15063.rs deleted-12
......@@ -1,12 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#![allow(unused_variables)]
4enum Two { A, B}
5impl Drop for Two {
6 fn drop(&mut self) {
7 println!("Dropping!");
8 }
9}
10fn main() {
11 let k = Two::A;
12}
tests/ui/issues/issue-15094.rs deleted-27
......@@ -1,27 +0,0 @@
1#![feature(fn_traits, unboxed_closures)]
2
3use std::{fmt, ops};
4
5struct Debuger<T> {
6 x: T
7}
8
9impl<T: fmt::Debug> ops::FnOnce<(),> for Debuger<T> {
10 type Output = ();
11 fn call_once(self, _args: ()) {
12 //~^ ERROR `call_once` has an incompatible type for trait
13 //~| NOTE expected signature `extern "rust-call" fn
14 //~| NOTE found signature `fn
15 //~| NOTE expected "rust-call" fn, found "Rust" fn
16 println!("{:?}", self.x);
17 }
18}
19
20fn make_shower<T>(x: T) -> Debuger<T> {
21 Debuger { x: x }
22}
23
24pub fn main() {
25 let show3 = make_shower(3);
26 show3();
27}
tests/ui/issues/issue-15094.stderr deleted-12
......@@ -1,12 +0,0 @@
1error[E0053]: method `call_once` has an incompatible type for trait
2 --> $DIR/issue-15094.rs:11:5
3 |
4LL | fn call_once(self, _args: ()) {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "Rust" fn
6 |
7 = note: expected signature `extern "rust-call" fn(Debuger<_>, ())`
8 found signature `fn(Debuger<_>, ())`
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0053`.
tests/ui/issues/issue-15104.rs deleted-13
......@@ -1,13 +0,0 @@
1//@ run-pass
2
3fn main() {
4 assert_eq!(count_members(&[1, 2, 3, 4]), 4);
5}
6
7fn count_members(v: &[usize]) -> usize {
8 match *v {
9 [] => 0,
10 [_] => 1,
11 [_, ref xs @ ..] => 1 + count_members(xs)
12 }
13}
tests/ui/issues/issue-15129-rpass.rs deleted-25
......@@ -1,25 +0,0 @@
1//@ run-pass
2
3pub enum T {
4 T1(()),
5 T2(())
6}
7
8pub enum V {
9 V1(isize),
10 V2(bool)
11}
12
13fn foo(x: (T, V)) -> String {
14 match x {
15 (T::T1(()), V::V1(i)) => format!("T1(()), V1({})", i),
16 (T::T2(()), V::V2(b)) => format!("T2(()), V2({})", b),
17 _ => String::new()
18 }
19}
20
21
22fn main() {
23 assert_eq!(foo((T::T1(()), V::V1(99))), "T1(()), V1(99)".to_string());
24 assert_eq!(foo((T::T2(()), V::V2(true))), "T2(()), V2(true)".to_string());
25}
tests/ui/issues/issue-15167.rs deleted-26
......@@ -1,26 +0,0 @@
1// macro f should not be able to inject a reference to 'n'.
2
3macro_rules! f { () => (n) }
4//~^ ERROR cannot find value `n` in this scope
5//~| ERROR cannot find value `n` in this scope
6//~| ERROR cannot find value `n` in this scope
7//~| ERROR cannot find value `n` in this scope
8
9fn main() -> (){
10 for n in 0..1 {
11 println!("{}", f!());
12 }
13
14 if let Some(n) = None {
15 println!("{}", f!());
16 }
17
18 if false {
19 } else if let Some(n) = None {
20 println!("{}", f!());
21 }
22
23 while let Some(n) = None {
24 println!("{}", f!());
25 }
26}
tests/ui/issues/issue-15167.stderr deleted-47
......@@ -1,47 +0,0 @@
1error[E0425]: cannot find value `n` in this scope
2 --> $DIR/issue-15167.rs:3:25
3 |
4LL | macro_rules! f { () => (n) }
5 | ^ not found in this scope
6...
7LL | println!("{}", f!());
8 | ---- in this macro invocation
9 |
10 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
11
12error[E0425]: cannot find value `n` in this scope
13 --> $DIR/issue-15167.rs:3:25
14 |
15LL | macro_rules! f { () => (n) }
16 | ^ not found in this scope
17...
18LL | println!("{}", f!());
19 | ---- in this macro invocation
20 |
21 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
22
23error[E0425]: cannot find value `n` in this scope
24 --> $DIR/issue-15167.rs:3:25
25 |
26LL | macro_rules! f { () => (n) }
27 | ^ not found in this scope
28...
29LL | println!("{}", f!());
30 | ---- in this macro invocation
31 |
32 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
33
34error[E0425]: cannot find value `n` in this scope
35 --> $DIR/issue-15167.rs:3:25
36 |
37LL | macro_rules! f { () => (n) }
38 | ^ not found in this scope
39...
40LL | println!("{}", f!());
41 | ---- in this macro invocation
42 |
43 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
44
45error: aborting due to 4 previous errors
46
47For more information about this error, try `rustc --explain E0425`.
tests/ui/issues/issue-15189.rs deleted-10
......@@ -1,10 +0,0 @@
1//@ run-pass
2macro_rules! third {
3 ($e:expr) => ({let x = 2; $e[x]})
4}
5
6fn main() {
7 let x = vec![10_usize,11_usize,12_usize,13_usize];
8 let t = third!(x);
9 assert_eq!(t,12_usize);
10}
tests/ui/issues/issue-15207.rs deleted-6
......@@ -1,6 +0,0 @@
1fn main() {
2 loop {
3 break.push(1) //~ ERROR no method named `push` found for type `!`
4 ;
5 }
6}
tests/ui/issues/issue-15207.stderr deleted-9
......@@ -1,9 +0,0 @@
1error[E0599]: no method named `push` found for type `!` in the current scope
2 --> $DIR/issue-15207.rs:3:15
3 |
4LL | break.push(1)
5 | ^^^^ method not found in `!`
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0599`.
tests/ui/issues/issue-15260.rs deleted-25
......@@ -1,25 +0,0 @@
1struct Foo {
2 a: usize,
3}
4
5fn main() {
6 let Foo {
7 a: _,
8 a: _
9 //~^ ERROR field `a` bound multiple times in the pattern
10 } = Foo { a: 29 };
11
12 let Foo {
13 a,
14 a: _
15 //~^ ERROR field `a` bound multiple times in the pattern
16 } = Foo { a: 29 };
17
18 let Foo {
19 a,
20 a: _,
21 //~^ ERROR field `a` bound multiple times in the pattern
22 a: x
23 //~^ ERROR field `a` bound multiple times in the pattern
24 } = Foo { a: 29 };
25}
tests/ui/issues/issue-15260.stderr deleted-36
......@@ -1,36 +0,0 @@
1error[E0025]: field `a` bound multiple times in the pattern
2 --> $DIR/issue-15260.rs:8:9
3 |
4LL | a: _,
5 | ---- first use of `a`
6LL | a: _
7 | ^^^^ multiple uses of `a` in pattern
8
9error[E0025]: field `a` bound multiple times in the pattern
10 --> $DIR/issue-15260.rs:14:9
11 |
12LL | a,
13 | - first use of `a`
14LL | a: _
15 | ^^^^ multiple uses of `a` in pattern
16
17error[E0025]: field `a` bound multiple times in the pattern
18 --> $DIR/issue-15260.rs:20:9
19 |
20LL | a,
21 | - first use of `a`
22LL | a: _,
23 | ^^^^ multiple uses of `a` in pattern
24
25error[E0025]: field `a` bound multiple times in the pattern
26 --> $DIR/issue-15260.rs:22:9
27 |
28LL | a,
29 | - first use of `a`
30...
31LL | a: x
32 | ^^^^ multiple uses of `a` in pattern
33
34error: aborting due to 4 previous errors
35
36For more information about this error, try `rustc --explain E0025`.
tests/ui/issues/issue-15381.rs deleted-10
......@@ -1,10 +0,0 @@
1fn main() {
2 let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];
3
4 for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
5 //~^ ERROR refutable pattern in `for` loop binding
6 //~| NOTE patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
7 //~| NOTE the matched value is of type `&[u8]`
8 println!("y={}", y);
9 }
10}
tests/ui/issues/issue-15381.stderr deleted-11
......@@ -1,11 +0,0 @@
1error[E0005]: refutable pattern in `for` loop binding
2 --> $DIR/issue-15381.rs:4:9
3 |
4LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
5 | ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
6 |
7 = note: the matched value is of type `&[u8]`
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0005`.
tests/ui/issues/issue-15444.rs deleted-22
......@@ -1,22 +0,0 @@
1//@ run-pass
2
3trait MyTrait {
4 fn foo(&self);
5}
6
7impl<A, B, C> MyTrait for fn(A, B) -> C {
8 fn foo(&self) {}
9}
10
11fn bar<T: MyTrait>(t: &T) {
12 t.foo()
13}
14
15fn thing(a: isize, b: isize) -> isize {
16 a + b
17}
18
19fn main() {
20 let thing: fn(isize, isize) -> isize = thing; // coerce to fn type
21 bar(&thing);
22}
tests/ui/issues/issue-15523-big.rs deleted-39
......@@ -1,39 +0,0 @@
1//@ run-pass
2// Issue 15523: derive(PartialOrd) should use the provided
3// discriminant values for the derived ordering.
4//
5// This test is checking corner cases that arise when you have
6// 64-bit values in the variants.
7
8#[derive(PartialEq, PartialOrd)]
9#[repr(u64)]
10enum Eu64 {
11 Pos2 = 2,
12 PosMax = !0,
13 Pos1 = 1,
14}
15
16#[derive(PartialEq, PartialOrd)]
17#[repr(i64)]
18enum Ei64 {
19 Pos2 = 2,
20 Neg1 = -1,
21 NegMin = 1 << 63,
22 PosMax = !(1 << 63),
23 Pos1 = 1,
24}
25
26fn main() {
27 assert!(Eu64::Pos2 > Eu64::Pos1);
28 assert!(Eu64::Pos2 < Eu64::PosMax);
29 assert!(Eu64::Pos1 < Eu64::PosMax);
30
31
32 assert!(Ei64::Pos2 > Ei64::Pos1);
33 assert!(Ei64::Pos2 > Ei64::Neg1);
34 assert!(Ei64::Pos1 > Ei64::Neg1);
35 assert!(Ei64::Pos2 > Ei64::NegMin);
36 assert!(Ei64::Pos1 > Ei64::NegMin);
37 assert!(Ei64::Pos2 < Ei64::PosMax);
38 assert!(Ei64::Pos1 < Ei64::PosMax);
39}
tests/ui/issues/issue-15523.rs deleted-42
......@@ -1,42 +0,0 @@
1//@ run-pass
2// Issue 15523: derive(PartialOrd) should use the provided
3// discriminant values for the derived ordering.
4//
5// This is checking the basic functionality.
6
7#[derive(PartialEq, PartialOrd)]
8enum E1 {
9 Pos2 = 2,
10 Neg1 = -1,
11 Pos1 = 1,
12}
13
14#[derive(PartialEq, PartialOrd)]
15#[repr(u8)]
16enum E2 {
17 Pos2 = 2,
18 PosMax = !0 as u8,
19 Pos1 = 1,
20}
21
22#[derive(PartialEq, PartialOrd)]
23#[repr(i8)]
24enum E3 {
25 Pos2 = 2,
26 Neg1 = -1_i8,
27 Pos1 = 1,
28}
29
30fn main() {
31 assert!(E1::Pos2 > E1::Pos1);
32 assert!(E1::Pos1 > E1::Neg1);
33 assert!(E1::Pos2 > E1::Neg1);
34
35 assert!(E2::Pos2 > E2::Pos1);
36 assert!(E2::Pos1 < E2::PosMax);
37 assert!(E2::Pos2 < E2::PosMax);
38
39 assert!(E3::Pos2 > E3::Pos1);
40 assert!(E3::Pos1 > E3::Neg1);
41 assert!(E3::Pos2 > E3::Neg1);
42}
tests/ui/issues/issue-15571.rs deleted-57
......@@ -1,57 +0,0 @@
1//@ run-pass
2
3fn match_on_local() {
4 let mut foo: Option<Box<_>> = Some(Box::new(5));
5 match foo {
6 None => {},
7 Some(x) => {
8 foo = Some(x);
9 }
10 }
11 println!("'{}'", foo.unwrap());
12}
13
14fn match_on_arg(mut foo: Option<Box<i32>>) {
15 match foo {
16 None => {}
17 Some(x) => {
18 foo = Some(x);
19 }
20 }
21 println!("'{}'", foo.unwrap());
22}
23
24fn match_on_binding() {
25 match Some(Box::new(7)) {
26 mut foo => {
27 match foo {
28 None => {},
29 Some(x) => {
30 foo = Some(x);
31 }
32 }
33 println!("'{}'", foo.unwrap());
34 }
35 }
36}
37
38fn match_on_upvar() {
39 let mut foo: Option<Box<_>> = Some(Box::new(8));
40 let f = move|| {
41 match foo {
42 None => {},
43 Some(x) => {
44 foo = Some(x);
45 }
46 }
47 println!("'{}'", foo.unwrap());
48 };
49 f();
50}
51
52fn main() {
53 match_on_local();
54 match_on_arg(Some(Box::new(6)));
55 match_on_binding();
56 match_on_upvar();
57}
tests/ui/issues/issue-15734.rs deleted-59
......@@ -1,59 +0,0 @@
1//@ run-pass
2//@ revisions: current next
3//@ ignore-compare-mode-next-solver (explicit revisions)
4//@[next] compile-flags: -Znext-solver
5
6use std::ops::Index;
7
8struct Mat<T> { data: Vec<T>, cols: usize, }
9
10impl<T> Mat<T> {
11 fn new(data: Vec<T>, cols: usize) -> Mat<T> {
12 Mat { data: data, cols: cols }
13 }
14 fn row<'a>(&'a self, row: usize) -> Row<&'a Mat<T>> {
15 Row { mat: self, row: row, }
16 }
17}
18
19impl<T> Index<(usize, usize)> for Mat<T> {
20 type Output = T;
21
22 fn index<'a>(&'a self, (row, col): (usize, usize)) -> &'a T {
23 &self.data[row * self.cols + col]
24 }
25}
26
27impl<'a, T> Index<(usize, usize)> for &'a Mat<T> {
28 type Output = T;
29
30 fn index<'b>(&'b self, index: (usize, usize)) -> &'b T {
31 (*self).index(index)
32 }
33}
34
35struct Row<M> { mat: M, row: usize, }
36
37impl<T, M: Index<(usize, usize), Output=T>> Index<usize> for Row<M> {
38 type Output = T;
39
40 fn index<'a>(&'a self, col: usize) -> &'a T {
41 &self.mat[(self.row, col)]
42 }
43}
44
45fn main() {
46 let m = Mat::new(vec![1, 2, 3, 4, 5, 6], 3);
47 let r = m.row(1);
48
49 assert_eq!(r.index(2), &6);
50 assert_eq!(r[2], 6);
51 assert_eq!(r[2], 6);
52 assert_eq!(6, r[2]);
53
54 let e = r[2];
55 assert_eq!(e, 6);
56
57 let e: usize = r[2];
58 assert_eq!(e, 6);
59}
tests/ui/issues/issue-15756.rs deleted-14
......@@ -1,14 +0,0 @@
1use std::slice::Chunks;
2use std::slice::ChunksMut;
3
4fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: ChunksMut<'a,T>)
5{
6 for
7 &mut something
8 //~^ ERROR the size for values of type
9 in arg2
10 {
11 }
12}
13
14fn main() {}
tests/ui/issues/issue-15756.stderr deleted-12
......@@ -1,12 +0,0 @@
1error[E0277]: the size for values of type `[T]` cannot be known at compilation time
2 --> $DIR/issue-15756.rs:7:10
3 |
4LL | &mut something
5 | ^^^^^^^^^ doesn't have a size known at compile-time
6 |
7 = help: the trait `Sized` is not implemented for `[T]`
8 = note: all local variables must have a statically known size
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0277`.
tests/ui/issues/issue-15763.rs deleted-88
......@@ -1,88 +0,0 @@
1//@ run-pass
2#![allow(unreachable_code)]
3
4#[derive(PartialEq, Debug)]
5struct Bar {
6 x: isize
7}
8impl Drop for Bar {
9 fn drop(&mut self) {
10 assert_eq!(self.x, 22);
11 }
12}
13
14#[derive(PartialEq, Debug)]
15struct Foo {
16 x: Bar,
17 a: isize
18}
19
20fn foo() -> Result<Foo, isize> {
21 return Ok(Foo {
22 x: Bar { x: 22 },
23 a: return Err(32)
24 });
25}
26
27fn baz() -> Result<Foo, isize> {
28 Ok(Foo {
29 x: Bar { x: 22 },
30 a: return Err(32)
31 })
32}
33
34// explicit immediate return
35fn aa() -> isize {
36 return 3;
37}
38
39// implicit immediate return
40fn bb() -> isize {
41 3
42}
43
44// implicit outptr return
45fn cc() -> Result<isize, isize> {
46 Ok(3)
47}
48
49// explicit outptr return
50fn dd() -> Result<isize, isize> {
51 return Ok(3);
52}
53
54trait A {
55 fn aaa(&self) -> isize {
56 3
57 }
58 fn bbb(&self) -> isize {
59 return 3;
60 }
61 fn ccc(&self) -> Result<isize, isize> {
62 Ok(3)
63 }
64 fn ddd(&self) -> Result<isize, isize> {
65 return Ok(3);
66 }
67}
68
69impl A for isize {}
70
71fn main() {
72 assert_eq!(foo(), Err(32));
73 assert_eq!(baz(), Err(32));
74
75 assert_eq!(aa(), 3);
76 assert_eq!(bb(), 3);
77 assert_eq!(cc().unwrap(), 3);
78 assert_eq!(dd().unwrap(), 3);
79
80 let i = Box::new(32isize) as Box<dyn A>;
81 assert_eq!(i.aaa(), 3);
82 let i = Box::new(32isize) as Box<dyn A>;
83 assert_eq!(i.bbb(), 3);
84 let i = Box::new(32isize) as Box<dyn A>;
85 assert_eq!(i.ccc().unwrap(), 3);
86 let i = Box::new(32isize) as Box<dyn A>;
87 assert_eq!(i.ddd().unwrap(), 3);
88}
tests/ui/issues/issue-15774.rs deleted-25
......@@ -1,25 +0,0 @@
1//@ edition: 2015
2//@ run-pass
3
4#![deny(warnings)]
5#![allow(unused_imports)]
6
7pub enum Foo { A }
8mod bar {
9 pub fn normal(x: ::Foo) {
10 use Foo::A;
11 match x {
12 A => {}
13 }
14 }
15 pub fn wrong(x: ::Foo) {
16 match x {
17 ::Foo::A => {}
18 }
19 }
20}
21
22pub fn main() {
23 bar::normal(Foo::A);
24 bar::wrong(Foo::A);
25}
tests/ui/issues/issue-15783.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ dont-require-annotations: NOTE
2
3pub fn foo(params: Option<&[&str]>) -> usize {
4 params.unwrap().first().unwrap().len()
5}
6
7fn main() {
8 let name = "Foo";
9 let x = Some(&[name]);
10 let msg = foo(x);
11 //~^ ERROR mismatched types
12 //~| NOTE expected enum `Option<&[&str]>`
13 //~| NOTE found enum `Option<&[&str; 1]>`
14 //~| NOTE expected `Option<&[&str]>`, found `Option<&[&str; 1]>`
15 assert_eq!(msg, 3);
16}
tests/ui/issues/issue-15783.stderr deleted-19
......@@ -1,19 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/issue-15783.rs:10:19
3 |
4LL | let msg = foo(x);
5 | --- ^ expected `Option<&[&str]>`, found `Option<&[&str; 1]>`
6 | |
7 | arguments to this function are incorrect
8 |
9 = note: expected enum `Option<&[&str]>`
10 found enum `Option<&[&str; 1]>`
11note: function defined here
12 --> $DIR/issue-15783.rs:3:8
13 |
14LL | pub fn foo(params: Option<&[&str]>) -> usize {
15 | ^^^ -----------------------
16
17error: aborting due to 1 previous error
18
19For more information about this error, try `rustc --explain E0308`.
tests/ui/issues/issue-15793.rs deleted-27
......@@ -1,27 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3
4enum NestedEnum {
5 First,
6 Second,
7 Third
8}
9enum Enum {
10 Variant1(bool),
11 Variant2(NestedEnum)
12}
13
14#[inline(never)]
15fn foo(x: Enum) -> isize {
16 match x {
17 Enum::Variant1(true) => 1,
18 Enum::Variant1(false) => 2,
19 Enum::Variant2(NestedEnum::Second) => 3,
20 Enum::Variant2(NestedEnum::Third) => 4,
21 Enum::Variant2(NestedEnum::First) => 5
22 }
23}
24
25fn main() {
26 assert_eq!(foo(Enum::Variant2(NestedEnum::Third)), 4);
27}
tests/ui/issues/issue-15858.rs deleted-35
......@@ -1,35 +0,0 @@
1//@ run-pass
2// FIXME(static_mut_refs): this could use an atomic
3#![allow(static_mut_refs)]
4static mut DROP_RAN: bool = false;
5
6trait Bar {
7 fn do_something(&mut self); //~ WARN method `do_something` is never used
8}
9
10struct BarImpl;
11
12impl Bar for BarImpl {
13 fn do_something(&mut self) {}
14}
15
16
17struct Foo<B: Bar>(#[allow(dead_code)] B);
18
19impl<B: Bar> Drop for Foo<B> {
20 fn drop(&mut self) {
21 unsafe {
22 DROP_RAN = true;
23 }
24 }
25}
26
27
28fn main() {
29 {
30 let _x: Foo<BarImpl> = Foo(BarImpl);
31 }
32 unsafe {
33 assert_eq!(DROP_RAN, true);
34 }
35}
tests/ui/issues/issue-15858.stderr deleted-12
......@@ -1,12 +0,0 @@
1warning: method `do_something` is never used
2 --> $DIR/issue-15858.rs:7:8
3 |
4LL | trait Bar {
5 | --- method in this trait
6LL | fn do_something(&mut self);
7 | ^^^^^^^^^^^^
8 |
9 = note: `#[warn(dead_code)]` on by default
10
11warning: 1 warning emitted
12
tests/ui/issues/issue-15896.rs deleted-15
......@@ -1,15 +0,0 @@
1// Regression test for #15896. It used to ICE rustc.
2
3fn main() {
4 enum R { REB(()) }
5 struct Tau { t: usize }
6 enum E { B(R, Tau) }
7
8 let e = E::B(R::REB(()), Tau { t: 3 });
9 let u = match e {
10 E::B(
11 Tau{t: x},
12 //~^ ERROR mismatched types
13 _) => x,
14 };
15}
tests/ui/issues/issue-15896.stderr deleted-12
......@@ -1,12 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/issue-15896.rs:11:11
3 |
4LL | let u = match e {
5 | - this expression has type `E`
6LL | E::B(
7LL | Tau{t: x},
8 | ^^^^^^^^^ expected `R`, found `Tau`
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0308`.
tests/ui/issues/issue-15965.rs deleted-7
......@@ -1,7 +0,0 @@
1fn main() {
2 return
3 { return () }
4//~^ ERROR type annotations needed [E0282]
5 ()
6 ;
7}
tests/ui/issues/issue-15965.stderr deleted-11
......@@ -1,11 +0,0 @@
1error[E0282]: type annotations needed
2 --> $DIR/issue-15965.rs:3:9
3 |
4LL | / { return () }
5LL | |
6LL | | ()
7 | |______^ cannot infer type
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0282`.
tests/ui/issues/issue-16048.rs deleted-30
......@@ -1,30 +0,0 @@
1trait NoLifetime {
2 fn get<'p, T : Test<'p>>(&self) -> T;
3 //~^ NOTE lifetimes in impl do not match this method in trait
4}
5
6trait Test<'p> {
7 fn new(buf: &'p mut [u8]) -> Self;
8}
9
10struct Foo<'a> {
11 buf: &'a mut [u8],
12}
13
14impl<'a> Test<'a> for Foo<'a> {
15 fn new(buf: &'a mut [u8]) -> Foo<'a> {
16 Foo { buf: buf }
17 }
18}
19
20impl<'a> NoLifetime for Foo<'a> {
21 fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T {
22 //~^ ERROR E0195
23 //~| NOTE lifetimes do not match method in trait
24 return *self as T;
25 //~^ ERROR non-primitive cast: `Foo<'a>` as `T`
26 //~| NOTE an `as` expression can only be used to convert between primitive types
27 }
28}
29
30fn main() {}
tests/ui/issues/issue-16048.stderr deleted-25
......@@ -1,25 +0,0 @@
1error[E0195]: lifetime parameters or bounds on method `get` do not match the trait declaration
2 --> $DIR/issue-16048.rs:21:11
3 |
4LL | fn get<'p, T : Test<'p>>(&self) -> T;
5 | ------------------ lifetimes in impl do not match this method in trait
6...
7LL | fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T {
8 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
9
10error[E0605]: non-primitive cast: `Foo<'a>` as `T`
11 --> $DIR/issue-16048.rs:24:16
12 |
13LL | return *self as T;
14 | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
15 |
16help: consider using the `From` trait instead
17 |
18LL - return *self as T;
19LL + return T::from(*self);
20 |
21
22error: aborting due to 2 previous errors
23
24Some errors have detailed explanations: E0195, E0605.
25For more information about an error, try `rustc --explain E0195`.
tests/ui/issues/issue-16149.rs deleted-11
......@@ -1,11 +0,0 @@
1extern "C" {
2 static externalValue: isize;
3}
4
5fn main() {
6 let boolValue = match 42 {
7 externalValue => true,
8 //~^ ERROR match bindings cannot shadow statics
9 _ => false,
10 };
11}
tests/ui/issues/issue-16149.stderr deleted-12
......@@ -1,12 +0,0 @@
1error[E0530]: match bindings cannot shadow statics
2 --> $DIR/issue-16149.rs:7:9
3 |
4LL | static externalValue: isize;
5 | ---------------------------- the static `externalValue` is defined here
6...
7LL | externalValue => true,
8 | ^^^^^^^^^^^^^ cannot be named the same as a static
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0530`.
tests/ui/issues/issue-16256.rs deleted-6
......@@ -1,6 +0,0 @@
1//@ run-pass
2
3fn main() {
4 let mut buf = Vec::new();
5 |c: u8| buf.push(c); //~ WARN unused closure that must be used
6}
tests/ui/issues/issue-16256.stderr deleted-11
......@@ -1,11 +0,0 @@
1warning: unused closure that must be used
2 --> $DIR/issue-16256.rs:5:5
3 |
4LL | |c: u8| buf.push(c);
5 | ^^^^^^^^^^^^^^^^^^^
6 |
7 = note: closures are lazy and do nothing unless called
8 = note: `#[warn(unused_must_use)]` on by default
9
10warning: 1 warning emitted
11
tests/ui/issues/issue-16401.rs deleted-15
......@@ -1,15 +0,0 @@
1struct Slice<T> {
2 data: *const T,
3 len: usize,
4}
5
6fn main() {
7 match () { //~ NOTE this expression has type `()`
8 Slice { data: data, len: len } => (),
9 //~^ ERROR mismatched types
10 //~| NOTE expected unit type `()`
11 //~| NOTE found struct `Slice<_>`
12 //~| NOTE expected `()`, found `Slice<_>`
13 _ => unreachable!()
14 }
15}
tests/ui/issues/issue-16401.stderr deleted-14
......@@ -1,14 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/issue-16401.rs:8:9
3 |
4LL | match () {
5 | -- this expression has type `()`
6LL | Slice { data: data, len: len } => (),
7 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Slice<_>`
8 |
9 = note: expected unit type `()`
10 found struct `Slice<_>`
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0308`.
tests/ui/issues/issue-16441.rs deleted-11
......@@ -1,11 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3
4struct Empty;
5
6// This used to cause an ICE
7#[allow(improper_ctypes_definitions)]
8extern "C" fn ice(_a: Empty) {}
9
10fn main() {
11}
tests/ui/issues/issue-16452.rs deleted-9
......@@ -1,9 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3
4fn main() {
5 if true { return }
6 match () {
7 () => { static MAGIC: usize = 0; }
8 }
9}
tests/ui/issues/issue-16492.rs deleted-67
......@@ -1,67 +0,0 @@
1//@ run-pass
2#![allow(non_snake_case)]
3
4use std::rc::Rc;
5use std::cell::Cell;
6
7struct Field {
8 number: usize,
9 state: Rc<Cell<usize>>
10}
11
12impl Field {
13 fn new(number: usize, state: Rc<Cell<usize>>) -> Field {
14 Field {
15 number: number,
16 state: state
17 }
18 }
19}
20
21impl Drop for Field {
22 fn drop(&mut self) {
23 println!("Dropping field {}", self.number);
24 assert_eq!(self.state.get(), self.number);
25 self.state.set(self.state.get()+1);
26 }
27}
28
29struct NoDropImpl {
30 _one: Field,
31 _two: Field,
32 _three: Field
33}
34
35struct HasDropImpl {
36 _one: Field,
37 _two: Field,
38 _three: Field
39}
40
41impl Drop for HasDropImpl {
42 fn drop(&mut self) {
43 println!("HasDropImpl.drop()");
44 assert_eq!(self._one.state.get(), 0);
45 self._one.state.set(1);
46 }
47}
48
49pub fn main() {
50 let state = Rc::new(Cell::new(1));
51 let noImpl = NoDropImpl {
52 _one: Field::new(1, state.clone()),
53 _two: Field::new(2, state.clone()),
54 _three: Field::new(3, state.clone())
55 };
56 drop(noImpl);
57 assert_eq!(state.get(), 4);
58
59 state.set(0);
60 let hasImpl = HasDropImpl {
61 _one: Field::new(1, state.clone()),
62 _two: Field::new(2, state.clone()),
63 _three: Field::new(3, state.clone())
64 };
65 drop(hasImpl);
66 assert_eq!(state.get(), 4);
67}
tests/ui/iterators/explicit-deref-non-deref-type-15756.rs created+16
......@@ -0,0 +1,16 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15756
2
3use std::slice::Chunks;
4use std::slice::ChunksMut;
5
6fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: ChunksMut<'a,T>)
7{
8 for
9 &mut something
10 //~^ ERROR the size for values of type
11 in arg2
12 {
13 }
14}
15
16fn main() {}
tests/ui/iterators/explicit-deref-non-deref-type-15756.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0277]: the size for values of type `[T]` cannot be known at compilation time
2 --> $DIR/explicit-deref-non-deref-type-15756.rs:9:10
3 |
4LL | &mut something
5 | ^^^^^^^^^ doesn't have a size known at compile-time
6 |
7 = help: the trait `Sized` is not implemented for `[T]`
8 = note: all local variables must have a statically known size
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0277`.
tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.rs created+24
......@@ -0,0 +1,24 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15034
2
3pub struct Lexer<'a> {
4 input: &'a str,
5}
6
7impl<'a> Lexer<'a> {
8 pub fn new(input: &'a str) -> Lexer<'a> {
9 Lexer { input: input }
10 }
11}
12
13struct Parser<'a> {
14 lexer: &'a mut Lexer<'a>,
15}
16
17impl<'a> Parser<'a> {
18 pub fn new(lexer: &'a mut Lexer) -> Parser<'a> {
19 Parser { lexer: lexer }
20 //~^ ERROR explicit lifetime required in the type of `lexer` [E0621]
21 }
22}
23
24fn main() {}
tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.stderr created+14
......@@ -0,0 +1,14 @@
1error[E0621]: explicit lifetime required in the type of `lexer`
2 --> $DIR/nondeterministic-lifetime-errors-15034.rs:19:9
3 |
4LL | Parser { lexer: lexer }
5 | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
6 |
7help: add explicit lifetime `'a` to the type of `lexer`
8 |
9LL | pub fn new(lexer: &'a mut Lexer<'a>) -> Parser<'a> {
10 | ++++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0621`.
tests/ui/lifetimes/struct-lifetime-inference-15735.rs created+19
......@@ -0,0 +1,19 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15735
2
3//@ check-pass
4#![allow(dead_code)]
5struct A<'a> {
6 a: &'a i32,
7 b: &'a i32,
8}
9
10impl <'a> A<'a> {
11 fn foo<'b>(&'b self) {
12 A {
13 a: self.a,
14 b: self.b,
15 };
16 }
17}
18
19fn main() { }
tests/ui/macros/for-loop-macro-rules-hygiene.rs created+12
......@@ -0,0 +1,12 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15189
2
3//@ run-pass
4macro_rules! third {
5 ($e:expr) => ({let x = 2; $e[x]})
6}
7
8fn main() {
9 let x = vec![10_usize,11_usize,12_usize,13_usize];
10 let t = third!(x);
11 assert_eq!(t,12_usize);
12}
tests/ui/macros/macro-hygiene-scope-15167.rs created+28
......@@ -0,0 +1,28 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15167
2
3// macro f should not be able to inject a reference to 'n'.
4
5macro_rules! f { () => (n) }
6//~^ ERROR cannot find value `n` in this scope
7//~| ERROR cannot find value `n` in this scope
8//~| ERROR cannot find value `n` in this scope
9//~| ERROR cannot find value `n` in this scope
10
11fn main() -> (){
12 for n in 0..1 {
13 println!("{}", f!());
14 }
15
16 if let Some(n) = None {
17 println!("{}", f!());
18 }
19
20 if false {
21 } else if let Some(n) = None {
22 println!("{}", f!());
23 }
24
25 while let Some(n) = None {
26 println!("{}", f!());
27 }
28}
tests/ui/macros/macro-hygiene-scope-15167.stderr created+47
......@@ -0,0 +1,47 @@
1error[E0425]: cannot find value `n` in this scope
2 --> $DIR/macro-hygiene-scope-15167.rs:5:25
3 |
4LL | macro_rules! f { () => (n) }
5 | ^ not found in this scope
6...
7LL | println!("{}", f!());
8 | ---- in this macro invocation
9 |
10 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
11
12error[E0425]: cannot find value `n` in this scope
13 --> $DIR/macro-hygiene-scope-15167.rs:5:25
14 |
15LL | macro_rules! f { () => (n) }
16 | ^ not found in this scope
17...
18LL | println!("{}", f!());
19 | ---- in this macro invocation
20 |
21 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
22
23error[E0425]: cannot find value `n` in this scope
24 --> $DIR/macro-hygiene-scope-15167.rs:5:25
25 |
26LL | macro_rules! f { () => (n) }
27 | ^ not found in this scope
28...
29LL | println!("{}", f!());
30 | ---- in this macro invocation
31 |
32 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
33
34error[E0425]: cannot find value `n` in this scope
35 --> $DIR/macro-hygiene-scope-15167.rs:5:25
36 |
37LL | macro_rules! f { () => (n) }
38 | ^ not found in this scope
39...
40LL | println!("{}", f!());
41 | ---- in this macro invocation
42 |
43 = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
44
45error: aborting due to 4 previous errors
46
47For more information about this error, try `rustc --explain E0425`.
tests/ui/moves/match-move-same-binding-15571.rs created+59
......@@ -0,0 +1,59 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15571
2
3//@ run-pass
4
5fn match_on_local() {
6 let mut foo: Option<Box<_>> = Some(Box::new(5));
7 match foo {
8 None => {},
9 Some(x) => {
10 foo = Some(x);
11 }
12 }
13 println!("'{}'", foo.unwrap());
14}
15
16fn match_on_arg(mut foo: Option<Box<i32>>) {
17 match foo {
18 None => {}
19 Some(x) => {
20 foo = Some(x);
21 }
22 }
23 println!("'{}'", foo.unwrap());
24}
25
26fn match_on_binding() {
27 match Some(Box::new(7)) {
28 mut foo => {
29 match foo {
30 None => {},
31 Some(x) => {
32 foo = Some(x);
33 }
34 }
35 println!("'{}'", foo.unwrap());
36 }
37 }
38}
39
40fn match_on_upvar() {
41 let mut foo: Option<Box<_>> = Some(Box::new(8));
42 let f = move|| {
43 match foo {
44 None => {},
45 Some(x) => {
46 foo = Some(x);
47 }
48 }
49 println!("'{}'", foo.unwrap());
50 };
51 f();
52}
53
54fn main() {
55 match_on_local();
56 match_on_arg(Some(Box::new(6)));
57 match_on_binding();
58 match_on_upvar();
59}
tests/ui/moves/use-correct-generic-args-in-borrow-suggest.rs created+13
......@@ -0,0 +1,13 @@
1//! Regression test for #145164: For normal calls, make sure the suggestion to borrow generic inputs
2//! uses the generic args from the callee's type rather than those attached to the callee's HIR
3//! node. In cases where the callee isn't an identifier expression, its HIR node won't have its
4//! generic arguments attached, which could lead to ICE when it had other generic args. In this
5//! case, the callee expression is `run.clone()`, to which `clone`'s generic arguments are attached.
6
7fn main() {
8 let value = String::new();
9 run.clone()(value, ());
10 run(value, ());
11 //~^ ERROR use of moved value: `value`
12}
13fn run<F, T: Clone>(value: T, f: F) {}
tests/ui/moves/use-correct-generic-args-in-borrow-suggest.stderr created+18
......@@ -0,0 +1,18 @@
1error[E0382]: use of moved value: `value`
2 --> $DIR/use-correct-generic-args-in-borrow-suggest.rs:10:9
3 |
4LL | let value = String::new();
5 | ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait
6LL | run.clone()(value, ());
7 | ----- value moved here
8LL | run(value, ());
9 | ^^^^^ value used here after move
10 |
11help: consider borrowing `value`
12 |
13LL | run.clone()(&value, ());
14 | +
15
16error: aborting due to 1 previous error
17
18For more information about this error, try `rustc --explain E0382`.
tests/ui/never/never-type-method-call-15207.rs created+8
......@@ -0,0 +1,8 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15207
2
3fn main() {
4 loop {
5 break.push(1) //~ ERROR no method named `push` found for type `!`
6 ;
7 }
8}
tests/ui/never/never-type-method-call-15207.stderr created+9
......@@ -0,0 +1,9 @@
1error[E0599]: no method named `push` found for type `!` in the current scope
2 --> $DIR/never-type-method-call-15207.rs:5:15
3 |
4LL | break.push(1)
5 | ^^^^ method not found in `!`
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0599`.
tests/ui/nll/issue-46589.nll.stderr+1-1
......@@ -1,5 +1,5 @@
11error[E0499]: cannot borrow `**other` as mutable more than once at a time
2 --> $DIR/issue-46589.rs:24:21
2 --> $DIR/issue-46589.rs:25:21
33 |
44LL | *other = match (*other).get_self() {
55 | -------- first mutable borrow occurs here
tests/ui/nll/issue-46589.polonius.stderr created+15
......@@ -0,0 +1,15 @@
1error[E0499]: cannot borrow `**other` as mutable more than once at a time
2 --> $DIR/issue-46589.rs:25:21
3 |
4LL | *other = match (*other).get_self() {
5 | -------- first mutable borrow occurs here
6LL | Some(s) => s,
7LL | None => (*other).new_self()
8 | ^^^^^^^^
9 | |
10 | second mutable borrow occurs here
11 | first borrow later used here
12
13error: aborting due to 1 previous error
14
15For more information about this error, try `rustc --explain E0499`.
tests/ui/nll/issue-46589.rs+6-6
......@@ -1,9 +1,10 @@
11//@ ignore-compare-mode-polonius (explicit revisions)
2//@ revisions: nll polonius_next polonius
3//@ [polonius_next] check-pass
4//@ [polonius_next] compile-flags: -Zpolonius=next
5//@ [polonius] check-pass
6//@ [polonius] compile-flags: -Zpolonius
2//@ revisions: nll polonius legacy
3//@ [nll] known-bug: #46589
4//@ [polonius] known-bug: #46589
5//@ [polonius] compile-flags: -Zpolonius=next
6//@ [legacy] check-pass
7//@ [legacy] compile-flags: -Zpolonius=legacy
78
89struct Foo;
910
......@@ -22,7 +23,6 @@ impl Foo {
2223 *other = match (*other).get_self() {
2324 Some(s) => s,
2425 None => (*other).new_self()
25 //[nll]~^ ERROR cannot borrow `**other` as mutable more than once at a time [E0499]
2626 };
2727
2828 let c = other;
tests/ui/nll/polonius/array-literal-index-oob-2024.rs created+12
......@@ -0,0 +1,12 @@
1// This test used to ICE under `-Zpolonius=next` when computing loan liveness
2// and taking kills into account during reachability traversal of the localized
3// constraint graph. Originally from another test but on edition 2024, as
4// seen in issue #135646.
5
6//@ compile-flags: -Zpolonius=next
7//@ edition: 2024
8//@ check-pass
9
10fn main() {
11 &{ [1, 2, 3][4] };
12}
tests/ui/nll/polonius/flow-sensitive-invariance.nll.stderr created+36
......@@ -0,0 +1,36 @@
1error: lifetime may not live long enough
2 --> $DIR/flow-sensitive-invariance.rs:20:17
3 |
4LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
5 | -- -- lifetime `'b` defined here
6 | |
7 | lifetime `'a` defined here
8LL | let returned_value = create_invariant();
9LL | if choice { Ok(returned_value) } else { Err(returned_value) }
10 | ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
11 |
12 = help: consider adding the following bound: `'b: 'a`
13 = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
14 = note: the struct `Invariant<'l>` is invariant over the parameter `'l`
15 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
16
17error: lifetime may not live long enough
18 --> $DIR/flow-sensitive-invariance.rs:20:45
19 |
20LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
21 | -- -- lifetime `'b` defined here
22 | |
23 | lifetime `'a` defined here
24LL | let returned_value = create_invariant();
25LL | if choice { Ok(returned_value) } else { Err(returned_value) }
26 | ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
27 |
28 = help: consider adding the following bound: `'a: 'b`
29 = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
30 = note: the struct `Invariant<'l>` is invariant over the parameter `'l`
31 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
32
33help: `'a` and `'b` must be the same: replace one with the other
34
35error: aborting due to 2 previous errors
36
tests/ui/nll/polonius/flow-sensitive-invariance.polonius.stderr created+36
......@@ -0,0 +1,36 @@
1error: lifetime may not live long enough
2 --> $DIR/flow-sensitive-invariance.rs:20:17
3 |
4LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
5 | -- -- lifetime `'b` defined here
6 | |
7 | lifetime `'a` defined here
8LL | let returned_value = create_invariant();
9LL | if choice { Ok(returned_value) } else { Err(returned_value) }
10 | ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
11 |
12 = help: consider adding the following bound: `'b: 'a`
13 = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
14 = note: the struct `Invariant<'l>` is invariant over the parameter `'l`
15 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
16
17error: lifetime may not live long enough
18 --> $DIR/flow-sensitive-invariance.rs:20:45
19 |
20LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
21 | -- -- lifetime `'b` defined here
22 | |
23 | lifetime `'a` defined here
24LL | let returned_value = create_invariant();
25LL | if choice { Ok(returned_value) } else { Err(returned_value) }
26 | ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
27 |
28 = help: consider adding the following bound: `'a: 'b`
29 = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
30 = note: the struct `Invariant<'l>` is invariant over the parameter `'l`
31 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
32
33help: `'a` and `'b` must be the same: replace one with the other
34
35error: aborting due to 2 previous errors
36
tests/ui/nll/polonius/flow-sensitive-invariance.rs created+34
......@@ -0,0 +1,34 @@
1// An example (from @steffahn) of reachability as an approximation of liveness where the polonius
2// alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation.
3
4//@ ignore-compare-mode-polonius (explicit revisions)
5//@ revisions: nll polonius legacy
6//@ [polonius] compile-flags: -Z polonius=next
7//@ [legacy] check-pass
8//@ [legacy] compile-flags: -Z polonius=legacy
9
10use std::cell::Cell;
11
12struct Invariant<'l>(Cell<&'l ()>);
13
14fn create_invariant<'l>() -> Invariant<'l> {
15 Invariant(Cell::new(&()))
16}
17
18fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
19 let returned_value = create_invariant();
20 if choice { Ok(returned_value) } else { Err(returned_value) }
21 //[nll]~^ ERROR lifetime may not live long enough
22 //[nll]~| ERROR lifetime may not live long enough
23 //[polonius]~^^^ ERROR lifetime may not live long enough
24 //[polonius]~| ERROR lifetime may not live long enough
25}
26
27fn use_it_but_its_the_same_region<'a: 'b, 'b: 'a>(
28 choice: bool,
29) -> Result<Invariant<'a>, Invariant<'b>> {
30 let returned_value = create_invariant();
31 if choice { Ok(returned_value) } else { Err(returned_value) }
32}
33
34fn main() {}
tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr+1-1
......@@ -1,5 +1,5 @@
11error[E0499]: cannot borrow `*elements` as mutable more than once at a time
2 --> $DIR/iterating-updating-cursor-issue-108704.rs:40:26
2 --> $DIR/iterating-updating-cursor-issue-108704.rs:41:26
33 |
44LL | for (idx, el) in elements.iter_mut().enumerate() {
55 | ^^^^^^^^
tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.polonius.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0499]: cannot borrow `*elements` as mutable more than once at a time
2 --> $DIR/iterating-updating-cursor-issue-108704.rs:41:26
3 |
4LL | for (idx, el) in elements.iter_mut().enumerate() {
5 | ^^^^^^^^
6 | |
7 | `*elements` was mutably borrowed here in the previous iteration of the loop
8 | first borrow used here, in later iteration of loop
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0499`.
tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs+4-3
......@@ -1,11 +1,12 @@
11#![crate_type = "lib"]
22
3// An example from #108704 of the linked-list cursor-like pattern of #46859/#48001.
3// An example from #108704 of the linked-list cursor-like pattern of #46859/#48001, where the
4// polonius alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation.
45
56//@ ignore-compare-mode-polonius (explicit revisions)
67//@ revisions: nll polonius legacy
78//@ [nll] known-bug: #108704
8//@ [polonius] check-pass
9//@ [polonius] known-bug: #108704
910//@ [polonius] compile-flags: -Z polonius=next
1011//@ [legacy] check-pass
1112//@ [legacy] compile-flags: -Z polonius=legacy
......@@ -32,7 +33,7 @@ fn merge_tree_ok(root: &mut Root, path: Vec<String>) {
3233 }
3334}
3435
35// NLLs fail here
36// NLLs and polonius alpha fail here
3637fn merge_tree_ko(root: &mut Root, path: Vec<String>) {
3738 let mut elements = &mut root.children;
3839
tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr+2-2
......@@ -1,5 +1,5 @@
11error[E0499]: cannot borrow `p.0` as mutable more than once at a time
2 --> $DIR/iterating-updating-cursor-issue-57165.rs:29:20
2 --> $DIR/iterating-updating-cursor-issue-57165.rs:30:20
33 |
44LL | while let Some(now) = p {
55 | ^^^ - first borrow used here, in later iteration of loop
......@@ -7,7 +7,7 @@ LL | while let Some(now) = p {
77 | `p.0` was mutably borrowed here in the previous iteration of the loop
88
99error[E0503]: cannot use `*p` because it was mutably borrowed
10 --> $DIR/iterating-updating-cursor-issue-57165.rs:29:27
10 --> $DIR/iterating-updating-cursor-issue-57165.rs:30:27
1111 |
1212LL | while let Some(now) = p {
1313 | --- ^
tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.polonius.stderr created+22
......@@ -0,0 +1,22 @@
1error[E0499]: cannot borrow `p.0` as mutable more than once at a time
2 --> $DIR/iterating-updating-cursor-issue-57165.rs:30:20
3 |
4LL | while let Some(now) = p {
5 | ^^^ - first borrow used here, in later iteration of loop
6 | |
7 | `p.0` was mutably borrowed here in the previous iteration of the loop
8
9error[E0503]: cannot use `*p` because it was mutably borrowed
10 --> $DIR/iterating-updating-cursor-issue-57165.rs:30:27
11 |
12LL | while let Some(now) = p {
13 | --- ^
14 | | |
15 | | use of borrowed `p.0`
16 | | borrow later used here
17 | `p.0` is borrowed here
18
19error: aborting due to 2 previous errors
20
21Some errors have detailed explanations: E0499, E0503.
22For more information about an error, try `rustc --explain E0499`.
tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs+4-3
......@@ -1,11 +1,12 @@
11#![crate_type = "lib"]
22
3// An example from #57165 of the linked-list cursor-like pattern of #46859/#48001.
3// An example from #57165 of the linked-list cursor-like pattern of #46859/#48001, where the
4// polonius alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation.
45
56//@ ignore-compare-mode-polonius (explicit revisions)
67//@ revisions: nll polonius legacy
78//@ [nll] known-bug: #57165
8//@ [polonius] check-pass
9//@ [polonius] known-bug: #57165
910//@ [polonius] compile-flags: -Z polonius=next
1011//@ [legacy] check-pass
1112//@ [legacy] compile-flags: -Z polonius=legacy
......@@ -22,7 +23,7 @@ fn no_control_flow() {
2223 }
2324}
2425
25// NLLs fail here
26// NLLs and polonius alpha fail here
2627fn conditional() {
2728 let mut b = Some(Box::new(X { next: None }));
2829 let mut p = &mut b;
tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr+1-1
......@@ -1,5 +1,5 @@
11error[E0506]: cannot assign to `*node_ref` because it is borrowed
2 --> $DIR/iterating-updating-cursor-issue-63908.rs:42:5
2 --> $DIR/iterating-updating-cursor-issue-63908.rs:43:5
33 |
44LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) {
55 | - let's call the lifetime of this reference `'1`
tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.polonius.stderr created+18
......@@ -0,0 +1,18 @@
1error[E0506]: cannot assign to `*node_ref` because it is borrowed
2 --> $DIR/iterating-updating-cursor-issue-63908.rs:43:5
3 |
4LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) {
5 | - let's call the lifetime of this reference `'1`
6LL | loop {
7LL | let next_ref = &mut node_ref.as_mut().unwrap().next;
8 | -------- `*node_ref` is borrowed here
9...
10LL | node_ref = next_ref;
11 | ------------------- assignment requires that `*node_ref` is borrowed for `'1`
12...
13LL | *node_ref = None;
14 | ^^^^^^^^^ `*node_ref` is assigned to here but it was already borrowed
15
16error: aborting due to 1 previous error
17
18For more information about this error, try `rustc --explain E0506`.
tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs+4-3
......@@ -1,11 +1,12 @@
11#![crate_type = "lib"]
22
3// An example from #63908 of the linked-list cursor-like pattern of #46859/#48001.
3// An example from #63908 of the linked-list cursor-like pattern of #46859/#48001, where the
4// polonius alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation.
45
56//@ ignore-compare-mode-polonius (explicit revisions)
67//@ revisions: nll polonius legacy
78//@ [nll] known-bug: #63908
8//@ [polonius] check-pass
9//@ [polonius] known-bug: #63908
910//@ [polonius] compile-flags: -Z polonius=next
1011//@ [legacy] check-pass
1112//@ [legacy] compile-flags: -Z polonius=legacy
......@@ -27,7 +28,7 @@ fn remove_last_node_recursive<T>(node_ref: &mut List<T>) {
2728 }
2829}
2930
30// NLLs fail here
31// NLLs and polonius alpha fail here
3132fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) {
3233 loop {
3334 let next_ref = &mut node_ref.as_mut().unwrap().next;
tests/ui/nll/polonius/iterating-updating-mutref.nll.stderr created+15
......@@ -0,0 +1,15 @@
1error[E0499]: cannot borrow `self.buf_read` as mutable more than once at a time
2 --> $DIR/iterating-updating-mutref.rs:61:23
3 |
4LL | pub fn next<'a>(&'a mut self) -> &'a str {
5 | -- lifetime `'a` defined here
6LL | loop {
7LL | let buf = self.buf_read.fill_buf();
8 | ^^^^^^^^^^^^^ `self.buf_read` was mutably borrowed here in the previous iteration of the loop
9LL | if let Some(s) = decode(buf) {
10LL | return s;
11 | - returning this value requires that `self.buf_read` is borrowed for `'a`
12
13error: aborting due to 1 previous error
14
15For more information about this error, try `rustc --explain E0499`.
tests/ui/nll/polonius/iterating-updating-mutref.rs created+87
......@@ -0,0 +1,87 @@
1// These are some examples of iterating through and updating a mutable ref, similar in spirit to the
2// linked-list-like pattern of #46859/#48001 where the polonius alpha analysis shows imprecision,
3// unlike the datalog implementation.
4//
5// They differ in that after the loans prior to the loop are either not live after the loop, or with
6// control flow and outlives relationships that are simple enough for the reachability
7// approximation. They're thus accepted by the alpha analysis, like NLLs did for the simplest cases
8// of flow-sensitivity.
9
10//@ ignore-compare-mode-polonius (explicit revisions)
11//@ revisions: nll polonius legacy
12//@ [nll] known-bug: #46859
13//@ [polonius] check-pass
14//@ [polonius] compile-flags: -Z polonius=next
15//@ [legacy] check-pass
16//@ [legacy] compile-flags: -Z polonius=legacy
17
18// The #46859 OP
19struct List<T> {
20 value: T,
21 next: Option<Box<List<T>>>,
22}
23
24fn to_refs<T>(mut list: &mut List<T>) -> Vec<&mut T> {
25 let mut result = vec![];
26 loop {
27 result.push(&mut list.value);
28 if let Some(n) = list.next.as_mut() {
29 list = n;
30 } else {
31 return result;
32 }
33 }
34}
35
36// A similar construction, where paths in the constraint graph are also clearly terminating, so it's
37// fine even for NLLs.
38fn to_refs2<T>(mut list: &mut List<T>) -> Vec<&mut T> {
39 let mut result = vec![];
40 loop {
41 result.push(&mut list.value);
42 if let Some(n) = list.next.as_mut() {
43 list = n;
44 } else {
45 break;
46 }
47 }
48
49 result
50}
51
52// Another MCVE from the same issue, but was rejected by NLLs.
53pub struct Decoder {
54 buf_read: BufRead,
55}
56
57impl Decoder {
58 // NLLs fail here
59 pub fn next<'a>(&'a mut self) -> &'a str {
60 loop {
61 let buf = self.buf_read.fill_buf();
62 if let Some(s) = decode(buf) {
63 return s;
64 }
65 // loop to get more input data
66
67 // At this point `buf` is not used anymore.
68 // With NLL I would expect the borrow to end here,
69 // such that `self.buf_read` is not borrowed anymore
70 // by the time we start the next loop iteration.
71 }
72 }
73}
74
75struct BufRead;
76
77impl BufRead {
78 fn fill_buf(&mut self) -> &[u8] {
79 unimplemented!()
80 }
81}
82
83fn decode(_: &[u8]) -> Option<&str> {
84 unimplemented!()
85}
86
87fn main() {}
tests/ui/nll/polonius/lending-iterator-sanity-checks.legacy.stderr created+28
......@@ -0,0 +1,28 @@
1error[E0499]: cannot borrow `*t` as mutable more than once at a time
2 --> $DIR/lending-iterator-sanity-checks.rs:19:19
3 |
4LL | fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> {
5 | - let's call the lifetime of this reference `'1`
6LL | let Some(i) = t.next() else { return None };
7 | - first mutable borrow occurs here
8LL | let Some(j) = t.next() else { return None };
9 | ^ second mutable borrow occurs here
10...
11LL | Some((i, j))
12 | ------------ returning this value requires that `*t` is borrowed for `'1`
13
14error[E0499]: cannot borrow `*t` as mutable more than once at a time
15 --> $DIR/lending-iterator-sanity-checks.rs:31:13
16 |
17LL | let i = t.next();
18 | - first mutable borrow occurs here
19...
20LL | let j = t.next();
21 | ^ second mutable borrow occurs here
22LL |
23LL | }
24 | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>`
25
26error: aborting due to 2 previous errors
27
28For more information about this error, try `rustc --explain E0499`.
tests/ui/nll/polonius/lending-iterator-sanity-checks.nll.stderr created+28
......@@ -0,0 +1,28 @@
1error[E0499]: cannot borrow `*t` as mutable more than once at a time
2 --> $DIR/lending-iterator-sanity-checks.rs:19:19
3 |
4LL | fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> {
5 | - let's call the lifetime of this reference `'1`
6LL | let Some(i) = t.next() else { return None };
7 | - first mutable borrow occurs here
8LL | let Some(j) = t.next() else { return None };
9 | ^ second mutable borrow occurs here
10...
11LL | Some((i, j))
12 | ------------ returning this value requires that `*t` is borrowed for `'1`
13
14error[E0499]: cannot borrow `*t` as mutable more than once at a time
15 --> $DIR/lending-iterator-sanity-checks.rs:31:13
16 |
17LL | let i = t.next();
18 | - first mutable borrow occurs here
19...
20LL | let j = t.next();
21 | ^ second mutable borrow occurs here
22LL |
23LL | }
24 | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>`
25
26error: aborting due to 2 previous errors
27
28For more information about this error, try `rustc --explain E0499`.
tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr created+26
......@@ -0,0 +1,26 @@
1error[E0499]: cannot borrow `*t` as mutable more than once at a time
2 --> $DIR/lending-iterator-sanity-checks.rs:19:19
3 |
4LL | let Some(i) = t.next() else { return None };
5 | - first mutable borrow occurs here
6LL | let Some(j) = t.next() else { return None };
7 | ^ second mutable borrow occurs here
8...
9LL | }
10 | - first borrow might be used here, when `i` is dropped and runs the destructor for type `<T as LendingIterator>::Item<'_>`
11
12error[E0499]: cannot borrow `*t` as mutable more than once at a time
13 --> $DIR/lending-iterator-sanity-checks.rs:31:13
14 |
15LL | let i = t.next();
16 | - first mutable borrow occurs here
17...
18LL | let j = t.next();
19 | ^ second mutable borrow occurs here
20LL |
21LL | }
22 | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>`
23
24error: aborting due to 2 previous errors
25
26For more information about this error, try `rustc --explain E0499`.
tests/ui/nll/polonius/lending-iterator-sanity-checks.rs created+71
......@@ -0,0 +1,71 @@
1// Some sanity checks for lending iterators with GATs. This is just some non-regression tests
2// ensuring the polonius alpha analysis, the datalog implementation, and NLLs agree in these common
3// cases of overlapping yielded items.
4
5//@ ignore-compare-mode-polonius (explicit revisions)
6//@ revisions: nll polonius legacy
7//@ [polonius] compile-flags: -Z polonius=next
8//@ [legacy] compile-flags: -Z polonius=legacy
9
10trait LendingIterator {
11 type Item<'a>
12 where
13 Self: 'a;
14 fn next(&mut self) -> Option<Self::Item<'_>>;
15}
16
17fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> {
18 let Some(i) = t.next() else { return None };
19 let Some(j) = t.next() else { return None };
20 //~^ ERROR cannot borrow `*t` as mutable more than once at a time
21
22 // `i` is obviously still (use-)live here, but we called `next` again to get `j`.
23 Some((i, j))
24}
25
26fn drop_live<T: LendingIterator>(t: &mut T) {
27 let i = t.next();
28
29 // Now `i` is use-dead here, but we don't know if the iterator items have a `Drop` impl, so it's
30 // still drop-live.
31 let j = t.next();
32 //~^ ERROR cannot borrow `*t` as mutable more than once at a time
33}
34
35// But we can still manually serialize the lifetimes with scopes (or preventing the destructor from
36// being called), so they're not overlapping.
37fn manually_non_overlapping<T: LendingIterator>(t: &mut T) {
38 {
39 let i = t.next();
40 }
41
42 let j = t.next(); // i is dead
43
44 drop(j);
45 let k = t.next(); // j is dead
46
47 let k = std::mem::ManuallyDrop::new(k);
48 let l = t.next(); // we told the compiler that k is not drop-live
49}
50
51// The cfg below is because there's a diagnostic ICE trying to explain the source of the error when
52// using the datalog implementation. We're not fixing *that*, outside of removing the implementation
53// in the future.
54#[cfg(not(legacy))] // FIXME: remove this cfg when removing the datalog implementation
55fn items_have_no_borrows<T: LendingIterator>(t: &mut T)
56where
57 for<'a> T::Item<'a>: 'static,
58{
59 let i = t.next();
60 let j = t.next();
61}
62
63fn items_are_copy<T: LendingIterator>(t: &mut T)
64where
65 for<'a> T::Item<'a>: Copy,
66{
67 let i = t.next();
68 let j = t.next();
69}
70
71fn main() {}
tests/ui/parser/generics-rangle-eq-15043.rs created+15
......@@ -0,0 +1,15 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15043
2
3//@ run-pass
4
5#![allow(warnings)]
6
7struct S<T>(T);
8
9static s1: S<S<usize>>=S(S(0));
10static s2: S<usize>=S(0);
11
12fn main() {
13 let foo: S<S<usize>>=S(S(0));
14 let foo: S<usize>=S(0);
15}
tests/ui/pattern/enum-struct-pattern-mismatch-15896.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15896
2
3// Regression test for #15896. It used to ICE rustc.
4
5fn main() {
6 enum R { REB(()) }
7 struct Tau { t: usize }
8 enum E { B(R, Tau) }
9
10 let e = E::B(R::REB(()), Tau { t: 3 });
11 let u = match e {
12 E::B(
13 Tau{t: x},
14 //~^ ERROR mismatched types
15 _) => x,
16 };
17}
tests/ui/pattern/enum-struct-pattern-mismatch-15896.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0308]: mismatched types
2 --> $DIR/enum-struct-pattern-mismatch-15896.rs:13:11
3 |
4LL | let u = match e {
5 | - this expression has type `E`
6LL | E::B(
7LL | Tau{t: x},
8 | ^^^^^^^^^ expected `R`, found `Tau`
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0308`.
tests/ui/pattern/refutable-pattern-for-loop-15381.rs created+12
......@@ -0,0 +1,12 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15381
2
3fn main() {
4 let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];
5
6 for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
7 //~^ ERROR refutable pattern in `for` loop binding
8 //~| NOTE patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
9 //~| NOTE the matched value is of type `&[u8]`
10 println!("y={}", y);
11 }
12}
tests/ui/pattern/refutable-pattern-for-loop-15381.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0005]: refutable pattern in `for` loop binding
2 --> $DIR/refutable-pattern-for-loop-15381.rs:6:9
3 |
4LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
5 | ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
6 |
7 = note: the matched value is of type `&[u8]`
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0005`.
tests/ui/pattern/slice-pattern-recursion-15104.rs created+15
......@@ -0,0 +1,15 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15104
2
3//@ run-pass
4
5fn main() {
6 assert_eq!(count_members(&[1, 2, 3, 4]), 4);
7}
8
9fn count_members(v: &[usize]) -> usize {
10 match *v {
11 [] => 0,
12 [_] => 1,
13 [_, ref xs @ ..] => 1 + count_members(xs)
14 }
15}
tests/ui/pattern/static-binding-shadow-16149.rs created+13
......@@ -0,0 +1,13 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16149
2
3extern "C" {
4 static externalValue: isize;
5}
6
7fn main() {
8 let boolValue = match 42 {
9 externalValue => true,
10 //~^ ERROR match bindings cannot shadow statics
11 _ => false,
12 };
13}
tests/ui/pattern/static-binding-shadow-16149.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0530]: match bindings cannot shadow statics
2 --> $DIR/static-binding-shadow-16149.rs:9:9
3 |
4LL | static externalValue: isize;
5 | ---------------------------- the static `externalValue` is defined here
6...
7LL | externalValue => true,
8 | ^^^^^^^^^^^^^ cannot be named the same as a static
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0530`.
tests/ui/pattern/struct-field-duplicate-binding-15260.rs created+27
......@@ -0,0 +1,27 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15260
2
3struct Foo {
4 a: usize,
5}
6
7fn main() {
8 let Foo {
9 a: _,
10 a: _
11 //~^ ERROR field `a` bound multiple times in the pattern
12 } = Foo { a: 29 };
13
14 let Foo {
15 a,
16 a: _
17 //~^ ERROR field `a` bound multiple times in the pattern
18 } = Foo { a: 29 };
19
20 let Foo {
21 a,
22 a: _,
23 //~^ ERROR field `a` bound multiple times in the pattern
24 a: x
25 //~^ ERROR field `a` bound multiple times in the pattern
26 } = Foo { a: 29 };
27}
tests/ui/pattern/struct-field-duplicate-binding-15260.stderr created+36
......@@ -0,0 +1,36 @@
1error[E0025]: field `a` bound multiple times in the pattern
2 --> $DIR/struct-field-duplicate-binding-15260.rs:10:9
3 |
4LL | a: _,
5 | ---- first use of `a`
6LL | a: _
7 | ^^^^ multiple uses of `a` in pattern
8
9error[E0025]: field `a` bound multiple times in the pattern
10 --> $DIR/struct-field-duplicate-binding-15260.rs:16:9
11 |
12LL | a,
13 | - first use of `a`
14LL | a: _
15 | ^^^^ multiple uses of `a` in pattern
16
17error[E0025]: field `a` bound multiple times in the pattern
18 --> $DIR/struct-field-duplicate-binding-15260.rs:22:9
19 |
20LL | a,
21 | - first use of `a`
22LL | a: _,
23 | ^^^^ multiple uses of `a` in pattern
24
25error[E0025]: field `a` bound multiple times in the pattern
26 --> $DIR/struct-field-duplicate-binding-15260.rs:24:9
27 |
28LL | a,
29 | - first use of `a`
30...
31LL | a: x
32 | ^^^^ multiple uses of `a` in pattern
33
34error: aborting due to 4 previous errors
35
36For more information about this error, try `rustc --explain E0025`.
tests/ui/pattern/tuple-enum-match-15129.rs created+26
......@@ -0,0 +1,26 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15129
2
3//@ run-pass
4
5pub enum T {
6 T1(()),
7 T2(()),
8}
9
10pub enum V {
11 V1(isize),
12 V2(bool),
13}
14
15fn foo(x: (T, V)) -> String {
16 match x {
17 (T::T1(()), V::V1(i)) => format!("T1(()), V1({})", i),
18 (T::T2(()), V::V2(b)) => format!("T2(()), V2({})", b),
19 _ => String::new(),
20 }
21}
22
23fn main() {
24 assert_eq!(foo((T::T1(()), V::V1(99))), "T1(()), V1(99)".to_string());
25 assert_eq!(foo((T::T2(()), V::V2(true))), "T2(()), V2(true)".to_string());
26}
tests/ui/pattern/unit-type-struct-pattern-mismatch-16401.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16401
2
3struct Slice<T> {
4 data: *const T,
5 len: usize,
6}
7
8fn main() {
9 match () { //~ NOTE this expression has type `()`
10 Slice { data: data, len: len } => (),
11 //~^ ERROR mismatched types
12 //~| NOTE expected unit type `()`
13 //~| NOTE found struct `Slice<_>`
14 //~| NOTE expected `()`, found `Slice<_>`
15 _ => unreachable!()
16 }
17}
tests/ui/pattern/unit-type-struct-pattern-mismatch-16401.stderr created+14
......@@ -0,0 +1,14 @@
1error[E0308]: mismatched types
2 --> $DIR/unit-type-struct-pattern-mismatch-16401.rs:10:9
3 |
4LL | match () {
5 | -- this expression has type `()`
6LL | Slice { data: data, len: len } => (),
7 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Slice<_>`
8 |
9 = note: expected unit type `()`
10 found struct `Slice<_>`
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0308`.
tests/ui/statics/conditional-static-declaration-16010.rs created+11
......@@ -0,0 +1,11 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16010
2
3//@ run-pass
4#![allow(dead_code)]
5
6fn main() {
7 if true { return }
8 match () {
9 () => { static MAGIC: usize = 0; }
10 }
11}
tests/ui/traits/fn-type-trait-impl-15444.rs created+24
......@@ -0,0 +1,24 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15444
2
3//@ run-pass
4
5trait MyTrait {
6 fn foo(&self);
7}
8
9impl<A, B, C> MyTrait for fn(A, B) -> C {
10 fn foo(&self) {}
11}
12
13fn bar<T: MyTrait>(t: &T) {
14 t.foo()
15}
16
17fn thing(a: isize, b: isize) -> isize {
18 a + b
19}
20
21fn main() {
22 let thing: fn(isize, isize) -> isize = thing; // coerce to fn type
23 bar(&thing);
24}
tests/ui/traits/index-trait-multiple-impls-15734.rs created+61
......@@ -0,0 +1,61 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15734
2
3//@ run-pass
4//@ revisions: current next
5//@ ignore-compare-mode-next-solver (explicit revisions)
6//@[next] compile-flags: -Znext-solver
7
8use std::ops::Index;
9
10struct Mat<T> { data: Vec<T>, cols: usize, }
11
12impl<T> Mat<T> {
13 fn new(data: Vec<T>, cols: usize) -> Mat<T> {
14 Mat { data: data, cols: cols }
15 }
16 fn row<'a>(&'a self, row: usize) -> Row<&'a Mat<T>> {
17 Row { mat: self, row: row, }
18 }
19}
20
21impl<T> Index<(usize, usize)> for Mat<T> {
22 type Output = T;
23
24 fn index<'a>(&'a self, (row, col): (usize, usize)) -> &'a T {
25 &self.data[row * self.cols + col]
26 }
27}
28
29impl<'a, T> Index<(usize, usize)> for &'a Mat<T> {
30 type Output = T;
31
32 fn index<'b>(&'b self, index: (usize, usize)) -> &'b T {
33 (*self).index(index)
34 }
35}
36
37struct Row<M> { mat: M, row: usize, }
38
39impl<T, M: Index<(usize, usize), Output=T>> Index<usize> for Row<M> {
40 type Output = T;
41
42 fn index<'a>(&'a self, col: usize) -> &'a T {
43 &self.mat[(self.row, col)]
44 }
45}
46
47fn main() {
48 let m = Mat::new(vec![1, 2, 3, 4, 5, 6], 3);
49 let r = m.row(1);
50
51 assert_eq!(r.index(2), &6);
52 assert_eq!(r[2], 6);
53 assert_eq!(r[2], 6);
54 assert_eq!(6, r[2]);
55
56 let e = r[2];
57 assert_eq!(e, 6);
58
59 let e: usize = r[2];
60 assert_eq!(e, 6);
61}
tests/ui/traits/lifetime-mismatch-trait-impl-16048.rs created+32
......@@ -0,0 +1,32 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16048
2
3trait NoLifetime {
4 fn get<'p, T : Test<'p>>(&self) -> T;
5 //~^ NOTE lifetimes in impl do not match this method in trait
6}
7
8trait Test<'p> {
9 fn new(buf: &'p mut [u8]) -> Self;
10}
11
12struct Foo<'a> {
13 buf: &'a mut [u8],
14}
15
16impl<'a> Test<'a> for Foo<'a> {
17 fn new(buf: &'a mut [u8]) -> Foo<'a> {
18 Foo { buf: buf }
19 }
20}
21
22impl<'a> NoLifetime for Foo<'a> {
23 fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T {
24 //~^ ERROR E0195
25 //~| NOTE lifetimes do not match method in trait
26 return *self as T;
27 //~^ ERROR non-primitive cast: `Foo<'a>` as `T`
28 //~| NOTE an `as` expression can only be used to convert between primitive types
29 }
30}
31
32fn main() {}
tests/ui/traits/lifetime-mismatch-trait-impl-16048.stderr created+25
......@@ -0,0 +1,25 @@
1error[E0195]: lifetime parameters or bounds on method `get` do not match the trait declaration
2 --> $DIR/lifetime-mismatch-trait-impl-16048.rs:23:11
3 |
4LL | fn get<'p, T : Test<'p>>(&self) -> T;
5 | ------------------ lifetimes in impl do not match this method in trait
6...
7LL | fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T {
8 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
9
10error[E0605]: non-primitive cast: `Foo<'a>` as `T`
11 --> $DIR/lifetime-mismatch-trait-impl-16048.rs:26:16
12 |
13LL | return *self as T;
14 | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
15 |
16help: consider using the `From` trait instead
17 |
18LL - return *self as T;
19LL + return T::from(*self);
20 |
21
22error: aborting due to 2 previous errors
23
24Some errors have detailed explanations: E0195, E0605.
25For more information about an error, try `rustc --explain E0195`.
tests/ui/wf/hir-wf-check-erase-regions.nll.stderr created+49
......@@ -0,0 +1,49 @@
1error[E0277]: `&'a T` is not an iterator
2 --> $DIR/hir-wf-check-erase-regions.rs:11:21
3 |
4LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'a T` is not an iterator
6 |
7 = help: the trait `Iterator` is not implemented for `&'a T`
8 = help: the trait `Iterator` is implemented for `&mut I`
9 = note: required for `Flatten<std::slice::Iter<'a, T>>` to implement `Iterator`
10note: required by a bound in `std::iter::IntoIterator::IntoIter`
11 --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
12
13error[E0277]: `&'a T` is not an iterator
14 --> $DIR/hir-wf-check-erase-regions.rs:11:5
15 |
16LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
17 | ^^^^^^^^^^^^^ `&'a T` is not an iterator
18 |
19 = help: the trait `Iterator` is not implemented for `&'a T`
20 = help: the trait `Iterator` is implemented for `&mut I`
21 = note: required for `&'a T` to implement `IntoIterator`
22note: required by a bound in `Flatten`
23 --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
24
25error[E0277]: `&'a T` is not an iterator
26 --> $DIR/hir-wf-check-erase-regions.rs:15:27
27 |
28LL | fn into_iter(self) -> Self::IntoIter {
29 | ^^^^^^^^^^^^^^ `&'a T` is not an iterator
30 |
31 = help: the trait `Iterator` is not implemented for `&'a T`
32 = help: the trait `Iterator` is implemented for `&mut I`
33 = note: required for `&'a T` to implement `IntoIterator`
34note: required by a bound in `Flatten`
35 --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
36
37error[E0277]: `&T` is not an iterator
38 --> $DIR/hir-wf-check-erase-regions.rs:15:27
39 |
40LL | fn into_iter(self) -> Self::IntoIter {
41 | ^^^^^^^^^^^^^^ `&T` is not an iterator
42 |
43 = help: the trait `Iterator` is not implemented for `&T`
44 = help: the trait `Iterator` is implemented for `&mut I`
45 = note: required for `&T` to implement `IntoIterator`
46
47error: aborting due to 4 previous errors
48
49For more information about this error, try `rustc --explain E0277`.
tests/ui/wf/hir-wf-check-erase-regions.polonius.stderr created+39
......@@ -0,0 +1,39 @@
1error[E0277]: `&'a T` is not an iterator
2 --> $DIR/hir-wf-check-erase-regions.rs:11:21
3 |
4LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'a T` is not an iterator
6 |
7 = help: the trait `Iterator` is not implemented for `&'a T`
8 = help: the trait `Iterator` is implemented for `&mut I`
9 = note: required for `Flatten<std::slice::Iter<'a, T>>` to implement `Iterator`
10note: required by a bound in `std::iter::IntoIterator::IntoIter`
11 --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
12
13error[E0277]: `&'a T` is not an iterator
14 --> $DIR/hir-wf-check-erase-regions.rs:11:5
15 |
16LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
17 | ^^^^^^^^^^^^^ `&'a T` is not an iterator
18 |
19 = help: the trait `Iterator` is not implemented for `&'a T`
20 = help: the trait `Iterator` is implemented for `&mut I`
21 = note: required for `&'a T` to implement `IntoIterator`
22note: required by a bound in `Flatten`
23 --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
24
25error[E0277]: `&'a T` is not an iterator
26 --> $DIR/hir-wf-check-erase-regions.rs:15:27
27 |
28LL | fn into_iter(self) -> Self::IntoIter {
29 | ^^^^^^^^^^^^^^ `&'a T` is not an iterator
30 |
31 = help: the trait `Iterator` is not implemented for `&'a T`
32 = help: the trait `Iterator` is implemented for `&mut I`
33 = note: required for `&'a T` to implement `IntoIterator`
34note: required by a bound in `Flatten`
35 --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
36
37error: aborting due to 3 previous errors
38
39For more information about this error, try `rustc --explain E0277`.
tests/ui/wf/hir-wf-check-erase-regions.rs+5-1
......@@ -1,6 +1,10 @@
11// Regression test for #87549.
22//@ incremental
33
4//@ ignore-compare-mode-polonius (explicit revisions)
5//@ revisions: nll polonius
6//@ [polonius] compile-flags: -Zpolonius=next
7
48pub struct Table<T, const N: usize>([Option<T>; N]);
59
610impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
......@@ -10,7 +14,7 @@ impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
1014
1115 fn into_iter(self) -> Self::IntoIter {
1216 //~^ ERROR `&'a T` is not an iterator
13 //~| ERROR `&T` is not an iterator
17 //[nll]~| ERROR `&T` is not an iterator
1418 unimplemented!()
1519 }
1620}
tests/ui/wf/hir-wf-check-erase-regions.stderr deleted-49
......@@ -1,49 +0,0 @@
1error[E0277]: `&'a T` is not an iterator
2 --> $DIR/hir-wf-check-erase-regions.rs:7:21
3 |
4LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'a T` is not an iterator
6 |
7 = help: the trait `Iterator` is not implemented for `&'a T`
8 = help: the trait `Iterator` is implemented for `&mut I`
9 = note: required for `Flatten<std::slice::Iter<'a, T>>` to implement `Iterator`
10note: required by a bound in `std::iter::IntoIterator::IntoIter`
11 --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
12
13error[E0277]: `&'a T` is not an iterator
14 --> $DIR/hir-wf-check-erase-regions.rs:7:5
15 |
16LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
17 | ^^^^^^^^^^^^^ `&'a T` is not an iterator
18 |
19 = help: the trait `Iterator` is not implemented for `&'a T`
20 = help: the trait `Iterator` is implemented for `&mut I`
21 = note: required for `&'a T` to implement `IntoIterator`
22note: required by a bound in `Flatten`
23 --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
24
25error[E0277]: `&'a T` is not an iterator
26 --> $DIR/hir-wf-check-erase-regions.rs:11:27
27 |
28LL | fn into_iter(self) -> Self::IntoIter {
29 | ^^^^^^^^^^^^^^ `&'a T` is not an iterator
30 |
31 = help: the trait `Iterator` is not implemented for `&'a T`
32 = help: the trait `Iterator` is implemented for `&mut I`
33 = note: required for `&'a T` to implement `IntoIterator`
34note: required by a bound in `Flatten`
35 --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
36
37error[E0277]: `&T` is not an iterator
38 --> $DIR/hir-wf-check-erase-regions.rs:11:27
39 |
40LL | fn into_iter(self) -> Self::IntoIter {
41 | ^^^^^^^^^^^^^^ `&T` is not an iterator
42 |
43 = help: the trait `Iterator` is not implemented for `&T`
44 = help: the trait `Iterator` is implemented for `&mut I`
45 = note: required for `&T` to implement `IntoIterator`
46
47error: aborting due to 4 previous errors
48
49For more information about this error, try `rustc --explain E0277`.
triagebot.toml+1-1
......@@ -1573,7 +1573,7 @@ changelog-branch = "master"
15731573[note]
15741574
15751575[behind-upstream]
1576days-threshold = 14
1576days-threshold = 28
15771577
15781578# Canonicalize issue numbers to avoid closing the wrong issue
15791579# when commits are included in subtrees, as well as warning links in commits.