| author | bors <bors@rust-lang.org> 2025-08-10 14:17:41 UTC |
| committer | bors <bors@rust-lang.org> 2025-08-10 14:17:41 UTC |
| log | 18eeac04fc5c2a4c4a8020dbdf1c652077ad0e4e |
| tree | 3bb0db94131d71006af1bfd0151bb9d530cf1315 |
| parent | 7f7b8ef27d86c865a7ab20c7c42f50811c6a914d |
| parent | 934cb10f1b21be3a855951fb9b1f38094946aac8 |
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: rollup191 files changed, 2532 insertions(+), 1681 deletions(-)
.github/ISSUE_TEMPLATE/documentation.yaml+6-6| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | name: Documentation problem |
| 2 | description: Create a report for a documentation problem. | |
| 2 | description: Report an issue with documentation content. | |
| 3 | 3 | labels: ["A-docs"] |
| 4 | 4 | body: |
| 5 | 5 | - type: markdown |
| ... | ... | @@ -19,20 +19,20 @@ body: |
| 19 | 19 | - [The Rustonomicon](https://github.com/rust-lang/nomicon/issues) |
| 20 | 20 | - [The Embedded Book](https://github.com/rust-embedded/book/issues) |
| 21 | 21 | |
| 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. | |
| 23 | 23 | |
| 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. | |
| 25 | 25 | |
| 26 | 26 | - type: textarea |
| 27 | 27 | id: location |
| 28 | 28 | attributes: |
| 29 | label: Location | |
| 29 | label: Location (URL) | |
| 30 | 30 | validations: |
| 31 | required: true | |
| 31 | required: true | |
| 32 | 32 | |
| 33 | 33 | - type: textarea |
| 34 | 34 | id: summary |
| 35 | 35 | attributes: |
| 36 | 36 | label: Summary |
| 37 | 37 | 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> { |
| 48 | 48 | | asm::InlineAsmArch::Arm64EC |
| 49 | 49 | | asm::InlineAsmArch::RiscV32 |
| 50 | 50 | | asm::InlineAsmArch::RiscV64 |
| 51 | | asm::InlineAsmArch::LoongArch32 | |
| 51 | 52 | | asm::InlineAsmArch::LoongArch64 |
| 52 | 53 | | asm::InlineAsmArch::S390x |
| 53 | 54 | ); |
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs+22-7| ... | ... | @@ -410,18 +410,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 410 | 410 | } |
| 411 | 411 | let typeck = self.infcx.tcx.typeck(self.mir_def_id()); |
| 412 | 412 | 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 | |
| 414 | 414 | && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind |
| 415 | 415 | { |
| 416 | 416 | 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) | |
| 418 | 418 | } else if let hir::Node::Expr(parent_expr) = parent |
| 419 | 419 | && let hir::ExprKind::Call(call, args) = parent_expr.kind |
| 420 | 420 | && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind() |
| 421 | 421 | { |
| 422 | (Some(*def_id), Some(call.hir_id), args, 0) | |
| 422 | (Some(*def_id), args, 0) | |
| 423 | 423 | } else { |
| 424 | (None, None, &[][..], 0) | |
| 424 | (None, &[][..], 0) | |
| 425 | 425 | }; |
| 426 | 426 | let ty = place.ty(self.body, self.infcx.tcx).ty; |
| 427 | 427 | |
| ... | ... | @@ -459,11 +459,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 459 | 459 | // If the moved place is used generically by the callee and a reference to it |
| 460 | 460 | // would still satisfy any bounds on its type, suggest borrowing. |
| 461 | 461 | 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 | |
| 463 | 463 | && let Some(ref_mutability) = self.suggest_borrow_generic_arg( |
| 464 | 464 | err, |
| 465 | typeck, | |
| 466 | call_expr, | |
| 465 | 467 | def_id, |
| 466 | generic_args, | |
| 467 | 468 | param, |
| 468 | 469 | moved_place, |
| 469 | 470 | pos + offset, |
| ... | ... | @@ -627,8 +628,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 627 | 628 | fn suggest_borrow_generic_arg( |
| 628 | 629 | &self, |
| 629 | 630 | err: &mut Diag<'_>, |
| 631 | typeck: &ty::TypeckResults<'tcx>, | |
| 632 | call_expr: &hir::Expr<'tcx>, | |
| 630 | 633 | callee_did: DefId, |
| 631 | generic_args: ty::GenericArgsRef<'tcx>, | |
| 632 | 634 | param: ty::ParamTy, |
| 633 | 635 | moved_place: PlaceRef<'tcx>, |
| 634 | 636 | moved_arg_pos: usize, |
| ... | ... | @@ -639,6 +641,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 639 | 641 | let sig = tcx.fn_sig(callee_did).instantiate_identity().skip_binder(); |
| 640 | 642 | let clauses = tcx.predicates_of(callee_did); |
| 641 | 643 | |
| 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 | ||
| 642 | 657 | // First, is there at least one method on one of `param`'s trait bounds? |
| 643 | 658 | // This keeps us from suggesting borrowing the argument to `mem::drop`, e.g. |
| 644 | 659 | 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; |
| 7 | 7 | /// |
| 8 | 8 | /// This models two sources of constraints: |
| 9 | 9 | /// - 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. | |
| 13 | 11 | /// - constraints that traverse the CFG via the same region, `a@p: a@q`, where `p` is a predecessor |
| 14 | 12 | /// of `q`. These depend on the liveness of the regions at these points, as well as their |
| 15 | 13 | /// variance. |
compiler/rustc_borrowck/src/polonius/liveness_constraints.rs+2-10| ... | ... | @@ -105,22 +105,14 @@ fn propagate_loans_between_points( |
| 105 | 105 | }); |
| 106 | 106 | } |
| 107 | 107 | |
| 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 | }; | |
| 112 | 108 | let Some(next_live_regions) = live_regions.row(next_point) else { |
| 113 | 109 | // There are no constraints to add: there are no live regions at the next point. |
| 114 | 110 | return; |
| 115 | 111 | }; |
| 116 | 112 | |
| 117 | 113 | 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. | |
| 124 | 116 | if let Some(&direction) = live_region_variances.get(&region) { |
| 125 | 117 | add_liveness_constraint( |
| 126 | 118 | region, |
compiler/rustc_borrowck/src/polonius/loan_liveness.rs+22-169| ... | ... | @@ -1,27 +1,18 @@ |
| 1 | use std::collections::{BTreeMap, BTreeSet}; | |
| 2 | ||
| 3 | 1 | use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; |
| 4 | use rustc_middle::mir::visit::Visitor; | |
| 5 | use rustc_middle::mir::{ | |
| 6 | Body, Local, Location, Place, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, | |
| 7 | }; | |
| 8 | use rustc_middle::ty::{RegionVid, TyCtxt}; | |
| 2 | use rustc_middle::ty::RegionVid; | |
| 9 | 3 | use rustc_mir_dataflow::points::PointIndex; |
| 10 | 4 | |
| 11 | 5 | use super::{LiveLoans, LocalizedOutlivesConstraintSet}; |
| 6 | use crate::BorrowSet; | |
| 12 | 7 | use crate::constraints::OutlivesConstraint; |
| 13 | use crate::dataflow::BorrowIndex; | |
| 14 | 8 | use crate::region_infer::values::LivenessValues; |
| 15 | 9 | use crate::type_check::Locations; |
| 16 | use crate::{BorrowSet, PlaceConflictBias, places_conflict}; | |
| 17 | 10 | |
| 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 | |
| 19 | 12 | /// traversing the full graph of constraints that combines: |
| 20 | 13 | /// - the localized constraints (the physical edges), |
| 21 | 14 | /// - with the constraints that hold at all points (the logical edges). |
| 22 | 15 | pub(super) fn compute_loan_liveness<'tcx>( |
| 23 | tcx: TyCtxt<'tcx>, | |
| 24 | body: &Body<'tcx>, | |
| 25 | 16 | liveness: &LivenessValues, |
| 26 | 17 | outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>, |
| 27 | 18 | borrow_set: &BorrowSet<'tcx>, |
| ... | ... | @@ -29,11 +20,6 @@ pub(super) fn compute_loan_liveness<'tcx>( |
| 29 | 20 | ) -> LiveLoans { |
| 30 | 21 | let mut live_loans = LiveLoans::new(borrow_set.len()); |
| 31 | 22 | |
| 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 | ||
| 37 | 23 | // Create the full graph with the physical edges we've localized earlier, and the logical edges |
| 38 | 24 | // of constraints that hold at all points. |
| 39 | 25 | let logical_constraints = |
| ... | ... | @@ -59,15 +45,15 @@ pub(super) fn compute_loan_liveness<'tcx>( |
| 59 | 45 | continue; |
| 60 | 46 | } |
| 61 | 47 | |
| 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. | |
| 71 | 57 | // |
| 72 | 58 | // Kills should prevent a loan from reaching its successor points in the CFG, but not |
| 73 | 59 | // 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>( |
| 92 | 78 | // two-step traversal described above: only kills encountered on exit via a backward |
| 93 | 79 | // edge are ignored. |
| 94 | 80 | // |
| 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. | |
| 109 | 86 | // |
| 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. | |
| 113 | 89 | |
| 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 | } | |
| 119 | 93 | |
| 120 | 94 | 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 | } | |
| 129 | 95 | stack.push(succ); |
| 130 | 96 | } |
| 131 | 97 | } |
| ... | ... | @@ -192,116 +158,3 @@ impl LocalizedConstraintGraph { |
| 192 | 158 | physical_edges.chain(materialized_edges) |
| 193 | 159 | } |
| 194 | 160 | } |
| 195 | ||
| 196 | /// Traverses the MIR and collects kills. | |
| 197 | fn 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 | ||
| 209 | struct 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. | |
| 220 | impl<'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 | ||
| 282 | impl<'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 { |
| 146 | 146 | /// - converting NLL typeck constraints to be localized |
| 147 | 147 | /// - encoding liveness constraints |
| 148 | 148 | /// |
| 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. | |
| 151 | 151 | /// |
| 152 | 152 | /// The constraint data will be used to compute errors and diagnostics. |
| 153 | 153 | pub(crate) fn compute_loan_liveness<'tcx>( |
| ... | ... | @@ -182,8 +182,6 @@ impl PoloniusContext { |
| 182 | 182 | // Now that we have a complete graph, we can compute reachability to trace the liveness of |
| 183 | 183 | // loans for the next step in the chain, the NLL loan scope and active loans computations. |
| 184 | 184 | let live_loans = compute_loan_liveness( |
| 185 | tcx, | |
| 186 | body, | |
| 187 | 185 | regioncx.liveness_constraints(), |
| 188 | 186 | regioncx.outlives_constraints(), |
| 189 | 187 | borrow_set, |
compiler/rustc_borrowck/src/polonius/typeck_constraints.rs+4-15| ... | ... | @@ -47,9 +47,7 @@ pub(super) fn convert_typeck_constraints<'tcx>( |
| 47 | 47 | tcx, |
| 48 | 48 | body, |
| 49 | 49 | stmt, |
| 50 | liveness, | |
| 51 | 50 | &outlives_constraint, |
| 52 | location, | |
| 53 | 51 | point, |
| 54 | 52 | universal_regions, |
| 55 | 53 | ) |
| ... | ... | @@ -78,9 +76,7 @@ fn localize_statement_constraint<'tcx>( |
| 78 | 76 | tcx: TyCtxt<'tcx>, |
| 79 | 77 | body: &Body<'tcx>, |
| 80 | 78 | stmt: &Statement<'tcx>, |
| 81 | liveness: &LivenessValues, | |
| 82 | 79 | outlives_constraint: &OutlivesConstraint<'tcx>, |
| 83 | current_location: Location, | |
| 84 | 80 | current_point: PointIndex, |
| 85 | 81 | universal_regions: &UniversalRegions<'tcx>, |
| 86 | 82 | ) -> LocalizedOutlivesConstraint { |
| ... | ... | @@ -98,8 +94,8 @@ fn localize_statement_constraint<'tcx>( |
| 98 | 94 | // - and that should be impossible in MIR |
| 99 | 95 | // |
| 100 | 96 | // 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!( | |
| 103 | 99 | { |
| 104 | 100 | let mut lhs_regions = FxHashSet::default(); |
| 105 | 101 | tcx.for_each_free_region(lhs, |region| { |
| ... | ... | @@ -119,16 +115,8 @@ fn localize_statement_constraint<'tcx>( |
| 119 | 115 | "there should be no common regions between the LHS and RHS of an assignment" |
| 120 | 116 | ); |
| 121 | 117 | |
| 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). | |
| 126 | 118 | 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; | |
| 132 | 120 | compute_constraint_direction( |
| 133 | 121 | tcx, |
| 134 | 122 | outlives_constraint, |
| ... | ... | @@ -195,6 +183,7 @@ fn localize_terminator_constraint<'tcx>( |
| 195 | 183 | } |
| 196 | 184 | } |
| 197 | 185 | } |
| 186 | ||
| 198 | 187 | /// For a given outlives constraint and CFG edge, returns the localized constraint with the |
| 199 | 188 | /// appropriate `from`-`to` direction. This is computed according to whether the constraint flows to |
| 200 | 189 | /// 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> { |
| 142 | 142 | |err, self_ty, trait_id| { |
| 143 | 143 | // FIXME(const_trait_impl): Do we need any of this on the non-const codepath? |
| 144 | 144 | |
| 145 | let trait_ref = TraitRef::from_method(tcx, trait_id, self.args); | |
| 145 | let trait_ref = TraitRef::from_assoc(tcx, trait_id, self.args); | |
| 146 | 146 | |
| 147 | 147 | match self_ty.kind() { |
| 148 | 148 | 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> { |
| 732 | 732 | let tcx = *self.tcx; |
| 733 | 733 | |
| 734 | 734 | 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); | |
| 736 | 736 | let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref); |
| 737 | 737 | let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty); |
| 738 | 738 |
compiler/rustc_feature/src/unstable.rs+1-1| ... | ... | @@ -545,7 +545,7 @@ declare_features! ( |
| 545 | 545 | (incomplete, inherent_associated_types, "1.52.0", Some(8995)), |
| 546 | 546 | /// Allows using `pointer` and `reference` in intra-doc links |
| 547 | 547 | (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. | |
| 549 | 549 | (unstable, large_assignments, "1.52.0", Some(83518)), |
| 550 | 550 | /// Allow to have type alias types for inter-crate use. |
| 551 | 551 | (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> { |
| 290 | 290 | debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst); |
| 291 | 291 | let trait_def_id = self.parent(def_id); |
| 292 | 292 | 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()..]) | |
| 298 | 295 | } |
| 299 | 296 | |
| 300 | 297 | 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> { |
| 585 | 585 | tcx.mk_args_from_iter(target_args.iter().chain(self.iter().skip(defs.count()))) |
| 586 | 586 | } |
| 587 | 587 | |
| 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). | |
| 588 | 591 | pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> GenericArgsRef<'tcx> { |
| 589 | 592 | tcx.mk_args(&self[..generics.count()]) |
| 590 | 593 | } |
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> { |
| 68 | 68 | } |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | #[derive_where(PartialEq, Eq, Debug; I: Interner)] | |
| 71 | #[derive_where(PartialEq, Debug; I: Interner)] | |
| 72 | 72 | struct WipGoalEvaluation<I: Interner> { |
| 73 | 73 | pub uncanonicalized_goal: Goal<I, I::Predicate>, |
| 74 | 74 | pub orig_values: Vec<I::GenericArg>, |
| ... | ... | @@ -78,6 +78,8 @@ struct WipGoalEvaluation<I: Interner> { |
| 78 | 78 | pub result: Option<QueryResult<I>>, |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | impl<I: Interner> Eq for WipGoalEvaluation<I> {} | |
| 82 | ||
| 81 | 83 | impl<I: Interner> WipGoalEvaluation<I> { |
| 82 | 84 | fn finalize(self) -> inspect::GoalEvaluation<I> { |
| 83 | 85 | inspect::GoalEvaluation { |
| ... | ... | @@ -98,7 +100,7 @@ impl<I: Interner> WipGoalEvaluation<I> { |
| 98 | 100 | /// This only exists during proof tree building and does not have |
| 99 | 101 | /// a corresponding struct in `inspect`. We need this to track a |
| 100 | 102 | /// bunch of metadata about the current evaluation. |
| 101 | #[derive_where(PartialEq, Eq, Debug; I: Interner)] | |
| 103 | #[derive_where(PartialEq, Debug; I: Interner)] | |
| 102 | 104 | struct WipCanonicalGoalEvaluationStep<I: Interner> { |
| 103 | 105 | /// Unlike `EvalCtxt::var_values`, we append a new |
| 104 | 106 | /// generic arg here whenever we create a new inference |
| ... | ... | @@ -111,6 +113,8 @@ struct WipCanonicalGoalEvaluationStep<I: Interner> { |
| 111 | 113 | evaluation: WipProbe<I>, |
| 112 | 114 | } |
| 113 | 115 | |
| 116 | impl<I: Interner> Eq for WipCanonicalGoalEvaluationStep<I> {} | |
| 117 | ||
| 114 | 118 | impl<I: Interner> WipCanonicalGoalEvaluationStep<I> { |
| 115 | 119 | fn current_evaluation_scope(&mut self) -> &mut WipProbe<I> { |
| 116 | 120 | let mut current = &mut self.evaluation; |
| ... | ... | @@ -132,7 +136,7 @@ impl<I: Interner> WipCanonicalGoalEvaluationStep<I> { |
| 132 | 136 | } |
| 133 | 137 | } |
| 134 | 138 | |
| 135 | #[derive_where(PartialEq, Eq, Debug; I: Interner)] | |
| 139 | #[derive_where(PartialEq, Debug; I: Interner)] | |
| 136 | 140 | struct WipProbe<I: Interner> { |
| 137 | 141 | initial_num_var_values: usize, |
| 138 | 142 | steps: Vec<WipProbeStep<I>>, |
| ... | ... | @@ -140,6 +144,8 @@ struct WipProbe<I: Interner> { |
| 140 | 144 | final_state: Option<inspect::CanonicalState<I, ()>>, |
| 141 | 145 | } |
| 142 | 146 | |
| 147 | impl<I: Interner> Eq for WipProbe<I> {} | |
| 148 | ||
| 143 | 149 | impl<I: Interner> WipProbe<I> { |
| 144 | 150 | fn finalize(self) -> inspect::Probe<I> { |
| 145 | 151 | inspect::Probe { |
| ... | ... | @@ -150,7 +156,7 @@ impl<I: Interner> WipProbe<I> { |
| 150 | 156 | } |
| 151 | 157 | } |
| 152 | 158 | |
| 153 | #[derive_where(PartialEq, Eq, Debug; I: Interner)] | |
| 159 | #[derive_where(PartialEq, Debug; I: Interner)] | |
| 154 | 160 | enum WipProbeStep<I: Interner> { |
| 155 | 161 | AddGoal(GoalSource, inspect::CanonicalState<I, Goal<I, I::Predicate>>), |
| 156 | 162 | NestedProbe(WipProbe<I>), |
| ... | ... | @@ -158,6 +164,8 @@ enum WipProbeStep<I: Interner> { |
| 158 | 164 | RecordImplArgs { impl_args: inspect::CanonicalState<I, I::GenericArgs> }, |
| 159 | 165 | } |
| 160 | 166 | |
| 167 | impl<I: Interner> Eq for WipProbeStep<I> {} | |
| 168 | ||
| 161 | 169 | impl<I: Interner> WipProbeStep<I> { |
| 162 | 170 | fn finalize(self) -> inspect::ProbeStep<I> { |
| 163 | 171 | 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>( |
| 342 | 342 | let upcast_ty = match tcx.trait_of_assoc(def_id) { |
| 343 | 343 | Some(trait_id) => trait_object_ty( |
| 344 | 344 | 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)), | |
| 346 | 346 | ), |
| 347 | 347 | // drop_in_place won't have a defining trait, skip the upcast |
| 348 | 348 | None => instance.args.type_at(0), |
| ... | ... | @@ -481,7 +481,7 @@ fn implemented_method<'tcx>( |
| 481 | 481 | trait_method = trait_method_bound; |
| 482 | 482 | method_id = instance.def_id(); |
| 483 | 483 | 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)); | |
| 485 | 485 | trait_id |
| 486 | 486 | } else { |
| 487 | 487 | return None; |
compiler/rustc_trait_selection/src/traits/mod.rs+1-1| ... | ... | @@ -763,7 +763,7 @@ fn instantiate_and_check_impossible_predicates<'tcx>( |
| 763 | 763 | // Specifically check trait fulfillment to avoid an error when trying to resolve |
| 764 | 764 | // associated items. |
| 765 | 765 | 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); | |
| 767 | 767 | predicates.push(trait_ref.upcast(tcx)); |
| 768 | 768 | } |
| 769 | 769 |
compiler/rustc_ty_utils/src/instance.rs+2-2| ... | ... | @@ -109,7 +109,7 @@ fn resolve_associated_item<'tcx>( |
| 109 | 109 | ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { |
| 110 | 110 | debug!(?trait_item_id, ?typing_env, ?trait_id, ?rcvr_args, "resolve_associated_item"); |
| 111 | 111 | |
| 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); | |
| 113 | 113 | |
| 114 | 114 | let input = typing_env.as_query_input(trait_ref); |
| 115 | 115 | let vtbl = match tcx.codegen_select_candidate(input) { |
| ... | ... | @@ -238,7 +238,7 @@ fn resolve_associated_item<'tcx>( |
| 238 | 238 | Some(ty::Instance::new_raw(leaf_def.item.def_id, args)) |
| 239 | 239 | } |
| 240 | 240 | 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); | |
| 242 | 242 | if trait_ref.has_non_region_infer() || trait_ref.has_non_region_param() { |
| 243 | 243 | // We only resolve totally substituted vtable entries. |
| 244 | 244 | None |
compiler/rustc_type_ir/src/binder.rs+7-14| ... | ... | @@ -1,5 +1,3 @@ |
| 1 | use std::fmt::Debug; | |
| 2 | use std::hash::Hash; | |
| 3 | 1 | use std::marker::PhantomData; |
| 4 | 2 | use std::ops::{ControlFlow, Deref}; |
| 5 | 3 | |
| ... | ... | @@ -23,18 +21,16 @@ use crate::{self as ty, Interner}; |
| 23 | 21 | /// for more details. |
| 24 | 22 | /// |
| 25 | 23 | /// `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)] | |
| 27 | 25 | #[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)] | |
| 32 | 26 | #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] |
| 33 | 27 | pub struct Binder<I: Interner, T> { |
| 34 | 28 | value: T, |
| 35 | 29 | bound_vars: I::BoundVarKinds, |
| 36 | 30 | } |
| 37 | 31 | |
| 32 | impl<I: Interner, T: Eq> Eq for Binder<I, T> {} | |
| 33 | ||
| 38 | 34 | // FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't |
| 39 | 35 | // understand how to turn `T` to `T::Lifted` in the output `type Lifted`. |
| 40 | 36 | impl<I: Interner, U: Interner, T> Lift<U> for Binder<I, T> |
| ... | ... | @@ -356,14 +352,9 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> { |
| 356 | 352 | /// `instantiate`. |
| 357 | 353 | /// |
| 358 | 354 | /// 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)] | |
| 364 | 356 | #[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)] | |
| 367 | 358 | #[cfg_attr( |
| 368 | 359 | feature = "nightly", |
| 369 | 360 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -374,6 +365,8 @@ pub struct EarlyBinder<I: Interner, T> { |
| 374 | 365 | _tcx: PhantomData<fn() -> I>, |
| 375 | 366 | } |
| 376 | 367 | |
| 368 | impl<I: Interner, T: Eq> Eq for EarlyBinder<I, T> {} | |
| 369 | ||
| 377 | 370 | /// For early binders, you should first call `instantiate` before using any visitors. |
| 378 | 371 | #[cfg(feature = "nightly")] |
| 379 | 372 | impl<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; |
| 11 | 11 | use crate::inherent::*; |
| 12 | 12 | use crate::{self as ty, Interner, TypingMode, UniverseIndex}; |
| 13 | 13 | |
| 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)] | |
| 19 | 15 | #[derive_where(Copy; I: Interner, V: Copy)] |
| 20 | 16 | #[cfg_attr( |
| 21 | 17 | feature = "nightly", |
| ... | ... | @@ -26,14 +22,12 @@ pub struct CanonicalQueryInput<I: Interner, V> { |
| 26 | 22 | pub typing_mode: TypingMode<I>, |
| 27 | 23 | } |
| 28 | 24 | |
| 25 | impl<I: Interner, V: Eq> Eq for CanonicalQueryInput<I, V> {} | |
| 26 | ||
| 29 | 27 | /// A "canonicalized" type `V` is one where all free inference |
| 30 | 28 | /// variables have been rewritten to "canonical vars". These are |
| 31 | 29 | /// 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)] | |
| 37 | 31 | #[derive_where(Copy; I: Interner, V: Copy)] |
| 38 | 32 | #[cfg_attr( |
| 39 | 33 | feature = "nightly", |
| ... | ... | @@ -45,6 +39,8 @@ pub struct Canonical<I: Interner, V> { |
| 45 | 39 | pub variables: I::CanonicalVarKinds, |
| 46 | 40 | } |
| 47 | 41 | |
| 42 | impl<I: Interner, V: Eq> Eq for Canonical<I, V> {} | |
| 43 | ||
| 48 | 44 | impl<I: Interner, V> Canonical<I, V> { |
| 49 | 45 | /// Allows you to map the `value` of a canonical while keeping the |
| 50 | 46 | /// same set of bound variables. |
| ... | ... | @@ -89,7 +85,7 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> { |
| 89 | 85 | /// canonical value. This is sufficient information for code to create |
| 90 | 86 | /// a copy of the canonical value in some other inference context, |
| 91 | 87 | /// 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)] | |
| 93 | 89 | #[cfg_attr( |
| 94 | 90 | feature = "nightly", |
| 95 | 91 | derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -116,6 +112,8 @@ pub enum CanonicalVarKind<I: Interner> { |
| 116 | 112 | PlaceholderConst(I::PlaceholderConst), |
| 117 | 113 | } |
| 118 | 114 | |
| 115 | impl<I: Interner> Eq for CanonicalVarKind<I> {} | |
| 116 | ||
| 119 | 117 | impl<I: Interner> CanonicalVarKind<I> { |
| 120 | 118 | pub fn universe(self) -> UniverseIndex { |
| 121 | 119 | match self { |
| ... | ... | @@ -223,7 +221,7 @@ pub enum CanonicalTyVarKind { |
| 223 | 221 | /// vectors with the original values that were replaced by canonical |
| 224 | 222 | /// variables. You will need to supply it later to instantiate the |
| 225 | 223 | /// canonicalized query response. |
| 226 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] | |
| 224 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | |
| 227 | 225 | #[cfg_attr( |
| 228 | 226 | feature = "nightly", |
| 229 | 227 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -233,6 +231,8 @@ pub struct CanonicalVarValues<I: Interner> { |
| 233 | 231 | pub var_values: I::GenericArgs, |
| 234 | 232 | } |
| 235 | 233 | |
| 234 | impl<I: Interner> Eq for CanonicalVarValues<I> {} | |
| 235 | ||
| 236 | 236 | impl<I: Interner> CanonicalVarValues<I> { |
| 237 | 237 | pub fn is_identity(&self) -> bool { |
| 238 | 238 | 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 |
| 10 | 10 | use crate::{self as ty, DebruijnIndex, Interner}; |
| 11 | 11 | |
| 12 | 12 | /// Represents a constant in Rust. |
| 13 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] | |
| 13 | #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | |
| 14 | 14 | #[cfg_attr( |
| 15 | 15 | feature = "nightly", |
| 16 | 16 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -45,6 +45,8 @@ pub enum ConstKind<I: Interner> { |
| 45 | 45 | Expr(I::ExprConst), |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | impl<I: Interner> Eq for ConstKind<I> {} | |
| 49 | ||
| 48 | 50 | impl<I: Interner> fmt::Debug for ConstKind<I> { |
| 49 | 51 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 50 | 52 | use ConstKind::*; |
| ... | ... | @@ -63,7 +65,7 @@ impl<I: Interner> fmt::Debug for ConstKind<I> { |
| 63 | 65 | } |
| 64 | 66 | |
| 65 | 67 | /// 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)] | |
| 67 | 69 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 68 | 70 | #[cfg_attr( |
| 69 | 71 | feature = "nightly", |
| ... | ... | @@ -74,6 +76,8 @@ pub struct UnevaluatedConst<I: Interner> { |
| 74 | 76 | pub args: I::GenericArgs, |
| 75 | 77 | } |
| 76 | 78 | |
| 79 | impl<I: Interner> Eq for UnevaluatedConst<I> {} | |
| 80 | ||
| 77 | 81 | impl<I: Interner> UnevaluatedConst<I> { |
| 78 | 82 | #[inline] |
| 79 | 83 | 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> { |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | // 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)] | |
| 22 | 22 | #[derive(TypeVisitable_Generic)] |
| 23 | 23 | #[cfg_attr(feature = "nightly", rustc_pass_by_value)] |
| 24 | 24 | pub enum TypeError<I: Interner> { |
| ... | ... | @@ -58,6 +58,8 @@ pub enum TypeError<I: Interner> { |
| 58 | 58 | TargetFeatureCast(I::DefId), |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | impl<I: Interner> Eq for TypeError<I> {} | |
| 62 | ||
| 61 | 63 | impl<I: Interner> TypeError<I> { |
| 62 | 64 | pub fn involves_regions(self) -> bool { |
| 63 | 65 | 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 |
| 4 | 4 | |
| 5 | 5 | use crate::Interner; |
| 6 | 6 | |
| 7 | #[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)] | |
| 7 | #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] | |
| 8 | 8 | #[cfg_attr( |
| 9 | 9 | feature = "nightly", |
| 10 | 10 | derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -15,7 +15,9 @@ pub enum GenericArgKind<I: Interner> { |
| 15 | 15 | Const(I::Const), |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | #[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)] | |
| 18 | impl<I: Interner> Eq for GenericArgKind<I> {} | |
| 19 | ||
| 20 | #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] | |
| 19 | 21 | #[cfg_attr( |
| 20 | 22 | feature = "nightly", |
| 21 | 23 | derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -24,3 +26,5 @@ pub enum TermKind<I: Interner> { |
| 24 | 26 | Ty(I::Ty), |
| 25 | 27 | Const(I::Const), |
| 26 | 28 | } |
| 29 | ||
| 30 | impl<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}; |
| 18 | 18 | /// |
| 19 | 19 | /// If neither of these functions are available, feel free to reach out to |
| 20 | 20 | /// 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)] | |
| 22 | 22 | #[cfg_attr( |
| 23 | 23 | feature = "nightly", |
| 24 | 24 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -90,6 +90,8 @@ pub enum TypingMode<I: Interner> { |
| 90 | 90 | PostAnalysis, |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | impl<I: Interner> Eq for TypingMode<I> {} | |
| 94 | ||
| 93 | 95 | impl<I: Interner> TypingMode<I> { |
| 94 | 96 | /// Analysis outside of a body does not define any opaque types. |
| 95 | 97 | 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}; |
| 6 | 6 | use crate::inherent::*; |
| 7 | 7 | use crate::{self as ty, Interner}; |
| 8 | 8 | |
| 9 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] | |
| 9 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | |
| 10 | 10 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 11 | 11 | #[cfg_attr( |
| 12 | 12 | feature = "nightly", |
| ... | ... | @@ -17,6 +17,8 @@ pub struct OpaqueTypeKey<I: Interner> { |
| 17 | 17 | pub args: I::GenericArgs, |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | impl<I: Interner> Eq for OpaqueTypeKey<I> {} | |
| 21 | ||
| 20 | 22 | impl<I: Interner> OpaqueTypeKey<I> { |
| 21 | 23 | pub fn iter_captured_args(self, cx: I) -> impl Iterator<Item = (usize, I::GenericArg)> { |
| 22 | 24 | 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 |
| 5 | 5 | |
| 6 | 6 | use crate::Interner; |
| 7 | 7 | |
| 8 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] | |
| 8 | #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | |
| 9 | 9 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 10 | 10 | #[cfg_attr( |
| 11 | 11 | feature = "nightly", |
| ... | ... | @@ -15,3 +15,5 @@ pub enum PatternKind<I: Interner> { |
| 15 | 15 | Range { start: I::Const, end: I::Const }, |
| 16 | 16 | Or(I::PatList), |
| 17 | 17 | } |
| 18 | ||
| 19 | impl<I: Interner> Eq for PatternKind<I> {} |
compiler/rustc_type_ir/src/predicate.rs+37-17| ... | ... | @@ -15,12 +15,8 @@ use crate::visit::TypeVisitableExt as _; |
| 15 | 15 | use crate::{self as ty, Interner}; |
| 16 | 16 | |
| 17 | 17 | /// `A: 'region` |
| 18 | #[derive_where(Clone; I: Interner, A: Clone)] | |
| 18 | #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)] | |
| 19 | 19 | #[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)] | |
| 24 | 20 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 25 | 21 | #[cfg_attr( |
| 26 | 22 | feature = "nightly", |
| ... | ... | @@ -28,6 +24,8 @@ use crate::{self as ty, Interner}; |
| 28 | 24 | )] |
| 29 | 25 | pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region); |
| 30 | 26 | |
| 27 | impl<I: Interner, A: Eq> Eq for OutlivesPredicate<I, A> {} | |
| 28 | ||
| 31 | 29 | // FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't |
| 32 | 30 | // understand how to turn `A` to `A::Lifted` in the output `type Lifted`. |
| 33 | 31 | impl<I: Interner, U: Interner, A> Lift<U> for OutlivesPredicate<I, A> |
| ... | ... | @@ -53,7 +51,7 @@ where |
| 53 | 51 | /// |
| 54 | 52 | /// Trait references also appear in object types like `Foo<U>`, but in |
| 55 | 53 | /// 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)] | |
| 57 | 55 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 58 | 56 | #[cfg_attr( |
| 59 | 57 | feature = "nightly", |
| ... | ... | @@ -67,6 +65,8 @@ pub struct TraitRef<I: Interner> { |
| 67 | 65 | _use_trait_ref_new_instead: (), |
| 68 | 66 | } |
| 69 | 67 | |
| 68 | impl<I: Interner> Eq for TraitRef<I> {} | |
| 69 | ||
| 70 | 70 | impl<I: Interner> TraitRef<I> { |
| 71 | 71 | pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self { |
| 72 | 72 | interner.debug_assert_args_compatible(trait_def_id, args); |
| ... | ... | @@ -82,7 +82,7 @@ impl<I: Interner> TraitRef<I> { |
| 82 | 82 | Self::new_from_args(interner, trait_def_id, args) |
| 83 | 83 | } |
| 84 | 84 | |
| 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> { | |
| 86 | 86 | let generics = interner.generics_of(trait_id); |
| 87 | 87 | TraitRef::new(interner, trait_id, args.iter().take(generics.count())) |
| 88 | 88 | } |
| ... | ... | @@ -128,7 +128,7 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> { |
| 128 | 128 | } |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] | |
| 131 | #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | |
| 132 | 132 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 133 | 133 | #[cfg_attr( |
| 134 | 134 | feature = "nightly", |
| ... | ... | @@ -145,6 +145,8 @@ pub struct TraitPredicate<I: Interner> { |
| 145 | 145 | pub polarity: PredicatePolarity, |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | impl<I: Interner> Eq for TraitPredicate<I> {} | |
| 149 | ||
| 148 | 150 | impl<I: Interner> TraitPredicate<I> { |
| 149 | 151 | pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { |
| 150 | 152 | Self { |
| ... | ... | @@ -271,7 +273,7 @@ impl fmt::Display for PredicatePolarity { |
| 271 | 273 | } |
| 272 | 274 | } |
| 273 | 275 | |
| 274 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] | |
| 276 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | |
| 275 | 277 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 276 | 278 | #[cfg_attr( |
| 277 | 279 | feature = "nightly", |
| ... | ... | @@ -286,6 +288,8 @@ pub enum ExistentialPredicate<I: Interner> { |
| 286 | 288 | AutoTrait(I::DefId), |
| 287 | 289 | } |
| 288 | 290 | |
| 291 | impl<I: Interner> Eq for ExistentialPredicate<I> {} | |
| 292 | ||
| 289 | 293 | impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> { |
| 290 | 294 | /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`), |
| 291 | 295 | /// 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>> { |
| 319 | 323 | /// ``` |
| 320 | 324 | /// The generic parameters don't include the erased `Self`, only trait |
| 321 | 325 | /// 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)] | |
| 323 | 327 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 324 | 328 | #[cfg_attr( |
| 325 | 329 | feature = "nightly", |
| ... | ... | @@ -333,6 +337,8 @@ pub struct ExistentialTraitRef<I: Interner> { |
| 333 | 337 | _use_existential_trait_ref_new_instead: (), |
| 334 | 338 | } |
| 335 | 339 | |
| 340 | impl<I: Interner> Eq for ExistentialTraitRef<I> {} | |
| 341 | ||
| 336 | 342 | impl<I: Interner> ExistentialTraitRef<I> { |
| 337 | 343 | pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self { |
| 338 | 344 | interner.debug_assert_existential_args_compatible(trait_def_id, args); |
| ... | ... | @@ -386,7 +392,7 @@ impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> { |
| 386 | 392 | } |
| 387 | 393 | |
| 388 | 394 | /// 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)] | |
| 390 | 396 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 391 | 397 | #[cfg_attr( |
| 392 | 398 | feature = "nightly", |
| ... | ... | @@ -402,6 +408,8 @@ pub struct ExistentialProjection<I: Interner> { |
| 402 | 408 | use_existential_projection_new_instead: (), |
| 403 | 409 | } |
| 404 | 410 | |
| 411 | impl<I: Interner> Eq for ExistentialProjection<I> {} | |
| 412 | ||
| 405 | 413 | impl<I: Interner> ExistentialProjection<I> { |
| 406 | 414 | pub fn new_from_args( |
| 407 | 415 | interner: I, |
| ... | ... | @@ -542,7 +550,7 @@ impl From<ty::AliasTyKind> for AliasTermKind { |
| 542 | 550 | /// * For a projection, this would be `<Ty as Trait<...>>::N<...>`. |
| 543 | 551 | /// * For an inherent projection, this would be `Ty::N<...>`. |
| 544 | 552 | /// * 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)] | |
| 546 | 554 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 547 | 555 | #[cfg_attr( |
| 548 | 556 | feature = "nightly", |
| ... | ... | @@ -578,6 +586,8 @@ pub struct AliasTerm<I: Interner> { |
| 578 | 586 | _use_alias_term_new_instead: (), |
| 579 | 587 | } |
| 580 | 588 | |
| 589 | impl<I: Interner> Eq for AliasTerm<I> {} | |
| 590 | ||
| 581 | 591 | impl<I: Interner> AliasTerm<I> { |
| 582 | 592 | pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> { |
| 583 | 593 | interner.debug_assert_args_compatible(def_id, args); |
| ... | ... | @@ -752,7 +762,7 @@ impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> { |
| 752 | 762 | /// equality between arbitrary types. Processing an instance of |
| 753 | 763 | /// Form #2 eventually yields one of these `ProjectionPredicate` |
| 754 | 764 | /// instances to normalize the LHS. |
| 755 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] | |
| 765 | #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | |
| 756 | 766 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 757 | 767 | #[cfg_attr( |
| 758 | 768 | feature = "nightly", |
| ... | ... | @@ -763,6 +773,8 @@ pub struct ProjectionPredicate<I: Interner> { |
| 763 | 773 | pub term: I::Term, |
| 764 | 774 | } |
| 765 | 775 | |
| 776 | impl<I: Interner> Eq for ProjectionPredicate<I> {} | |
| 777 | ||
| 766 | 778 | impl<I: Interner> ProjectionPredicate<I> { |
| 767 | 779 | pub fn self_ty(self) -> I::Ty { |
| 768 | 780 | self.projection_term.self_ty() |
| ... | ... | @@ -813,7 +825,7 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> { |
| 813 | 825 | |
| 814 | 826 | /// Used by the new solver to normalize an alias. This always expects the `term` to |
| 815 | 827 | /// 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)] | |
| 817 | 829 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 818 | 830 | #[cfg_attr( |
| 819 | 831 | feature = "nightly", |
| ... | ... | @@ -824,6 +836,8 @@ pub struct NormalizesTo<I: Interner> { |
| 824 | 836 | pub term: I::Term, |
| 825 | 837 | } |
| 826 | 838 | |
| 839 | impl<I: Interner> Eq for NormalizesTo<I> {} | |
| 840 | ||
| 827 | 841 | impl<I: Interner> NormalizesTo<I> { |
| 828 | 842 | pub fn self_ty(self) -> I::Ty { |
| 829 | 843 | self.alias.self_ty() |
| ... | ... | @@ -848,7 +862,7 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> { |
| 848 | 862 | } |
| 849 | 863 | } |
| 850 | 864 | |
| 851 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] | |
| 865 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | |
| 852 | 866 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 853 | 867 | #[cfg_attr( |
| 854 | 868 | feature = "nightly", |
| ... | ... | @@ -859,6 +873,8 @@ pub struct HostEffectPredicate<I: Interner> { |
| 859 | 873 | pub constness: BoundConstness, |
| 860 | 874 | } |
| 861 | 875 | |
| 876 | impl<I: Interner> Eq for HostEffectPredicate<I> {} | |
| 877 | ||
| 862 | 878 | impl<I: Interner> HostEffectPredicate<I> { |
| 863 | 879 | pub fn self_ty(self) -> I::Ty { |
| 864 | 880 | self.trait_ref.self_ty() |
| ... | ... | @@ -892,7 +908,7 @@ impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> { |
| 892 | 908 | /// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates |
| 893 | 909 | /// whether the `a` type is the type that we should label as "expected" when |
| 894 | 910 | /// presenting user diagnostics. |
| 895 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] | |
| 911 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | |
| 896 | 912 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 897 | 913 | #[cfg_attr( |
| 898 | 914 | feature = "nightly", |
| ... | ... | @@ -904,8 +920,10 @@ pub struct SubtypePredicate<I: Interner> { |
| 904 | 920 | pub b: I::Ty, |
| 905 | 921 | } |
| 906 | 922 | |
| 923 | impl<I: Interner> Eq for SubtypePredicate<I> {} | |
| 924 | ||
| 907 | 925 | /// 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)] | |
| 909 | 927 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 910 | 928 | #[cfg_attr( |
| 911 | 929 | feature = "nightly", |
| ... | ... | @@ -916,6 +934,8 @@ pub struct CoercePredicate<I: Interner> { |
| 916 | 934 | pub b: I::Ty, |
| 917 | 935 | } |
| 918 | 936 | |
| 937 | impl<I: Interner> Eq for CoercePredicate<I> {} | |
| 938 | ||
| 919 | 939 | #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] |
| 920 | 940 | #[cfg_attr( |
| 921 | 941 | feature = "nightly", |
compiler/rustc_type_ir/src/predicate_kind.rs+6-2| ... | ... | @@ -9,7 +9,7 @@ use crate::{self as ty, Interner}; |
| 9 | 9 | |
| 10 | 10 | /// A clause is something that can appear in where bounds or be inferred |
| 11 | 11 | /// by implied bounds. |
| 12 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] | |
| 12 | #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | |
| 13 | 13 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 14 | 14 | #[cfg_attr( |
| 15 | 15 | feature = "nightly", |
| ... | ... | @@ -55,7 +55,9 @@ pub enum ClauseKind<I: Interner> { |
| 55 | 55 | ), |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] | |
| 58 | impl<I: Interner> Eq for ClauseKind<I> {} | |
| 59 | ||
| 60 | #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | |
| 59 | 61 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 60 | 62 | #[cfg_attr( |
| 61 | 63 | feature = "nightly", |
| ... | ... | @@ -109,6 +111,8 @@ pub enum PredicateKind<I: Interner> { |
| 109 | 111 | AliasRelate(I::Term, I::Term, AliasRelationDirection), |
| 110 | 112 | } |
| 111 | 113 | |
| 114 | impl<I: Interner> Eq for PredicateKind<I> {} | |
| 115 | ||
| 112 | 116 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] |
| 113 | 117 | #[cfg_attr( |
| 114 | 118 | feature = "nightly", |
compiler/rustc_type_ir/src/region_kind.rs+3-1| ... | ... | @@ -125,7 +125,7 @@ rustc_index::newtype_index! { |
| 125 | 125 | /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ |
| 126 | 126 | /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ |
| 127 | 127 | /// [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)] | |
| 129 | 129 | #[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))] |
| 130 | 130 | pub enum RegionKind<I: Interner> { |
| 131 | 131 | /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. |
| ... | ... | @@ -177,6 +177,8 @@ pub enum RegionKind<I: Interner> { |
| 177 | 177 | ReError(I::ErrorGuaranteed), |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | impl<I: Interner> Eq for RegionKind<I> {} | |
| 181 | ||
| 180 | 182 | impl<I: Interner> fmt::Debug for RegionKind<I> { |
| 181 | 183 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 182 | 184 | match self { |
compiler/rustc_type_ir/src/relate.rs+3-1| ... | ... | @@ -33,7 +33,7 @@ pub enum StructurallyRelateAliases { |
| 33 | 33 | /// a miscompilation or unsoundness. |
| 34 | 34 | /// |
| 35 | 35 | /// 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)] | |
| 37 | 37 | pub enum VarianceDiagInfo<I: Interner> { |
| 38 | 38 | /// No additional information - this is the default. |
| 39 | 39 | /// We will not add any additional information to error messages. |
| ... | ... | @@ -51,6 +51,8 @@ pub enum VarianceDiagInfo<I: Interner> { |
| 51 | 51 | }, |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | impl<I: Interner> Eq for VarianceDiagInfo<I> {} | |
| 55 | ||
| 54 | 56 | impl<I: Interner> VarianceDiagInfo<I> { |
| 55 | 57 | /// Mirrors `Variance::xform` - used to 'combine' the existing |
| 56 | 58 | /// and new `VarianceDiagInfo`s when our variance changes. |
compiler/rustc_type_ir/src/solve/inspect.rs+18-13| ... | ... | @@ -17,9 +17,6 @@ |
| 17 | 17 | //! |
| 18 | 18 | //! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html |
| 19 | 19 | |
| 20 | use std::fmt::Debug; | |
| 21 | use std::hash::Hash; | |
| 22 | ||
| 23 | 20 | use derive_where::derive_where; |
| 24 | 21 | use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; |
| 25 | 22 | |
| ... | ... | @@ -32,25 +29,23 @@ use crate::{Canonical, CanonicalVarValues, Interner}; |
| 32 | 29 | /// This is only ever used as [CanonicalState]. Any type information in proof |
| 33 | 30 | /// trees used mechanically has to be canonicalized as we otherwise leak |
| 34 | 31 | /// inference variables from a nested `InferCtxt`. |
| 35 | #[derive_where(Clone; I: Interner, T: Clone)] | |
| 32 | #[derive_where(Clone, PartialEq, Hash, Debug; I: Interner, T)] | |
| 36 | 33 | #[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)] | |
| 41 | 34 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 42 | 35 | pub struct State<I: Interner, T> { |
| 43 | 36 | pub var_values: CanonicalVarValues<I>, |
| 44 | 37 | pub data: T, |
| 45 | 38 | } |
| 46 | 39 | |
| 40 | impl<I: Interner, T: Eq> Eq for State<I, T> {} | |
| 41 | ||
| 47 | 42 | pub type CanonicalState<I, T> = Canonical<I, State<I, T>>; |
| 48 | 43 | |
| 49 | 44 | /// When evaluating a goal we also store the original values |
| 50 | 45 | /// for the `CanonicalVarValues` of the canonicalized goal. |
| 51 | 46 | /// We use this to map any [CanonicalState] from the local `InferCtxt` |
| 52 | 47 | /// 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)] | |
| 54 | 49 | pub struct GoalEvaluation<I: Interner> { |
| 55 | 50 | pub uncanonicalized_goal: Goal<I, I::Predicate>, |
| 56 | 51 | pub orig_values: Vec<I::GenericArg>, |
| ... | ... | @@ -58,7 +53,9 @@ pub struct GoalEvaluation<I: Interner> { |
| 58 | 53 | pub result: QueryResult<I>, |
| 59 | 54 | } |
| 60 | 55 | |
| 61 | #[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 56 | impl<I: Interner> Eq for GoalEvaluation<I> {} | |
| 57 | ||
| 58 | #[derive_where(PartialEq, Hash, Debug; I: Interner)] | |
| 62 | 59 | pub enum GoalEvaluationKind<I: Interner> { |
| 63 | 60 | Overflow, |
| 64 | 61 | Evaluation { |
| ... | ... | @@ -67,10 +64,12 @@ pub enum GoalEvaluationKind<I: Interner> { |
| 67 | 64 | }, |
| 68 | 65 | } |
| 69 | 66 | |
| 67 | impl<I: Interner> Eq for GoalEvaluationKind<I> {} | |
| 68 | ||
| 70 | 69 | /// A self-contained computation during trait solving. This either |
| 71 | 70 | /// corresponds to a `EvalCtxt::probe(_X)` call or the root evaluation |
| 72 | 71 | /// of a goal. |
| 73 | #[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 72 | #[derive_where(PartialEq, Hash, Debug; I: Interner)] | |
| 74 | 73 | pub struct Probe<I: Interner> { |
| 75 | 74 | /// What happened inside of this probe in chronological order. |
| 76 | 75 | pub steps: Vec<ProbeStep<I>>, |
| ... | ... | @@ -78,7 +77,9 @@ pub struct Probe<I: Interner> { |
| 78 | 77 | pub final_state: CanonicalState<I, ()>, |
| 79 | 78 | } |
| 80 | 79 | |
| 81 | #[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 80 | impl<I: Interner> Eq for Probe<I> {} | |
| 81 | ||
| 82 | #[derive_where(PartialEq, Hash, Debug; I: Interner)] | |
| 82 | 83 | pub enum ProbeStep<I: Interner> { |
| 83 | 84 | /// We added a goal to the `EvalCtxt` which will get proven |
| 84 | 85 | /// the next time `EvalCtxt::try_evaluate_added_goals` is called. |
| ... | ... | @@ -97,10 +98,12 @@ pub enum ProbeStep<I: Interner> { |
| 97 | 98 | MakeCanonicalResponse { shallow_certainty: Certainty }, |
| 98 | 99 | } |
| 99 | 100 | |
| 101 | impl<I: Interner> Eq for ProbeStep<I> {} | |
| 102 | ||
| 100 | 103 | /// What kind of probe we're in. In case the probe represents a candidate, or |
| 101 | 104 | /// the final result of the current goal - via [ProbeKind::Root] - we also |
| 102 | 105 | /// store the [QueryResult]. |
| 103 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 106 | #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] | |
| 104 | 107 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 105 | 108 | pub enum ProbeKind<I: Interner> { |
| 106 | 109 | /// The root inference context while proving a goal. |
| ... | ... | @@ -125,3 +128,5 @@ pub enum ProbeKind<I: Interner> { |
| 125 | 128 | /// Checking that a rigid alias is well-formed. |
| 126 | 129 | RigidAlias { result: QueryResult<I> }, |
| 127 | 130 | } |
| 131 | ||
| 132 | impl<I: Interner> Eq for ProbeKind<I> {} |
compiler/rustc_type_ir/src/solve/mod.rs+21-16| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | pub mod inspect; |
| 2 | 2 | |
| 3 | use std::fmt; | |
| 4 | 3 | use std::hash::Hash; |
| 5 | 4 | |
| 6 | 5 | use derive_where::derive_where; |
| ... | ... | @@ -32,12 +31,8 @@ pub struct NoSolution; |
| 32 | 31 | /// |
| 33 | 32 | /// Most of the time the `param_env` contains the `where`-bounds of the function |
| 34 | 33 | /// 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)] | |
| 36 | 35 | #[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)] | |
| 41 | 36 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 42 | 37 | #[cfg_attr( |
| 43 | 38 | feature = "nightly", |
| ... | ... | @@ -48,6 +43,8 @@ pub struct Goal<I: Interner, P> { |
| 48 | 43 | pub predicate: P, |
| 49 | 44 | } |
| 50 | 45 | |
| 46 | impl<I: Interner, P: Eq> Eq for Goal<I, P> {} | |
| 47 | ||
| 51 | 48 | impl<I: Interner, P> Goal<I, P> { |
| 52 | 49 | pub fn new(cx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> { |
| 53 | 50 | Goal { param_env, predicate: predicate.upcast(cx) } |
| ... | ... | @@ -98,12 +95,8 @@ pub enum GoalSource { |
| 98 | 95 | NormalizeGoal(PathKind), |
| 99 | 96 | } |
| 100 | 97 | |
| 101 | #[derive_where(Clone; I: Interner, Goal<I, P>: Clone)] | |
| 98 | #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal<I, P>)] | |
| 102 | 99 | #[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)] | |
| 107 | 100 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 108 | 101 | #[cfg_attr( |
| 109 | 102 | feature = "nightly", |
| ... | ... | @@ -114,8 +107,10 @@ pub struct QueryInput<I: Interner, P> { |
| 114 | 107 | pub predefined_opaques_in_body: I::PredefinedOpaques, |
| 115 | 108 | } |
| 116 | 109 | |
| 110 | impl<I: Interner, P: Eq> Eq for QueryInput<I, P> {} | |
| 111 | ||
| 117 | 112 | /// 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)] | |
| 119 | 114 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 120 | 115 | #[cfg_attr( |
| 121 | 116 | feature = "nightly", |
| ... | ... | @@ -125,8 +120,10 @@ pub struct PredefinedOpaquesData<I: Interner> { |
| 125 | 120 | pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>, |
| 126 | 121 | } |
| 127 | 122 | |
| 123 | impl<I: Interner> Eq for PredefinedOpaquesData<I> {} | |
| 124 | ||
| 128 | 125 | /// 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)] | |
| 130 | 127 | pub enum CandidateSource<I: Interner> { |
| 131 | 128 | /// A user written impl. |
| 132 | 129 | /// |
| ... | ... | @@ -189,6 +186,8 @@ pub enum CandidateSource<I: Interner> { |
| 189 | 186 | CoherenceUnknowable, |
| 190 | 187 | } |
| 191 | 188 | |
| 189 | impl<I: Interner> Eq for CandidateSource<I> {} | |
| 190 | ||
| 192 | 191 | #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] |
| 193 | 192 | pub enum ParamEnvSource { |
| 194 | 193 | /// Preferred eagerly. |
| ... | ... | @@ -217,7 +216,7 @@ pub enum BuiltinImplSource { |
| 217 | 216 | TraitUpcasting(usize), |
| 218 | 217 | } |
| 219 | 218 | |
| 220 | #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] | |
| 219 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | |
| 221 | 220 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 222 | 221 | #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] |
| 223 | 222 | pub struct Response<I: Interner> { |
| ... | ... | @@ -227,8 +226,10 @@ pub struct Response<I: Interner> { |
| 227 | 226 | pub external_constraints: I::ExternalConstraints, |
| 228 | 227 | } |
| 229 | 228 | |
| 229 | impl<I: Interner> Eq for Response<I> {} | |
| 230 | ||
| 230 | 231 | /// 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)] | |
| 232 | 233 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 233 | 234 | #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] |
| 234 | 235 | pub struct ExternalConstraintsData<I: Interner> { |
| ... | ... | @@ -237,6 +238,8 @@ pub struct ExternalConstraintsData<I: Interner> { |
| 237 | 238 | pub normalization_nested_goals: NestedNormalizationGoals<I>, |
| 238 | 239 | } |
| 239 | 240 | |
| 241 | impl<I: Interner> Eq for ExternalConstraintsData<I> {} | |
| 242 | ||
| 240 | 243 | impl<I: Interner> ExternalConstraintsData<I> { |
| 241 | 244 | pub fn is_empty(&self) -> bool { |
| 242 | 245 | self.region_constraints.is_empty() |
| ... | ... | @@ -245,11 +248,13 @@ impl<I: Interner> ExternalConstraintsData<I> { |
| 245 | 248 | } |
| 246 | 249 | } |
| 247 | 250 | |
| 248 | #[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)] | |
| 251 | #[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)] | |
| 249 | 252 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 250 | 253 | #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] |
| 251 | 254 | pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>); |
| 252 | 255 | |
| 256 | impl<I: Interner> Eq for NestedNormalizationGoals<I> {} | |
| 257 | ||
| 253 | 258 | impl<I: Interner> NestedNormalizationGoals<I> { |
| 254 | 259 | pub fn empty() -> Self { |
| 255 | 260 | NestedNormalizationGoals(vec![]) |
compiler/rustc_type_ir/src/ty_kind.rs+24-8| ... | ... | @@ -69,7 +69,7 @@ impl AliasTyKind { |
| 69 | 69 | /// Types written by the user start out as `hir::TyKind` and get |
| 70 | 70 | /// converted to this representation using `<dyn HirTyLowerer>::lower_ty`. |
| 71 | 71 | #[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)] | |
| 73 | 73 | #[cfg_attr( |
| 74 | 74 | feature = "nightly", |
| 75 | 75 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -268,6 +268,8 @@ pub enum TyKind<I: Interner> { |
| 268 | 268 | Error(I::ErrorGuaranteed), |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | impl<I: Interner> Eq for TyKind<I> {} | |
| 272 | ||
| 271 | 273 | impl<I: Interner> TyKind<I> { |
| 272 | 274 | pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> { |
| 273 | 275 | match self { |
| ... | ... | @@ -404,7 +406,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> { |
| 404 | 406 | /// * For a projection, this would be `<Ty as Trait<...>>::N<...>`. |
| 405 | 407 | /// * For an inherent projection, this would be `Ty::N<...>`. |
| 406 | 408 | /// * 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)] | |
| 408 | 410 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 409 | 411 | #[cfg_attr( |
| 410 | 412 | feature = "nightly", |
| ... | ... | @@ -440,6 +442,8 @@ pub struct AliasTy<I: Interner> { |
| 440 | 442 | pub(crate) _use_alias_ty_new_instead: (), |
| 441 | 443 | } |
| 442 | 444 | |
| 445 | impl<I: Interner> Eq for AliasTy<I> {} | |
| 446 | ||
| 443 | 447 | impl<I: Interner> AliasTy<I> { |
| 444 | 448 | pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> { |
| 445 | 449 | interner.debug_assert_args_compatible(def_id, args); |
| ... | ... | @@ -720,7 +724,7 @@ impl fmt::Debug for InferTy { |
| 720 | 724 | } |
| 721 | 725 | } |
| 722 | 726 | |
| 723 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 727 | #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] | |
| 724 | 728 | #[cfg_attr( |
| 725 | 729 | feature = "nightly", |
| 726 | 730 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -731,7 +735,9 @@ pub struct TypeAndMut<I: Interner> { |
| 731 | 735 | pub mutbl: Mutability, |
| 732 | 736 | } |
| 733 | 737 | |
| 734 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)] | |
| 738 | impl<I: Interner> Eq for TypeAndMut<I> {} | |
| 739 | ||
| 740 | #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] | |
| 735 | 741 | #[cfg_attr( |
| 736 | 742 | feature = "nightly", |
| 737 | 743 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -748,6 +754,8 @@ pub struct FnSig<I: Interner> { |
| 748 | 754 | pub abi: I::Abi, |
| 749 | 755 | } |
| 750 | 756 | |
| 757 | impl<I: Interner> Eq for FnSig<I> {} | |
| 758 | ||
| 751 | 759 | impl<I: Interner> FnSig<I> { |
| 752 | 760 | pub fn inputs(self) -> I::FnInputTys { |
| 753 | 761 | self.inputs_and_output.inputs() |
| ... | ... | @@ -845,11 +853,13 @@ impl<I: Interner> fmt::Debug for FnSig<I> { |
| 845 | 853 | |
| 846 | 854 | // FIXME: this is a distinct type because we need to define `Encode`/`Decode` |
| 847 | 855 | // 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)] | |
| 849 | 857 | #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] |
| 850 | 858 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 851 | 859 | pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>); |
| 852 | 860 | |
| 861 | impl<I: Interner> Eq for UnsafeBinderInner<I> {} | |
| 862 | ||
| 853 | 863 | impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> { |
| 854 | 864 | fn from(value: ty::Binder<I, I::Ty>) -> Self { |
| 855 | 865 | UnsafeBinderInner(value) |
| ... | ... | @@ -906,7 +916,7 @@ where |
| 906 | 916 | } |
| 907 | 917 | |
| 908 | 918 | // 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)] | |
| 910 | 920 | #[cfg_attr( |
| 911 | 921 | feature = "nightly", |
| 912 | 922 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -916,6 +926,8 @@ pub struct FnSigTys<I: Interner> { |
| 916 | 926 | pub inputs_and_output: I::Tys, |
| 917 | 927 | } |
| 918 | 928 | |
| 929 | impl<I: Interner> Eq for FnSigTys<I> {} | |
| 930 | ||
| 919 | 931 | impl<I: Interner> FnSigTys<I> { |
| 920 | 932 | pub fn inputs(self) -> I::FnInputTys { |
| 921 | 933 | self.inputs_and_output.inputs() |
| ... | ... | @@ -958,7 +970,7 @@ impl<I: Interner> ty::Binder<I, FnSigTys<I>> { |
| 958 | 970 | } |
| 959 | 971 | } |
| 960 | 972 | |
| 961 | #[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)] | |
| 973 | #[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)] | |
| 962 | 974 | #[cfg_attr( |
| 963 | 975 | feature = "nightly", |
| 964 | 976 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -970,7 +982,9 @@ pub struct FnHeader<I: Interner> { |
| 970 | 982 | pub abi: I::Abi, |
| 971 | 983 | } |
| 972 | 984 | |
| 973 | #[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)] | |
| 985 | impl<I: Interner> Eq for FnHeader<I> {} | |
| 986 | ||
| 987 | #[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)] | |
| 974 | 988 | #[cfg_attr( |
| 975 | 989 | feature = "nightly", |
| 976 | 990 | derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) |
| ... | ... | @@ -980,3 +994,5 @@ pub struct CoroutineWitnessTypes<I: Interner> { |
| 980 | 994 | pub types: I::Tys, |
| 981 | 995 | pub assumptions: I::RegionAssumptions, |
| 982 | 996 | } |
| 997 | ||
| 998 | impl<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}; |
| 101 | 101 | /// `yield` inside the coroutine. |
| 102 | 102 | /// * `GR`: The "return type", which is the type of value returned upon |
| 103 | 103 | /// 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)] | |
| 105 | 105 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 106 | 106 | pub struct ClosureArgs<I: Interner> { |
| 107 | 107 | /// Lifetime and type parameters from the enclosing function, |
| ... | ... | @@ -112,6 +112,8 @@ pub struct ClosureArgs<I: Interner> { |
| 112 | 112 | pub args: I::GenericArgs, |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | impl<I: Interner> Eq for ClosureArgs<I> {} | |
| 116 | ||
| 115 | 117 | /// Struct returned by `split()`. |
| 116 | 118 | pub struct ClosureArgsParts<I: Interner> { |
| 117 | 119 | /// This is the args of the typeck root. |
| ... | ... | @@ -203,12 +205,14 @@ impl<I: Interner> ClosureArgs<I> { |
| 203 | 205 | } |
| 204 | 206 | } |
| 205 | 207 | |
| 206 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 208 | #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] | |
| 207 | 209 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 208 | 210 | pub struct CoroutineClosureArgs<I: Interner> { |
| 209 | 211 | pub args: I::GenericArgs, |
| 210 | 212 | } |
| 211 | 213 | |
| 214 | impl<I: Interner> Eq for CoroutineClosureArgs<I> {} | |
| 215 | ||
| 212 | 216 | /// See docs for explanation of how each argument is used. |
| 213 | 217 | /// |
| 214 | 218 | /// See [`CoroutineClosureSignature`] for how these arguments are put together |
| ... | ... | @@ -348,7 +352,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt { |
| 348 | 352 | } |
| 349 | 353 | } |
| 350 | 354 | |
| 351 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 355 | #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] | |
| 352 | 356 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 353 | 357 | pub struct CoroutineClosureSignature<I: Interner> { |
| 354 | 358 | pub tupled_inputs_ty: I::Ty, |
| ... | ... | @@ -371,6 +375,8 @@ pub struct CoroutineClosureSignature<I: Interner> { |
| 371 | 375 | pub abi: I::Abi, |
| 372 | 376 | } |
| 373 | 377 | |
| 378 | impl<I: Interner> Eq for CoroutineClosureSignature<I> {} | |
| 379 | ||
| 374 | 380 | impl<I: Interner> CoroutineClosureSignature<I> { |
| 375 | 381 | /// Construct a coroutine from the closure signature. Since a coroutine signature |
| 376 | 382 | /// 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> { |
| 541 | 547 | } |
| 542 | 548 | } |
| 543 | 549 | |
| 544 | #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | |
| 550 | #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] | |
| 545 | 551 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 546 | 552 | pub struct GenSig<I: Interner> { |
| 547 | 553 | pub resume_ty: I::Ty, |
| ... | ... | @@ -549,13 +555,16 @@ pub struct GenSig<I: Interner> { |
| 549 | 555 | pub return_ty: I::Ty, |
| 550 | 556 | } |
| 551 | 557 | |
| 558 | impl<I: Interner> Eq for GenSig<I> {} | |
| 552 | 559 | /// 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)] | |
| 554 | 561 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 555 | 562 | pub struct CoroutineArgs<I: Interner> { |
| 556 | 563 | pub args: I::GenericArgs, |
| 557 | 564 | } |
| 558 | 565 | |
| 566 | impl<I: Interner> Eq for CoroutineArgs<I> {} | |
| 567 | ||
| 559 | 568 | pub struct CoroutineArgsParts<I: Interner> { |
| 560 | 569 | /// This is the args of the typeck root. |
| 561 | 570 | 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; |
| 135 | 135 | /// ]); |
| 136 | 136 | /// ``` |
| 137 | 137 | /// |
| 138 | /// ## `Entry` API | |
| 139 | /// | |
| 138 | 140 | /// `BTreeMap` implements an [`Entry API`], which allows for complex |
| 139 | 141 | /// methods of getting, setting, updating and removing keys and their values: |
| 140 | 142 | /// |
library/core/src/time.rs+4-4| ... | ... | @@ -373,7 +373,6 @@ impl Duration { |
| 373 | 373 | /// # Examples |
| 374 | 374 | /// |
| 375 | 375 | /// ``` |
| 376 | /// #![feature(duration_constructors_lite)] | |
| 377 | 376 | /// use std::time::Duration; |
| 378 | 377 | /// |
| 379 | 378 | /// let duration = Duration::from_hours(6); |
| ... | ... | @@ -381,7 +380,8 @@ impl Duration { |
| 381 | 380 | /// assert_eq!(6 * 60 * 60, duration.as_secs()); |
| 382 | 381 | /// assert_eq!(0, duration.subsec_nanos()); |
| 383 | 382 | /// ``` |
| 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")] | |
| 385 | 385 | #[must_use] |
| 386 | 386 | #[inline] |
| 387 | 387 | pub const fn from_hours(hours: u64) -> Duration { |
| ... | ... | @@ -401,7 +401,6 @@ impl Duration { |
| 401 | 401 | /// # Examples |
| 402 | 402 | /// |
| 403 | 403 | /// ``` |
| 404 | /// #![feature(duration_constructors_lite)] | |
| 405 | 404 | /// use std::time::Duration; |
| 406 | 405 | /// |
| 407 | 406 | /// let duration = Duration::from_mins(10); |
| ... | ... | @@ -409,7 +408,8 @@ impl Duration { |
| 409 | 408 | /// assert_eq!(10 * 60, duration.as_secs()); |
| 410 | 409 | /// assert_eq!(0, duration.subsec_nanos()); |
| 411 | 410 | /// ``` |
| 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")] | |
| 413 | 413 | #[must_use] |
| 414 | 414 | #[inline] |
| 415 | 415 | pub const fn from_mins(mins: u64) -> Duration { |
library/coretests/tests/lib.rs-1| ... | ... | @@ -36,7 +36,6 @@ |
| 36 | 36 | #![feature(drop_guard)] |
| 37 | 37 | #![feature(duration_constants)] |
| 38 | 38 | #![feature(duration_constructors)] |
| 39 | #![feature(duration_constructors_lite)] | |
| 40 | 39 | #![feature(error_generic_member_access)] |
| 41 | 40 | #![feature(exact_div)] |
| 42 | 41 | #![feature(exact_size_is_empty)] |
library/std/src/collections/hash/map.rs+4| ... | ... | @@ -135,6 +135,8 @@ use crate::ops::Index; |
| 135 | 135 | /// ]); |
| 136 | 136 | /// ``` |
| 137 | 137 | /// |
| 138 | /// ## `Entry` API | |
| 139 | /// | |
| 138 | 140 | /// `HashMap` implements an [`Entry` API](#method.entry), which allows |
| 139 | 141 | /// for complex methods of getting, setting, updating and removing keys and |
| 140 | 142 | /// their values: |
| ... | ... | @@ -167,6 +169,8 @@ use crate::ops::Index; |
| 167 | 169 | /// player_stats.entry("mana").and_modify(|mana| *mana += 200).or_insert(100); |
| 168 | 170 | /// ``` |
| 169 | 171 | /// |
| 172 | /// ## Usage with custom key types | |
| 173 | /// | |
| 170 | 174 | /// The easiest way to use `HashMap` with a custom key type is to derive [`Eq`] and [`Hash`]. |
| 171 | 175 | /// We must also derive [`PartialEq`]. |
| 172 | 176 | /// |
src/bootstrap/src/core/build_steps/llvm.rs+7| ... | ... | @@ -421,6 +421,13 @@ impl Step for Llvm { |
| 421 | 421 | ldflags.shared.push(" -latomic"); |
| 422 | 422 | } |
| 423 | 423 | |
| 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 | ||
| 424 | 431 | if target.is_msvc() { |
| 425 | 432 | cfg.define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreaded"); |
| 426 | 433 | cfg.static_crt(true); |
src/bootstrap/src/core/builder/cargo.rs+9| ... | ... | @@ -433,6 +433,15 @@ impl Builder<'_> { |
| 433 | 433 | let out_dir = self.stage_out(compiler, mode); |
| 434 | 434 | cargo.env("CARGO_TARGET_DIR", &out_dir); |
| 435 | 435 | |
| 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 | ||
| 436 | 445 | // Found with `rg "init_env_logger\("`. If anyone uses `init_env_logger` |
| 437 | 446 | // from out of tree it shouldn't matter, since x.py is only used for |
| 438 | 447 | // building in-tree. |
src/bootstrap/src/utils/exec.rs+83-82| ... | ... | @@ -80,11 +80,21 @@ impl CommandFingerprint { |
| 80 | 80 | /// Helper method to format both Command and BootstrapCommand as a short execution line, |
| 81 | 81 | /// without all the other details (e.g. environment variables). |
| 82 | 82 | 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 | |
| 88 | 98 | } |
| 89 | 99 | } |
| 90 | 100 | |
| ... | ... | @@ -434,8 +444,8 @@ impl From<Command> for BootstrapCommand { |
| 434 | 444 | enum CommandStatus { |
| 435 | 445 | /// The command has started and finished with some status. |
| 436 | 446 | 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, | |
| 439 | 449 | } |
| 440 | 450 | |
| 441 | 451 | /// Create a new BootstrapCommand. This is a helper function to make command creation |
| ... | ... | @@ -456,9 +466,9 @@ pub struct CommandOutput { |
| 456 | 466 | |
| 457 | 467 | impl CommandOutput { |
| 458 | 468 | #[must_use] |
| 459 | pub fn did_not_start(stdout: OutputMode, stderr: OutputMode) -> Self { | |
| 469 | pub fn not_finished(stdout: OutputMode, stderr: OutputMode) -> Self { | |
| 460 | 470 | Self { |
| 461 | status: CommandStatus::DidNotStart, | |
| 471 | status: CommandStatus::DidNotStartOrFinish, | |
| 462 | 472 | stdout: match stdout { |
| 463 | 473 | OutputMode::Print => None, |
| 464 | 474 | OutputMode::Capture => Some(vec![]), |
| ... | ... | @@ -489,7 +499,7 @@ impl CommandOutput { |
| 489 | 499 | pub fn is_success(&self) -> bool { |
| 490 | 500 | match self.status { |
| 491 | 501 | CommandStatus::Finished(status) => status.success(), |
| 492 | CommandStatus::DidNotStart => false, | |
| 502 | CommandStatus::DidNotStartOrFinish => false, | |
| 493 | 503 | } |
| 494 | 504 | } |
| 495 | 505 | |
| ... | ... | @@ -501,7 +511,7 @@ impl CommandOutput { |
| 501 | 511 | pub fn status(&self) -> Option<ExitStatus> { |
| 502 | 512 | match self.status { |
| 503 | 513 | CommandStatus::Finished(status) => Some(status), |
| 504 | CommandStatus::DidNotStart => None, | |
| 514 | CommandStatus::DidNotStartOrFinish => None, | |
| 505 | 515 | } |
| 506 | 516 | } |
| 507 | 517 | |
| ... | ... | @@ -745,25 +755,11 @@ impl ExecutionContext { |
| 745 | 755 | self.start(command, stdout, stderr).wait_for_output(self) |
| 746 | 756 | } |
| 747 | 757 | |
| 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."); | |
| 767 | 763 | } |
| 768 | 764 | exit!(1); |
| 769 | 765 | } |
| ... | ... | @@ -856,7 +852,7 @@ impl<'a> DeferredCommand<'a> { |
| 856 | 852 | && command.should_cache |
| 857 | 853 | { |
| 858 | 854 | 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); | |
| 860 | 856 | } |
| 861 | 857 | |
| 862 | 858 | output |
| ... | ... | @@ -872,6 +868,8 @@ impl<'a> DeferredCommand<'a> { |
| 872 | 868 | executed_at: &'a std::panic::Location<'a>, |
| 873 | 869 | exec_ctx: &ExecutionContext, |
| 874 | 870 | ) -> CommandOutput { |
| 871 | use std::fmt::Write; | |
| 872 | ||
| 875 | 873 | command.mark_as_executed(); |
| 876 | 874 | |
| 877 | 875 | let process = match process.take() { |
| ... | ... | @@ -881,79 +879,82 @@ impl<'a> DeferredCommand<'a> { |
| 881 | 879 | |
| 882 | 880 | let created_at = command.get_created_location(); |
| 883 | 881 | |
| 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 | } | |
| 885 | 888 | |
| 886 | let output = match process { | |
| 889 | let (output, fail_reason) = match process { | |
| 887 | 890 | Ok(child) => match child.wait_with_output() { |
| 888 | Ok(result) if result.status.success() => { | |
| 891 | Ok(output) if output.status.success() => { | |
| 889 | 892 | // Successful execution |
| 890 | CommandOutput::from_output(result, stdout, stderr) | |
| 893 | (CommandOutput::from_output(output, stdout, stderr), None) | |
| 891 | 894 | } |
| 892 | Ok(result) => { | |
| 893 | // Command ran but failed | |
| 894 | use std::fmt::Write; | |
| 895 | ||
| 896 | writeln!( | |
| 897 | message, | |
| 898 | r#" | |
| 899 | Command {command:?} did not execute successfully. | |
| 900 | Expected success, got {} | |
| 901 | Created at: {created_at} | |
| 902 | Executed 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)), | |
| 904 | 901 | ) |
| 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 | |
| 917 | 902 | } |
| 918 | 903 | Err(e) => { |
| 919 | 904 | // 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)), | |
| 926 | 908 | ) |
| 927 | .unwrap(); | |
| 928 | ||
| 929 | CommandOutput::did_not_start(stdout, stderr) | |
| 930 | 909 | } |
| 931 | 910 | }, |
| 932 | 911 | Err(e) => { |
| 933 | 912 | // 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))) | |
| 944 | 914 | } |
| 945 | 915 | }; |
| 946 | 916 | |
| 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} | |
| 938 | Created at: {created_at} | |
| 939 | Executed 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 | ||
| 948 | 949 | match command.failure_behavior { |
| 949 | 950 | BehaviorOnFailure::DelayFail => { |
| 950 | 951 | if exec_ctx.fail_fast { |
| 951 | exec_ctx.fail(&message, output); | |
| 952 | exec_ctx.fail(&error_message); | |
| 952 | 953 | } |
| 953 | exec_ctx.add_to_delay_failure(message); | |
| 954 | exec_ctx.add_to_delay_failure(error_message); | |
| 954 | 955 | } |
| 955 | 956 | BehaviorOnFailure::Exit => { |
| 956 | exec_ctx.fail(&message, output); | |
| 957 | exec_ctx.fail(&error_message); | |
| 957 | 958 | } |
| 958 | 959 | BehaviorOnFailure::Ignore => { |
| 959 | 960 | // 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 | ||
| 3 | This 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 | ||
| 5 | This 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 | ||
| 7 | You should [set this variable] by running `source qnxsdp-env.sh`. | |
| 8 | See [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 | ||
| 3 | This environment variable is used on Apple targets. | |
| 4 | It is passed through to the linker (currently either as `-isysroot` or `-syslibroot`). | |
| 5 | ||
| 6 | Note 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 | ||
| 3 | This 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 | ||
| 3 | The tracking feature for this issue is [#125586] | |
| 4 | ||
| 5 | [#125586]: https://github.com/rust-lang/rust/issues/125586 | |
| 6 | ||
| 7 | --- | |
| 8 | ||
| 9 | This flag takes either a boolean or the string "auto". | |
| 10 | ||
| 11 | When enabled, use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output. | |
| 12 | Use "auto" to try and autodetect whether the terminal emulator supports hyperlinks. | |
| 13 | Currently, "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 |
| 19 | 19 | - M68k |
| 20 | 20 | - CSKY |
| 21 | 21 | - SPARC |
| 22 | - LoongArch32 | |
| 23 | 22 | |
| 24 | 23 | ## Register classes |
| 25 | 24 | |
| ... | ... | @@ -54,8 +53,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect |
| 54 | 53 | | CSKY | `freg` | `f[0-31]` | `f` | |
| 55 | 54 | | SPARC | `reg` | `r[2-29]` | `r` | |
| 56 | 55 | | SPARC | `yreg` | `y` | Only clobbers | |
| 57 | | LoongArch32 | `reg` | `$r1`, `$r[4-20]`, `$r[23,30]` | `r` | | |
| 58 | | LoongArch32 | `freg` | `$f[0-31]` | `f` | | |
| 59 | 56 | |
| 60 | 57 | > **Notes**: |
| 61 | 58 | > - 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 |
| 94 | 91 | | CSKY | `freg` | None | `f32`, | |
| 95 | 92 | | SPARC | `reg` | None | `i8`, `i16`, `i32`, `i64` (SPARC64 only) | |
| 96 | 93 | | SPARC | `yreg` | N/A | Only clobbers | |
| 97 | | LoongArch32 | `reg` | None | `i8`, `i16`, `i32`, `f32` | | |
| 98 | | LoongArch32 | `freg` | None | `f32`, `f64` | | |
| 99 | 94 | |
| 100 | 95 | ## Register aliases |
| 101 | 96 |
src/doc/unstable-book/src/library-features/duration-constructors-lite.md deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | # `duration_constructors_lite` | |
| 2 | ||
| 3 | The tracking issue for this feature is: [#140881] | |
| 4 | ||
| 5 | [#140881]: https://github.com/rust-lang/rust/issues/140881 | |
| 6 | ||
| 7 | ------------------------ | |
| 8 | ||
| 9 | Add the methods `from_mins`, `from_hours` to `Duration`. | |
| 10 | ||
| 11 | For `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] |
| 7 | 7 | ------------------------ |
| 8 | 8 | |
| 9 | 9 | Add the methods `from_days` and `from_weeks` to `Duration`. |
| 10 | For `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( |
| 409 | 409 | // We ensure temp dir destructor is called. |
| 410 | 410 | std::mem::drop(temp_dir); |
| 411 | 411 | 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); | |
| 415 | 413 | } |
| 416 | 414 | } |
| 417 | 415 |
src/tools/compiletest/src/runtest.rs+1-1| ... | ... | @@ -1766,7 +1766,7 @@ impl<'test> TestCx<'test> { |
| 1766 | 1766 | |
| 1767 | 1767 | match self.config.compare_mode { |
| 1768 | 1768 | Some(CompareMode::Polonius) => { |
| 1769 | rustc.args(&["-Zpolonius"]); | |
| 1769 | rustc.args(&["-Zpolonius=next"]); | |
| 1770 | 1770 | } |
| 1771 | 1771 | Some(CompareMode::NextSolver) => { |
| 1772 | 1772 | rustc.args(&["-Znext-solver"]); |
src/tools/tidy/src/features.rs+35| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | //! * All unstable lang features have tests to ensure they are actually unstable. |
| 10 | 10 | //! * Language features in a group are sorted by feature name. |
| 11 | 11 | |
| 12 | use std::collections::BTreeSet; | |
| 12 | 13 | use std::collections::hash_map::{Entry, HashMap}; |
| 13 | 14 | use std::ffi::OsStr; |
| 14 | 15 | use std::num::NonZeroU32; |
| ... | ... | @@ -21,6 +22,7 @@ use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many}; |
| 21 | 22 | mod tests; |
| 22 | 23 | |
| 23 | 24 | mod version; |
| 25 | use regex::Regex; | |
| 24 | 26 | use version::Version; |
| 25 | 27 | |
| 26 | 28 | const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start"; |
| ... | ... | @@ -623,3 +625,36 @@ fn map_lib_features( |
| 623 | 625 | }, |
| 624 | 626 | ); |
| 625 | 627 | } |
| 628 | ||
| 629 | fn 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 | ||
| 637 | pub 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}; |
| 6 | 6 | |
| 7 | 7 | pub const PATH_STR: &str = "doc/unstable-book"; |
| 8 | 8 | |
| 9 | pub const ENV_VARS_DIR: &str = "src/compiler-environment-variables"; | |
| 10 | ||
| 9 | 11 | pub const COMPILER_FLAGS_DIR: &str = "src/compiler-flags"; |
| 10 | 12 | |
| 11 | 13 | pub 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; |
| 5 | 5 | use std::fs::{self, write}; |
| 6 | 6 | use std::path::Path; |
| 7 | 7 | |
| 8 | use tidy::features::{Features, collect_lang_features, collect_lib_features}; | |
| 8 | use tidy::features::{Features, collect_env_vars, collect_lang_features, collect_lib_features}; | |
| 9 | 9 | use tidy::t; |
| 10 | 10 | use 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, | |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | 15 | fn 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) { |
| 27 | 27 | t!(write(path, content), path); |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | fn 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 | ||
| 30 | 35 | fn set_to_summary_str(set: &BTreeSet<String>, dir: &str) -> String { |
| 31 | 36 | set.iter() |
| 32 | 37 | .map(|ref n| format!(" - [{}]({}/{}.md)", n.replace('-', "_"), dir, n)) |
| ... | ... | @@ -59,7 +64,7 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur |
| 59 | 64 | t!(write(&summary_path, content), summary_path); |
| 60 | 65 | } |
| 61 | 66 | |
| 62 | fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) { | |
| 67 | fn generate_feature_files(src: &Path, out: &Path, features: &Features) { | |
| 63 | 68 | let unstable_features = collect_unstable_feature_names(features); |
| 64 | 69 | let unstable_section_file_names = collect_unstable_book_section_file_names(src); |
| 65 | 70 | t!(fs::create_dir_all(&out)); |
| ... | ... | @@ -83,6 +88,16 @@ fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) { |
| 83 | 88 | } |
| 84 | 89 | } |
| 85 | 90 | |
| 91 | fn 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 | ||
| 86 | 101 | fn copy_recursive(from: &Path, to: &Path) { |
| 87 | 102 | for entry in t!(fs::read_dir(from)) { |
| 88 | 103 | let e = t!(entry); |
| ... | ... | @@ -112,21 +127,23 @@ fn main() { |
| 112 | 127 | .into_iter() |
| 113 | 128 | .filter(|&(ref name, _)| !lang_features.contains_key(name)) |
| 114 | 129 | .collect(); |
| 130 | let env_vars = collect_env_vars(compiler_path); | |
| 115 | 131 | |
| 116 | 132 | let doc_src_path = src_path.join(PATH_STR); |
| 117 | 133 | |
| 118 | 134 | t!(fs::create_dir_all(&dest_path)); |
| 119 | 135 | |
| 120 | generate_unstable_book_files( | |
| 136 | generate_feature_files( | |
| 121 | 137 | &doc_src_path.join(LANG_FEATURES_DIR), |
| 122 | 138 | &dest_path.join(LANG_FEATURES_DIR), |
| 123 | 139 | &lang_features, |
| 124 | 140 | ); |
| 125 | generate_unstable_book_files( | |
| 141 | generate_feature_files( | |
| 126 | 142 | &doc_src_path.join(LIB_FEATURES_DIR), |
| 127 | 143 | &dest_path.join(LIB_FEATURES_DIR), |
| 128 | 144 | &lib_features, |
| 129 | 145 | ); |
| 146 | generate_env_files(&doc_src_path.join(ENV_VARS_DIR), &dest_path.join(ENV_VARS_DIR), &env_vars); | |
| 130 | 147 | |
| 131 | 148 | copy_recursive(&doc_src_path, &dest_path); |
| 132 | 149 |
src/tools/unstable-book-gen/src/stub-env-var.md created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | # `{name}` | |
| 2 | ||
| 3 | Environment 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 | ||
| 5 | See [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 @@ |
| 1 | 1 | //@ add-core-stubs |
| 2 | //@ revisions: loongarch32 loongarch64 | |
| 3 | ||
| 2 | 4 | //@ 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 | ||
| 4 | 12 | //@ compile-flags: -Zmerge-functions=disabled |
| 5 | //@ needs-llvm-components: loongarch | |
| 6 | 13 | |
| 7 | 14 | #![feature(no_core, f16)] |
| 8 | 15 | #![crate_type = "rlib"] |
| ... | ... | @@ -22,7 +29,7 @@ extern "C" { |
| 22 | 29 | // CHECK-LABEL: sym_fn: |
| 23 | 30 | // CHECK: #APP |
| 24 | 31 | // 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) | |
| 26 | 33 | // CHECK: #NO_APP |
| 27 | 34 | #[no_mangle] |
| 28 | 35 | pub unsafe fn sym_fn() { |
| ... | ... | @@ -32,7 +39,7 @@ pub unsafe fn sym_fn() { |
| 32 | 39 | // CHECK-LABEL: sym_static: |
| 33 | 40 | // CHECK: #APP |
| 34 | 41 | // 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) | |
| 36 | 43 | // CHECK: #NO_APP |
| 37 | 44 | #[no_mangle] |
| 38 | 45 | pub unsafe fn sym_static() { |
| ... | ... | @@ -87,16 +94,18 @@ check!(reg_i32, i32, reg, "move"); |
| 87 | 94 | // CHECK: #NO_APP |
| 88 | 95 | check!(reg_f32, f32, reg, "move"); |
| 89 | 96 | |
| 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)] | |
| 94 | 102 | check!(reg_i64, i64, reg, "move"); |
| 95 | 103 | |
| 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)] | |
| 100 | 109 | check!(reg_f64, f64, reg, "move"); |
| 101 | 110 | |
| 102 | 111 | // CHECK-LABEL: reg_ptr: |
| ... | ... | @@ -153,16 +162,18 @@ check_reg!(r4_i32, i32, "$r4", "move"); |
| 153 | 162 | // CHECK: #NO_APP |
| 154 | 163 | check_reg!(r4_f32, f32, "$r4", "move"); |
| 155 | 164 | |
| 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)] | |
| 160 | 170 | check_reg!(r4_i64, i64, "$r4", "move"); |
| 161 | 171 | |
| 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)] | |
| 166 | 177 | check_reg!(r4_f64, f64, "$r4", "move"); |
| 167 | 178 | |
| 168 | 179 | // 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 | ||
| 5 | fn main() { | |
| 6 | &{ [1, 2, 3][4] }; | |
| 7 | } |
tests/run-make/raw-dylib-link-ordinal/exporter.def+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | LIBRARY exporter |
| 2 | 2 | EXPORTS |
| 3 | 3 | exported_function @13 NONAME |
| 4 | exported_variable @5 NONAME | |
| 4 | exported_variable @5 NONAME DATA | |
| 5 | 5 | print_exported_variable @9 NONAME |
tests/run-make/raw-dylib-link-ordinal/rmake.rs+2-1| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | |
| 12 | 12 | //@ only-windows |
| 13 | 13 | |
| 14 | use run_make_support::{cc, diff, is_windows_msvc, run, rustc}; | |
| 14 | use run_make_support::{cc, diff, extra_c_flags, is_windows_msvc, run, rustc}; | |
| 15 | 15 | |
| 16 | 16 | // NOTE: build_native_dynamic lib is not used, as the special `def` files |
| 17 | 17 | // must be passed to the CC compiler. |
| ... | ... | @@ -24,6 +24,7 @@ fn main() { |
| 24 | 24 | cc().input("exporter.obj") |
| 25 | 25 | .arg("exporter.def") |
| 26 | 26 | .args(&["-link", "-dll", "-noimplib", "-out:exporter.dll"]) |
| 27 | .args(extra_c_flags()) | |
| 27 | 28 | .run(); |
| 28 | 29 | } else { |
| 29 | 30 | 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 @@ |
| 1 | error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm | |
| 2 | --> $DIR/bad-reg.rs:27:18 | |
| 3 | | | |
| 4 | LL | asm!("", out("$r0") _); | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | ||
| 7 | error: invalid register `$tp`: reserved for TLS | |
| 8 | --> $DIR/bad-reg.rs:29:18 | |
| 9 | | | |
| 10 | LL | asm!("", out("$tp") _); | |
| 11 | | ^^^^^^^^^^^^ | |
| 12 | ||
| 13 | error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm | |
| 14 | --> $DIR/bad-reg.rs:31:18 | |
| 15 | | | |
| 16 | LL | asm!("", out("$sp") _); | |
| 17 | | ^^^^^^^^^^^^ | |
| 18 | ||
| 19 | error: invalid register `$r21`: reserved by the ABI | |
| 20 | --> $DIR/bad-reg.rs:33:18 | |
| 21 | | | |
| 22 | LL | asm!("", out("$r21") _); | |
| 23 | | ^^^^^^^^^^^^^ | |
| 24 | ||
| 25 | error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm | |
| 26 | --> $DIR/bad-reg.rs:35:18 | |
| 27 | | | |
| 28 | LL | asm!("", out("$fp") _); | |
| 29 | | ^^^^^^^^^^^^ | |
| 30 | ||
| 31 | error: 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 | | | |
| 34 | LL | asm!("", out("$r31") _); | |
| 35 | | ^^^^^^^^^^^^^ | |
| 36 | ||
| 37 | error: aborting due to 6 previous errors | |
| 38 |
tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 1 | error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm | |
| 2 | --> $DIR/bad-reg.rs:27:18 | |
| 3 | | | |
| 4 | LL | asm!("", out("$r0") _); | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | ||
| 7 | error: invalid register `$tp`: reserved for TLS | |
| 8 | --> $DIR/bad-reg.rs:29:18 | |
| 9 | | | |
| 10 | LL | asm!("", out("$tp") _); | |
| 11 | | ^^^^^^^^^^^^ | |
| 12 | ||
| 13 | error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm | |
| 14 | --> $DIR/bad-reg.rs:31:18 | |
| 15 | | | |
| 16 | LL | asm!("", out("$sp") _); | |
| 17 | | ^^^^^^^^^^^^ | |
| 18 | ||
| 19 | error: invalid register `$r21`: reserved by the ABI | |
| 20 | --> $DIR/bad-reg.rs:33:18 | |
| 21 | | | |
| 22 | LL | asm!("", out("$r21") _); | |
| 23 | | ^^^^^^^^^^^^^ | |
| 24 | ||
| 25 | error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm | |
| 26 | --> $DIR/bad-reg.rs:35:18 | |
| 27 | | | |
| 28 | LL | asm!("", out("$fp") _); | |
| 29 | | ^^^^^^^^^^^^ | |
| 30 | ||
| 31 | error: 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 | | | |
| 34 | LL | asm!("", out("$r31") _); | |
| 35 | | ^^^^^^^^^^^^^ | |
| 36 | ||
| 37 | error: register class `freg` requires at least one of the following target features: d, f | |
| 38 | --> $DIR/bad-reg.rs:41:26 | |
| 39 | | | |
| 40 | LL | asm!("/* {} */", in(freg) f); | |
| 41 | | ^^^^^^^^^^ | |
| 42 | ||
| 43 | error: register class `freg` requires at least one of the following target features: d, f | |
| 44 | --> $DIR/bad-reg.rs:43:26 | |
| 45 | | | |
| 46 | LL | asm!("/* {} */", out(freg) _); | |
| 47 | | ^^^^^^^^^^^ | |
| 48 | ||
| 49 | error: register class `freg` requires at least one of the following target features: d, f | |
| 50 | --> $DIR/bad-reg.rs:45:26 | |
| 51 | | | |
| 52 | LL | asm!("/* {} */", in(freg) d); | |
| 53 | | ^^^^^^^^^^ | |
| 54 | ||
| 55 | error: register class `freg` requires at least one of the following target features: d, f | |
| 56 | --> $DIR/bad-reg.rs:47:26 | |
| 57 | | | |
| 58 | LL | asm!("/* {} */", out(freg) d); | |
| 59 | | ^^^^^^^^^^^ | |
| 60 | ||
| 61 | error: aborting due to 10 previous errors | |
| 62 |
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr+6-6| ... | ... | @@ -1,35 +1,35 @@ |
| 1 | 1 | error: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | asm!("", out("$r0") _); |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | 7 | error: invalid register `$tp`: reserved for TLS |
| 8 | --> $DIR/bad-reg.rs:24:18 | |
| 8 | --> $DIR/bad-reg.rs:29:18 | |
| 9 | 9 | | |
| 10 | 10 | LL | asm!("", out("$tp") _); |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | error: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | asm!("", out("$sp") _); |
| 17 | 17 | | ^^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | error: invalid register `$r21`: reserved by the ABI |
| 20 | --> $DIR/bad-reg.rs:28:18 | |
| 20 | --> $DIR/bad-reg.rs:33:18 | |
| 21 | 21 | | |
| 22 | 22 | LL | asm!("", out("$r21") _); |
| 23 | 23 | | ^^^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | error: 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 | |
| 27 | 27 | | |
| 28 | 28 | LL | asm!("", out("$fp") _); |
| 29 | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | 31 | error: 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 | |
| 33 | 33 | | |
| 34 | 34 | LL | asm!("", out("$r31") _); |
| 35 | 35 | | ^^^^^^^^^^^^^ |
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr+10-10| ... | ... | @@ -1,59 +1,59 @@ |
| 1 | 1 | error: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | asm!("", out("$r0") _); |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | 7 | error: invalid register `$tp`: reserved for TLS |
| 8 | --> $DIR/bad-reg.rs:24:18 | |
| 8 | --> $DIR/bad-reg.rs:29:18 | |
| 9 | 9 | | |
| 10 | 10 | LL | asm!("", out("$tp") _); |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | error: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | asm!("", out("$sp") _); |
| 17 | 17 | | ^^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | error: invalid register `$r21`: reserved by the ABI |
| 20 | --> $DIR/bad-reg.rs:28:18 | |
| 20 | --> $DIR/bad-reg.rs:33:18 | |
| 21 | 21 | | |
| 22 | 22 | LL | asm!("", out("$r21") _); |
| 23 | 23 | | ^^^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | error: 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 | |
| 27 | 27 | | |
| 28 | 28 | LL | asm!("", out("$fp") _); |
| 29 | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | 31 | error: 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 | |
| 33 | 33 | | |
| 34 | 34 | LL | asm!("", out("$r31") _); |
| 35 | 35 | | ^^^^^^^^^^^^^ |
| 36 | 36 | |
| 37 | 37 | error: 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 | |
| 39 | 39 | | |
| 40 | 40 | LL | asm!("/* {} */", in(freg) f); |
| 41 | 41 | | ^^^^^^^^^^ |
| 42 | 42 | |
| 43 | 43 | error: 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 | |
| 45 | 45 | | |
| 46 | 46 | LL | asm!("/* {} */", out(freg) _); |
| 47 | 47 | | ^^^^^^^^^^^ |
| 48 | 48 | |
| 49 | 49 | error: 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 | |
| 51 | 51 | | |
| 52 | 52 | LL | asm!("/* {} */", in(freg) d); |
| 53 | 53 | | ^^^^^^^^^^ |
| 54 | 54 | |
| 55 | 55 | error: 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 | |
| 57 | 57 | | |
| 58 | 58 | LL | asm!("/* {} */", out(freg) d); |
| 59 | 59 | | ^^^^^^^^^^^ |
tests/ui/asm/loongarch/bad-reg.rs+10-5| ... | ... | @@ -1,6 +1,11 @@ |
| 1 | 1 | //@ add-core-stubs |
| 2 | 2 | //@ 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 | |
| 4 | 9 | //@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu |
| 5 | 10 | //@[loongarch64_lp64d] needs-llvm-components: loongarch |
| 6 | 11 | //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat |
| ... | ... | @@ -34,12 +39,12 @@ fn f() { |
| 34 | 39 | |
| 35 | 40 | asm!("", out("$f0") _); // ok |
| 36 | 41 | 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 | |
| 38 | 43 | 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 | |
| 40 | 45 | 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 | |
| 42 | 47 | 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 | |
| 44 | 49 | } |
| 45 | 50 | } |
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 | ||
| 5 | pub fn foo(params: Option<&[&str]>) -> usize { | |
| 6 | params.unwrap().first().unwrap().len() | |
| 7 | } | |
| 8 | ||
| 9 | fn 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/array-slice-coercion-mismatch-15783.rs:12:19 | |
| 3 | | | |
| 4 | LL | 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]>` | |
| 11 | note: function defined here | |
| 12 | --> $DIR/array-slice-coercion-mismatch-15783.rs:5:8 | |
| 13 | | | |
| 14 | LL | pub fn foo(params: Option<&[&str]>) -> usize { | |
| 15 | | ^^^ ----------------------- | |
| 16 | ||
| 17 | error: aborting due to 1 previous error | |
| 18 | ||
| 19 | For 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 | ||
| 5 | fn 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 @@ |
| 1 | warning: unused closure that must be used | |
| 2 | --> $DIR/unused-closure-ice-16256.rs:7:5 | |
| 3 | | | |
| 4 | LL | |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 | ||
| 10 | warning: 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 | ||
| 6 | enum NestedEnum { | |
| 7 | First, | |
| 8 | Second, | |
| 9 | Third | |
| 10 | } | |
| 11 | enum Enum { | |
| 12 | Variant1(bool), | |
| 13 | Variant2(NestedEnum) | |
| 14 | } | |
| 15 | ||
| 16 | #[inline(never)] | |
| 17 | fn 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 | ||
| 27 | fn 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)] | |
| 12 | enum Eu64 { | |
| 13 | Pos2 = 2, | |
| 14 | PosMax = !0, | |
| 15 | Pos1 = 1, | |
| 16 | } | |
| 17 | ||
| 18 | #[derive(PartialEq, PartialOrd)] | |
| 19 | #[repr(i64)] | |
| 20 | enum Ei64 { | |
| 21 | Pos2 = 2, | |
| 22 | Neg1 = -1, | |
| 23 | NegMin = 1 << 63, | |
| 24 | PosMax = !(1 << 63), | |
| 25 | Pos1 = 1, | |
| 26 | } | |
| 27 | ||
| 28 | fn 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)] | |
| 10 | enum E1 { | |
| 11 | Pos2 = 2, | |
| 12 | Neg1 = -1, | |
| 13 | Pos1 = 1, | |
| 14 | } | |
| 15 | ||
| 16 | #[derive(PartialEq, PartialOrd)] | |
| 17 | #[repr(u8)] | |
| 18 | enum E2 { | |
| 19 | Pos2 = 2, | |
| 20 | PosMax = !0 as u8, | |
| 21 | Pos1 = 1, | |
| 22 | } | |
| 23 | ||
| 24 | #[derive(PartialEq, PartialOrd)] | |
| 25 | #[repr(i8)] | |
| 26 | enum E3 { | |
| 27 | Pos2 = 2, | |
| 28 | Neg1 = -1_i8, | |
| 29 | Pos1 = 1, | |
| 30 | } | |
| 31 | ||
| 32 | fn 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 @@ |
| 1 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>` | |
| 2 | --> $DIR/dropck-normalize-errors.rs:19:28 | |
| 3 | | | |
| 4 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | |
| 5 | | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 6 | | | |
| 7 | help: this trait has no implementations, consider adding one | |
| 8 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 9 | | | |
| 10 | LL | trait NonImplementedTrait { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: required because it appears within the type `BDecoder` | |
| 13 | --> $DIR/dropck-normalize-errors.rs:30:12 | |
| 14 | | | |
| 15 | LL | pub struct BDecoder { | |
| 16 | | ^^^^^^^^ | |
| 17 | note: required because it appears within the type `ADecoder<'a>` | |
| 18 | --> $DIR/dropck-normalize-errors.rs:16:12 | |
| 19 | | | |
| 20 | LL | pub struct ADecoder<'a> { | |
| 21 | | ^^^^^^^^ | |
| 22 | = note: the return type of a function must have a statically known size | |
| 23 | ||
| 24 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder` | |
| 25 | --> $DIR/dropck-normalize-errors.rs:27:20 | |
| 26 | | | |
| 27 | LL | type Decoder = BDecoder; | |
| 28 | | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 29 | | | |
| 30 | help: this trait has no implementations, consider adding one | |
| 31 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 32 | | | |
| 33 | LL | trait NonImplementedTrait { | |
| 34 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 35 | note: required because it appears within the type `BDecoder` | |
| 36 | --> $DIR/dropck-normalize-errors.rs:30:12 | |
| 37 | | | |
| 38 | LL | pub struct BDecoder { | |
| 39 | | ^^^^^^^^ | |
| 40 | note: required by a bound in `Decode::Decoder` | |
| 41 | --> $DIR/dropck-normalize-errors.rs:8:5 | |
| 42 | | | |
| 43 | LL | type Decoder; | |
| 44 | | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder` | |
| 45 | help: consider relaxing the implicit `Sized` restriction | |
| 46 | | | |
| 47 | LL | type Decoder: ?Sized; | |
| 48 | | ++++++++ | |
| 49 | ||
| 50 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied | |
| 51 | --> $DIR/dropck-normalize-errors.rs:31:22 | |
| 52 | | | |
| 53 | LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc, | |
| 54 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 55 | | | |
| 56 | help: this trait has no implementations, consider adding one | |
| 57 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 58 | | | |
| 59 | LL | trait NonImplementedTrait { | |
| 60 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 61 | ||
| 62 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied | |
| 63 | --> $DIR/dropck-normalize-errors.rs:19:28 | |
| 64 | | | |
| 65 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | |
| 66 | | ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 67 | | | |
| 68 | help: this trait has no implementations, consider adding one | |
| 69 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 70 | | | |
| 71 | LL | trait NonImplementedTrait { | |
| 72 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 73 | ||
| 74 | error: aborting due to 4 previous errors | |
| 75 | ||
| 76 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/drop/dropck-normalize-errors.polonius.stderr created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>` | |
| 2 | --> $DIR/dropck-normalize-errors.rs:19:28 | |
| 3 | | | |
| 4 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | |
| 5 | | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 6 | | | |
| 7 | help: this trait has no implementations, consider adding one | |
| 8 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 9 | | | |
| 10 | LL | trait NonImplementedTrait { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: required because it appears within the type `BDecoder` | |
| 13 | --> $DIR/dropck-normalize-errors.rs:30:12 | |
| 14 | | | |
| 15 | LL | pub struct BDecoder { | |
| 16 | | ^^^^^^^^ | |
| 17 | note: required because it appears within the type `ADecoder<'a>` | |
| 18 | --> $DIR/dropck-normalize-errors.rs:16:12 | |
| 19 | | | |
| 20 | LL | pub struct ADecoder<'a> { | |
| 21 | | ^^^^^^^^ | |
| 22 | = note: the return type of a function must have a statically known size | |
| 23 | ||
| 24 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder` | |
| 25 | --> $DIR/dropck-normalize-errors.rs:27:20 | |
| 26 | | | |
| 27 | LL | type Decoder = BDecoder; | |
| 28 | | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 29 | | | |
| 30 | help: this trait has no implementations, consider adding one | |
| 31 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 32 | | | |
| 33 | LL | trait NonImplementedTrait { | |
| 34 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 35 | note: required because it appears within the type `BDecoder` | |
| 36 | --> $DIR/dropck-normalize-errors.rs:30:12 | |
| 37 | | | |
| 38 | LL | pub struct BDecoder { | |
| 39 | | ^^^^^^^^ | |
| 40 | note: required by a bound in `Decode::Decoder` | |
| 41 | --> $DIR/dropck-normalize-errors.rs:8:5 | |
| 42 | | | |
| 43 | LL | type Decoder; | |
| 44 | | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder` | |
| 45 | help: consider relaxing the implicit `Sized` restriction | |
| 46 | | | |
| 47 | LL | type Decoder: ?Sized; | |
| 48 | | ++++++++ | |
| 49 | ||
| 50 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied | |
| 51 | --> $DIR/dropck-normalize-errors.rs:31:22 | |
| 52 | | | |
| 53 | LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc, | |
| 54 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 55 | | | |
| 56 | help: this trait has no implementations, consider adding one | |
| 57 | --> $DIR/dropck-normalize-errors.rs:11:1 | |
| 58 | | | |
| 59 | LL | trait NonImplementedTrait { | |
| 60 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 61 | ||
| 62 | error: aborting due to 3 previous errors | |
| 63 | ||
| 64 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/drop/dropck-normalize-errors.rs+5-1| ... | ... | @@ -1,5 +1,9 @@ |
| 1 | 1 | // Test that we don't ICE when computing the drop types for |
| 2 | 2 | |
| 3 | //@ ignore-compare-mode-polonius (explicit revisions) | |
| 4 | //@ revisions: nll polonius | |
| 5 | //@ [polonius] compile-flags: -Zpolonius=next | |
| 6 | ||
| 3 | 7 | trait Decode<'a> { |
| 4 | 8 | type Decoder; |
| 5 | 9 | } |
| ... | ... | @@ -14,7 +18,7 @@ pub struct ADecoder<'a> { |
| 14 | 18 | } |
| 15 | 19 | fn make_a_decoder<'a>() -> ADecoder<'a> { |
| 16 | 20 | //~^ ERROR the trait bound |
| 17 | //~| ERROR the trait bound | |
| 21 | //[nll]~| ERROR the trait bound | |
| 18 | 22 | panic!() |
| 19 | 23 | } |
| 20 | 24 |
tests/ui/drop/dropck-normalize-errors.stderr deleted-76| ... | ... | @@ -1,76 +0,0 @@ |
| 1 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>` | |
| 2 | --> $DIR/dropck-normalize-errors.rs:15:28 | |
| 3 | | | |
| 4 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | |
| 5 | | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 6 | | | |
| 7 | help: this trait has no implementations, consider adding one | |
| 8 | --> $DIR/dropck-normalize-errors.rs:7:1 | |
| 9 | | | |
| 10 | LL | trait NonImplementedTrait { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: required because it appears within the type `BDecoder` | |
| 13 | --> $DIR/dropck-normalize-errors.rs:26:12 | |
| 14 | | | |
| 15 | LL | pub struct BDecoder { | |
| 16 | | ^^^^^^^^ | |
| 17 | note: required because it appears within the type `ADecoder<'a>` | |
| 18 | --> $DIR/dropck-normalize-errors.rs:12:12 | |
| 19 | | | |
| 20 | LL | pub struct ADecoder<'a> { | |
| 21 | | ^^^^^^^^ | |
| 22 | = note: the return type of a function must have a statically known size | |
| 23 | ||
| 24 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder` | |
| 25 | --> $DIR/dropck-normalize-errors.rs:23:20 | |
| 26 | | | |
| 27 | LL | type Decoder = BDecoder; | |
| 28 | | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 29 | | | |
| 30 | help: this trait has no implementations, consider adding one | |
| 31 | --> $DIR/dropck-normalize-errors.rs:7:1 | |
| 32 | | | |
| 33 | LL | trait NonImplementedTrait { | |
| 34 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 35 | note: required because it appears within the type `BDecoder` | |
| 36 | --> $DIR/dropck-normalize-errors.rs:26:12 | |
| 37 | | | |
| 38 | LL | pub struct BDecoder { | |
| 39 | | ^^^^^^^^ | |
| 40 | note: required by a bound in `Decode::Decoder` | |
| 41 | --> $DIR/dropck-normalize-errors.rs:4:5 | |
| 42 | | | |
| 43 | LL | type Decoder; | |
| 44 | | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder` | |
| 45 | help: consider relaxing the implicit `Sized` restriction | |
| 46 | | | |
| 47 | LL | type Decoder: ?Sized; | |
| 48 | | ++++++++ | |
| 49 | ||
| 50 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied | |
| 51 | --> $DIR/dropck-normalize-errors.rs:27:22 | |
| 52 | | | |
| 53 | LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc, | |
| 54 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 55 | | | |
| 56 | help: this trait has no implementations, consider adding one | |
| 57 | --> $DIR/dropck-normalize-errors.rs:7:1 | |
| 58 | | | |
| 59 | LL | trait NonImplementedTrait { | |
| 60 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 61 | ||
| 62 | error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied | |
| 63 | --> $DIR/dropck-normalize-errors.rs:15:28 | |
| 64 | | | |
| 65 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | |
| 66 | | ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | |
| 67 | | | |
| 68 | help: this trait has no implementations, consider adding one | |
| 69 | --> $DIR/dropck-normalize-errors.rs:7:1 | |
| 70 | | | |
| 71 | LL | trait NonImplementedTrait { | |
| 72 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 73 | ||
| 74 | error: aborting due to 4 previous errors | |
| 75 | ||
| 76 | For 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)] | |
| 6 | enum Two { A, B} | |
| 7 | impl Drop for Two { | |
| 8 | fn drop(&mut self) { | |
| 9 | println!("Dropping!"); | |
| 10 | } | |
| 11 | } | |
| 12 | fn 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)] | |
| 6 | static mut DROP_RAN: bool = false; | |
| 7 | ||
| 8 | trait Bar { | |
| 9 | fn do_something(&mut self); //~ WARN method `do_something` is never used | |
| 10 | } | |
| 11 | ||
| 12 | struct BarImpl; | |
| 13 | ||
| 14 | impl Bar for BarImpl { | |
| 15 | fn do_something(&mut self) {} | |
| 16 | } | |
| 17 | ||
| 18 | ||
| 19 | struct Foo<B: Bar>(#[allow(dead_code)] B); | |
| 20 | ||
| 21 | impl<B: Bar> Drop for Foo<B> { | |
| 22 | fn drop(&mut self) { | |
| 23 | unsafe { | |
| 24 | DROP_RAN = true; | |
| 25 | } | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | ||
| 30 | fn 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 @@ |
| 1 | warning: method `do_something` is never used | |
| 2 | --> $DIR/generic-drop-trait-bound-15858.rs:9:8 | |
| 3 | | | |
| 4 | LL | trait Bar { | |
| 5 | | --- method in this trait | |
| 6 | LL | fn do_something(&mut self); | |
| 7 | | ^^^^^^^^^^^^ | |
| 8 | | | |
| 9 | = note: `#[warn(dead_code)]` on by default | |
| 10 | ||
| 11 | warning: 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)] | |
| 7 | struct Bar { | |
| 8 | x: isize | |
| 9 | } | |
| 10 | impl Drop for Bar { | |
| 11 | fn drop(&mut self) { | |
| 12 | assert_eq!(self.x, 22); | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | #[derive(PartialEq, Debug)] | |
| 17 | struct Foo { | |
| 18 | x: Bar, | |
| 19 | a: isize | |
| 20 | } | |
| 21 | ||
| 22 | fn foo() -> Result<Foo, isize> { | |
| 23 | return Ok(Foo { | |
| 24 | x: Bar { x: 22 }, | |
| 25 | a: return Err(32) | |
| 26 | }); | |
| 27 | } | |
| 28 | ||
| 29 | fn baz() -> Result<Foo, isize> { | |
| 30 | Ok(Foo { | |
| 31 | x: Bar { x: 22 }, | |
| 32 | a: return Err(32) | |
| 33 | }) | |
| 34 | } | |
| 35 | ||
| 36 | // explicit immediate return | |
| 37 | fn aa() -> isize { | |
| 38 | return 3; | |
| 39 | } | |
| 40 | ||
| 41 | // implicit immediate return | |
| 42 | fn bb() -> isize { | |
| 43 | 3 | |
| 44 | } | |
| 45 | ||
| 46 | // implicit outptr return | |
| 47 | fn cc() -> Result<isize, isize> { | |
| 48 | Ok(3) | |
| 49 | } | |
| 50 | ||
| 51 | // explicit outptr return | |
| 52 | fn dd() -> Result<isize, isize> { | |
| 53 | return Ok(3); | |
| 54 | } | |
| 55 | ||
| 56 | trait 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 | ||
| 71 | impl A for isize {} | |
| 72 | ||
| 73 | fn 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 | ||
| 8 | use std::mem; | |
| 9 | ||
| 10 | static mut DROP_COUNT: usize = 0; | |
| 11 | ||
| 12 | struct Fragment; | |
| 13 | ||
| 14 | impl Drop for Fragment { | |
| 15 | fn drop(&mut self) { | |
| 16 | unsafe { | |
| 17 | DROP_COUNT += 1; | |
| 18 | } | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn 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 | ||
| 6 | use std::rc::Rc; | |
| 7 | use std::cell::Cell; | |
| 8 | ||
| 9 | struct Field { | |
| 10 | number: usize, | |
| 11 | state: Rc<Cell<usize>> | |
| 12 | } | |
| 13 | ||
| 14 | impl Field { | |
| 15 | fn new(number: usize, state: Rc<Cell<usize>>) -> Field { | |
| 16 | Field { | |
| 17 | number: number, | |
| 18 | state: state | |
| 19 | } | |
| 20 | } | |
| 21 | } | |
| 22 | ||
| 23 | impl 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 | ||
| 31 | struct NoDropImpl { | |
| 32 | _one: Field, | |
| 33 | _two: Field, | |
| 34 | _three: Field | |
| 35 | } | |
| 36 | ||
| 37 | struct HasDropImpl { | |
| 38 | _one: Field, | |
| 39 | _two: Field, | |
| 40 | _three: Field | |
| 41 | } | |
| 42 | ||
| 43 | impl 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 | ||
| 51 | pub 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 | ||
| 6 | struct Empty; | |
| 7 | ||
| 8 | // This used to cause an ICE | |
| 9 | #[allow(improper_ctypes_definitions)] | |
| 10 | extern "C" fn ice(_a: Empty) {} | |
| 11 | ||
| 12 | fn 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 | ||
| 5 | use std::{fmt, ops}; | |
| 6 | ||
| 7 | struct Debuger<T> { | |
| 8 | x: T | |
| 9 | } | |
| 10 | ||
| 11 | impl<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 | ||
| 22 | fn make_shower<T>(x: T) -> Debuger<T> { | |
| 23 | Debuger { x: x } | |
| 24 | } | |
| 25 | ||
| 26 | pub 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 @@ |
| 1 | error[E0053]: method `call_once` has an incompatible type for trait | |
| 2 | --> $DIR/fn-traits-call-once-signature-15094.rs:13:5 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 9 | pub enum Foo { A } | |
| 10 | mod 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 | ||
| 24 | pub 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 | ||
| 8 | fn 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 | ||
| 3 | fn 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 @@ |
| 1 | error[E0282]: type annotations needed | |
| 2 | --> $DIR/return-block-type-inference-15965.rs:5:9 | |
| 3 | | | |
| 4 | LL | / { return () } | |
| 5 | LL | | | |
| 6 | LL | | () | |
| 7 | | |______^ cannot infer type | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0282`. |
tests/ui/issues/issue-15034.rs deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | pub struct Lexer<'a> { | |
| 2 | input: &'a str, | |
| 3 | } | |
| 4 | ||
| 5 | impl<'a> Lexer<'a> { | |
| 6 | pub fn new(input: &'a str) -> Lexer<'a> { | |
| 7 | Lexer { input: input } | |
| 8 | } | |
| 9 | } | |
| 10 | ||
| 11 | struct Parser<'a> { | |
| 12 | lexer: &'a mut Lexer<'a>, | |
| 13 | } | |
| 14 | ||
| 15 | impl<'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 | ||
| 22 | fn main() {} |
tests/ui/issues/issue-15034.stderr deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | error[E0621]: explicit lifetime required in the type of `lexer` | |
| 2 | --> $DIR/issue-15034.rs:17:9 | |
| 3 | | | |
| 4 | LL | Parser { lexer: lexer } | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required | |
| 6 | | | |
| 7 | help: add explicit lifetime `'a` to the type of `lexer` | |
| 8 | | | |
| 9 | LL | pub fn new(lexer: &'a mut Lexer<'a>) -> Parser<'a> { | |
| 10 | | ++++ | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For 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 | ||
| 5 | struct S<T>(T); | |
| 6 | ||
| 7 | static s1: S<S<usize>>=S(S(0)); | |
| 8 | static s2: S<usize>=S(0); | |
| 9 | ||
| 10 | fn 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)] | |
| 4 | enum Two { A, B} | |
| 5 | impl Drop for Two { | |
| 6 | fn drop(&mut self) { | |
| 7 | println!("Dropping!"); | |
| 8 | } | |
| 9 | } | |
| 10 | fn 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 | ||
| 3 | use std::{fmt, ops}; | |
| 4 | ||
| 5 | struct Debuger<T> { | |
| 6 | x: T | |
| 7 | } | |
| 8 | ||
| 9 | impl<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 | ||
| 20 | fn make_shower<T>(x: T) -> Debuger<T> { | |
| 21 | Debuger { x: x } | |
| 22 | } | |
| 23 | ||
| 24 | pub fn main() { | |
| 25 | let show3 = make_shower(3); | |
| 26 | show3(); | |
| 27 | } |
tests/ui/issues/issue-15094.stderr deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | error[E0053]: method `call_once` has an incompatible type for trait | |
| 2 | --> $DIR/issue-15094.rs:11:5 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 3 | fn main() { | |
| 4 | assert_eq!(count_members(&[1, 2, 3, 4]), 4); | |
| 5 | } | |
| 6 | ||
| 7 | fn 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 | ||
| 3 | pub enum T { | |
| 4 | T1(()), | |
| 5 | T2(()) | |
| 6 | } | |
| 7 | ||
| 8 | pub enum V { | |
| 9 | V1(isize), | |
| 10 | V2(bool) | |
| 11 | } | |
| 12 | ||
| 13 | fn 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 | ||
| 22 | fn 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 | ||
| 3 | macro_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 | ||
| 9 | fn 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 @@ |
| 1 | error[E0425]: cannot find value `n` in this scope | |
| 2 | --> $DIR/issue-15167.rs:3:25 | |
| 3 | | | |
| 4 | LL | macro_rules! f { () => (n) } | |
| 5 | | ^ not found in this scope | |
| 6 | ... | |
| 7 | LL | 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 | ||
| 12 | error[E0425]: cannot find value `n` in this scope | |
| 13 | --> $DIR/issue-15167.rs:3:25 | |
| 14 | | | |
| 15 | LL | macro_rules! f { () => (n) } | |
| 16 | | ^ not found in this scope | |
| 17 | ... | |
| 18 | LL | 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 | ||
| 23 | error[E0425]: cannot find value `n` in this scope | |
| 24 | --> $DIR/issue-15167.rs:3:25 | |
| 25 | | | |
| 26 | LL | macro_rules! f { () => (n) } | |
| 27 | | ^ not found in this scope | |
| 28 | ... | |
| 29 | LL | 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 | ||
| 34 | error[E0425]: cannot find value `n` in this scope | |
| 35 | --> $DIR/issue-15167.rs:3:25 | |
| 36 | | | |
| 37 | LL | macro_rules! f { () => (n) } | |
| 38 | | ^ not found in this scope | |
| 39 | ... | |
| 40 | LL | 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 | ||
| 45 | error: aborting due to 4 previous errors | |
| 46 | ||
| 47 | For more information about this error, try `rustc --explain E0425`. |
tests/ui/issues/issue-15189.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | macro_rules! third { | |
| 3 | ($e:expr) => ({let x = 2; $e[x]}) | |
| 4 | } | |
| 5 | ||
| 6 | fn 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 @@ |
| 1 | fn 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 @@ |
| 1 | error[E0599]: no method named `push` found for type `!` in the current scope | |
| 2 | --> $DIR/issue-15207.rs:3:15 | |
| 3 | | | |
| 4 | LL | break.push(1) | |
| 5 | | ^^^^ method not found in `!` | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0599`. |
tests/ui/issues/issue-15260.rs deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | struct Foo { | |
| 2 | a: usize, | |
| 3 | } | |
| 4 | ||
| 5 | fn 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 @@ |
| 1 | error[E0025]: field `a` bound multiple times in the pattern | |
| 2 | --> $DIR/issue-15260.rs:8:9 | |
| 3 | | | |
| 4 | LL | a: _, | |
| 5 | | ---- first use of `a` | |
| 6 | LL | a: _ | |
| 7 | | ^^^^ multiple uses of `a` in pattern | |
| 8 | ||
| 9 | error[E0025]: field `a` bound multiple times in the pattern | |
| 10 | --> $DIR/issue-15260.rs:14:9 | |
| 11 | | | |
| 12 | LL | a, | |
| 13 | | - first use of `a` | |
| 14 | LL | a: _ | |
| 15 | | ^^^^ multiple uses of `a` in pattern | |
| 16 | ||
| 17 | error[E0025]: field `a` bound multiple times in the pattern | |
| 18 | --> $DIR/issue-15260.rs:20:9 | |
| 19 | | | |
| 20 | LL | a, | |
| 21 | | - first use of `a` | |
| 22 | LL | a: _, | |
| 23 | | ^^^^ multiple uses of `a` in pattern | |
| 24 | ||
| 25 | error[E0025]: field `a` bound multiple times in the pattern | |
| 26 | --> $DIR/issue-15260.rs:22:9 | |
| 27 | | | |
| 28 | LL | a, | |
| 29 | | - first use of `a` | |
| 30 | ... | |
| 31 | LL | a: x | |
| 32 | | ^^^^ multiple uses of `a` in pattern | |
| 33 | ||
| 34 | error: aborting due to 4 previous errors | |
| 35 | ||
| 36 | For more information about this error, try `rustc --explain E0025`. |
tests/ui/issues/issue-15381.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | fn 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 @@ |
| 1 | error[E0005]: refutable pattern in `for` loop binding | |
| 2 | --> $DIR/issue-15381.rs:4:9 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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 | ||
| 3 | trait MyTrait { | |
| 4 | fn foo(&self); | |
| 5 | } | |
| 6 | ||
| 7 | impl<A, B, C> MyTrait for fn(A, B) -> C { | |
| 8 | fn foo(&self) {} | |
| 9 | } | |
| 10 | ||
| 11 | fn bar<T: MyTrait>(t: &T) { | |
| 12 | t.foo() | |
| 13 | } | |
| 14 | ||
| 15 | fn thing(a: isize, b: isize) -> isize { | |
| 16 | a + b | |
| 17 | } | |
| 18 | ||
| 19 | fn 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)] | |
| 10 | enum Eu64 { | |
| 11 | Pos2 = 2, | |
| 12 | PosMax = !0, | |
| 13 | Pos1 = 1, | |
| 14 | } | |
| 15 | ||
| 16 | #[derive(PartialEq, PartialOrd)] | |
| 17 | #[repr(i64)] | |
| 18 | enum Ei64 { | |
| 19 | Pos2 = 2, | |
| 20 | Neg1 = -1, | |
| 21 | NegMin = 1 << 63, | |
| 22 | PosMax = !(1 << 63), | |
| 23 | Pos1 = 1, | |
| 24 | } | |
| 25 | ||
| 26 | fn 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)] | |
| 8 | enum E1 { | |
| 9 | Pos2 = 2, | |
| 10 | Neg1 = -1, | |
| 11 | Pos1 = 1, | |
| 12 | } | |
| 13 | ||
| 14 | #[derive(PartialEq, PartialOrd)] | |
| 15 | #[repr(u8)] | |
| 16 | enum E2 { | |
| 17 | Pos2 = 2, | |
| 18 | PosMax = !0 as u8, | |
| 19 | Pos1 = 1, | |
| 20 | } | |
| 21 | ||
| 22 | #[derive(PartialEq, PartialOrd)] | |
| 23 | #[repr(i8)] | |
| 24 | enum E3 { | |
| 25 | Pos2 = 2, | |
| 26 | Neg1 = -1_i8, | |
| 27 | Pos1 = 1, | |
| 28 | } | |
| 29 | ||
| 30 | fn 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 | ||
| 3 | fn 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 | ||
| 14 | fn 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 | ||
| 24 | fn 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 | ||
| 38 | fn 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 | ||
| 52 | fn 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 | ||
| 6 | use std::ops::Index; | |
| 7 | ||
| 8 | struct Mat<T> { data: Vec<T>, cols: usize, } | |
| 9 | ||
| 10 | impl<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 | ||
| 19 | impl<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 | ||
| 27 | impl<'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 | ||
| 35 | struct Row<M> { mat: M, row: usize, } | |
| 36 | ||
| 37 | impl<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 | ||
| 45 | fn 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 @@ |
| 1 | use std::slice::Chunks; | |
| 2 | use std::slice::ChunksMut; | |
| 3 | ||
| 4 | fn 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 | ||
| 14 | fn main() {} |
tests/ui/issues/issue-15756.stderr deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | error[E0277]: the size for values of type `[T]` cannot be known at compilation time | |
| 2 | --> $DIR/issue-15756.rs:7:10 | |
| 3 | | | |
| 4 | LL | &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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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)] | |
| 5 | struct Bar { | |
| 6 | x: isize | |
| 7 | } | |
| 8 | impl Drop for Bar { | |
| 9 | fn drop(&mut self) { | |
| 10 | assert_eq!(self.x, 22); | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | #[derive(PartialEq, Debug)] | |
| 15 | struct Foo { | |
| 16 | x: Bar, | |
| 17 | a: isize | |
| 18 | } | |
| 19 | ||
| 20 | fn foo() -> Result<Foo, isize> { | |
| 21 | return Ok(Foo { | |
| 22 | x: Bar { x: 22 }, | |
| 23 | a: return Err(32) | |
| 24 | }); | |
| 25 | } | |
| 26 | ||
| 27 | fn baz() -> Result<Foo, isize> { | |
| 28 | Ok(Foo { | |
| 29 | x: Bar { x: 22 }, | |
| 30 | a: return Err(32) | |
| 31 | }) | |
| 32 | } | |
| 33 | ||
| 34 | // explicit immediate return | |
| 35 | fn aa() -> isize { | |
| 36 | return 3; | |
| 37 | } | |
| 38 | ||
| 39 | // implicit immediate return | |
| 40 | fn bb() -> isize { | |
| 41 | 3 | |
| 42 | } | |
| 43 | ||
| 44 | // implicit outptr return | |
| 45 | fn cc() -> Result<isize, isize> { | |
| 46 | Ok(3) | |
| 47 | } | |
| 48 | ||
| 49 | // explicit outptr return | |
| 50 | fn dd() -> Result<isize, isize> { | |
| 51 | return Ok(3); | |
| 52 | } | |
| 53 | ||
| 54 | trait 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 | ||
| 69 | impl A for isize {} | |
| 70 | ||
| 71 | fn 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 | ||
| 7 | pub enum Foo { A } | |
| 8 | mod 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 | ||
| 22 | pub 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 | ||
| 3 | pub fn foo(params: Option<&[&str]>) -> usize { | |
| 4 | params.unwrap().first().unwrap().len() | |
| 5 | } | |
| 6 | ||
| 7 | fn 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/issue-15783.rs:10:19 | |
| 3 | | | |
| 4 | LL | 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]>` | |
| 11 | note: function defined here | |
| 12 | --> $DIR/issue-15783.rs:3:8 | |
| 13 | | | |
| 14 | LL | pub fn foo(params: Option<&[&str]>) -> usize { | |
| 15 | | ^^^ ----------------------- | |
| 16 | ||
| 17 | error: aborting due to 1 previous error | |
| 18 | ||
| 19 | For 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 | ||
| 4 | enum NestedEnum { | |
| 5 | First, | |
| 6 | Second, | |
| 7 | Third | |
| 8 | } | |
| 9 | enum Enum { | |
| 10 | Variant1(bool), | |
| 11 | Variant2(NestedEnum) | |
| 12 | } | |
| 13 | ||
| 14 | #[inline(never)] | |
| 15 | fn 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 | ||
| 25 | fn 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)] | |
| 4 | static mut DROP_RAN: bool = false; | |
| 5 | ||
| 6 | trait Bar { | |
| 7 | fn do_something(&mut self); //~ WARN method `do_something` is never used | |
| 8 | } | |
| 9 | ||
| 10 | struct BarImpl; | |
| 11 | ||
| 12 | impl Bar for BarImpl { | |
| 13 | fn do_something(&mut self) {} | |
| 14 | } | |
| 15 | ||
| 16 | ||
| 17 | struct Foo<B: Bar>(#[allow(dead_code)] B); | |
| 18 | ||
| 19 | impl<B: Bar> Drop for Foo<B> { | |
| 20 | fn drop(&mut self) { | |
| 21 | unsafe { | |
| 22 | DROP_RAN = true; | |
| 23 | } | |
| 24 | } | |
| 25 | } | |
| 26 | ||
| 27 | ||
| 28 | fn 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 @@ |
| 1 | warning: method `do_something` is never used | |
| 2 | --> $DIR/issue-15858.rs:7:8 | |
| 3 | | | |
| 4 | LL | trait Bar { | |
| 5 | | --- method in this trait | |
| 6 | LL | fn do_something(&mut self); | |
| 7 | | ^^^^^^^^^^^^ | |
| 8 | | | |
| 9 | = note: `#[warn(dead_code)]` on by default | |
| 10 | ||
| 11 | warning: 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 | ||
| 3 | fn 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/issue-15896.rs:11:11 | |
| 3 | | | |
| 4 | LL | let u = match e { | |
| 5 | | - this expression has type `E` | |
| 6 | LL | E::B( | |
| 7 | LL | Tau{t: x}, | |
| 8 | | ^^^^^^^^^ expected `R`, found `Tau` | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For more information about this error, try `rustc --explain E0308`. |
tests/ui/issues/issue-15965.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | fn 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 @@ |
| 1 | error[E0282]: type annotations needed | |
| 2 | --> $DIR/issue-15965.rs:3:9 | |
| 3 | | | |
| 4 | LL | / { return () } | |
| 5 | LL | | | |
| 6 | LL | | () | |
| 7 | | |______^ cannot infer type | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0282`. |
tests/ui/issues/issue-16048.rs deleted-30| ... | ... | @@ -1,30 +0,0 @@ |
| 1 | trait NoLifetime { | |
| 2 | fn get<'p, T : Test<'p>>(&self) -> T; | |
| 3 | //~^ NOTE lifetimes in impl do not match this method in trait | |
| 4 | } | |
| 5 | ||
| 6 | trait Test<'p> { | |
| 7 | fn new(buf: &'p mut [u8]) -> Self; | |
| 8 | } | |
| 9 | ||
| 10 | struct Foo<'a> { | |
| 11 | buf: &'a mut [u8], | |
| 12 | } | |
| 13 | ||
| 14 | impl<'a> Test<'a> for Foo<'a> { | |
| 15 | fn new(buf: &'a mut [u8]) -> Foo<'a> { | |
| 16 | Foo { buf: buf } | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | impl<'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 | ||
| 30 | fn main() {} |
tests/ui/issues/issue-16048.stderr deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | error[E0195]: lifetime parameters or bounds on method `get` do not match the trait declaration | |
| 2 | --> $DIR/issue-16048.rs:21:11 | |
| 3 | | | |
| 4 | LL | fn get<'p, T : Test<'p>>(&self) -> T; | |
| 5 | | ------------------ lifetimes in impl do not match this method in trait | |
| 6 | ... | |
| 7 | LL | fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T { | |
| 8 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait | |
| 9 | ||
| 10 | error[E0605]: non-primitive cast: `Foo<'a>` as `T` | |
| 11 | --> $DIR/issue-16048.rs:24:16 | |
| 12 | | | |
| 13 | LL | 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 | | | |
| 16 | help: consider using the `From` trait instead | |
| 17 | | | |
| 18 | LL - return *self as T; | |
| 19 | LL + return T::from(*self); | |
| 20 | | | |
| 21 | ||
| 22 | error: aborting due to 2 previous errors | |
| 23 | ||
| 24 | Some errors have detailed explanations: E0195, E0605. | |
| 25 | For more information about an error, try `rustc --explain E0195`. |
tests/ui/issues/issue-16149.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | extern "C" { | |
| 2 | static externalValue: isize; | |
| 3 | } | |
| 4 | ||
| 5 | fn 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 @@ |
| 1 | error[E0530]: match bindings cannot shadow statics | |
| 2 | --> $DIR/issue-16149.rs:7:9 | |
| 3 | | | |
| 4 | LL | static externalValue: isize; | |
| 5 | | ---------------------------- the static `externalValue` is defined here | |
| 6 | ... | |
| 7 | LL | externalValue => true, | |
| 8 | | ^^^^^^^^^^^^^ cannot be named the same as a static | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 3 | fn 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 @@ |
| 1 | warning: unused closure that must be used | |
| 2 | --> $DIR/issue-16256.rs:5:5 | |
| 3 | | | |
| 4 | LL | |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 | ||
| 10 | warning: 1 warning emitted | |
| 11 |
tests/ui/issues/issue-16401.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | struct Slice<T> { | |
| 2 | data: *const T, | |
| 3 | len: usize, | |
| 4 | } | |
| 5 | ||
| 6 | fn 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/issue-16401.rs:8:9 | |
| 3 | | | |
| 4 | LL | match () { | |
| 5 | | -- this expression has type `()` | |
| 6 | LL | Slice { data: data, len: len } => (), | |
| 7 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Slice<_>` | |
| 8 | | | |
| 9 | = note: expected unit type `()` | |
| 10 | found struct `Slice<_>` | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For 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 | ||
| 4 | struct Empty; | |
| 5 | ||
| 6 | // This used to cause an ICE | |
| 7 | #[allow(improper_ctypes_definitions)] | |
| 8 | extern "C" fn ice(_a: Empty) {} | |
| 9 | ||
| 10 | fn main() { | |
| 11 | } |
tests/ui/issues/issue-16452.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | ||
| 4 | fn 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 | ||
| 4 | use std::rc::Rc; | |
| 5 | use std::cell::Cell; | |
| 6 | ||
| 7 | struct Field { | |
| 8 | number: usize, | |
| 9 | state: Rc<Cell<usize>> | |
| 10 | } | |
| 11 | ||
| 12 | impl Field { | |
| 13 | fn new(number: usize, state: Rc<Cell<usize>>) -> Field { | |
| 14 | Field { | |
| 15 | number: number, | |
| 16 | state: state | |
| 17 | } | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | impl 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 | ||
| 29 | struct NoDropImpl { | |
| 30 | _one: Field, | |
| 31 | _two: Field, | |
| 32 | _three: Field | |
| 33 | } | |
| 34 | ||
| 35 | struct HasDropImpl { | |
| 36 | _one: Field, | |
| 37 | _two: Field, | |
| 38 | _three: Field | |
| 39 | } | |
| 40 | ||
| 41 | impl 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 | ||
| 49 | pub 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 | ||
| 3 | use std::slice::Chunks; | |
| 4 | use std::slice::ChunksMut; | |
| 5 | ||
| 6 | fn 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 | ||
| 16 | fn main() {} |
tests/ui/iterators/explicit-deref-non-deref-type-15756.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[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 | | | |
| 4 | LL | &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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 3 | pub struct Lexer<'a> { | |
| 4 | input: &'a str, | |
| 5 | } | |
| 6 | ||
| 7 | impl<'a> Lexer<'a> { | |
| 8 | pub fn new(input: &'a str) -> Lexer<'a> { | |
| 9 | Lexer { input: input } | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | struct Parser<'a> { | |
| 14 | lexer: &'a mut Lexer<'a>, | |
| 15 | } | |
| 16 | ||
| 17 | impl<'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 | ||
| 24 | fn main() {} |
tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.stderr created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | error[E0621]: explicit lifetime required in the type of `lexer` | |
| 2 | --> $DIR/nondeterministic-lifetime-errors-15034.rs:19:9 | |
| 3 | | | |
| 4 | LL | Parser { lexer: lexer } | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required | |
| 6 | | | |
| 7 | help: add explicit lifetime `'a` to the type of `lexer` | |
| 8 | | | |
| 9 | LL | pub fn new(lexer: &'a mut Lexer<'a>) -> Parser<'a> { | |
| 10 | | ++++ | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For 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)] | |
| 5 | struct A<'a> { | |
| 6 | a: &'a i32, | |
| 7 | b: &'a i32, | |
| 8 | } | |
| 9 | ||
| 10 | impl <'a> A<'a> { | |
| 11 | fn foo<'b>(&'b self) { | |
| 12 | A { | |
| 13 | a: self.a, | |
| 14 | b: self.b, | |
| 15 | }; | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | fn 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 | |
| 4 | macro_rules! third { | |
| 5 | ($e:expr) => ({let x = 2; $e[x]}) | |
| 6 | } | |
| 7 | ||
| 8 | fn 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 | ||
| 5 | macro_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 | ||
| 11 | fn 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 @@ |
| 1 | error[E0425]: cannot find value `n` in this scope | |
| 2 | --> $DIR/macro-hygiene-scope-15167.rs:5:25 | |
| 3 | | | |
| 4 | LL | macro_rules! f { () => (n) } | |
| 5 | | ^ not found in this scope | |
| 6 | ... | |
| 7 | LL | 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 | ||
| 12 | error[E0425]: cannot find value `n` in this scope | |
| 13 | --> $DIR/macro-hygiene-scope-15167.rs:5:25 | |
| 14 | | | |
| 15 | LL | macro_rules! f { () => (n) } | |
| 16 | | ^ not found in this scope | |
| 17 | ... | |
| 18 | LL | 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 | ||
| 23 | error[E0425]: cannot find value `n` in this scope | |
| 24 | --> $DIR/macro-hygiene-scope-15167.rs:5:25 | |
| 25 | | | |
| 26 | LL | macro_rules! f { () => (n) } | |
| 27 | | ^ not found in this scope | |
| 28 | ... | |
| 29 | LL | 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 | ||
| 34 | error[E0425]: cannot find value `n` in this scope | |
| 35 | --> $DIR/macro-hygiene-scope-15167.rs:5:25 | |
| 36 | | | |
| 37 | LL | macro_rules! f { () => (n) } | |
| 38 | | ^ not found in this scope | |
| 39 | ... | |
| 40 | LL | 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 | ||
| 45 | error: aborting due to 4 previous errors | |
| 46 | ||
| 47 | For 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 | ||
| 5 | fn 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 | ||
| 16 | fn 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 | ||
| 26 | fn 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 | ||
| 40 | fn 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 | ||
| 54 | fn 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 | ||
| 7 | fn main() { | |
| 8 | let value = String::new(); | |
| 9 | run.clone()(value, ()); | |
| 10 | run(value, ()); | |
| 11 | //~^ ERROR use of moved value: `value` | |
| 12 | } | |
| 13 | fn 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 @@ |
| 1 | error[E0382]: use of moved value: `value` | |
| 2 | --> $DIR/use-correct-generic-args-in-borrow-suggest.rs:10:9 | |
| 3 | | | |
| 4 | LL | let value = String::new(); | |
| 5 | | ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait | |
| 6 | LL | run.clone()(value, ()); | |
| 7 | | ----- value moved here | |
| 8 | LL | run(value, ()); | |
| 9 | | ^^^^^ value used here after move | |
| 10 | | | |
| 11 | help: consider borrowing `value` | |
| 12 | | | |
| 13 | LL | run.clone()(&value, ()); | |
| 14 | | + | |
| 15 | ||
| 16 | error: aborting due to 1 previous error | |
| 17 | ||
| 18 | For 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 | ||
| 3 | fn 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 @@ |
| 1 | error[E0599]: no method named `push` found for type `!` in the current scope | |
| 2 | --> $DIR/never-type-method-call-15207.rs:5:15 | |
| 3 | | | |
| 4 | LL | break.push(1) | |
| 5 | | ^^^^ method not found in `!` | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0599`. |
tests/ui/nll/issue-46589.nll.stderr+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error[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 | |
| 3 | 3 | | |
| 4 | 4 | LL | *other = match (*other).get_self() { |
| 5 | 5 | | -------- first mutable borrow occurs here |
tests/ui/nll/issue-46589.polonius.stderr created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | error[E0499]: cannot borrow `**other` as mutable more than once at a time | |
| 2 | --> $DIR/issue-46589.rs:25:21 | |
| 3 | | | |
| 4 | LL | *other = match (*other).get_self() { | |
| 5 | | -------- first mutable borrow occurs here | |
| 6 | LL | Some(s) => s, | |
| 7 | LL | None => (*other).new_self() | |
| 8 | | ^^^^^^^^ | |
| 9 | | | | |
| 10 | | second mutable borrow occurs here | |
| 11 | | first borrow later used here | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 | ||
| 15 | For more information about this error, try `rustc --explain E0499`. |
tests/ui/nll/issue-46589.rs+6-6| ... | ... | @@ -1,9 +1,10 @@ |
| 1 | 1 | //@ 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 | |
| 7 | 8 | |
| 8 | 9 | struct Foo; |
| 9 | 10 | |
| ... | ... | @@ -22,7 +23,6 @@ impl Foo { |
| 22 | 23 | *other = match (*other).get_self() { |
| 23 | 24 | Some(s) => s, |
| 24 | 25 | None => (*other).new_self() |
| 25 | //[nll]~^ ERROR cannot borrow `**other` as mutable more than once at a time [E0499] | |
| 26 | 26 | }; |
| 27 | 27 | |
| 28 | 28 | 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 | ||
| 10 | fn main() { | |
| 11 | &{ [1, 2, 3][4] }; | |
| 12 | } |
tests/ui/nll/polonius/flow-sensitive-invariance.nll.stderr created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | error: lifetime may not live long enough | |
| 2 | --> $DIR/flow-sensitive-invariance.rs:20:17 | |
| 3 | | | |
| 4 | LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { | |
| 5 | | -- -- lifetime `'b` defined here | |
| 6 | | | | |
| 7 | | lifetime `'a` defined here | |
| 8 | LL | let returned_value = create_invariant(); | |
| 9 | LL | 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 | ||
| 17 | error: lifetime may not live long enough | |
| 18 | --> $DIR/flow-sensitive-invariance.rs:20:45 | |
| 19 | | | |
| 20 | LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { | |
| 21 | | -- -- lifetime `'b` defined here | |
| 22 | | | | |
| 23 | | lifetime `'a` defined here | |
| 24 | LL | let returned_value = create_invariant(); | |
| 25 | LL | 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 | ||
| 33 | help: `'a` and `'b` must be the same: replace one with the other | |
| 34 | ||
| 35 | error: aborting due to 2 previous errors | |
| 36 |
tests/ui/nll/polonius/flow-sensitive-invariance.polonius.stderr created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | error: lifetime may not live long enough | |
| 2 | --> $DIR/flow-sensitive-invariance.rs:20:17 | |
| 3 | | | |
| 4 | LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { | |
| 5 | | -- -- lifetime `'b` defined here | |
| 6 | | | | |
| 7 | | lifetime `'a` defined here | |
| 8 | LL | let returned_value = create_invariant(); | |
| 9 | LL | 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 | ||
| 17 | error: lifetime may not live long enough | |
| 18 | --> $DIR/flow-sensitive-invariance.rs:20:45 | |
| 19 | | | |
| 20 | LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { | |
| 21 | | -- -- lifetime `'b` defined here | |
| 22 | | | | |
| 23 | | lifetime `'a` defined here | |
| 24 | LL | let returned_value = create_invariant(); | |
| 25 | LL | 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 | ||
| 33 | help: `'a` and `'b` must be the same: replace one with the other | |
| 34 | ||
| 35 | error: 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 | ||
| 10 | use std::cell::Cell; | |
| 11 | ||
| 12 | struct Invariant<'l>(Cell<&'l ()>); | |
| 13 | ||
| 14 | fn create_invariant<'l>() -> Invariant<'l> { | |
| 15 | Invariant(Cell::new(&())) | |
| 16 | } | |
| 17 | ||
| 18 | fn 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 | ||
| 27 | fn 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 | ||
| 34 | fn main() {} |
tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error[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 | |
| 3 | 3 | | |
| 4 | 4 | LL | for (idx, el) in elements.iter_mut().enumerate() { |
| 5 | 5 | | ^^^^^^^^ |
tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.polonius.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[E0499]: cannot borrow `*elements` as mutable more than once at a time | |
| 2 | --> $DIR/iterating-updating-cursor-issue-108704.rs:41:26 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 @@ |
| 1 | 1 | #![crate_type = "lib"] |
| 2 | 2 | |
| 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. | |
| 4 | 5 | |
| 5 | 6 | //@ ignore-compare-mode-polonius (explicit revisions) |
| 6 | 7 | //@ revisions: nll polonius legacy |
| 7 | 8 | //@ [nll] known-bug: #108704 |
| 8 | //@ [polonius] check-pass | |
| 9 | //@ [polonius] known-bug: #108704 | |
| 9 | 10 | //@ [polonius] compile-flags: -Z polonius=next |
| 10 | 11 | //@ [legacy] check-pass |
| 11 | 12 | //@ [legacy] compile-flags: -Z polonius=legacy |
| ... | ... | @@ -32,7 +33,7 @@ fn merge_tree_ok(root: &mut Root, path: Vec<String>) { |
| 32 | 33 | } |
| 33 | 34 | } |
| 34 | 35 | |
| 35 | // NLLs fail here | |
| 36 | // NLLs and polonius alpha fail here | |
| 36 | 37 | fn merge_tree_ko(root: &mut Root, path: Vec<String>) { |
| 37 | 38 | let mut elements = &mut root.children; |
| 38 | 39 |
tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr+2-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error[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 | |
| 3 | 3 | | |
| 4 | 4 | LL | while let Some(now) = p { |
| 5 | 5 | | ^^^ - first borrow used here, in later iteration of loop |
| ... | ... | @@ -7,7 +7,7 @@ LL | while let Some(now) = p { |
| 7 | 7 | | `p.0` was mutably borrowed here in the previous iteration of the loop |
| 8 | 8 | |
| 9 | 9 | error[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 | |
| 11 | 11 | | |
| 12 | 12 | LL | while let Some(now) = p { |
| 13 | 13 | | --- ^ |
tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.polonius.stderr created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | error[E0499]: cannot borrow `p.0` as mutable more than once at a time | |
| 2 | --> $DIR/iterating-updating-cursor-issue-57165.rs:30:20 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 9 | error[E0503]: cannot use `*p` because it was mutably borrowed | |
| 10 | --> $DIR/iterating-updating-cursor-issue-57165.rs:30:27 | |
| 11 | | | |
| 12 | LL | 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 | ||
| 19 | error: aborting due to 2 previous errors | |
| 20 | ||
| 21 | Some errors have detailed explanations: E0499, E0503. | |
| 22 | For 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 @@ |
| 1 | 1 | #![crate_type = "lib"] |
| 2 | 2 | |
| 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. | |
| 4 | 5 | |
| 5 | 6 | //@ ignore-compare-mode-polonius (explicit revisions) |
| 6 | 7 | //@ revisions: nll polonius legacy |
| 7 | 8 | //@ [nll] known-bug: #57165 |
| 8 | //@ [polonius] check-pass | |
| 9 | //@ [polonius] known-bug: #57165 | |
| 9 | 10 | //@ [polonius] compile-flags: -Z polonius=next |
| 10 | 11 | //@ [legacy] check-pass |
| 11 | 12 | //@ [legacy] compile-flags: -Z polonius=legacy |
| ... | ... | @@ -22,7 +23,7 @@ fn no_control_flow() { |
| 22 | 23 | } |
| 23 | 24 | } |
| 24 | 25 | |
| 25 | // NLLs fail here | |
| 26 | // NLLs and polonius alpha fail here | |
| 26 | 27 | fn conditional() { |
| 27 | 28 | let mut b = Some(Box::new(X { next: None })); |
| 28 | 29 | let mut p = &mut b; |
tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error[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 | |
| 3 | 3 | | |
| 4 | 4 | LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) { |
| 5 | 5 | | - 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 @@ |
| 1 | error[E0506]: cannot assign to `*node_ref` because it is borrowed | |
| 2 | --> $DIR/iterating-updating-cursor-issue-63908.rs:43:5 | |
| 3 | | | |
| 4 | LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) { | |
| 5 | | - let's call the lifetime of this reference `'1` | |
| 6 | LL | loop { | |
| 7 | LL | let next_ref = &mut node_ref.as_mut().unwrap().next; | |
| 8 | | -------- `*node_ref` is borrowed here | |
| 9 | ... | |
| 10 | LL | node_ref = next_ref; | |
| 11 | | ------------------- assignment requires that `*node_ref` is borrowed for `'1` | |
| 12 | ... | |
| 13 | LL | *node_ref = None; | |
| 14 | | ^^^^^^^^^ `*node_ref` is assigned to here but it was already borrowed | |
| 15 | ||
| 16 | error: aborting due to 1 previous error | |
| 17 | ||
| 18 | For 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 @@ |
| 1 | 1 | #![crate_type = "lib"] |
| 2 | 2 | |
| 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. | |
| 4 | 5 | |
| 5 | 6 | //@ ignore-compare-mode-polonius (explicit revisions) |
| 6 | 7 | //@ revisions: nll polonius legacy |
| 7 | 8 | //@ [nll] known-bug: #63908 |
| 8 | //@ [polonius] check-pass | |
| 9 | //@ [polonius] known-bug: #63908 | |
| 9 | 10 | //@ [polonius] compile-flags: -Z polonius=next |
| 10 | 11 | //@ [legacy] check-pass |
| 11 | 12 | //@ [legacy] compile-flags: -Z polonius=legacy |
| ... | ... | @@ -27,7 +28,7 @@ fn remove_last_node_recursive<T>(node_ref: &mut List<T>) { |
| 27 | 28 | } |
| 28 | 29 | } |
| 29 | 30 | |
| 30 | // NLLs fail here | |
| 31 | // NLLs and polonius alpha fail here | |
| 31 | 32 | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) { |
| 32 | 33 | loop { |
| 33 | 34 | 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 @@ |
| 1 | error[E0499]: cannot borrow `self.buf_read` as mutable more than once at a time | |
| 2 | --> $DIR/iterating-updating-mutref.rs:61:23 | |
| 3 | | | |
| 4 | LL | pub fn next<'a>(&'a mut self) -> &'a str { | |
| 5 | | -- lifetime `'a` defined here | |
| 6 | LL | loop { | |
| 7 | LL | let buf = self.buf_read.fill_buf(); | |
| 8 | | ^^^^^^^^^^^^^ `self.buf_read` was mutably borrowed here in the previous iteration of the loop | |
| 9 | LL | if let Some(s) = decode(buf) { | |
| 10 | LL | return s; | |
| 11 | | - returning this value requires that `self.buf_read` is borrowed for `'a` | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 | ||
| 15 | For 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 | |
| 19 | struct List<T> { | |
| 20 | value: T, | |
| 21 | next: Option<Box<List<T>>>, | |
| 22 | } | |
| 23 | ||
| 24 | fn 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. | |
| 38 | fn 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. | |
| 53 | pub struct Decoder { | |
| 54 | buf_read: BufRead, | |
| 55 | } | |
| 56 | ||
| 57 | impl 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 | ||
| 75 | struct BufRead; | |
| 76 | ||
| 77 | impl BufRead { | |
| 78 | fn fill_buf(&mut self) -> &[u8] { | |
| 79 | unimplemented!() | |
| 80 | } | |
| 81 | } | |
| 82 | ||
| 83 | fn decode(_: &[u8]) -> Option<&str> { | |
| 84 | unimplemented!() | |
| 85 | } | |
| 86 | ||
| 87 | fn main() {} |
tests/ui/nll/polonius/lending-iterator-sanity-checks.legacy.stderr created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | error[E0499]: cannot borrow `*t` as mutable more than once at a time | |
| 2 | --> $DIR/lending-iterator-sanity-checks.rs:19:19 | |
| 3 | | | |
| 4 | LL | fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> { | |
| 5 | | - let's call the lifetime of this reference `'1` | |
| 6 | LL | let Some(i) = t.next() else { return None }; | |
| 7 | | - first mutable borrow occurs here | |
| 8 | LL | let Some(j) = t.next() else { return None }; | |
| 9 | | ^ second mutable borrow occurs here | |
| 10 | ... | |
| 11 | LL | Some((i, j)) | |
| 12 | | ------------ returning this value requires that `*t` is borrowed for `'1` | |
| 13 | ||
| 14 | error[E0499]: cannot borrow `*t` as mutable more than once at a time | |
| 15 | --> $DIR/lending-iterator-sanity-checks.rs:31:13 | |
| 16 | | | |
| 17 | LL | let i = t.next(); | |
| 18 | | - first mutable borrow occurs here | |
| 19 | ... | |
| 20 | LL | let j = t.next(); | |
| 21 | | ^ second mutable borrow occurs here | |
| 22 | LL | | |
| 23 | LL | } | |
| 24 | | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>` | |
| 25 | ||
| 26 | error: aborting due to 2 previous errors | |
| 27 | ||
| 28 | For 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 @@ |
| 1 | error[E0499]: cannot borrow `*t` as mutable more than once at a time | |
| 2 | --> $DIR/lending-iterator-sanity-checks.rs:19:19 | |
| 3 | | | |
| 4 | LL | fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> { | |
| 5 | | - let's call the lifetime of this reference `'1` | |
| 6 | LL | let Some(i) = t.next() else { return None }; | |
| 7 | | - first mutable borrow occurs here | |
| 8 | LL | let Some(j) = t.next() else { return None }; | |
| 9 | | ^ second mutable borrow occurs here | |
| 10 | ... | |
| 11 | LL | Some((i, j)) | |
| 12 | | ------------ returning this value requires that `*t` is borrowed for `'1` | |
| 13 | ||
| 14 | error[E0499]: cannot borrow `*t` as mutable more than once at a time | |
| 15 | --> $DIR/lending-iterator-sanity-checks.rs:31:13 | |
| 16 | | | |
| 17 | LL | let i = t.next(); | |
| 18 | | - first mutable borrow occurs here | |
| 19 | ... | |
| 20 | LL | let j = t.next(); | |
| 21 | | ^ second mutable borrow occurs here | |
| 22 | LL | | |
| 23 | LL | } | |
| 24 | | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>` | |
| 25 | ||
| 26 | error: aborting due to 2 previous errors | |
| 27 | ||
| 28 | For 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 @@ |
| 1 | error[E0499]: cannot borrow `*t` as mutable more than once at a time | |
| 2 | --> $DIR/lending-iterator-sanity-checks.rs:19:19 | |
| 3 | | | |
| 4 | LL | let Some(i) = t.next() else { return None }; | |
| 5 | | - first mutable borrow occurs here | |
| 6 | LL | let Some(j) = t.next() else { return None }; | |
| 7 | | ^ second mutable borrow occurs here | |
| 8 | ... | |
| 9 | LL | } | |
| 10 | | - first borrow might be used here, when `i` is dropped and runs the destructor for type `<T as LendingIterator>::Item<'_>` | |
| 11 | ||
| 12 | error[E0499]: cannot borrow `*t` as mutable more than once at a time | |
| 13 | --> $DIR/lending-iterator-sanity-checks.rs:31:13 | |
| 14 | | | |
| 15 | LL | let i = t.next(); | |
| 16 | | - first mutable borrow occurs here | |
| 17 | ... | |
| 18 | LL | let j = t.next(); | |
| 19 | | ^ second mutable borrow occurs here | |
| 20 | LL | | |
| 21 | LL | } | |
| 22 | | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>` | |
| 23 | ||
| 24 | error: aborting due to 2 previous errors | |
| 25 | ||
| 26 | For 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 | ||
| 10 | trait LendingIterator { | |
| 11 | type Item<'a> | |
| 12 | where | |
| 13 | Self: 'a; | |
| 14 | fn next(&mut self) -> Option<Self::Item<'_>>; | |
| 15 | } | |
| 16 | ||
| 17 | fn 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 | ||
| 26 | fn 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. | |
| 37 | fn 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 | |
| 55 | fn items_have_no_borrows<T: LendingIterator>(t: &mut T) | |
| 56 | where | |
| 57 | for<'a> T::Item<'a>: 'static, | |
| 58 | { | |
| 59 | let i = t.next(); | |
| 60 | let j = t.next(); | |
| 61 | } | |
| 62 | ||
| 63 | fn items_are_copy<T: LendingIterator>(t: &mut T) | |
| 64 | where | |
| 65 | for<'a> T::Item<'a>: Copy, | |
| 66 | { | |
| 67 | let i = t.next(); | |
| 68 | let j = t.next(); | |
| 69 | } | |
| 70 | ||
| 71 | fn 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 | ||
| 7 | struct S<T>(T); | |
| 8 | ||
| 9 | static s1: S<S<usize>>=S(S(0)); | |
| 10 | static s2: S<usize>=S(0); | |
| 11 | ||
| 12 | fn 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 | ||
| 5 | fn 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/enum-struct-pattern-mismatch-15896.rs:13:11 | |
| 3 | | | |
| 4 | LL | let u = match e { | |
| 5 | | - this expression has type `E` | |
| 6 | LL | E::B( | |
| 7 | LL | Tau{t: x}, | |
| 8 | | ^^^^^^^^^ expected `R`, found `Tau` | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 3 | fn 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 @@ |
| 1 | error[E0005]: refutable pattern in `for` loop binding | |
| 2 | --> $DIR/refutable-pattern-for-loop-15381.rs:6:9 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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 | ||
| 5 | fn main() { | |
| 6 | assert_eq!(count_members(&[1, 2, 3, 4]), 4); | |
| 7 | } | |
| 8 | ||
| 9 | fn 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 | ||
| 3 | extern "C" { | |
| 4 | static externalValue: isize; | |
| 5 | } | |
| 6 | ||
| 7 | fn 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 @@ |
| 1 | error[E0530]: match bindings cannot shadow statics | |
| 2 | --> $DIR/static-binding-shadow-16149.rs:9:9 | |
| 3 | | | |
| 4 | LL | static externalValue: isize; | |
| 5 | | ---------------------------- the static `externalValue` is defined here | |
| 6 | ... | |
| 7 | LL | externalValue => true, | |
| 8 | | ^^^^^^^^^^^^^ cannot be named the same as a static | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 3 | struct Foo { | |
| 4 | a: usize, | |
| 5 | } | |
| 6 | ||
| 7 | fn 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 @@ |
| 1 | error[E0025]: field `a` bound multiple times in the pattern | |
| 2 | --> $DIR/struct-field-duplicate-binding-15260.rs:10:9 | |
| 3 | | | |
| 4 | LL | a: _, | |
| 5 | | ---- first use of `a` | |
| 6 | LL | a: _ | |
| 7 | | ^^^^ multiple uses of `a` in pattern | |
| 8 | ||
| 9 | error[E0025]: field `a` bound multiple times in the pattern | |
| 10 | --> $DIR/struct-field-duplicate-binding-15260.rs:16:9 | |
| 11 | | | |
| 12 | LL | a, | |
| 13 | | - first use of `a` | |
| 14 | LL | a: _ | |
| 15 | | ^^^^ multiple uses of `a` in pattern | |
| 16 | ||
| 17 | error[E0025]: field `a` bound multiple times in the pattern | |
| 18 | --> $DIR/struct-field-duplicate-binding-15260.rs:22:9 | |
| 19 | | | |
| 20 | LL | a, | |
| 21 | | - first use of `a` | |
| 22 | LL | a: _, | |
| 23 | | ^^^^ multiple uses of `a` in pattern | |
| 24 | ||
| 25 | error[E0025]: field `a` bound multiple times in the pattern | |
| 26 | --> $DIR/struct-field-duplicate-binding-15260.rs:24:9 | |
| 27 | | | |
| 28 | LL | a, | |
| 29 | | - first use of `a` | |
| 30 | ... | |
| 31 | LL | a: x | |
| 32 | | ^^^^ multiple uses of `a` in pattern | |
| 33 | ||
| 34 | error: aborting due to 4 previous errors | |
| 35 | ||
| 36 | For 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 | ||
| 5 | pub enum T { | |
| 6 | T1(()), | |
| 7 | T2(()), | |
| 8 | } | |
| 9 | ||
| 10 | pub enum V { | |
| 11 | V1(isize), | |
| 12 | V2(bool), | |
| 13 | } | |
| 14 | ||
| 15 | fn 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 | ||
| 23 | fn 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 | ||
| 3 | struct Slice<T> { | |
| 4 | data: *const T, | |
| 5 | len: usize, | |
| 6 | } | |
| 7 | ||
| 8 | fn 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/unit-type-struct-pattern-mismatch-16401.rs:10:9 | |
| 3 | | | |
| 4 | LL | match () { | |
| 5 | | -- this expression has type `()` | |
| 6 | LL | Slice { data: data, len: len } => (), | |
| 7 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Slice<_>` | |
| 8 | | | |
| 9 | = note: expected unit type `()` | |
| 10 | found struct `Slice<_>` | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For 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 | ||
| 6 | fn 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 | ||
| 5 | trait MyTrait { | |
| 6 | fn foo(&self); | |
| 7 | } | |
| 8 | ||
| 9 | impl<A, B, C> MyTrait for fn(A, B) -> C { | |
| 10 | fn foo(&self) {} | |
| 11 | } | |
| 12 | ||
| 13 | fn bar<T: MyTrait>(t: &T) { | |
| 14 | t.foo() | |
| 15 | } | |
| 16 | ||
| 17 | fn thing(a: isize, b: isize) -> isize { | |
| 18 | a + b | |
| 19 | } | |
| 20 | ||
| 21 | fn 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 | ||
| 8 | use std::ops::Index; | |
| 9 | ||
| 10 | struct Mat<T> { data: Vec<T>, cols: usize, } | |
| 11 | ||
| 12 | impl<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 | ||
| 21 | impl<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 | ||
| 29 | impl<'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 | ||
| 37 | struct Row<M> { mat: M, row: usize, } | |
| 38 | ||
| 39 | impl<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 | ||
| 47 | fn 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 | ||
| 3 | trait NoLifetime { | |
| 4 | fn get<'p, T : Test<'p>>(&self) -> T; | |
| 5 | //~^ NOTE lifetimes in impl do not match this method in trait | |
| 6 | } | |
| 7 | ||
| 8 | trait Test<'p> { | |
| 9 | fn new(buf: &'p mut [u8]) -> Self; | |
| 10 | } | |
| 11 | ||
| 12 | struct Foo<'a> { | |
| 13 | buf: &'a mut [u8], | |
| 14 | } | |
| 15 | ||
| 16 | impl<'a> Test<'a> for Foo<'a> { | |
| 17 | fn new(buf: &'a mut [u8]) -> Foo<'a> { | |
| 18 | Foo { buf: buf } | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | impl<'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 | ||
| 32 | fn main() {} |
tests/ui/traits/lifetime-mismatch-trait-impl-16048.stderr created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | error[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 | | | |
| 4 | LL | fn get<'p, T : Test<'p>>(&self) -> T; | |
| 5 | | ------------------ lifetimes in impl do not match this method in trait | |
| 6 | ... | |
| 7 | LL | fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T { | |
| 8 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait | |
| 9 | ||
| 10 | error[E0605]: non-primitive cast: `Foo<'a>` as `T` | |
| 11 | --> $DIR/lifetime-mismatch-trait-impl-16048.rs:26:16 | |
| 12 | | | |
| 13 | LL | 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 | | | |
| 16 | help: consider using the `From` trait instead | |
| 17 | | | |
| 18 | LL - return *self as T; | |
| 19 | LL + return T::from(*self); | |
| 20 | | | |
| 21 | ||
| 22 | error: aborting due to 2 previous errors | |
| 23 | ||
| 24 | Some errors have detailed explanations: E0195, E0605. | |
| 25 | For 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 @@ |
| 1 | error[E0277]: `&'a T` is not an iterator | |
| 2 | --> $DIR/hir-wf-check-erase-regions.rs:11:21 | |
| 3 | | | |
| 4 | LL | 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` | |
| 10 | note: required by a bound in `std::iter::IntoIterator::IntoIter` | |
| 11 | --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | |
| 12 | ||
| 13 | error[E0277]: `&'a T` is not an iterator | |
| 14 | --> $DIR/hir-wf-check-erase-regions.rs:11:5 | |
| 15 | | | |
| 16 | LL | 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` | |
| 22 | note: required by a bound in `Flatten` | |
| 23 | --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL | |
| 24 | ||
| 25 | error[E0277]: `&'a T` is not an iterator | |
| 26 | --> $DIR/hir-wf-check-erase-regions.rs:15:27 | |
| 27 | | | |
| 28 | LL | 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` | |
| 34 | note: required by a bound in `Flatten` | |
| 35 | --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL | |
| 36 | ||
| 37 | error[E0277]: `&T` is not an iterator | |
| 38 | --> $DIR/hir-wf-check-erase-regions.rs:15:27 | |
| 39 | | | |
| 40 | LL | 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 | ||
| 47 | error: aborting due to 4 previous errors | |
| 48 | ||
| 49 | For 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 @@ |
| 1 | error[E0277]: `&'a T` is not an iterator | |
| 2 | --> $DIR/hir-wf-check-erase-regions.rs:11:21 | |
| 3 | | | |
| 4 | LL | 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` | |
| 10 | note: required by a bound in `std::iter::IntoIterator::IntoIter` | |
| 11 | --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | |
| 12 | ||
| 13 | error[E0277]: `&'a T` is not an iterator | |
| 14 | --> $DIR/hir-wf-check-erase-regions.rs:11:5 | |
| 15 | | | |
| 16 | LL | 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` | |
| 22 | note: required by a bound in `Flatten` | |
| 23 | --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL | |
| 24 | ||
| 25 | error[E0277]: `&'a T` is not an iterator | |
| 26 | --> $DIR/hir-wf-check-erase-regions.rs:15:27 | |
| 27 | | | |
| 28 | LL | 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` | |
| 34 | note: required by a bound in `Flatten` | |
| 35 | --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL | |
| 36 | ||
| 37 | error: aborting due to 3 previous errors | |
| 38 | ||
| 39 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/wf/hir-wf-check-erase-regions.rs+5-1| ... | ... | @@ -1,6 +1,10 @@ |
| 1 | 1 | // Regression test for #87549. |
| 2 | 2 | //@ incremental |
| 3 | 3 | |
| 4 | //@ ignore-compare-mode-polonius (explicit revisions) | |
| 5 | //@ revisions: nll polonius | |
| 6 | //@ [polonius] compile-flags: -Zpolonius=next | |
| 7 | ||
| 4 | 8 | pub struct Table<T, const N: usize>([Option<T>; N]); |
| 5 | 9 | |
| 6 | 10 | impl<'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> { |
| 10 | 14 | |
| 11 | 15 | fn into_iter(self) -> Self::IntoIter { |
| 12 | 16 | //~^ ERROR `&'a T` is not an iterator |
| 13 | //~| ERROR `&T` is not an iterator | |
| 17 | //[nll]~| ERROR `&T` is not an iterator | |
| 14 | 18 | unimplemented!() |
| 15 | 19 | } |
| 16 | 20 | } |
tests/ui/wf/hir-wf-check-erase-regions.stderr deleted-49| ... | ... | @@ -1,49 +0,0 @@ |
| 1 | error[E0277]: `&'a T` is not an iterator | |
| 2 | --> $DIR/hir-wf-check-erase-regions.rs:7:21 | |
| 3 | | | |
| 4 | LL | 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` | |
| 10 | note: required by a bound in `std::iter::IntoIterator::IntoIter` | |
| 11 | --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | |
| 12 | ||
| 13 | error[E0277]: `&'a T` is not an iterator | |
| 14 | --> $DIR/hir-wf-check-erase-regions.rs:7:5 | |
| 15 | | | |
| 16 | LL | 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` | |
| 22 | note: required by a bound in `Flatten` | |
| 23 | --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL | |
| 24 | ||
| 25 | error[E0277]: `&'a T` is not an iterator | |
| 26 | --> $DIR/hir-wf-check-erase-regions.rs:11:27 | |
| 27 | | | |
| 28 | LL | 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` | |
| 34 | note: required by a bound in `Flatten` | |
| 35 | --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL | |
| 36 | ||
| 37 | error[E0277]: `&T` is not an iterator | |
| 38 | --> $DIR/hir-wf-check-erase-regions.rs:11:27 | |
| 39 | | | |
| 40 | LL | 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 | ||
| 47 | error: aborting due to 4 previous errors | |
| 48 | ||
| 49 | For more information about this error, try `rustc --explain E0277`. |
triagebot.toml+1-1| ... | ... | @@ -1573,7 +1573,7 @@ changelog-branch = "master" |
| 1573 | 1573 | [note] |
| 1574 | 1574 | |
| 1575 | 1575 | [behind-upstream] |
| 1576 | days-threshold = 14 | |
| 1576 | days-threshold = 28 | |
| 1577 | 1577 | |
| 1578 | 1578 | # Canonicalize issue numbers to avoid closing the wrong issue |
| 1579 | 1579 | # when commits are included in subtrees, as well as warning links in commits. |