From b43aa960d0a7d09f137cc6b7f26605f6183cd72f Mon Sep 17 00:00:00 2001 From: johanngan Date: Sun, 10 Jan 2021 01:18:23 -0600 Subject: [PATCH 01/31] Print failure message on all tests that should panic, but don't This already happens with should_panic tests without an expected message. This commit fixes should_panic tests with an expected message to have the same behavior. --- library/test/src/test_result.rs | 2 +- library/test/src/tests.rs | 39 ++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs index 465f3f8f99427..598fb670bb4bf 100644 --- a/library/test/src/test_result.rs +++ b/library/test/src/test_result.rs @@ -63,7 +63,7 @@ pub fn calc_result<'a>( )) } } - (&ShouldPanic::Yes, Ok(())) => { + (&ShouldPanic::Yes, Ok(())) | (&ShouldPanic::YesWithMessage(_), Ok(())) => { TestResult::TrFailedMsg("test did not panic as expected".to_string()) } _ if desc.allow_fail => TestResult::TrAllowedFail, diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 74313cc4438ed..a629829b88514 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -228,21 +228,30 @@ fn test_should_panic_non_string_message_type() { #[test] #[cfg(not(target_os = "emscripten"))] fn test_should_panic_but_succeeds() { - fn f() {} - let desc = TestDescAndFn { - desc: TestDesc { - name: StaticTestName("whatever"), - ignore: false, - should_panic: ShouldPanic::Yes, - allow_fail: false, - test_type: TestType::Unknown, - }, - testfn: DynTestFn(Box::new(f)), - }; - let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); - let result = rx.recv().unwrap().result; - assert_eq!(result, TrFailedMsg("test did not panic as expected".to_string())); + let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")]; + + for &should_panic in should_panic_variants.iter() { + fn f() {} + let desc = TestDescAndFn { + desc: TestDesc { + name: StaticTestName("whatever"), + ignore: false, + should_panic, + allow_fail: false, + test_type: TestType::Unknown, + }, + testfn: DynTestFn(Box::new(f)), + }; + let (tx, rx) = channel(); + run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No); + let result = rx.recv().unwrap().result; + assert_eq!( + result, + TrFailedMsg("test did not panic as expected".to_string()), + "should_panic == {:?}", + should_panic + ); + } } fn report_time_test_template(report_time: bool) -> Option { From 2624b3e443b6a09c8338c92c09bc8d8b41fa5cb4 Mon Sep 17 00:00:00 2001 From: Chris Pardy Date: Sun, 22 Nov 2020 20:03:42 -0500 Subject: [PATCH 02/31] Improve diagnostics for Precise Capture --- compiler/rustc_middle/src/ty/mod.rs | 21 ++- compiler/rustc_typeck/src/check/upvar.rs | 149 +++++++++++++++--- compiler/rustc_typeck/src/check/writeback.rs | 2 +- compiler/rustc_typeck/src/expr_use_visitor.rs | 2 +- .../capture-analysis-1.rs | 36 +++++ .../capture-analysis-1.stderr | 77 +++++++++ .../capture-analysis-2.rs | 31 ++++ .../capture-analysis-2.stderr | 65 ++++++++ .../deep-multilevel-struct.rs | 52 ++++++ .../deep-multilevel-struct.stderr | 70 ++++++++ .../deep-multilevel-tuple.rs | 28 ++++ .../deep-multilevel-tuple.stderr | 70 ++++++++ .../simple-struct-min-capture.rs | 4 +- .../simple-struct-min-capture.stderr | 5 +- 14 files changed, 581 insertions(+), 31 deletions(-) create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1399fc76e02d6..82f6352872169 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -741,8 +741,20 @@ pub struct CapturedPlace<'tcx> { pub struct CaptureInfo<'tcx> { /// Expr Id pointing to use that resulted in selecting the current capture kind /// + /// Eg: + /// ```rust,no_run + /// let mut t = (0,1); + /// + /// let c = || { + /// println!("{}",t); // L1 + /// t.1 = 4; // L2 + /// }; + /// ``` + /// `capture_kind_expr_id` will point to the use on L2 and `path_expr_id` will point to the + /// use on L1. + /// /// If the user doesn't enable feature `capture_disjoint_fields` (RFC 2229) then, it is - /// possible that we don't see the use of a particular place resulting in expr_id being + /// possible that we don't see the use of a particular place resulting in capture_kind_expr_id being /// None. In such case we fallback on uvpars_mentioned for span. /// /// Eg: @@ -756,7 +768,12 @@ pub struct CaptureInfo<'tcx> { /// /// In this example, if `capture_disjoint_fields` is **not** set, then x will be captured, /// but we won't see it being used during capture analysis, since it's essentially a discard. - pub expr_id: Option, + pub capture_kind_expr_id: Option, + /// Expr Id pointing to use that resulted the corresponding place being captured + /// + /// See `capture_kind_expr_id` for example. + /// + pub path_expr_id: Option, /// Capture mode that was selected pub capture_kind: UpvarCapture<'tcx>, diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index e8cbefd44ee6d..44652864f6ef0 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -42,7 +42,7 @@ use rustc_infer::infer::UpvarRegion; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, ProjectionKind}; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts}; use rustc_span::sym; -use rustc_span::{Span, Symbol}; +use rustc_span::{MultiSpan, Span, Symbol}; /// Describe the relationship between the paths of two places /// eg: @@ -135,7 +135,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let upvar_id = ty::UpvarId::new(var_hir_id, local_def_id); let capture_kind = self.init_capture_kind(capture_clause, upvar_id, span); - let info = ty::CaptureInfo { expr_id: None, capture_kind }; + let info = ty::CaptureInfo { + capture_kind_expr_id: None, + path_expr_id: None, + capture_kind, + }; capture_information.insert(place, info); } @@ -298,8 +302,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(capture_kind) = upvar_capture_map.get(&upvar_id) { // upvar_capture_map only stores the UpvarCapture (CaptureKind), // so we create a fake capture info with no expression. - let fake_capture_info = - ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind }; + let fake_capture_info = ty::CaptureInfo { + capture_kind_expr_id: None, + path_expr_id: None, + capture_kind: *capture_kind, + }; determine_capture_info(fake_capture_info, capture_info).capture_kind } else { capture_info.capture_kind @@ -349,20 +356,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// ``` /// { - /// Place(base: hir_id_s, projections: [], ....) -> (hir_id_L5, ByValue), - /// Place(base: hir_id_p, projections: [Field(0, 0)], ...) -> (hir_id_L2, ByRef(MutBorrow)) - /// Place(base: hir_id_p, projections: [Field(1, 0)], ...) -> (hir_id_L3, ByRef(ImmutBorrow)) - /// Place(base: hir_id_p, projections: [], ...) -> (hir_id_L4, ByRef(ImmutBorrow)) + /// Place(base: hir_id_s, projections: [], ....) -> { + /// capture_kind_expr: hir_id_L5, + /// path_expr_id: hir_id_L5, + /// capture_kind: ByValue + /// }, + /// Place(base: hir_id_p, projections: [Field(0, 0)], ...) -> { + /// capture_kind_expr: hir_id_L2, + /// path_expr_id: hir_id_L2, + /// capture_kind: ByValue + /// }, + /// Place(base: hir_id_p, projections: [Field(1, 0)], ...) -> { + /// capture_kind_expr: hir_id_L3, + /// path_expr_id: hir_id_L3, + /// capture_kind: ByValue + /// }, + /// Place(base: hir_id_p, projections: [], ...) -> { + /// capture_kind_expr: hir_id_L4, + /// path_expr_id: hir_id_L4, + /// capture_kind: ByValue + /// }, /// ``` /// /// After the min capture analysis, we get: /// ``` /// { /// hir_id_s -> [ - /// Place(base: hir_id_s, projections: [], ....) -> (hir_id_L4, ByValue) + /// Place(base: hir_id_s, projections: [], ....) -> { + /// capture_kind_expr: hir_id_L5, + /// path_expr_id: hir_id_L5, + /// capture_kind: ByValue + /// }, /// ], /// hir_id_p -> [ - /// Place(base: hir_id_p, projections: [], ...) -> (hir_id_L2, ByRef(MutBorrow)), + /// Place(base: hir_id_p, projections: [], ...) -> { + /// capture_kind_expr: hir_id_L2, + /// path_expr_id: hir_id_L4, + /// capture_kind: ByValue + /// }, /// ], /// ``` fn compute_min_captures( @@ -415,8 +446,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // current place is ancestor of possible_descendant PlaceAncestryRelation::Ancestor => { descendant_found = true; + let backup_path_expr_id = updated_capture_info.path_expr_id; + updated_capture_info = determine_capture_info(updated_capture_info, possible_descendant.info); + + // we need to keep the ancestor's `path_expr_id` + updated_capture_info.path_expr_id = backup_path_expr_id; false } @@ -431,9 +467,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // current place is descendant of possible_ancestor PlaceAncestryRelation::Descendant => { ancestor_found = true; + let backup_path_expr_id = possible_ancestor.info.path_expr_id; possible_ancestor.info = determine_capture_info(possible_ancestor.info, capture_info); + // we need to keep the ancestor's `path_expr_id` + possible_ancestor.info.path_expr_id = backup_path_expr_id; + // Only one ancestor of the current place will be in the list. break; } @@ -508,7 +548,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let capture_str = construct_capture_info_string(self.tcx, place, capture_info); let output_str = format!("Capturing {}", capture_str); - let span = capture_info.expr_id.map_or(closure_span, |e| self.tcx.hir().span(e)); + let span = + capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e)); diag.span_note(span, &output_str); } diag.emit(); @@ -532,9 +573,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { construct_capture_info_string(self.tcx, place, capture_info); let output_str = format!("Min Capture {}", capture_str); - let span = - capture_info.expr_id.map_or(closure_span, |e| self.tcx.hir().span(e)); - diag.span_note(span, &output_str); + if capture.info.path_expr_id != capture.info.capture_kind_expr_id { + let path_span = capture_info + .path_expr_id + .map_or(closure_span, |e| self.tcx.hir().span(e)); + let capture_kind_span = capture_info + .capture_kind_expr_id + .map_or(closure_span, |e| self.tcx.hir().span(e)); + + let mut multi_span: MultiSpan = + MultiSpan::from_spans(vec![path_span, capture_kind_span]); + + let capture_kind_label = + construct_capture_kind_reason_string(self.tcx, place, capture_info); + let path_label = construct_path_string(self.tcx, place); + + multi_span.push_span_label(path_span, path_label); + multi_span.push_span_label(capture_kind_span, capture_kind_label); + + diag.span_note(multi_span, &output_str); + } else { + let span = capture_info + .path_expr_id + .map_or(closure_span, |e| self.tcx.hir().span(e)); + + diag.span_note(span, &output_str); + }; } } diag.emit(); @@ -632,7 +696,8 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> { ); let capture_info = ty::CaptureInfo { - expr_id: Some(diag_expr_id), + capture_kind_expr_id: Some(diag_expr_id), + path_expr_id: Some(diag_expr_id), capture_kind: ty::UpvarCapture::ByValue(Some(usage_span)), }; @@ -752,7 +817,8 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> { let new_upvar_borrow = ty::UpvarBorrow { kind, region: curr_upvar_borrow.region }; let capture_info = ty::CaptureInfo { - expr_id: Some(diag_expr_id), + capture_kind_expr_id: Some(diag_expr_id), + path_expr_id: Some(diag_expr_id), capture_kind: ty::UpvarCapture::ByRef(new_upvar_borrow), }; let updated_info = determine_capture_info(curr_capture_info, capture_info); @@ -814,7 +880,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> { self.fcx.init_capture_kind(self.capture_clause, upvar_id, self.closure_span); let expr_id = Some(diag_expr_id); - let capture_info = ty::CaptureInfo { expr_id, capture_kind }; + let capture_info = ty::CaptureInfo { + capture_kind_expr_id: expr_id, + path_expr_id: expr_id, + capture_kind, + }; debug!("Capturing new place {:?}, capture_info={:?}", place_with_id, capture_info); @@ -880,11 +950,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { } } -fn construct_capture_info_string( - tcx: TyCtxt<'_>, - place: &Place<'tcx>, - capture_info: &ty::CaptureInfo<'tcx>, -) -> String { +fn construct_place_string(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String { let variable_name = match place.base { PlaceBase::Upvar(upvar_id) => var_name(tcx, upvar_id.var_path.hir_id).to_string(), _ => bug!("Capture_information should only contain upvars"), @@ -904,11 +970,42 @@ fn construct_capture_info_string( projections_str.push_str(proj.as_str()); } + format!("{}[{}]", variable_name, projections_str) +} + +fn construct_capture_kind_reason_string( + tcx: TyCtxt<'_>, + place: &Place<'tcx>, + capture_info: &ty::CaptureInfo<'tcx>, +) -> String { + let place_str = construct_place_string(tcx, &place); + let capture_kind_str = match capture_info.capture_kind { ty::UpvarCapture::ByValue(_) => "ByValue".into(), ty::UpvarCapture::ByRef(borrow) => format!("{:?}", borrow.kind), }; - format!("{}[{}] -> {}", variable_name, projections_str, capture_kind_str) + + format!("{} captured as {} here", place_str, capture_kind_str) +} + +fn construct_path_string(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String { + let place_str = construct_place_string(tcx, &place); + + format!("{} used here", place_str) +} + +fn construct_capture_info_string( + tcx: TyCtxt<'_>, + place: &Place<'tcx>, + capture_info: &ty::CaptureInfo<'tcx>, +) -> String { + let place_str = construct_place_string(tcx, &place); + + let capture_kind_str = match capture_info.capture_kind { + ty::UpvarCapture::ByValue(_) => "ByValue".into(), + ty::UpvarCapture::ByRef(borrow) => format!("{:?}", borrow.kind), + }; + format!("{} -> {}", place_str, capture_kind_str) } fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol { @@ -920,7 +1017,9 @@ fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol { /// (Note: CaptureInfo contains CaptureKind and an expression that led to capture it in that way) /// /// If both `CaptureKind`s are considered equivalent, then the CaptureInfo is selected based -/// on the `CaptureInfo` containing an associated expression id. +/// on the `CaptureInfo` containing an associated `capture_kind_expr_id`. +/// +/// It is the caller's duty to figure out which path_expr_id to use. /// /// If both the CaptureKind and Expression are considered to be equivalent, /// then `CaptureInfo` A is preferred. This can be useful in cases where we want to priortize @@ -971,7 +1070,7 @@ fn determine_capture_info( }; if eq_capture_kind { - match (capture_info_a.expr_id, capture_info_b.expr_id) { + match (capture_info_a.capture_kind_expr_id, capture_info_b.capture_kind_expr_id) { (Some(_), _) | (None, None) => capture_info_a, (None, Some(_)) => capture_info_b, } diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 7c9cfe69fc94b..3612da1ffa3d1 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -348,7 +348,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let min_list_wb = min_list .iter() .map(|captured_place| { - let locatable = captured_place.info.expr_id.unwrap_or( + let locatable = captured_place.info.path_expr_id.unwrap_or( self.tcx().hir().local_def_id_to_hir_id(closure_def_id.expect_local()), ); diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 01519e4c8f7c4..b6f77aedc1661 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -630,7 +630,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { PlaceBase::Local(*var_hir_id) }; let place_with_id = PlaceWithHirId::new( - capture_info.expr_id.unwrap_or(closure_expr.hir_id), + capture_info.path_expr_id.unwrap_or(closure_expr.hir_id), place.base_ty, place_base, place.projections.clone(), diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs new file mode 100644 index 0000000000000..fbcba6fc200e2 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs @@ -0,0 +1,36 @@ + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let p = Point { x: 10, y: 10 }; + let q = Point { x: 10, y: 10 }; + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ First Pass analysis includes: + //~| Min Capture analysis includes: + println!("{:?}", p); + //~^ NOTE: Capturing p[] -> ImmBorrow + //~| NOTE: Min Capture p[] -> ImmBorrow + println!("{:?}", p.x); + //~^ NOTE: Capturing p[(0, 0)] -> ImmBorrow + + println!("{:?}", q.x); + //~^ NOTE: Capturing q[(0, 0)] -> ImmBorrow + println!("{:?}", q); + //~^ NOTE: Capturing q[] -> ImmBorrow + //~| NOTE: Min Capture q[] -> ImmBorrow + }; +} \ No newline at end of file diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr new file mode 100644 index 0000000000000..f15d656be64a5 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr @@ -0,0 +1,77 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/capture-analysis-1.rs:18:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-analysis-1.rs:2:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error: First Pass analysis includes: + --> $DIR/capture-analysis-1.rs:21:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", p); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing p[] -> ImmBorrow + --> $DIR/capture-analysis-1.rs:24:26 + | +LL | println!("{:?}", p); + | ^ +note: Capturing p[(0, 0)] -> ImmBorrow + --> $DIR/capture-analysis-1.rs:27:26 + | +LL | println!("{:?}", p.x); + | ^^^ +note: Capturing q[(0, 0)] -> ImmBorrow + --> $DIR/capture-analysis-1.rs:30:26 + | +LL | println!("{:?}", q.x); + | ^^^ +note: Capturing q[] -> ImmBorrow + --> $DIR/capture-analysis-1.rs:32:26 + | +LL | println!("{:?}", q); + | ^ + +error: Min Capture analysis includes: + --> $DIR/capture-analysis-1.rs:21:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", p); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture p[] -> ImmBorrow + --> $DIR/capture-analysis-1.rs:24:26 + | +LL | println!("{:?}", p); + | ^ +note: Min Capture q[] -> ImmBorrow + --> $DIR/capture-analysis-1.rs:32:26 + | +LL | println!("{:?}", q); + | ^ + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs new file mode 100644 index 0000000000000..7758dac4a5635 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs @@ -0,0 +1,31 @@ + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] + +#[derive(Debug)] +struct Point { + x: String, + y: i32, +} + +fn main() { + let mut p = Point { x: String::new(), y: 10 }; + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ First Pass analysis includes: + //~| Min Capture analysis includes: + let _x = p.x; + //~^ NOTE: Capturing p[(0, 0)] -> ByValue + //~| NOTE: p[] captured as ByValue here + println!("{:?}", p); + //~^ NOTE: Capturing p[] -> ImmBorrow + //~| NOTE: Min Capture p[] -> ByValue + //~| NOTE: p[] used here + }; +} \ No newline at end of file diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr new file mode 100644 index 0000000000000..2805476d8d272 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr @@ -0,0 +1,65 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/capture-analysis-2.rs:17:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-analysis-2.rs:2:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error: First Pass analysis includes: + --> $DIR/capture-analysis-2.rs:20:5 + | +LL | / || { +LL | | +LL | | +LL | | let _x = p.x; +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing p[(0, 0)] -> ByValue + --> $DIR/capture-analysis-2.rs:23:18 + | +LL | let _x = p.x; + | ^^^ +note: Capturing p[] -> ImmBorrow + --> $DIR/capture-analysis-2.rs:26:26 + | +LL | println!("{:?}", p); + | ^ + +error: Min Capture analysis includes: + --> $DIR/capture-analysis-2.rs:20:5 + | +LL | / || { +LL | | +LL | | +LL | | let _x = p.x; +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture p[] -> ByValue + --> $DIR/capture-analysis-2.rs:23:18 + | +LL | let _x = p.x; + | ^^^ p[] captured as ByValue here +... +LL | println!("{:?}", p); + | ^ p[] used here + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs new file mode 100644 index 0000000000000..f81866bb7e096 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs @@ -0,0 +1,52 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] +#![allow(unused)] + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} +#[derive(Debug)] +struct Line { + p: Point, + q: Point +} +#[derive(Debug)] +struct Plane { + a: Line, + b: Line, +} + +fn main() { + let mut p = Plane { + a: Line { + p: Point { x: 1,y: 2 }, + q: Point { x: 3,y: 4 }, + }, + b: Line { + p: Point { x: 1,y: 2 }, + q: Point { x: 3,y: 4 }, + } + }; + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + let x = &p.a.p.x; + //~^ NOTE: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow + p.b.q.y = 9; + //~^ NOTE: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow + //~| NOTE: p[] captured as MutBorrow here + println!("{:?}", p); + //~^ NOTE: Capturing p[] -> ImmBorrow + //~| NOTE: Min Capture p[] -> MutBorrow + //~| NOTE: p[] used here + }; +} diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr new file mode 100644 index 0000000000000..863f1009131a1 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr @@ -0,0 +1,70 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/deep-multilevel-struct.rs:36:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/deep-multilevel-struct.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error: First Pass analysis includes: + --> $DIR/deep-multilevel-struct.rs:39:5 + | +LL | / || { +LL | | +LL | | +LL | | let x = &p.a.p.x; +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow + --> $DIR/deep-multilevel-struct.rs:42:18 + | +LL | let x = &p.a.p.x; + | ^^^^^^^ +note: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow + --> $DIR/deep-multilevel-struct.rs:44:9 + | +LL | p.b.q.y = 9; + | ^^^^^^^ +note: Capturing p[] -> ImmBorrow + --> $DIR/deep-multilevel-struct.rs:47:26 + | +LL | println!("{:?}", p); + | ^ + +error: Min Capture analysis includes: + --> $DIR/deep-multilevel-struct.rs:39:5 + | +LL | / || { +LL | | +LL | | +LL | | let x = &p.a.p.x; +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture p[] -> MutBorrow + --> $DIR/deep-multilevel-struct.rs:44:9 + | +LL | p.b.q.y = 9; + | ^^^^^^^ p[] captured as MutBorrow here +... +LL | println!("{:?}", p); + | ^ p[] used here + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs new file mode 100644 index 0000000000000..8f53b2b8aa090 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs @@ -0,0 +1,28 @@ + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] +#![allow(unused)] + +fn main() { + let mut t = (((1,2),(3,4)),((5,6),(7,8))); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + let x = &t.0.0.0; + //~^ NOTE: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow + t.1.1.1 = 9; + //~^ NOTE: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow + //~| NOTE: t[] captured as MutBorrow here + println!("{:?}", t); + //~^ NOTE: Min Capture t[] -> MutBorrow + //~| NOTE: Capturing t[] -> ImmBorrow + //~| NOTE: t[] used here + }; +} diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr new file mode 100644 index 0000000000000..8fce18f3d6084 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr @@ -0,0 +1,70 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/deep-multilevel-tuple.rs:12:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/deep-multilevel-tuple.rs:2:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error: First Pass analysis includes: + --> $DIR/deep-multilevel-tuple.rs:15:5 + | +LL | / || { +LL | | +LL | | +LL | | let x = &t.0.0.0; +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow + --> $DIR/deep-multilevel-tuple.rs:18:18 + | +LL | let x = &t.0.0.0; + | ^^^^^^^ +note: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow + --> $DIR/deep-multilevel-tuple.rs:20:9 + | +LL | t.1.1.1 = 9; + | ^^^^^^^ +note: Capturing t[] -> ImmBorrow + --> $DIR/deep-multilevel-tuple.rs:23:26 + | +LL | println!("{:?}", t); + | ^ + +error: Min Capture analysis includes: + --> $DIR/deep-multilevel-tuple.rs:15:5 + | +LL | / || { +LL | | +LL | | +LL | | let x = &t.0.0.0; +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture t[] -> MutBorrow + --> $DIR/deep-multilevel-tuple.rs:20:9 + | +LL | t.1.1.1 = 9; + | ^^^^^^^ t[] captured as MutBorrow here +... +LL | println!("{:?}", t); + | ^ t[] used here + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs index aaff3531e5850..a6b5e12d2ed78 100644 --- a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs +++ b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs @@ -32,9 +32,11 @@ fn main() { //~| ERROR: Min Capture analysis includes: p.x += 10; //~^ NOTE: Capturing p[(0, 0)] -> MutBorrow - //~| NOTE: Min Capture p[] -> MutBorrow + //~| NOTE: p[] captured as MutBorrow here println!("{:?}", p); //~^ NOTE: Capturing p[] -> ImmBorrow + //~| NOTE: Min Capture p[] -> MutBorrow + //~| NOTE: p[] used here }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr index 30d3d5f504eb9..cbbc879219915 100644 --- a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr +++ b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr @@ -55,7 +55,10 @@ note: Min Capture p[] -> MutBorrow --> $DIR/simple-struct-min-capture.rs:33:9 | LL | p.x += 10; - | ^^^ + | ^^^ p[] captured as MutBorrow here +... +LL | println!("{:?}", p); + | ^ p[] used here error: aborting due to 3 previous errors; 1 warning emitted From 3056dd0bb5ae20a4c90e01c3e6ab95eadce21aba Mon Sep 17 00:00:00 2001 From: Chris Pardy Date: Fri, 15 Jan 2021 20:16:27 -0500 Subject: [PATCH 03/31] fix tidy --- .../ui/closures/2229_closure_analysis/capture-analysis-1.rs | 3 +-- .../ui/closures/2229_closure_analysis/capture-analysis-2.rs | 3 +-- .../ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs index fbcba6fc200e2..4368c830e1c61 100644 --- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs @@ -1,4 +1,3 @@ - #![feature(capture_disjoint_fields)] //~^ WARNING: the feature `capture_disjoint_fields` is incomplete //~| NOTE: `#[warn(incomplete_features)]` on by default @@ -33,4 +32,4 @@ fn main() { //~^ NOTE: Capturing q[] -> ImmBorrow //~| NOTE: Min Capture q[] -> ImmBorrow }; -} \ No newline at end of file +} diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs index 7758dac4a5635..ab7fce6a43099 100644 --- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs @@ -1,4 +1,3 @@ - #![feature(capture_disjoint_fields)] //~^ WARNING: the feature `capture_disjoint_fields` is incomplete //~| NOTE: `#[warn(incomplete_features)]` on by default @@ -28,4 +27,4 @@ fn main() { //~| NOTE: Min Capture p[] -> ByValue //~| NOTE: p[] used here }; -} \ No newline at end of file +} diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs index 8f53b2b8aa090..fb03a02efa09e 100644 --- a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs +++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs @@ -1,4 +1,3 @@ - #![feature(capture_disjoint_fields)] //~^ WARNING: the feature `capture_disjoint_fields` is incomplete //~| NOTE: `#[warn(incomplete_features)]` on by default From b8115b8f67996aae101faadadefa7bc282ec2f21 Mon Sep 17 00:00:00 2001 From: Chris Pardy Date: Sat, 16 Jan 2021 00:11:03 -0500 Subject: [PATCH 04/31] fix line numbers --- .../capture-analysis-1.stderr | 20 +++++++++---------- .../capture-analysis-2.stderr | 14 ++++++------- .../deep-multilevel-tuple.stderr | 16 +++++++-------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr index f15d656be64a5..09255343af0e8 100644 --- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/capture-analysis-1.rs:18:13 + --> $DIR/capture-analysis-1.rs:17:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/capture-analysis-1.rs:2:12 + --> $DIR/capture-analysis-1.rs:1:12 | LL | #![feature(capture_disjoint_fields)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![feature(capture_disjoint_fields)] = note: see issue #53488 for more information error: First Pass analysis includes: - --> $DIR/capture-analysis-1.rs:21:5 + --> $DIR/capture-analysis-1.rs:20:5 | LL | / || { LL | | @@ -29,28 +29,28 @@ LL | | }; | |_____^ | note: Capturing p[] -> ImmBorrow - --> $DIR/capture-analysis-1.rs:24:26 + --> $DIR/capture-analysis-1.rs:23:26 | LL | println!("{:?}", p); | ^ note: Capturing p[(0, 0)] -> ImmBorrow - --> $DIR/capture-analysis-1.rs:27:26 + --> $DIR/capture-analysis-1.rs:26:26 | LL | println!("{:?}", p.x); | ^^^ note: Capturing q[(0, 0)] -> ImmBorrow - --> $DIR/capture-analysis-1.rs:30:26 + --> $DIR/capture-analysis-1.rs:29:26 | LL | println!("{:?}", q.x); | ^^^ note: Capturing q[] -> ImmBorrow - --> $DIR/capture-analysis-1.rs:32:26 + --> $DIR/capture-analysis-1.rs:31:26 | LL | println!("{:?}", q); | ^ error: Min Capture analysis includes: - --> $DIR/capture-analysis-1.rs:21:5 + --> $DIR/capture-analysis-1.rs:20:5 | LL | / || { LL | | @@ -62,12 +62,12 @@ LL | | }; | |_____^ | note: Min Capture p[] -> ImmBorrow - --> $DIR/capture-analysis-1.rs:24:26 + --> $DIR/capture-analysis-1.rs:23:26 | LL | println!("{:?}", p); | ^ note: Min Capture q[] -> ImmBorrow - --> $DIR/capture-analysis-1.rs:32:26 + --> $DIR/capture-analysis-1.rs:31:26 | LL | println!("{:?}", q); | ^ diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr index 2805476d8d272..0e48d6b300b72 100644 --- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/capture-analysis-2.rs:17:13 + --> $DIR/capture-analysis-2.rs:16:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/capture-analysis-2.rs:2:12 + --> $DIR/capture-analysis-2.rs:1:12 | LL | #![feature(capture_disjoint_fields)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![feature(capture_disjoint_fields)] = note: see issue #53488 for more information error: First Pass analysis includes: - --> $DIR/capture-analysis-2.rs:20:5 + --> $DIR/capture-analysis-2.rs:19:5 | LL | / || { LL | | @@ -29,18 +29,18 @@ LL | | }; | |_____^ | note: Capturing p[(0, 0)] -> ByValue - --> $DIR/capture-analysis-2.rs:23:18 + --> $DIR/capture-analysis-2.rs:22:18 | LL | let _x = p.x; | ^^^ note: Capturing p[] -> ImmBorrow - --> $DIR/capture-analysis-2.rs:26:26 + --> $DIR/capture-analysis-2.rs:25:26 | LL | println!("{:?}", p); | ^ error: Min Capture analysis includes: - --> $DIR/capture-analysis-2.rs:20:5 + --> $DIR/capture-analysis-2.rs:19:5 | LL | / || { LL | | @@ -52,7 +52,7 @@ LL | | }; | |_____^ | note: Min Capture p[] -> ByValue - --> $DIR/capture-analysis-2.rs:23:18 + --> $DIR/capture-analysis-2.rs:22:18 | LL | let _x = p.x; | ^^^ p[] captured as ByValue here diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr index 8fce18f3d6084..252db44473222 100644 --- a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr +++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/deep-multilevel-tuple.rs:12:13 + --> $DIR/deep-multilevel-tuple.rs:11:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/deep-multilevel-tuple.rs:2:12 + --> $DIR/deep-multilevel-tuple.rs:1:12 | LL | #![feature(capture_disjoint_fields)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![feature(capture_disjoint_fields)] = note: see issue #53488 for more information error: First Pass analysis includes: - --> $DIR/deep-multilevel-tuple.rs:15:5 + --> $DIR/deep-multilevel-tuple.rs:14:5 | LL | / || { LL | | @@ -29,23 +29,23 @@ LL | | }; | |_____^ | note: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow - --> $DIR/deep-multilevel-tuple.rs:18:18 + --> $DIR/deep-multilevel-tuple.rs:17:18 | LL | let x = &t.0.0.0; | ^^^^^^^ note: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow - --> $DIR/deep-multilevel-tuple.rs:20:9 + --> $DIR/deep-multilevel-tuple.rs:19:9 | LL | t.1.1.1 = 9; | ^^^^^^^ note: Capturing t[] -> ImmBorrow - --> $DIR/deep-multilevel-tuple.rs:23:26 + --> $DIR/deep-multilevel-tuple.rs:22:26 | LL | println!("{:?}", t); | ^ error: Min Capture analysis includes: - --> $DIR/deep-multilevel-tuple.rs:15:5 + --> $DIR/deep-multilevel-tuple.rs:14:5 | LL | / || { LL | | @@ -57,7 +57,7 @@ LL | | }; | |_____^ | note: Min Capture t[] -> MutBorrow - --> $DIR/deep-multilevel-tuple.rs:20:9 + --> $DIR/deep-multilevel-tuple.rs:19:9 | LL | t.1.1.1 = 9; | ^^^^^^^ t[] captured as MutBorrow here From 63a1eeea234105fd9c1ed30ac2b6e0d9bf41a1e9 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 18 Jan 2021 11:55:23 -0600 Subject: [PATCH 05/31] Reset LateContext enclosing body in nested items Prevents LateContext::maybe_typeck_results() from returning data in a nested item without a body. Consequently, LateContext::qpath_res is less likely to ICE when called in a nested item. Would have prevented rust-lang/rust-clippy#4545, presumably. --- compiler/rustc_lint/src/late.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 015e109871182..3821a393efb8b 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -140,6 +140,8 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { let generics = self.context.generics.take(); self.context.generics = it.kind.generics(); + let old_cached_typeck_results = self.context.cached_typeck_results.take(); + let old_enclosing_body = self.context.enclosing_body.take(); self.with_lint_attrs(it.hir_id, &it.attrs, |cx| { cx.with_param_env(it.hir_id, |cx| { lint_callback!(cx, check_item, it); @@ -147,6 +149,8 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas lint_callback!(cx, check_item_post, it); }); }); + self.context.enclosing_body = old_enclosing_body; + self.context.cached_typeck_results.set(old_cached_typeck_results); self.context.generics = generics; } From 21fb586c0c72a546bae445df1588cef464502ada Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 18 Jan 2021 13:29:37 -0600 Subject: [PATCH 06/31] Query for TypeckResults in LateContext::qpath_res Actually fulfills the documented guarantees. --- compiler/rustc_lint/src/context.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 3971a3099823f..3f92d66d88bce 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -746,6 +746,14 @@ impl<'tcx> LateContext<'tcx> { hir::QPath::Resolved(_, ref path) => path.res, hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self .maybe_typeck_results() + .filter(|typeck_results| typeck_results.hir_owner == id.owner) + .or_else(|| { + if self.tcx.has_typeck_results(id.owner.to_def_id()) { + Some(self.tcx.typeck(id.owner)) + } else { + None + } + }) .and_then(|typeck_results| typeck_results.type_dependent_def(id)) .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), } From 0724573448a09f90d087f5341de483f9ef85a9be Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 12 Dec 2020 15:25:55 +0100 Subject: [PATCH 07/31] Move a few more types to `rustc_type_ir` --- Cargo.lock | 1 + compiler/rustc_middle/src/infer/unify_key.rs | 53 +-- compiler/rustc_middle/src/ty/diagnostics.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 85 +--- compiler/rustc_middle/src/ty/print/pretty.rs | 26 +- .../rustc_middle/src/ty/structural_impls.rs | 59 +-- compiler/rustc_middle/src/ty/sty.rs | 57 +-- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/lib.rs | 406 ++++++++++++++++++ 9 files changed, 426 insertions(+), 265 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2c06a2adb14e..bea1879e793b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4314,6 +4314,7 @@ dependencies = [ "bitflags", "rustc_data_structures", "rustc_index", + "rustc_macros", "rustc_serialize", ] diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 16e9aafb25a54..8318bdefc8e18 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -1,4 +1,4 @@ -use crate::ty::{self, FloatVarValue, InferConst, IntVarValue, Ty, TyCtxt}; +use crate::ty::{self, InferConst, Ty, TyCtxt}; use rustc_data_structures::snapshot_vec; use rustc_data_structures::undo_log::UndoLogs; use rustc_data_structures::unify::{ @@ -15,36 +15,6 @@ pub trait ToType { fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>; } -/// Raw `TyVid` are used as the unification key for `sub_relations`; -/// they carry no values. -impl UnifyKey for ty::TyVid { - type Value = (); - fn index(&self) -> u32 { - self.index - } - fn from_index(i: u32) -> ty::TyVid { - ty::TyVid { index: i } - } - fn tag() -> &'static str { - "TyVid" - } -} - -impl UnifyKey for ty::IntVid { - type Value = Option; - fn index(&self) -> u32 { - self.index - } - fn from_index(i: u32) -> ty::IntVid { - ty::IntVid { index: i } - } - fn tag() -> &'static str { - "IntVid" - } -} - -impl EqUnifyValue for IntVarValue {} - #[derive(PartialEq, Copy, Clone, Debug)] pub struct RegionVidKey { /// The minimum region vid in the unification set. This is needed @@ -80,7 +50,7 @@ impl UnifyKey for ty::RegionVid { } } -impl ToType for IntVarValue { +impl ToType for ty::IntVarValue { fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match *self { ty::IntType(i) => tcx.mk_mach_int(i), @@ -89,24 +59,7 @@ impl ToType for IntVarValue { } } -// Floating point type keys - -impl UnifyKey for ty::FloatVid { - type Value = Option; - fn index(&self) -> u32 { - self.index - } - fn from_index(i: u32) -> ty::FloatVid { - ty::FloatVid { index: i } - } - fn tag() -> &'static str { - "FloatVid" - } -} - -impl EqUnifyValue for FloatVarValue {} - -impl ToType for FloatVarValue { +impl ToType for ty::FloatVarValue { fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { tcx.mk_mach_float(self.0) } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 3adcdbe591fc3..e386d973ee447 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -1,8 +1,7 @@ //! Diagnostics related methods for `TyS`. -use crate::ty::sty::InferTy; use crate::ty::TyKind::*; -use crate::ty::{TyCtxt, TyS}; +use crate::ty::{InferTy, TyCtxt, TyS}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c6970df01785e..87730197da003 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -65,7 +65,6 @@ use std::ptr; use std::str; pub use self::sty::BoundRegionKind::*; -pub use self::sty::InferTy::*; pub use self::sty::RegionKind; pub use self::sty::RegionKind::*; pub use self::sty::TyKind::*; @@ -74,13 +73,14 @@ pub use self::sty::{BoundRegion, BoundRegionKind, EarlyBoundRegion, FreeRegion, pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig}; pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts}; pub use self::sty::{ClosureSubstsParts, GeneratorSubstsParts}; -pub use self::sty::{ConstVid, FloatVid, IntVid, RegionVid, TyVid}; -pub use self::sty::{ExistentialPredicate, InferTy, ParamConst, ParamTy, ProjectionTy}; +pub use self::sty::{ConstVid, RegionVid}; +pub use self::sty::{ExistentialPredicate, ParamConst, ParamTy, ProjectionTy}; pub use self::sty::{ExistentialProjection, PolyExistentialProjection}; pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; pub use self::sty::{PolyTraitRef, TraitRef, TyKind}; pub use crate::ty::diagnostics::*; -pub use rustc_type_ir::{DebruijnIndex, TypeFlags, INNERMOST}; +pub use rustc_type_ir::InferTy::*; +pub use rustc_type_ir::*; pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; @@ -421,14 +421,6 @@ impl Visibility { } } -#[derive(Copy, Clone, PartialEq, TyDecodable, TyEncodable, HashStable)] -pub enum Variance { - Covariant, // T <: T iff A <: B -- e.g., function return type - Invariant, // T <: T iff B == A -- e.g., type of mutable cell - Contravariant, // T <: T iff B <: A -- e.g., function param type - Bivariant, // T <: T -- e.g., unused type parameter -} - /// The crate variances map is computed during typeck and contains the /// variance of every item in the local crate. You should not use it /// directly, because to do so will make your pass dependent on the @@ -443,66 +435,6 @@ pub struct CrateVariancesMap<'tcx> { pub variances: FxHashMap, } -impl Variance { - /// `a.xform(b)` combines the variance of a context with the - /// variance of a type with the following meaning. If we are in a - /// context with variance `a`, and we encounter a type argument in - /// a position with variance `b`, then `a.xform(b)` is the new - /// variance with which the argument appears. - /// - /// Example 1: - /// - /// *mut Vec - /// - /// Here, the "ambient" variance starts as covariant. `*mut T` is - /// invariant with respect to `T`, so the variance in which the - /// `Vec` appears is `Covariant.xform(Invariant)`, which - /// yields `Invariant`. Now, the type `Vec` is covariant with - /// respect to its type argument `T`, and hence the variance of - /// the `i32` here is `Invariant.xform(Covariant)`, which results - /// (again) in `Invariant`. - /// - /// Example 2: - /// - /// fn(*const Vec, *mut Vec` appears is - /// `Contravariant.xform(Covariant)` or `Contravariant`. The same - /// is true for its `i32` argument. In the `*mut T` case, the - /// variance of `Vec` is `Contravariant.xform(Invariant)`, - /// and hence the outermost type is `Invariant` with respect to - /// `Vec` (and its `i32` argument). - /// - /// Source: Figure 1 of "Taming the Wildcards: - /// Combining Definition- and Use-Site Variance" published in PLDI'11. - pub fn xform(self, v: ty::Variance) -> ty::Variance { - match (self, v) { - // Figure 1, column 1. - (ty::Covariant, ty::Covariant) => ty::Covariant, - (ty::Covariant, ty::Contravariant) => ty::Contravariant, - (ty::Covariant, ty::Invariant) => ty::Invariant, - (ty::Covariant, ty::Bivariant) => ty::Bivariant, - - // Figure 1, column 2. - (ty::Contravariant, ty::Covariant) => ty::Contravariant, - (ty::Contravariant, ty::Contravariant) => ty::Covariant, - (ty::Contravariant, ty::Invariant) => ty::Invariant, - (ty::Contravariant, ty::Bivariant) => ty::Bivariant, - - // Figure 1, column 3. - (ty::Invariant, _) => ty::Invariant, - - // Figure 1, column 4. - (ty::Bivariant, _) => ty::Bivariant, - } - } -} - // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. #[derive(Copy, Clone, PartialEq, Eq, Hash)] @@ -804,15 +736,6 @@ pub struct CaptureInfo<'tcx> { pub type UpvarListMap = FxHashMap>; pub type UpvarCaptureMap<'tcx> = FxHashMap>; -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum IntVarValue { - IntType(ast::IntTy), - UintType(ast::UintTy), -} - -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct FloatVarValue(pub ast::FloatTy); - impl ty::EarlyBoundRegion { /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 8911de41c6d8e..9c7e0e60c14d6 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -557,14 +557,19 @@ pub trait PrettyPrinter<'tcx>: } ty::FnPtr(ref bare_fn) => p!(print(bare_fn)), ty::Infer(infer_ty) => { + let verbose = self.tcx().sess.verbose(); if let ty::TyVar(ty_vid) = infer_ty { if let Some(name) = self.infer_ty_name(ty_vid) { p!(write("{}", name)) } else { - p!(write("{}", infer_ty)) + if verbose { + p!(write("{:?}", infer_ty)) + } else { + p!(write("{}", infer_ty)) + } } } else { - p!(write("{}", infer_ty)) + if verbose { p!(write("{:?}", infer_ty)) } else { p!(write("{}", infer_ty)) } } } ty::Error(_) => p!("[type error]"), @@ -1246,7 +1251,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> { pub region_highlight_mode: RegionHighlightMode, - pub name_resolver: Option Option>>, + pub name_resolver: Option Option>>, } impl Deref for FmtPrinter<'a, 'tcx, F> { @@ -2007,21 +2012,6 @@ define_print_and_forward_display! { p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); } - ty::InferTy { - if cx.tcx().sess.verbose() { - p!(write("{:?}", self)); - return Ok(cx); - } - match *self { - ty::TyVar(_) => p!("_"), - ty::IntVar(_) => p!(write("{}", "{integer}")), - ty::FloatVar(_) => p!(write("{}", "{float}")), - ty::FreshTy(v) => p!(write("FreshTy({})", v)), - ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)), - ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v)) - } - } - ty::TraitRef<'tcx> { p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path())) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 44c173e356dfb..0ca94a9f1805d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -111,81 +111,24 @@ impl fmt::Debug for ty::FreeRegion { } } -impl fmt::Debug for ty::Variance { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match *self { - ty::Covariant => "+", - ty::Contravariant => "-", - ty::Invariant => "o", - ty::Bivariant => "*", - }) - } -} - impl fmt::Debug for ty::FnSig<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output()) } } -impl fmt::Debug for ty::TyVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}t", self.index) - } -} - impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "_#{}c", self.index) } } -impl fmt::Debug for ty::IntVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}i", self.index) - } -} - -impl fmt::Debug for ty::FloatVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}f", self.index) - } -} - impl fmt::Debug for ty::RegionVid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "'_#{}r", self.index()) } } -impl fmt::Debug for ty::InferTy { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - ty::TyVar(ref v) => v.fmt(f), - ty::IntVar(ref v) => v.fmt(f), - ty::FloatVar(ref v) => v.fmt(f), - ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v), - } - } -} - -impl fmt::Debug for ty::IntVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - ty::IntType(ref v) => v.fmt(f), - ty::UintType(ref v) => v.fmt(f), - } - } -} - -impl fmt::Debug for ty::FloatVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - impl fmt::Debug for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { with_no_trimmed_paths(|| fmt::Display::fmt(self, f)) @@ -274,7 +217,7 @@ TrivialTypeFoldableAndLiftImpls! { u64, String, crate::middle::region::Scope, - ::rustc_ast::FloatTy, + crate::ty::FloatTy, ::rustc_ast::InlineAsmOptions, ::rustc_ast::InlineAsmTemplatePiece, ::rustc_ast::NodeId, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e53977b5eb978..aeba1843dbc12 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2,11 +2,11 @@ #![allow(rustc::usage_of_ty_tykind)] -use self::InferTy::*; use self::TyKind::*; use crate::infer::canonical::Canonical; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; +use crate::ty::InferTy::{self, *}; use crate::ty::{ self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness, }; @@ -1426,12 +1426,6 @@ pub struct EarlyBoundRegion { pub name: Symbol, } -/// A **ty**pe **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -pub struct TyVid { - pub index: u32, -} - /// A **`const`** **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] pub struct ConstVid<'tcx> { @@ -1439,18 +1433,6 @@ pub struct ConstVid<'tcx> { pub phantom: PhantomData<&'tcx ()>, } -/// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -pub struct IntVid { - pub index: u32, -} - -/// An **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -pub struct FloatVid { - pub index: u32, -} - rustc_index::newtype_index! { /// A **region** (lifetime) **v**ariable **ID**. pub struct RegionVid { @@ -1464,43 +1446,6 @@ impl Atom for RegionVid { } } -/// A placeholder for a type that hasn't been inferred yet. -/// -/// E.g., if we have an empty array (`[]`), then we create a fresh -/// type variable for the element type since we won't know until it's -/// used what the element type is supposed to be. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable)] -pub enum InferTy { - /// A type variable. - TyVar(TyVid), - /// An integral type variable (`{integer}`). - /// - /// These are created when the compiler sees an integer literal like - /// `1` that could be several different types (`u8`, `i32`, `u32`, etc.). - /// We don't know until it's used what type it's supposed to be, so - /// we create a fresh type variable. - IntVar(IntVid), - /// A floating-point type variable (`{float}`). - /// - /// These are created when the compiler sees an float literal like - /// `1.0` that could be either an `f32` or an `f64`. - /// We don't know until it's used what type it's supposed to be, so - /// we create a fresh type variable. - FloatVar(FloatVid), - - /// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement - /// for an unbound type variable. This is convenient for caching etc. See - /// `rustc_infer::infer::freshen` for more details. - /// - /// Compare with [`TyVar`][Self::TyVar]. - FreshTy(u32), - /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar]. - FreshIntTy(u32), - /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar]. - FreshFloatTy(u32), -} - rustc_index::newtype_index! { pub struct BoundVar { .. } } diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index d50451b7794c6..3f64bd899979f 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -12,3 +12,4 @@ bitflags = "1.2.1" rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 37abb4496ac3f..7e70af21c03cd 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -4,8 +4,13 @@ #[macro_use] extern crate bitflags; +#[macro_use] +extern crate rustc_macros; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; +use std::fmt; +use std::mem::discriminant; bitflags! { /// Flags that we track on types. These flags are propagated upwards @@ -197,8 +202,409 @@ impl DebruijnIndex { } } +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Encodable, Decodable)] +pub enum IntTy { + Isize, + I8, + I16, + I32, + I64, + I128, +} + +impl IntTy { + pub fn name_str(&self) -> &'static str { + match *self { + IntTy::Isize => "isize", + IntTy::I8 => "i8", + IntTy::I16 => "i16", + IntTy::I32 => "i32", + IntTy::I64 => "i64", + IntTy::I128 => "i128", + } + } + + pub fn bit_width(&self) -> Option { + Some(match *self { + IntTy::Isize => return None, + IntTy::I8 => 8, + IntTy::I16 => 16, + IntTy::I32 => 32, + IntTy::I64 => 64, + IntTy::I128 => 128, + }) + } + + pub fn normalize(&self, target_width: u32) -> Self { + match self { + IntTy::Isize => match target_width { + 16 => IntTy::I16, + 32 => IntTy::I32, + 64 => IntTy::I64, + _ => unreachable!(), + }, + _ => *self, + } + } +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)] +#[derive(Encodable, Decodable)] +pub enum UintTy { + Usize, + U8, + U16, + U32, + U64, + U128, +} + +impl UintTy { + pub fn name_str(&self) -> &'static str { + match *self { + UintTy::Usize => "usize", + UintTy::U8 => "u8", + UintTy::U16 => "u16", + UintTy::U32 => "u32", + UintTy::U64 => "u64", + UintTy::U128 => "u128", + } + } + + pub fn bit_width(&self) -> Option { + Some(match *self { + UintTy::Usize => return None, + UintTy::U8 => 8, + UintTy::U16 => 16, + UintTy::U32 => 32, + UintTy::U64 => 64, + UintTy::U128 => 128, + }) + } + + pub fn normalize(&self, target_width: u32) -> Self { + match self { + UintTy::Usize => match target_width { + 16 => UintTy::U16, + 32 => UintTy::U32, + 64 => UintTy::U64, + _ => unreachable!(), + }, + _ => *self, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Encodable, Decodable)] +pub enum FloatTy { + F32, + F64, +} + +impl FloatTy { + pub fn name_str(self) -> &'static str { + match self { + FloatTy::F32 => "f32", + FloatTy::F64 => "f64", + } + } + + pub fn bit_width(self) -> u64 { + match self { + FloatTy::F32 => 32, + FloatTy::F64 => 64, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum IntVarValue { + IntType(IntTy), + UintType(UintTy), +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct FloatVarValue(pub FloatTy); + +/// A **ty**pe **v**ariable **ID**. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +pub struct TyVid { + pub index: u32, +} + +/// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +pub struct IntVid { + pub index: u32, +} + +/// An **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +pub struct FloatVid { + pub index: u32, +} + +/// A placeholder for a type that hasn't been inferred yet. +/// +/// E.g., if we have an empty array (`[]`), then we create a fresh +/// type variable for the element type since we won't know until it's +/// used what the element type is supposed to be. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +pub enum InferTy { + /// A type variable. + TyVar(TyVid), + /// An integral type variable (`{integer}`). + /// + /// These are created when the compiler sees an integer literal like + /// `1` that could be several different types (`u8`, `i32`, `u32`, etc.). + /// We don't know until it's used what type it's supposed to be, so + /// we create a fresh type variable. + IntVar(IntVid), + /// A floating-point type variable (`{float}`). + /// + /// These are created when the compiler sees an float literal like + /// `1.0` that could be either an `f32` or an `f64`. + /// We don't know until it's used what type it's supposed to be, so + /// we create a fresh type variable. + FloatVar(FloatVid), + + /// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement + /// for an unbound type variable. This is convenient for caching etc. See + /// `rustc_infer::infer::freshen` for more details. + /// + /// Compare with [`TyVar`][Self::TyVar]. + FreshTy(u32), + /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar]. + FreshIntTy(u32), + /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar]. + FreshFloatTy(u32), +} + +/// Raw `TyVid` are used as the unification key for `sub_relations`; +/// they carry no values. +impl UnifyKey for TyVid { + type Value = (); + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> TyVid { + TyVid { index: i } + } + fn tag() -> &'static str { + "TyVid" + } +} + +impl EqUnifyValue for IntVarValue {} + +impl UnifyKey for IntVid { + type Value = Option; + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> IntVid { + IntVid { index: i } + } + fn tag() -> &'static str { + "IntVid" + } +} + +impl EqUnifyValue for FloatVarValue {} + +impl UnifyKey for FloatVid { + type Value = Option; + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> FloatVid { + FloatVid { index: i } + } + fn tag() -> &'static str { + "FloatVid" + } +} + +#[derive(Copy, Clone, PartialEq, Decodable, Encodable)] +pub enum Variance { + Covariant, // T <: T iff A <: B -- e.g., function return type + Invariant, // T <: T iff B == A -- e.g., type of mutable cell + Contravariant, // T <: T iff B <: A -- e.g., function param type + Bivariant, // T <: T -- e.g., unused type parameter +} + +impl Variance { + /// `a.xform(b)` combines the variance of a context with the + /// variance of a type with the following meaning. If we are in a + /// context with variance `a`, and we encounter a type argument in + /// a position with variance `b`, then `a.xform(b)` is the new + /// variance with which the argument appears. + /// + /// Example 1: + /// + /// *mut Vec + /// + /// Here, the "ambient" variance starts as covariant. `*mut T` is + /// invariant with respect to `T`, so the variance in which the + /// `Vec` appears is `Covariant.xform(Invariant)`, which + /// yields `Invariant`. Now, the type `Vec` is covariant with + /// respect to its type argument `T`, and hence the variance of + /// the `i32` here is `Invariant.xform(Covariant)`, which results + /// (again) in `Invariant`. + /// + /// Example 2: + /// + /// fn(*const Vec, *mut Vec` appears is + /// `Contravariant.xform(Covariant)` or `Contravariant`. The same + /// is true for its `i32` argument. In the `*mut T` case, the + /// variance of `Vec` is `Contravariant.xform(Invariant)`, + /// and hence the outermost type is `Invariant` with respect to + /// `Vec` (and its `i32` argument). + /// + /// Source: Figure 1 of "Taming the Wildcards: + /// Combining Definition- and Use-Site Variance" published in PLDI'11. + pub fn xform(self, v: Variance) -> Variance { + match (self, v) { + // Figure 1, column 1. + (Variance::Covariant, Variance::Covariant) => Variance::Covariant, + (Variance::Covariant, Variance::Contravariant) => Variance::Contravariant, + (Variance::Covariant, Variance::Invariant) => Variance::Invariant, + (Variance::Covariant, Variance::Bivariant) => Variance::Bivariant, + + // Figure 1, column 2. + (Variance::Contravariant, Variance::Covariant) => Variance::Contravariant, + (Variance::Contravariant, Variance::Contravariant) => Variance::Covariant, + (Variance::Contravariant, Variance::Invariant) => Variance::Invariant, + (Variance::Contravariant, Variance::Bivariant) => Variance::Bivariant, + + // Figure 1, column 3. + (Variance::Invariant, _) => Variance::Invariant, + + // Figure 1, column 4. + (Variance::Bivariant, _) => Variance::Bivariant, + } + } +} + impl HashStable for DebruijnIndex { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.as_u32().hash_stable(ctx, hasher); } } + +impl HashStable for IntTy { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + discriminant(self).hash_stable(ctx, hasher); + } +} + +impl HashStable for UintTy { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + discriminant(self).hash_stable(ctx, hasher); + } +} + +impl HashStable for FloatTy { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + discriminant(self).hash_stable(ctx, hasher); + } +} + +impl HashStable for InferTy { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + use InferTy::*; + match self { + TyVar(v) => v.index.hash_stable(ctx, hasher), + IntVar(v) => v.index.hash_stable(ctx, hasher), + FloatVar(v) => v.index.hash_stable(ctx, hasher), + FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher), + } + } +} + +impl HashStable for Variance { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + discriminant(self).hash_stable(ctx, hasher); + } +} + +impl fmt::Debug for IntVarValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + IntVarValue::IntType(ref v) => v.fmt(f), + IntVarValue::UintType(ref v) => v.fmt(f), + } + } +} + +impl fmt::Debug for FloatVarValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Debug for TyVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}t", self.index) + } +} + +impl fmt::Debug for IntVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}i", self.index) + } +} + +impl fmt::Debug for FloatVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}f", self.index) + } +} + +impl fmt::Debug for InferTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InferTy::*; + match *self { + TyVar(ref v) => v.fmt(f), + IntVar(ref v) => v.fmt(f), + FloatVar(ref v) => v.fmt(f), + FreshTy(v) => write!(f, "FreshTy({:?})", v), + FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), + FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v), + } + } +} + +impl fmt::Debug for Variance { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match *self { + Variance::Covariant => "+", + Variance::Contravariant => "-", + Variance::Invariant => "o", + Variance::Bivariant => "*", + }) + } +} + +impl fmt::Display for InferTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InferTy::*; + match *self { + TyVar(_) => write!(f, "_"), + IntVar(_) => write!(f, "{}", "{integer}"), + FloatVar(_) => write!(f, "{}", "{float}"), + FreshTy(v) => write!(f, "FreshTy({})", v), + FreshIntTy(v) => write!(f, "FreshIntTy({})", v), + FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v), + } + } +} From 933bb18956f8e8a57e130ce0c9d342becc0ad0ae Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 12 Dec 2020 15:28:49 +0100 Subject: [PATCH 08/31] Use `rustc_type_ir::{IntTy,UintTy,FloatTy} instead of the `rustc_ast` ones in types --- compiler/rustc_middle/src/ty/cast.rs | 3 +- compiler/rustc_middle/src/ty/context.rs | 70 ++++++++++---------- compiler/rustc_middle/src/ty/error.rs | 3 +- compiler/rustc_middle/src/ty/fast_reject.rs | 7 +- compiler/rustc_middle/src/ty/layout.rs | 45 ++++++++++--- compiler/rustc_middle/src/ty/mod.rs | 51 ++++++++++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 7 +- compiler/rustc_middle/src/ty/sty.rs | 17 +++-- compiler/rustc_middle/src/ty/util.rs | 14 ++-- 9 files changed, 143 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index d737d1ebf56c6..20a6af5f6c13b 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -3,13 +3,12 @@ use crate::ty::{self, Ty}; -use rustc_ast as ast; use rustc_macros::HashStable; /// Types that are represented as ints. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum IntTy { - U(ast::UintTy), + U(ty::UintTy), I, CEnum, Bool, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1cbf761e6c738..1255302f74384 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -19,10 +19,10 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs use crate::ty::TyKind::*; use crate::ty::{ self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid, - DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, - IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, - ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, - TyVid, TypeAndMut, Visibility, + DefIdTree, ExistentialPredicate, FloatTy, FloatVar, FloatVid, GenericParamDefKind, InferConst, + InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, + PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind, ReprOptions, + TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, Visibility, }; use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; @@ -839,20 +839,20 @@ impl<'tcx> CommonTypes<'tcx> { bool: mk(Bool), char: mk(Char), never: mk(Never), - isize: mk(Int(ast::IntTy::Isize)), - i8: mk(Int(ast::IntTy::I8)), - i16: mk(Int(ast::IntTy::I16)), - i32: mk(Int(ast::IntTy::I32)), - i64: mk(Int(ast::IntTy::I64)), - i128: mk(Int(ast::IntTy::I128)), - usize: mk(Uint(ast::UintTy::Usize)), - u8: mk(Uint(ast::UintTy::U8)), - u16: mk(Uint(ast::UintTy::U16)), - u32: mk(Uint(ast::UintTy::U32)), - u64: mk(Uint(ast::UintTy::U64)), - u128: mk(Uint(ast::UintTy::U128)), - f32: mk(Float(ast::FloatTy::F32)), - f64: mk(Float(ast::FloatTy::F64)), + isize: mk(Int(ty::IntTy::Isize)), + i8: mk(Int(ty::IntTy::I8)), + i16: mk(Int(ty::IntTy::I16)), + i32: mk(Int(ty::IntTy::I32)), + i64: mk(Int(ty::IntTy::I64)), + i128: mk(Int(ty::IntTy::I128)), + usize: mk(Uint(ty::UintTy::Usize)), + u8: mk(Uint(ty::UintTy::U8)), + u16: mk(Uint(ty::UintTy::U16)), + u32: mk(Uint(ty::UintTy::U32)), + u64: mk(Uint(ty::UintTy::U64)), + u128: mk(Uint(ty::UintTy::U128)), + f32: mk(Float(ty::FloatTy::F32)), + f64: mk(Float(ty::FloatTy::F64)), str_: mk(Str), self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), @@ -2102,32 +2102,32 @@ impl<'tcx> TyCtxt<'tcx> { if pred.kind() != binder { self.mk_predicate(binder) } else { pred } } - pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> { + pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> { match tm { - ast::IntTy::Isize => self.types.isize, - ast::IntTy::I8 => self.types.i8, - ast::IntTy::I16 => self.types.i16, - ast::IntTy::I32 => self.types.i32, - ast::IntTy::I64 => self.types.i64, - ast::IntTy::I128 => self.types.i128, + IntTy::Isize => self.types.isize, + IntTy::I8 => self.types.i8, + IntTy::I16 => self.types.i16, + IntTy::I32 => self.types.i32, + IntTy::I64 => self.types.i64, + IntTy::I128 => self.types.i128, } } - pub fn mk_mach_uint(self, tm: ast::UintTy) -> Ty<'tcx> { + pub fn mk_mach_uint(self, tm: UintTy) -> Ty<'tcx> { match tm { - ast::UintTy::Usize => self.types.usize, - ast::UintTy::U8 => self.types.u8, - ast::UintTy::U16 => self.types.u16, - ast::UintTy::U32 => self.types.u32, - ast::UintTy::U64 => self.types.u64, - ast::UintTy::U128 => self.types.u128, + UintTy::Usize => self.types.usize, + UintTy::U8 => self.types.u8, + UintTy::U16 => self.types.u16, + UintTy::U32 => self.types.u32, + UintTy::U64 => self.types.u64, + UintTy::U128 => self.types.u128, } } - pub fn mk_mach_float(self, tm: ast::FloatTy) -> Ty<'tcx> { + pub fn mk_mach_float(self, tm: FloatTy) -> Ty<'tcx> { match tm { - ast::FloatTy::F32 => self.types.f32, - ast::FloatTy::F64 => self.types.f64, + FloatTy::F32 => self.types.f32, + FloatTy::F64 => self.types.f64, } } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index f172790fe5fff..c211f07bed8c2 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -1,7 +1,6 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::diagnostics::suggest_constraining_type_param; use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt}; -use rustc_ast as ast; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, DiagnosticBuilder}; use rustc_hir as hir; @@ -48,7 +47,7 @@ pub enum TypeError<'tcx> { Sorts(ExpectedFound>), IntMismatch(ExpectedFound), - FloatMismatch(ExpectedFound), + FloatMismatch(ExpectedFound), Traits(ExpectedFound), VariadicMismatch(ExpectedFound), diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 860f91db2bf7a..94d75a469d3d7 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -1,6 +1,5 @@ use crate::ich::StableHashingContext; use crate::ty::{self, Ty, TyCtxt}; -use rustc_ast as ast; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::def_id::DefId; use std::fmt::Debug; @@ -24,9 +23,9 @@ where { BoolSimplifiedType, CharSimplifiedType, - IntSimplifiedType(ast::IntTy), - UintSimplifiedType(ast::UintTy), - FloatSimplifiedType(ast::FloatTy), + IntSimplifiedType(ty::IntTy), + UintSimplifiedType(ty::UintTy), + FloatSimplifiedType(ty::FloatTy), AdtSimplifiedType(D), StrSimplifiedType, ArraySimplifiedType, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 195e840866aec..03728ed59ad73 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -4,7 +4,7 @@ use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::subst::Subst; use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; -use rustc_ast::{self as ast, IntTy, UintTy}; +use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; @@ -30,6 +30,8 @@ use std::ops::Bound; pub trait IntegerExt { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>; fn from_attr(cx: &C, ity: attr::IntType) -> Integer; + fn from_int_ty(cx: &C, ity: ty::IntTy) -> Integer; + fn from_uint_ty(cx: &C, uty: ty::UintTy) -> Integer; fn repr_discr<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, @@ -60,17 +62,38 @@ impl IntegerExt for Integer { let dl = cx.data_layout(); match ity { - attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8, - attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16, - attr::SignedInt(IntTy::I32) | attr::UnsignedInt(UintTy::U32) => I32, - attr::SignedInt(IntTy::I64) | attr::UnsignedInt(UintTy::U64) => I64, - attr::SignedInt(IntTy::I128) | attr::UnsignedInt(UintTy::U128) => I128, - attr::SignedInt(IntTy::Isize) | attr::UnsignedInt(UintTy::Usize) => { + attr::SignedInt(ast::IntTy::I8) | attr::UnsignedInt(ast::UintTy::U8) => I8, + attr::SignedInt(ast::IntTy::I16) | attr::UnsignedInt(ast::UintTy::U16) => I16, + attr::SignedInt(ast::IntTy::I32) | attr::UnsignedInt(ast::UintTy::U32) => I32, + attr::SignedInt(ast::IntTy::I64) | attr::UnsignedInt(ast::UintTy::U64) => I64, + attr::SignedInt(ast::IntTy::I128) | attr::UnsignedInt(ast::UintTy::U128) => I128, + attr::SignedInt(ast::IntTy::Isize) | attr::UnsignedInt(ast::UintTy::Usize) => { dl.ptr_sized_integer() } } } + fn from_int_ty(cx: &C, ity: ty::IntTy) -> Integer { + match ity { + ty::IntTy::I8 => I8, + ty::IntTy::I16 => I16, + ty::IntTy::I32 => I32, + ty::IntTy::I64 => I64, + ty::IntTy::I128 => I128, + ty::IntTy::Isize => cx.data_layout().ptr_sized_integer(), + } + } + fn from_uint_ty(cx: &C, ity: ty::UintTy) -> Integer { + match ity { + ty::UintTy::U8 => I8, + ty::UintTy::U16 => I16, + ty::UintTy::U32 => I32, + ty::UintTy::U64 => I64, + ty::UintTy::U128 => I128, + ty::UintTy::Usize => cx.data_layout().ptr_sized_integer(), + } + } + /// Finds the appropriate Integer type and signedness for the given /// signed discriminant range and `#[repr]` attribute. /// N.B.: `u128` values above `i128::MAX` will be treated as signed, but @@ -487,11 +510,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { self, Scalar { value: Int(I32, false), valid_range: 0..=0x10FFFF }, )), - ty::Int(ity) => scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true)), - ty::Uint(ity) => scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false)), + ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), + ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)), ty::Float(fty) => scalar(match fty { - ast::FloatTy::F32 => F32, - ast::FloatTy::F64 => F64, + ty::FloatTy::F32 => F32, + ty::FloatTy::F64 => F64, }), ty::FnPtr(_) => { let mut ptr = scalar_unit(Pointer); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 87730197da003..7f4a494e37cb4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -3045,6 +3045,57 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { None } +pub fn int_ty(ity: ast::IntTy) -> IntTy { + match ity { + ast::IntTy::Isize => IntTy::Isize, + ast::IntTy::I8 => IntTy::I8, + ast::IntTy::I16 => IntTy::I16, + ast::IntTy::I32 => IntTy::I32, + ast::IntTy::I64 => IntTy::I64, + ast::IntTy::I128 => IntTy::I128, + } +} + +pub fn uint_ty(uty: ast::UintTy) -> UintTy { + match uty { + ast::UintTy::Usize => UintTy::Usize, + ast::UintTy::U8 => UintTy::U8, + ast::UintTy::U16 => UintTy::U16, + ast::UintTy::U32 => UintTy::U32, + ast::UintTy::U64 => UintTy::U64, + ast::UintTy::U128 => UintTy::U128, + } +} + +pub fn float_ty(fty: ast::FloatTy) -> FloatTy { + match fty { + ast::FloatTy::F32 => FloatTy::F32, + ast::FloatTy::F64 => FloatTy::F64, + } +} + +pub fn ast_int_ty(ity: IntTy) -> ast::IntTy { + match ity { + IntTy::Isize => ast::IntTy::Isize, + IntTy::I8 => ast::IntTy::I8, + IntTy::I16 => ast::IntTy::I16, + IntTy::I32 => ast::IntTy::I32, + IntTy::I64 => ast::IntTy::I64, + IntTy::I128 => ast::IntTy::I128, + } +} + +pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy { + match uty { + UintTy::Usize => ast::UintTy::Usize, + UintTy::U8 => ast::UintTy::U8, + UintTy::U16 => ast::UintTy::U16, + UintTy::U32 => ast::UintTy::U32, + UintTy::U64 => ast::UintTy::U64, + UintTy::U128 => ast::UintTy::U128, + } +} + pub fn provide(providers: &mut ty::query::Providers) { context::provide(providers); erase_regions::provide(providers); diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 9c7e0e60c14d6..4937fdd73144d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3,7 +3,6 @@ use crate::mir::interpret::{AllocId, ConstValue, GlobalAlloc, Pointer, Scalar}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; -use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; @@ -973,7 +972,7 @@ pub trait PrettyPrinter<'tcx>: ty::TyS { kind: ty::Array( - ty::TyS { kind: ty::Uint(ast::UintTy::U8), .. }, + ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, ty::Const { val: ty::ConstKind::Value(ConstValue::Scalar(int)), .. @@ -1002,10 +1001,10 @@ pub trait PrettyPrinter<'tcx>: (Scalar::Int(int), ty::Bool) if int == ScalarInt::FALSE => p!("false"), (Scalar::Int(int), ty::Bool) if int == ScalarInt::TRUE => p!("true"), // Float - (Scalar::Int(int), ty::Float(ast::FloatTy::F32)) => { + (Scalar::Int(int), ty::Float(ty::FloatTy::F32)) => { p!(write("{}f32", Single::try_from(int).unwrap())) } - (Scalar::Int(int), ty::Float(ast::FloatTy::F64)) => { + (Scalar::Int(int), ty::Float(ty::FloatTy::F64)) => { p!(write("{}f64", Double::try_from(int).unwrap())) } // Int diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index aeba1843dbc12..9cec0eb5be3c5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -12,7 +12,6 @@ use crate::ty::{ }; use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS}; use polonius_engine::Atom; -use rustc_ast as ast; use rustc_data_structures::captures::Captures; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -104,13 +103,13 @@ pub enum TyKind<'tcx> { Char, /// A primitive signed integer type. For example, `i32`. - Int(ast::IntTy), + Int(ty::IntTy), /// A primitive unsigned integer type. For example, `u32`. - Uint(ast::UintTy), + Uint(ty::UintTy), /// A primitive floating-point type. For example, `f64`. - Float(ast::FloatTy), + Float(ty::FloatTy), /// Algebraic data types (ADT). For example: structures, enumerations and unions. /// @@ -1798,7 +1797,7 @@ impl<'tcx> TyS<'tcx> { pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self.kind() { Array(ty, _) | Slice(ty) => ty, - Str => tcx.mk_mach_uint(ast::UintTy::U8), + Str => tcx.mk_mach_uint(ty::UintTy::U8), _ => bug!("`sequence_element_type` called on non-sequence value: {}", self), } } @@ -1938,7 +1937,7 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_ptr_sized_integral(&self) -> bool { - matches!(self.kind(), Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize)) + matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize)) } #[inline] @@ -2126,9 +2125,9 @@ impl<'tcx> TyS<'tcx> { pub fn to_opt_closure_kind(&self) -> Option { match self.kind() { Int(int_ty) => match int_ty { - ast::IntTy::I8 => Some(ty::ClosureKind::Fn), - ast::IntTy::I16 => Some(ty::ClosureKind::FnMut), - ast::IntTy::I32 => Some(ty::ClosureKind::FnOnce), + ty::IntTy::I8 => Some(ty::ClosureKind::Fn), + ty::IntTy::I16 => Some(ty::ClosureKind::FnMut), + ty::IntTy::I32 => Some(ty::ClosureKind::FnOnce), _ => bug!("cannot convert type `{:?}` to a closure kind", self), }, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index a64580336ad62..8edde8794ed27 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -34,7 +34,7 @@ impl<'tcx> fmt::Display for Discr<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match *self.ty.kind() { ty::Int(ity) => { - let size = ty::tls::with(|tcx| Integer::from_attr(&tcx, SignedInt(ity)).size()); + let size = ty::tls::with(|tcx| Integer::from_int_ty(&tcx, ity).size()); let x = self.val; // sign extend the raw representation to be an i128 let x = size.sign_extend(x) as i128; @@ -59,8 +59,8 @@ fn unsigned_max(size: Size) -> u128 { fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) { let (int, signed) = match *ty.kind() { - Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true), - Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false), + Int(ity) => (Integer::from_int_ty(&tcx, ity), true), + Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false), _ => bug!("non integer discriminant"), }; (int.size(), signed) @@ -642,8 +642,8 @@ impl<'tcx> ty::TyS<'tcx> { } ty::Char => Some(std::char::MAX as u128), ty::Float(fty) => Some(match fty { - ast::FloatTy::F32 => rustc_apfloat::ieee::Single::INFINITY.to_bits(), - ast::FloatTy::F64 => rustc_apfloat::ieee::Double::INFINITY.to_bits(), + ty::FloatTy::F32 => rustc_apfloat::ieee::Single::INFINITY.to_bits(), + ty::FloatTy::F64 => rustc_apfloat::ieee::Double::INFINITY.to_bits(), }), _ => None, }; @@ -661,8 +661,8 @@ impl<'tcx> ty::TyS<'tcx> { } ty::Char => Some(0), ty::Float(fty) => Some(match fty { - ast::FloatTy::F32 => (-::rustc_apfloat::ieee::Single::INFINITY).to_bits(), - ast::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(), + ty::FloatTy::F32 => (-::rustc_apfloat::ieee::Single::INFINITY).to_bits(), + ty::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(), }), _ => None, }; From 50e1ae15e9f3035b06bae00e1b1dc7a358546d3e Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 12 Dec 2020 15:32:30 +0100 Subject: [PATCH 09/31] Use ty::{IntTy,UintTy,FloatTy} in rustc --- compiler/rustc_codegen_cranelift/src/lib.rs | 3 +- compiler/rustc_codegen_llvm/src/builder.rs | 3 +- .../src/debuginfo/metadata.rs | 35 ++++++----- compiler/rustc_codegen_llvm/src/type_.rs | 37 ++++++------ compiler/rustc_codegen_ssa/src/mir/block.rs | 20 +++---- compiler/rustc_infer/src/infer/combine.rs | 3 +- compiler/rustc_lint/src/types.rs | 60 ++++++++++++------- compiler/rustc_mir/src/interpret/cast.rs | 12 ++-- compiler/rustc_mir/src/interpret/operator.rs | 3 +- .../src/build/matches/simplify.rs | 5 +- compiler/rustc_mir_build/src/thir/constant.rs | 8 +-- .../src/thir/pattern/deconstruct_pat.rs | 11 ++-- .../rustc_mir_build/src/thir/pattern/mod.rs | 8 +-- compiler/rustc_passes/src/intrinsicck.rs | 4 +- compiler/rustc_symbol_mangling/src/v0.rs | 3 +- compiler/rustc_traits/src/chalk/db.rs | 28 ++++----- compiler/rustc_traits/src/chalk/lowering.rs | 58 +++++++++--------- compiler/rustc_typeck/src/astconv/mod.rs | 6 +- compiler/rustc_typeck/src/check/cast.rs | 3 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 14 +++-- .../rustc_typeck/src/check/method/probe.rs | 29 +++++---- .../src/coherence/inherent_impls.rs | 29 +++++---- 22 files changed, 188 insertions(+), 194 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 6e4f3bf2898d8..f31c58b92e407 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -83,7 +83,6 @@ mod vtable; mod prelude { pub(crate) use std::convert::{TryFrom, TryInto}; - pub(crate) use rustc_ast::ast::{FloatTy, IntTy, UintTy}; pub(crate) use rustc_span::Span; pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -91,7 +90,7 @@ mod prelude { pub(crate) use rustc_middle::mir::{self, *}; pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout}; pub(crate) use rustc_middle::ty::{ - self, FnSig, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, + self, FloatTy, FnSig, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, UintTy, }; pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx}; diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index f122fa14e70be..d2f4d3edc2207 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -304,9 +304,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { lhs: Self::Value, rhs: Self::Value, ) -> (Self::Value, Self::Value) { - use rustc_ast::IntTy::*; - use rustc_ast::UintTy::*; use rustc_middle::ty::{Int, Uint}; + use rustc_middle::ty::{IntTy::*, UintTy::*}; let new_kind = match ty.kind() { Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index b9ae796325023..3a4e1492af337 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -18,7 +18,6 @@ use crate::llvm::debuginfo::{ }; use crate::value::Value; -use rustc_ast as ast; use rustc_codegen_ssa::traits::*; use rustc_data_structures::const_cstr; use rustc_data_structures::fingerprint::Fingerprint; @@ -830,37 +829,37 @@ trait MsvcBasicName { fn msvc_basic_name(self) -> &'static str; } -impl MsvcBasicName for ast::IntTy { +impl MsvcBasicName for ty::IntTy { fn msvc_basic_name(self) -> &'static str { match self { - ast::IntTy::Isize => "ptrdiff_t", - ast::IntTy::I8 => "__int8", - ast::IntTy::I16 => "__int16", - ast::IntTy::I32 => "__int32", - ast::IntTy::I64 => "__int64", - ast::IntTy::I128 => "__int128", + ty::IntTy::Isize => "ptrdiff_t", + ty::IntTy::I8 => "__int8", + ty::IntTy::I16 => "__int16", + ty::IntTy::I32 => "__int32", + ty::IntTy::I64 => "__int64", + ty::IntTy::I128 => "__int128", } } } -impl MsvcBasicName for ast::UintTy { +impl MsvcBasicName for ty::UintTy { fn msvc_basic_name(self) -> &'static str { match self { - ast::UintTy::Usize => "size_t", - ast::UintTy::U8 => "unsigned __int8", - ast::UintTy::U16 => "unsigned __int16", - ast::UintTy::U32 => "unsigned __int32", - ast::UintTy::U64 => "unsigned __int64", - ast::UintTy::U128 => "unsigned __int128", + ty::UintTy::Usize => "size_t", + ty::UintTy::U8 => "unsigned __int8", + ty::UintTy::U16 => "unsigned __int16", + ty::UintTy::U32 => "unsigned __int32", + ty::UintTy::U64 => "unsigned __int64", + ty::UintTy::U128 => "unsigned __int128", } } } -impl MsvcBasicName for ast::FloatTy { +impl MsvcBasicName for ty::FloatTy { fn msvc_basic_name(self) -> &'static str { match self { - ast::FloatTy::F32 => "float", - ast::FloatTy::F64 => "double", + ty::FloatTy::F32 => "float", + ty::FloatTy::F64 => "double", } } } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index a43724fd49599..8fd0caae479a8 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -7,13 +7,12 @@ use crate::llvm; use crate::llvm::{Bool, False, True}; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_ast as ast; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; use rustc_middle::bug; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::{AddressSpace, Align, Integer, Size}; @@ -80,32 +79,32 @@ impl CodegenCx<'ll, 'tcx> { self.type_i8() } - crate fn type_int_from_ty(&self, t: ast::IntTy) -> &'ll Type { + crate fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type { match t { - ast::IntTy::Isize => self.type_isize(), - ast::IntTy::I8 => self.type_i8(), - ast::IntTy::I16 => self.type_i16(), - ast::IntTy::I32 => self.type_i32(), - ast::IntTy::I64 => self.type_i64(), - ast::IntTy::I128 => self.type_i128(), + ty::IntTy::Isize => self.type_isize(), + ty::IntTy::I8 => self.type_i8(), + ty::IntTy::I16 => self.type_i16(), + ty::IntTy::I32 => self.type_i32(), + ty::IntTy::I64 => self.type_i64(), + ty::IntTy::I128 => self.type_i128(), } } - crate fn type_uint_from_ty(&self, t: ast::UintTy) -> &'ll Type { + crate fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type { match t { - ast::UintTy::Usize => self.type_isize(), - ast::UintTy::U8 => self.type_i8(), - ast::UintTy::U16 => self.type_i16(), - ast::UintTy::U32 => self.type_i32(), - ast::UintTy::U64 => self.type_i64(), - ast::UintTy::U128 => self.type_i128(), + ty::UintTy::Usize => self.type_isize(), + ty::UintTy::U8 => self.type_i8(), + ty::UintTy::U16 => self.type_i16(), + ty::UintTy::U32 => self.type_i32(), + ty::UintTy::U64 => self.type_i64(), + ty::UintTy::U128 => self.type_i128(), } } - crate fn type_float_from_ty(&self, t: ast::FloatTy) -> &'ll Type { + crate fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type { match t { - ast::FloatTy::F32 => self.type_f32(), - ast::FloatTy::F64 => self.type_f64(), + ty::FloatTy::F32 => self.type_f32(), + ty::FloatTy::F64 => self.type_f64(), } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index ecac05fd95572..c821908167870 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -875,20 +875,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::Uint(_) => value.to_string(), ty::Int(int_ty) => { match int_ty.normalize(bx.tcx().sess.target.pointer_width) { - ast::IntTy::I8 => (value as i8).to_string(), - ast::IntTy::I16 => (value as i16).to_string(), - ast::IntTy::I32 => (value as i32).to_string(), - ast::IntTy::I64 => (value as i64).to_string(), - ast::IntTy::I128 => (value as i128).to_string(), - ast::IntTy::Isize => unreachable!(), + ty::IntTy::I8 => (value as i8).to_string(), + ty::IntTy::I16 => (value as i16).to_string(), + ty::IntTy::I32 => (value as i32).to_string(), + ty::IntTy::I64 => (value as i64).to_string(), + ty::IntTy::I128 => (value as i128).to_string(), + ty::IntTy::Isize => unreachable!(), } } - ty::Float(ast::FloatTy::F32) => { - f32::from_bits(value as u32).to_string() - } - ty::Float(ast::FloatTy::F64) => { - f64::from_bits(value as u64).to_string() - } + ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(), + ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(), _ => span_bug!(span, "asm const has bad type {}", ty), }; InlineAsmOperandRef::Const { string } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index b344086e95e77..e034ac5e8fd70 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -34,7 +34,6 @@ use super::{InferCtxt, MiscVariable, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; -use rustc_ast as ast; use rustc_data_structures::sso::SsoHashMap; use rustc_hir::def_id::DefId; use rustc_middle::traits::ObligationCause; @@ -281,7 +280,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { &self, vid_is_expected: bool, vid: ty::FloatVid, - val: ast::FloatTy, + val: ty::FloatTy, ) -> RelateResult<'tcx, Ty<'tcx>> { self.inner .borrow_mut() diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 424f91b3f883e..1e879d2937060 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -168,25 +168,25 @@ fn lint_overflowing_range_endpoint<'tcx>( // For `isize` & `usize`, be conservative with the warnings, so that the // warnings are consistent between 32- and 64-bit platforms. -fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) { +fn int_ty_range(int_ty: ty::IntTy) -> (i128, i128) { match int_ty { - ast::IntTy::Isize => (i64::MIN.into(), i64::MAX.into()), - ast::IntTy::I8 => (i8::MIN.into(), i8::MAX.into()), - ast::IntTy::I16 => (i16::MIN.into(), i16::MAX.into()), - ast::IntTy::I32 => (i32::MIN.into(), i32::MAX.into()), - ast::IntTy::I64 => (i64::MIN.into(), i64::MAX.into()), - ast::IntTy::I128 => (i128::MIN, i128::MAX), + ty::IntTy::Isize => (i64::MIN.into(), i64::MAX.into()), + ty::IntTy::I8 => (i8::MIN.into(), i8::MAX.into()), + ty::IntTy::I16 => (i16::MIN.into(), i16::MAX.into()), + ty::IntTy::I32 => (i32::MIN.into(), i32::MAX.into()), + ty::IntTy::I64 => (i64::MIN.into(), i64::MAX.into()), + ty::IntTy::I128 => (i128::MIN, i128::MAX), } } -fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) { +fn uint_ty_range(uint_ty: ty::UintTy) -> (u128, u128) { let max = match uint_ty { - ast::UintTy::Usize => u64::MAX.into(), - ast::UintTy::U8 => u8::MAX.into(), - ast::UintTy::U16 => u16::MAX.into(), - ast::UintTy::U32 => u32::MAX.into(), - ast::UintTy::U64 => u64::MAX.into(), - ast::UintTy::U128 => u128::MAX, + ty::UintTy::Usize => u64::MAX.into(), + ty::UintTy::U8 => u8::MAX.into(), + ty::UintTy::U16 => u16::MAX.into(), + ty::UintTy::U32 => u32::MAX.into(), + ty::UintTy::U64 => u64::MAX.into(), + ty::UintTy::U128 => u128::MAX, }; (0, max) } @@ -258,8 +258,8 @@ fn report_bin_hex_error( // // No suggestion for: `isize`, `usize`. fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> { - use rustc_ast::IntTy::*; - use rustc_ast::UintTy::*; + use ty::IntTy::*; + use ty::UintTy::*; macro_rules! find_fit { ($ty:expr, $val:expr, $negative:expr, $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => { @@ -302,7 +302,7 @@ fn lint_int_literal<'tcx>( type_limits: &TypeLimits, e: &'tcx hir::Expr<'tcx>, lit: &hir::Lit, - t: ast::IntTy, + t: ty::IntTy, v: u128, ) { let int_type = t.normalize(cx.sess().target.pointer_width); @@ -314,7 +314,14 @@ fn lint_int_literal<'tcx>( // avoiding use of -min to prevent overflow/panic if (negative && v > max + 1) || (!negative && v > max) { if let Some(repr_str) = get_bin_hex_repr(cx, lit) { - report_bin_hex_error(cx, e, attr::IntType::SignedInt(t), repr_str, v, negative); + report_bin_hex_error( + cx, + e, + attr::IntType::SignedInt(ty::ast_int_ty(t)), + repr_str, + v, + negative, + ); return; } @@ -351,7 +358,7 @@ fn lint_uint_literal<'tcx>( cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>, lit: &hir::Lit, - t: ast::UintTy, + t: ty::UintTy, ) { let uint_type = t.normalize(cx.sess().target.pointer_width); let (min, max) = uint_ty_range(uint_type); @@ -391,7 +398,14 @@ fn lint_uint_literal<'tcx>( } } if let Some(repr_str) = get_bin_hex_repr(cx, lit) { - report_bin_hex_error(cx, e, attr::IntType::UnsignedInt(t), repr_str, lit_val, false); + report_bin_hex_error( + cx, + e, + attr::IntType::UnsignedInt(ty::ast_uint_ty(t)), + repr_str, + lit_val, + false, + ); return; } cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { @@ -430,8 +444,8 @@ fn lint_literal<'tcx>( ty::Float(t) => { let is_infinite = match lit.node { ast::LitKind::Float(v, _) => match t { - ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), - ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), + ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), + ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), }, _ => bug!(), }; @@ -984,7 +998,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Some("consider using `u32` or `libc::wchar_t` instead".into()), }, - ty::Int(ast::IntTy::I128) | ty::Uint(ast::UintTy::U128) => FfiUnsafe { + ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => FfiUnsafe { ty, reason: "128-bit integers don't currently have a known stable ABI".into(), help: None, diff --git a/compiler/rustc_mir/src/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index 6d224bcc50b0f..128d8cff95e6b 100644 --- a/compiler/rustc_mir/src/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs @@ -2,13 +2,11 @@ use std::convert::TryFrom; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::{Float, FloatConvert}; -use rustc_ast::FloatTy; -use rustc_attr as attr; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; -use rustc_middle::ty::{self, Ty, TypeAndMut}; +use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut}; use rustc_span::symbol::sym; use rustc_target::abi::{Integer, LayoutOf, Variants}; @@ -203,8 +201,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match *cast_ty.kind() { Int(_) | Uint(_) | RawPtr(_) => { let size = match *cast_ty.kind() { - Int(t) => Integer::from_attr(self, attr::IntType::SignedInt(t)).size(), - Uint(t) => Integer::from_attr(self, attr::IntType::UnsignedInt(t)).size(), + Int(t) => Integer::from_int_ty(self, t).size(), + Uint(t) => Integer::from_uint_ty(self, t).size(), RawPtr(_) => self.pointer_size(), _ => bug!(), }; @@ -235,7 +233,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match *dest_ty.kind() { // float -> uint Uint(t) => { - let size = Integer::from_attr(self, attr::IntType::UnsignedInt(t)).size(); + let size = Integer::from_uint_ty(self, t).size(); // `to_u128` is a saturating cast, which is what we need // (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r). let v = f.to_u128(size.bits_usize()).value; @@ -244,7 +242,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // float -> int Int(t) => { - let size = Integer::from_attr(self, attr::IntType::SignedInt(t)).size(); + let size = Integer::from_int_ty(self, t).size(); // `to_i128` is a saturating cast, which is what we need // (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r). let v = f.to_i128(size.bits_usize()).value; diff --git a/compiler/rustc_mir/src/interpret/operator.rs b/compiler/rustc_mir/src/interpret/operator.rs index fc266fa74bfa9..f5081655015b4 100644 --- a/compiler/rustc_mir/src/interpret/operator.rs +++ b/compiler/rustc_mir/src/interpret/operator.rs @@ -1,10 +1,9 @@ use std::convert::TryFrom; use rustc_apfloat::Float; -use rustc_ast::FloatTy; use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; -use rustc_middle::ty::{self, layout::TyAndLayout, Ty}; +use rustc_middle::ty::{self, layout::TyAndLayout, FloatTy, Ty}; use rustc_target::abi::LayoutOf; use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 705266d4a0bd8..02cc4de529035 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -15,7 +15,6 @@ use crate::build::matches::{Ascription, Binding, Candidate, MatchPair}; use crate::build::Builder; use crate::thir::{self, *}; -use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::RangeEnd; use rustc_middle::mir::Place; use rustc_middle::ty; @@ -203,13 +202,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0) } ty::Int(ity) => { - let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); + let size = Integer::from_int_ty(&tcx, ity).size(); let max = size.truncate(u128::MAX); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { - let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); + let size = Integer::from_uint_ty(&tcx, uty).size(); let max = size.truncate(u128::MAX); (Some((0, max, size)), 0) } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index dfe82317f48c6..969f7d1e3a458 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -39,7 +39,7 @@ crate fn lit_to_const<'tcx>( let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::Ptr(id.into())) } - (ast::LitKind::Byte(n), ty::Uint(ast::UintTy::U8)) => { + (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) } (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { @@ -56,11 +56,11 @@ crate fn lit_to_const<'tcx>( Ok(ty::Const::from_value(tcx, lit, ty)) } -fn parse_float<'tcx>(num: Symbol, fty: ast::FloatTy, neg: bool) -> Result, ()> { +fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Result, ()> { let num = num.as_str(); use rustc_apfloat::ieee::{Double, Single}; let scalar = match fty { - ast::FloatTy::F32 => { + ty::FloatTy::F32 => { num.parse::().map_err(|_| ())?; let mut f = num.parse::().unwrap_or_else(|e| { panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e) @@ -70,7 +70,7 @@ fn parse_float<'tcx>(num: Symbol, fty: ast::FloatTy, neg: bool) -> Result { + ty::FloatTy::F64 => { num.parse::().map_err(|_| ())?; let mut f = num.parse::().unwrap_or_else(|e| { panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index db2fa5730a338..e67166c99c8da 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -52,7 +52,6 @@ use super::{FieldPat, Pat, PatKind, PatRange}; use rustc_data_structures::captures::Captures; use rustc_index::vec::Idx; -use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::def_id::DefId; use rustc_hir::{HirId, RangeEnd}; use rustc_middle::mir::interpret::ConstValue; @@ -103,10 +102,10 @@ impl IntRange { ty::Bool => Some((Size::from_bytes(1), 0)), ty::Char => Some((Size::from_bytes(4), 0)), ty::Int(ity) => { - let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); + let size = Integer::from_int_ty(&tcx, ity).size(); Some((size, 1u128 << (size.bits() as u128 - 1))) } - ty::Uint(uty) => Some((Integer::from_attr(&tcx, UnsignedInt(uty)).size(), 0)), + ty::Uint(uty) => Some((Integer::from_uint_ty(&tcx, uty).size(), 0)), _ => None, } } @@ -167,7 +166,7 @@ impl IntRange { fn signed_bias(tcx: TyCtxt<'_>, ty: Ty<'_>) -> u128 { match *ty.kind() { ty::Int(ity) => { - let bits = Integer::from_attr(&tcx, SignedInt(ity)).size().bits() as u128; + let bits = Integer::from_int_ty(&tcx, ity).size().bits() as u128; 1u128 << (bits - 1) } _ => 0, @@ -959,13 +958,13 @@ impl<'tcx> SplitWildcard<'tcx> { smallvec![NonExhaustive] } &ty::Int(ity) => { - let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128; + let bits = Integer::from_int_ty(&cx.tcx, ity).size().bits() as u128; let min = 1u128 << (bits - 1); let max = min - 1; smallvec![make_range(min, max)] } &ty::Uint(uty) => { - let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); + let size = Integer::from_uint_ty(&cx.tcx, uty).size(); let max = size.truncate(u128::MAX); smallvec![make_range(0, max)] } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 7e9a3a37278b7..7186e26be800e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -9,7 +9,6 @@ pub(crate) use self::check_match::check_match; use crate::thir::util::UserAnnotatedTyHelpers; -use rustc_ast as ast; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -1069,20 +1068,19 @@ crate fn compare_const_vals<'tcx>( if let (Some(a), Some(b)) = (a_bits, b_bits) { use rustc_apfloat::Float; return match *ty.kind() { - ty::Float(ast::FloatTy::F32) => { + ty::Float(ty::FloatTy::F32) => { let l = rustc_apfloat::ieee::Single::from_bits(a); let r = rustc_apfloat::ieee::Single::from_bits(b); l.partial_cmp(&r) } - ty::Float(ast::FloatTy::F64) => { + ty::Float(ty::FloatTy::F64) => { let l = rustc_apfloat::ieee::Double::from_bits(a); let r = rustc_apfloat::ieee::Double::from_bits(b); l.partial_cmp(&r) } ty::Int(ity) => { - use rustc_attr::SignedInt; use rustc_middle::ty::layout::IntegerExt; - let size = rustc_target::abi::Integer::from_attr(&tcx, SignedInt(ity)).size(); + let size = rustc_target::abi::Integer::from_int_ty(&tcx, ity).size(); let a = size.sign_extend(a); let b = size.sign_extend(b); Some((a as i128).cmp(&(b as i128))) diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index ee90e9c54f69d..0f4bb635eeefd 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -1,4 +1,4 @@ -use rustc_ast::{FloatTy, InlineAsmTemplatePiece, IntTy, UintTy}; +use rustc_ast::InlineAsmTemplatePiece; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -7,7 +7,7 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_index::vec::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy}; use rustc_session::lint; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Pointer, VariantIdx}; diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 7b6e6ad0696a1..c84e2cb45a6c4 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -1,4 +1,3 @@ -use rustc_ast::{FloatTy, IntTy, UintTy}; use rustc_data_structures::base_n; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; @@ -6,7 +5,7 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy}; use rustc_target::spec::abi::Abi; use std::fmt::Write; diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 1893d74335ab8..bb48ed936188b 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -346,26 +346,26 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t (ty::Char, Scalar(Char)) => true, (ty::Int(ty1), Scalar(Int(ty2))) => matches!( (ty1, ty2), - (ast::IntTy::Isize, chalk_ir::IntTy::Isize) - | (ast::IntTy::I8, chalk_ir::IntTy::I8) - | (ast::IntTy::I16, chalk_ir::IntTy::I16) - | (ast::IntTy::I32, chalk_ir::IntTy::I32) - | (ast::IntTy::I64, chalk_ir::IntTy::I64) - | (ast::IntTy::I128, chalk_ir::IntTy::I128) + (ty::IntTy::Isize, chalk_ir::IntTy::Isize) + | (ty::IntTy::I8, chalk_ir::IntTy::I8) + | (ty::IntTy::I16, chalk_ir::IntTy::I16) + | (ty::IntTy::I32, chalk_ir::IntTy::I32) + | (ty::IntTy::I64, chalk_ir::IntTy::I64) + | (ty::IntTy::I128, chalk_ir::IntTy::I128) ), (ty::Uint(ty1), Scalar(Uint(ty2))) => matches!( (ty1, ty2), - (ast::UintTy::Usize, chalk_ir::UintTy::Usize) - | (ast::UintTy::U8, chalk_ir::UintTy::U8) - | (ast::UintTy::U16, chalk_ir::UintTy::U16) - | (ast::UintTy::U32, chalk_ir::UintTy::U32) - | (ast::UintTy::U64, chalk_ir::UintTy::U64) - | (ast::UintTy::U128, chalk_ir::UintTy::U128) + (ty::UintTy::Usize, chalk_ir::UintTy::Usize) + | (ty::UintTy::U8, chalk_ir::UintTy::U8) + | (ty::UintTy::U16, chalk_ir::UintTy::U16) + | (ty::UintTy::U32, chalk_ir::UintTy::U32) + | (ty::UintTy::U64, chalk_ir::UintTy::U64) + | (ty::UintTy::U128, chalk_ir::UintTy::U128) ), (ty::Float(ty1), Scalar(Float(ty2))) => matches!( (ty1, ty2), - (ast::FloatTy::F32, chalk_ir::FloatTy::F32) - | (ast::FloatTy::F64, chalk_ir::FloatTy::F64) + (ty::FloatTy::F32, chalk_ir::FloatTy::F32) + | (ty::FloatTy::F64, chalk_ir::FloatTy::F64) ), (&ty::Tuple(substs), Tuple(len, _)) => substs.len() == *len, (&ty::Array(..), Array(..)) => true, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 48d47054a4182..2a1a3f57e2313 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -233,8 +233,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq>> impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty> { - use rustc_ast as ast; - let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)); let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)); let float = |f| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Float(f)); @@ -243,24 +241,24 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ty::Bool => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool), ty::Char => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Char), ty::Int(ty) => match ty { - ast::IntTy::Isize => int(chalk_ir::IntTy::Isize), - ast::IntTy::I8 => int(chalk_ir::IntTy::I8), - ast::IntTy::I16 => int(chalk_ir::IntTy::I16), - ast::IntTy::I32 => int(chalk_ir::IntTy::I32), - ast::IntTy::I64 => int(chalk_ir::IntTy::I64), - ast::IntTy::I128 => int(chalk_ir::IntTy::I128), + ty::IntTy::Isize => int(chalk_ir::IntTy::Isize), + ty::IntTy::I8 => int(chalk_ir::IntTy::I8), + ty::IntTy::I16 => int(chalk_ir::IntTy::I16), + ty::IntTy::I32 => int(chalk_ir::IntTy::I32), + ty::IntTy::I64 => int(chalk_ir::IntTy::I64), + ty::IntTy::I128 => int(chalk_ir::IntTy::I128), }, ty::Uint(ty) => match ty { - ast::UintTy::Usize => uint(chalk_ir::UintTy::Usize), - ast::UintTy::U8 => uint(chalk_ir::UintTy::U8), - ast::UintTy::U16 => uint(chalk_ir::UintTy::U16), - ast::UintTy::U32 => uint(chalk_ir::UintTy::U32), - ast::UintTy::U64 => uint(chalk_ir::UintTy::U64), - ast::UintTy::U128 => uint(chalk_ir::UintTy::U128), + ty::UintTy::Usize => uint(chalk_ir::UintTy::Usize), + ty::UintTy::U8 => uint(chalk_ir::UintTy::U8), + ty::UintTy::U16 => uint(chalk_ir::UintTy::U16), + ty::UintTy::U32 => uint(chalk_ir::UintTy::U32), + ty::UintTy::U64 => uint(chalk_ir::UintTy::U64), + ty::UintTy::U128 => uint(chalk_ir::UintTy::U128), }, ty::Float(ty) => match ty { - ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32), - ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64), + ty::FloatTy::F32 => float(chalk_ir::FloatTy::F32), + ty::FloatTy::F64 => float(chalk_ir::FloatTy::F64), }, ty::Adt(def, substs) => { chalk_ir::TyKind::Adt(chalk_ir::AdtId(def), substs.lower_into(interner)) @@ -347,24 +345,24 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty> { chalk_ir::Scalar::Bool => ty::Bool, chalk_ir::Scalar::Char => ty::Char, chalk_ir::Scalar::Int(int_ty) => match int_ty { - chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize), - chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8), - chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16), - chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32), - chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64), - chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128), + chalk_ir::IntTy::Isize => ty::Int(ty::IntTy::Isize), + chalk_ir::IntTy::I8 => ty::Int(ty::IntTy::I8), + chalk_ir::IntTy::I16 => ty::Int(ty::IntTy::I16), + chalk_ir::IntTy::I32 => ty::Int(ty::IntTy::I32), + chalk_ir::IntTy::I64 => ty::Int(ty::IntTy::I64), + chalk_ir::IntTy::I128 => ty::Int(ty::IntTy::I128), }, chalk_ir::Scalar::Uint(int_ty) => match int_ty { - chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize), - chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8), - chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16), - chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32), - chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64), - chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128), + chalk_ir::UintTy::Usize => ty::Uint(ty::UintTy::Usize), + chalk_ir::UintTy::U8 => ty::Uint(ty::UintTy::U8), + chalk_ir::UintTy::U16 => ty::Uint(ty::UintTy::U16), + chalk_ir::UintTy::U32 => ty::Uint(ty::UintTy::U32), + chalk_ir::UintTy::U64 => ty::Uint(ty::UintTy::U64), + chalk_ir::UintTy::U128 => ty::Uint(ty::UintTy::U128), }, chalk_ir::Scalar::Float(float_ty) => match float_ty { - chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32), - chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64), + chalk_ir::FloatTy::F32 => ty::Float(ty::FloatTy::F32), + chalk_ir::FloatTy::F64 => ty::Float(ty::FloatTy::F64), }, }, TyKind::Array(ty, c) => { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 059f9b41068c7..437813ea41bd5 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2059,9 +2059,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { match prim_ty { hir::PrimTy::Bool => tcx.types.bool, hir::PrimTy::Char => tcx.types.char, - hir::PrimTy::Int(it) => tcx.mk_mach_int(it), - hir::PrimTy::Uint(uit) => tcx.mk_mach_uint(uit), - hir::PrimTy::Float(ft) => tcx.mk_mach_float(ft), + hir::PrimTy::Int(it) => tcx.mk_mach_int(ty::int_ty(it)), + hir::PrimTy::Uint(uit) => tcx.mk_mach_uint(ty::uint_ty(uit)), + hir::PrimTy::Float(ft) => tcx.mk_mach_float(ty::float_ty(ft)), hir::PrimTy::Str => tcx.types.str_, } } diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 39dac0a909f6f..7924ffe8a6fd5 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -32,7 +32,6 @@ use super::FnCtxt; use crate::hir::def_id::DefId; use crate::type_error_struct; -use rustc_ast as ast; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; @@ -660,7 +659,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { (_, Int(Bool)) => Err(CastError::CastToBool), // * -> Char - (Int(U(ast::UintTy::U8)), Int(Char)) => Ok(CastKind::U8CharCast), // u8-char-cast + (Int(U(ty::UintTy::U8)), Int(Char)) => Ok(CastKind::U8CharCast), // u8-char-cast (_, Int(Char)) => Err(CastError::CastToChar), // prim -> float,ptr diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 6df9e3ab7dbe8..ee693e4b5da2e 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -373,13 +373,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // in C but we just error out instead and require explicit casts. let arg_ty = self.structurally_resolved_type(arg.span, arg_ty); match arg_ty.kind() { - ty::Float(ast::FloatTy::F32) => { + ty::Float(ty::FloatTy::F32) => { variadic_error(tcx.sess, arg.span, arg_ty, "c_double"); } - ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => { + ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => { variadic_error(tcx.sess, arg.span, arg_ty, "c_int"); } - ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => { + ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => { variadic_error(tcx.sess, arg.span, arg_ty, "c_uint"); } ty::FnDef(..) => { @@ -408,8 +408,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ast::LitKind::Byte(_) => tcx.types.u8, ast::LitKind::Char(_) => tcx.types.char, - ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t), - ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t), + ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(ty::int_ty(t)), + ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(ty::uint_ty(t)), ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => { let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() { ty::Int(_) | ty::Uint(_) => Some(ty), @@ -420,7 +420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); opt_ty.unwrap_or_else(|| self.next_int_var()) } - ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t), + ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => { + tcx.mk_mach_float(ty::float_ty(t)) + } ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => { let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() { ty::Float(_) => Some(ty), diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 8335239f804b0..158c214759db2 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -8,7 +8,6 @@ use crate::errors::MethodCallOnUnknownType; use crate::hir::def::DefKind; use crate::hir::def_id::DefId; -use rustc_ast as ast; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; @@ -662,30 +661,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } ty::Int(i) => { let lang_def_id = match i { - ast::IntTy::I8 => lang_items.i8_impl(), - ast::IntTy::I16 => lang_items.i16_impl(), - ast::IntTy::I32 => lang_items.i32_impl(), - ast::IntTy::I64 => lang_items.i64_impl(), - ast::IntTy::I128 => lang_items.i128_impl(), - ast::IntTy::Isize => lang_items.isize_impl(), + ty::IntTy::I8 => lang_items.i8_impl(), + ty::IntTy::I16 => lang_items.i16_impl(), + ty::IntTy::I32 => lang_items.i32_impl(), + ty::IntTy::I64 => lang_items.i64_impl(), + ty::IntTy::I128 => lang_items.i128_impl(), + ty::IntTy::Isize => lang_items.isize_impl(), }; self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::Uint(i) => { let lang_def_id = match i { - ast::UintTy::U8 => lang_items.u8_impl(), - ast::UintTy::U16 => lang_items.u16_impl(), - ast::UintTy::U32 => lang_items.u32_impl(), - ast::UintTy::U64 => lang_items.u64_impl(), - ast::UintTy::U128 => lang_items.u128_impl(), - ast::UintTy::Usize => lang_items.usize_impl(), + ty::UintTy::U8 => lang_items.u8_impl(), + ty::UintTy::U16 => lang_items.u16_impl(), + ty::UintTy::U32 => lang_items.u32_impl(), + ty::UintTy::U64 => lang_items.u64_impl(), + ty::UintTy::U128 => lang_items.u128_impl(), + ty::UintTy::Usize => lang_items.usize_impl(), }; self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::Float(f) => { let (lang_def_id1, lang_def_id2) = match f { - ast::FloatTy::F32 => (lang_items.f32_impl(), lang_items.f32_runtime_impl()), - ast::FloatTy::F64 => (lang_items.f64_impl(), lang_items.f64_runtime_impl()), + ty::FloatTy::F32 => (lang_items.f32_impl(), lang_items.f32_runtime_impl()), + ty::FloatTy::F64 => (lang_items.f64_impl(), lang_items.f64_runtime_impl()), }; self.assemble_inherent_impl_for_primitive(lang_def_id1); self.assemble_inherent_impl_for_primitive(lang_def_id2); diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index 6b6c66932c868..8a500852a0326 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs @@ -13,7 +13,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc_ast as ast; use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. @@ -178,7 +177,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Int(ast::IntTy::I8) => { + ty::Int(ty::IntTy::I8) => { self.check_primitive_impl( def_id, lang_items.i8_impl(), @@ -189,7 +188,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Int(ast::IntTy::I16) => { + ty::Int(ty::IntTy::I16) => { self.check_primitive_impl( def_id, lang_items.i16_impl(), @@ -200,7 +199,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Int(ast::IntTy::I32) => { + ty::Int(ty::IntTy::I32) => { self.check_primitive_impl( def_id, lang_items.i32_impl(), @@ -211,7 +210,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Int(ast::IntTy::I64) => { + ty::Int(ty::IntTy::I64) => { self.check_primitive_impl( def_id, lang_items.i64_impl(), @@ -222,7 +221,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Int(ast::IntTy::I128) => { + ty::Int(ty::IntTy::I128) => { self.check_primitive_impl( def_id, lang_items.i128_impl(), @@ -233,7 +232,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Int(ast::IntTy::Isize) => { + ty::Int(ty::IntTy::Isize) => { self.check_primitive_impl( def_id, lang_items.isize_impl(), @@ -244,7 +243,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Uint(ast::UintTy::U8) => { + ty::Uint(ty::UintTy::U8) => { self.check_primitive_impl( def_id, lang_items.u8_impl(), @@ -255,7 +254,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Uint(ast::UintTy::U16) => { + ty::Uint(ty::UintTy::U16) => { self.check_primitive_impl( def_id, lang_items.u16_impl(), @@ -266,7 +265,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Uint(ast::UintTy::U32) => { + ty::Uint(ty::UintTy::U32) => { self.check_primitive_impl( def_id, lang_items.u32_impl(), @@ -277,7 +276,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Uint(ast::UintTy::U64) => { + ty::Uint(ty::UintTy::U64) => { self.check_primitive_impl( def_id, lang_items.u64_impl(), @@ -288,7 +287,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Uint(ast::UintTy::U128) => { + ty::Uint(ty::UintTy::U128) => { self.check_primitive_impl( def_id, lang_items.u128_impl(), @@ -299,7 +298,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Uint(ast::UintTy::Usize) => { + ty::Uint(ty::UintTy::Usize) => { self.check_primitive_impl( def_id, lang_items.usize_impl(), @@ -310,7 +309,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Float(ast::FloatTy::F32) => { + ty::Float(ty::FloatTy::F32) => { self.check_primitive_impl( def_id, lang_items.f32_impl(), @@ -321,7 +320,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { assoc_items, ); } - ty::Float(ast::FloatTy::F64) => { + ty::Float(ty::FloatTy::F64) => { self.check_primitive_impl( def_id, lang_items.f64_impl(), From e0d64b9b0d7a21556e0dd30f90a657a79f158033 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 12 Dec 2020 15:32:45 +0100 Subject: [PATCH 10/31] Use ty::{IntTy,UintTy,FloatTy} in rustdoc and clippy --- src/librustdoc/clean/types.rs | 39 ++++++++++++++++++- .../clippy/clippy_lints/src/bytecount.rs | 3 +- src/tools/clippy/clippy_lints/src/consts.rs | 8 ++-- .../clippy/clippy_lints/src/enum_clike.rs | 3 +- .../clippy/clippy_lints/src/float_literal.rs | 8 ++-- .../clippy/clippy_lints/src/mutex_atomic.rs | 5 +-- .../clippy/clippy_lints/src/transmute.rs | 6 +-- src/tools/clippy/clippy_lints/src/types.rs | 8 ++-- .../clippy/clippy_lints/src/utils/mod.rs | 13 +++---- 9 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 666b11b5f806d..48ac5255a32c1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -11,7 +11,6 @@ use std::{slice, vec}; use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; use rustc_ast::{self as ast, AttrStyle}; -use rustc_ast::{FloatTy, IntTy, UintTy}; use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_feature::UnstableFeatures; @@ -21,7 +20,7 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::Mutability; use rustc_index::vec::IndexVec; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt}; use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; @@ -1423,6 +1422,7 @@ impl GetDefId for Type { impl PrimitiveType { crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType { + use ast::{FloatTy, IntTy, UintTy}; match prim { hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize, hir::PrimTy::Int(IntTy::I8) => PrimitiveType::I8, @@ -1657,6 +1657,41 @@ impl From for PrimitiveType { } } +impl From for PrimitiveType { + fn from(int_ty: ty::IntTy) -> PrimitiveType { + match int_ty { + ty::IntTy::Isize => PrimitiveType::Isize, + ty::IntTy::I8 => PrimitiveType::I8, + ty::IntTy::I16 => PrimitiveType::I16, + ty::IntTy::I32 => PrimitiveType::I32, + ty::IntTy::I64 => PrimitiveType::I64, + ty::IntTy::I128 => PrimitiveType::I128, + } + } +} + +impl From for PrimitiveType { + fn from(uint_ty: ty::UintTy) -> PrimitiveType { + match uint_ty { + ty::UintTy::Usize => PrimitiveType::Usize, + ty::UintTy::U8 => PrimitiveType::U8, + ty::UintTy::U16 => PrimitiveType::U16, + ty::UintTy::U32 => PrimitiveType::U32, + ty::UintTy::U64 => PrimitiveType::U64, + ty::UintTy::U128 => PrimitiveType::U128, + } + } +} + +impl From for PrimitiveType { + fn from(float_ty: ty::FloatTy) -> PrimitiveType { + match float_ty { + ty::FloatTy::F32 => PrimitiveType::F32, + ty::FloatTy::F64 => PrimitiveType::F64, + } + } +} + impl From for PrimitiveType { fn from(prim_ty: hir::PrimTy) -> PrimitiveType { match prim_ty { diff --git a/src/tools/clippy/clippy_lints/src/bytecount.rs b/src/tools/clippy/clippy_lints/src/bytecount.rs index 38a0e27c4cf5b..ac9098a7584d6 100644 --- a/src/tools/clippy/clippy_lints/src/bytecount.rs +++ b/src/tools/clippy/clippy_lints/src/bytecount.rs @@ -2,11 +2,10 @@ use crate::utils::{ contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability, span_lint_and_sugg, }; use if_chain::if_chain; -use rustc_ast::ast::UintTy; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::ty::{self, UintTy}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; use rustc_span::Symbol; diff --git a/src/tools/clippy/clippy_lints/src/consts.rs b/src/tools/clippy/clippy_lints/src/consts.rs index 166eadf86c177..640cffd24a701 100644 --- a/src/tools/clippy/clippy_lints/src/consts.rs +++ b/src/tools/clippy/clippy_lints/src/consts.rs @@ -2,14 +2,14 @@ use crate::utils::{clip, sext, unsext}; use if_chain::if_chain; -use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; +use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_data_structures::sync::Lrc; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, QPath, UnOp}; use rustc_lint::LateContext; use rustc_middle::mir::interpret::Scalar; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; +use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Symbol; use std::cmp::Ordering::{self, Equal}; @@ -167,8 +167,8 @@ pub fn lit_to_constant(lit: &LitKind, ty: Option>) -> Constant { LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { - FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()), - FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()), + ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()), + ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()), }, LitKind::Float(ref is, LitFloatType::Unsuffixed) => match ty.expect("type of float is known").kind() { ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()), diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index fb80f48a9ccf3..ae56a8ba5ab4b 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -3,10 +3,9 @@ use crate::consts::{miri_to_const, Constant}; use crate::utils::span_lint; -use rustc_ast::ast::{IntTy, UintTy}; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::ty::{self, IntTy, UintTy}; use rustc_middle::ty::util::IntTypeExt; use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::convert::TryFrom; diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs index 1fe4461533b36..be646cbe4d043 100644 --- a/src/tools/clippy/clippy_lints/src/float_literal.rs +++ b/src/tools/clippy/clippy_lints/src/float_literal.rs @@ -1,10 +1,10 @@ use crate::utils::{numeric_literal, span_lint_and_sugg}; use if_chain::if_chain; -use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; +use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::ty::{self, FloatTy}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::fmt; @@ -75,8 +75,8 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { let digits = count_digits(&sym_str); let max = max_digits(fty); let type_suffix = match lit_float_ty { - LitFloatType::Suffixed(FloatTy::F32) => Some("f32"), - LitFloatType::Suffixed(FloatTy::F64) => Some("f64"), + LitFloatType::Suffixed(ast::FloatTy::F32) => Some("f32"), + LitFloatType::Suffixed(ast::FloatTy::F64) => Some("f64"), LitFloatType::Unsuffixed => None }; let (is_whole, mut float_str) = match fty { diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs index ea986874291e0..40b236493a313 100644 --- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs +++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs @@ -3,7 +3,6 @@ //! This lint is **warn** by default use crate::utils::{is_type_diagnostic_item, span_lint}; -use rustc_ast::ast; use rustc_hir::Expr; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; @@ -77,8 +76,8 @@ impl<'tcx> LateLintPass<'tcx> for Mutex { atomic_name ); match *mutex_param.kind() { - ty::Uint(t) if t != ast::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), - ty::Int(t) if t != ast::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), + ty::Uint(t) if t != ty::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), + ty::Int(t) if t != ty::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg), }; } diff --git a/src/tools/clippy/clippy_lints/src/transmute.rs b/src/tools/clippy/clippy_lints/src/transmute.rs index b0909f7317740..d977cea4da50b 100644 --- a/src/tools/clippy/clippy_lints/src/transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute.rs @@ -443,7 +443,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { ); }, ), - (ty::Int(ast::IntTy::I32) | ty::Uint(ast::UintTy::U32), &ty::Char) => { + (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => { span_lint_and_then( cx, TRANSMUTE_INT_TO_CHAR, @@ -468,7 +468,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) => { if_chain! { if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); - if let ty::Uint(ast::UintTy::U8) = slice_ty.kind(); + if let ty::Uint(ty::UintTy::U8) = slice_ty.kind(); if from_mutbl == to_mutbl; then { let postfix = if *from_mutbl == Mutability::Mut { @@ -536,7 +536,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { } }, ), - (ty::Int(ast::IntTy::I8) | ty::Uint(ast::UintTy::U8), ty::Bool) => { + (ty::Int(ty::IntTy::I8) | ty::Uint(ty::UintTy::U8), ty::Bool) => { span_lint_and_then( cx, TRANSMUTE_INT_TO_BOOL, diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs index 3b5a83d2a0bec..17cef0af3e9c9 100644 --- a/src/tools/clippy/clippy_lints/src/types.rs +++ b/src/tools/clippy/clippy_lints/src/types.rs @@ -5,7 +5,7 @@ use std::cmp::Ordering; use std::collections::BTreeMap; use if_chain::if_chain; -use rustc_ast::{FloatTy, IntTy, LitFloatType, LitIntType, LitKind, UintTy}; +use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor}; @@ -18,7 +18,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::TypeFoldable; -use rustc_middle::ty::{self, InferTy, Ty, TyCtxt, TyS, TypeAndMut, TypeckResults}; +use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TyS, TypeAndMut, TypeckResults, UintTy}; use rustc_semver::RustcVersion; use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass}; use rustc_span::hygiene::{ExpnKind, MacroKind}; @@ -1106,9 +1106,7 @@ fn is_empty_block(expr: &Expr<'_>) -> bool { expr.kind, ExprKind::Block( Block { - stmts: &[], - expr: None, - .. + stmts: &[], expr: None, .. }, _, ) diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 9b262517a9834..46b2b06d1a280 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -35,7 +35,6 @@ use std::mem; use if_chain::if_chain; use rustc_ast::ast::{self, Attribute, LitKind}; -use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir as hir; @@ -1224,27 +1223,27 @@ pub fn get_arg_name(pat: &Pat<'_>) -> Option { } } -pub fn int_bits(tcx: TyCtxt<'_>, ity: ast::IntTy) -> u64 { - Integer::from_attr(&tcx, attr::IntType::SignedInt(ity)).size().bits() +pub fn int_bits(tcx: TyCtxt<'_>, ity: ty::IntTy) -> u64 { + Integer::from_int_ty(&tcx, ity).size().bits() } #[allow(clippy::cast_possible_wrap)] /// Turn a constant int byte representation into an i128 -pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: ast::IntTy) -> i128 { +pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: ty::IntTy) -> i128 { let amt = 128 - int_bits(tcx, ity); ((u as i128) << amt) >> amt } #[allow(clippy::cast_sign_loss)] /// clip unused bytes -pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: ast::IntTy) -> u128 { +pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: ty::IntTy) -> u128 { let amt = 128 - int_bits(tcx, ity); ((u as u128) << amt) >> amt } /// clip unused bytes -pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: ast::UintTy) -> u128 { - let bits = Integer::from_attr(&tcx, attr::IntType::UnsignedInt(ity)).size().bits(); +pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: ty::UintTy) -> u128 { + let bits = Integer::from_uint_ty(&tcx, ity).size().bits(); let amt = 128 - bits; (u << amt) >> amt } From eaba3daa60d789997c0be3da11619df2469e9a7e Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 18 Jan 2021 13:36:32 -0600 Subject: [PATCH 11/31] Remove qpath_res util function --- src/tools/clippy/clippy_lints/src/default.rs | 4 ++-- .../clippy_lints/src/drop_forget_ref.rs | 4 ++-- src/tools/clippy/clippy_lints/src/exit.rs | 4 ++-- .../clippy/clippy_lints/src/functions.rs | 8 +++---- .../clippy/clippy_lints/src/let_if_seq.rs | 4 ++-- src/tools/clippy/clippy_lints/src/loops.rs | 22 +++++++++---------- .../clippy/clippy_lints/src/manual_strip.rs | 8 +++---- .../clippy/clippy_lints/src/mem_forget.rs | 4 ++-- .../clippy/clippy_lints/src/no_effect.rs | 6 ++--- .../clippy/clippy_lints/src/non_copy_const.rs | 4 ++-- .../clippy_lints/src/to_string_in_display.rs | 4 ++-- src/tools/clippy/clippy_lints/src/types.rs | 12 +++++----- .../clippy_lints/src/utils/internal_lints.rs | 6 ++--- .../clippy/clippy_lints/src/utils/mod.rs | 13 ----------- 14 files changed, 45 insertions(+), 58 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index f7224811e6e79..6fa1378b8c73d 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -1,5 +1,5 @@ use crate::utils::{ - any_parent_is_automatically_derived, contains_name, match_def_path, paths, qpath_res, snippet_with_macro_callsite, + any_parent_is_automatically_derived, contains_name, match_def_path, paths, snippet_with_macro_callsite, }; use crate::utils::{span_lint_and_note, span_lint_and_sugg}; use if_chain::if_chain; @@ -231,7 +231,7 @@ fn is_expr_default<'tcx>(expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> bool if_chain! { if let ExprKind::Call(ref fn_expr, _) = &expr.kind; if let ExprKind::Path(qpath) = &fn_expr.kind; - if let Res::Def(_, def_id) = qpath_res(cx, qpath, fn_expr.hir_id); + if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id); then { // right hand side of assignment is `Default::default` match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD) diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index cf528d189b4b1..a84f9c4628716 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -1,4 +1,4 @@ -use crate::utils::{is_copy, match_def_path, paths, qpath_res, span_lint_and_note}; +use crate::utils::{is_copy, match_def_path, paths, span_lint_and_note}; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { if let ExprKind::Call(ref path, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = path.kind; if args.len() == 1; - if let Some(def_id) = qpath_res(cx, qpath, path.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id(); then { let lint; let msg; diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index 7337d98c8be37..915859270009b 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -1,4 +1,4 @@ -use crate::utils::{is_entrypoint_fn, match_def_path, paths, qpath_res, span_lint}; +use crate::utils::{is_entrypoint_fn, match_def_path, paths, span_lint}; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; @@ -29,7 +29,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit { if_chain! { if let ExprKind::Call(ref path_expr, ref _args) = e.kind; if let ExprKind::Path(ref path) = path_expr.kind; - if let Some(def_id) = qpath_res(cx, path, path_expr.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::EXIT); then { let parent = cx.tcx.hir().get_parent_item(e.hir_id); diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs index fd93548b55c6d..8795425461033 100644 --- a/src/tools/clippy/clippy_lints/src/functions.rs +++ b/src/tools/clippy/clippy_lints/src/functions.rs @@ -1,7 +1,7 @@ use crate::utils::{ attr_by_name, attrs::is_proc_macro, is_must_use_ty, is_trait_impl_item, is_type_diagnostic_item, iter_input_pats, - last_path_segment, match_def_path, must_use_attr, qpath_res, return_ty, snippet, snippet_opt, span_lint, - span_lint_and_help, span_lint_and_then, trait_ref_of_method, type_is_unsafe_function, + last_path_segment, match_def_path, must_use_attr, return_ty, snippet, snippet_opt, span_lint, span_lint_and_help, + span_lint_and_then, trait_ref_of_method, type_is_unsafe_function, }; use if_chain::if_chain; use rustc_ast::ast::Attribute; @@ -659,7 +659,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> { impl<'a, 'tcx> DerefVisitor<'a, 'tcx> { fn check_arg(&self, ptr: &hir::Expr<'_>) { if let hir::ExprKind::Path(ref qpath) = ptr.kind { - if let Res::Local(id) = qpath_res(self.cx, qpath, ptr.hir_id) { + if let Res::Local(id) = self.cx.qpath_res(qpath, ptr.hir_id) { if self.ptrs.contains(&id) { span_lint( self.cx, @@ -722,7 +722,7 @@ fn is_mutated_static(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool { use hir::ExprKind::{Field, Index, Path}; match e.kind { - Path(ref qpath) => !matches!(qpath_res(cx, qpath, e.hir_id), Res::Local(_)), + Path(ref qpath) => !matches!(cx.qpath_res(qpath, e.hir_id), Res::Local(_)), Field(ref inner, _) | Index(ref inner, _) => is_mutated_static(cx, inner), _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs index db717cd1240a4..5886c2360e362 100644 --- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs +++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs @@ -1,4 +1,4 @@ -use crate::utils::{qpath_res, snippet, span_lint_and_then, visitors::LocalUsedVisitor}; +use crate::utils::{snippet, span_lint_and_then, visitors::LocalUsedVisitor}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; @@ -145,7 +145,7 @@ fn check_assign<'tcx>( if let hir::StmtKind::Semi(ref expr) = expr.kind; if let hir::ExprKind::Assign(ref var, ref value, _) = expr.kind; if let hir::ExprKind::Path(ref qpath) = var.kind; - if let Res::Local(local_id) = qpath_res(cx, qpath, var.hir_id); + if let Res::Local(local_id) = cx.qpath_res(qpath, var.hir_id); if decl == local_id; then { let mut v = LocalUsedVisitor::new(decl); diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs index 1c5ab2874b048..1ae2c6ca95788 100644 --- a/src/tools/clippy/clippy_lints/src/loops.rs +++ b/src/tools/clippy/clippy_lints/src/loops.rs @@ -6,9 +6,9 @@ use crate::utils::visitors::LocalUsedVisitor; use crate::utils::{ contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, - last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, qpath_res, single_segment_path, - snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, - span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq, + last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, single_segment_path, snippet, + snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, + span_lint_and_then, sugg, SpanlessEq, }; use if_chain::if_chain; use rustc_ast::ast; @@ -848,7 +848,7 @@ fn same_var<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, var: HirId) -> bool { if let ExprKind::Path(qpath) = &expr.kind; if let QPath::Resolved(None, path) = qpath; if path.segments.len() == 1; - if let Res::Local(local_id) = qpath_res(cx, qpath, expr.hir_id); + if let Res::Local(local_id) = cx.qpath_res(qpath, expr.hir_id); then { // our variable! local_id == var @@ -1420,7 +1420,7 @@ fn detect_same_item_push<'tcx>( // Make sure that the push does not involve possibly mutating values match pushed_item.kind { ExprKind::Path(ref qpath) => { - match qpath_res(cx, qpath, pushed_item.hir_id) { + match cx.qpath_res(qpath, pushed_item.hir_id) { // immutable bindings that are initialized with literal or constant Res::Local(hir_id) => { if_chain! { @@ -1437,7 +1437,7 @@ fn detect_same_item_push<'tcx>( ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), // immutable bindings that are initialized with constant ExprKind::Path(ref path) => { - if let Res::Def(DefKind::Const, ..) = qpath_res(cx, path, init.hir_id) { + if let Res::Def(DefKind::Const, ..) = cx.qpath_res(path, init.hir_id) { emit_lint(cx, vec, pushed_item); } } @@ -2028,7 +2028,7 @@ fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option if let ExprKind::Path(ref qpath) = bound.kind; if let QPath::Resolved(None, _) = *qpath; then { - let res = qpath_res(cx, qpath, bound.hir_id); + let res = cx.qpath_res(qpath, bound.hir_id); if let Res::Local(hir_id) = res { let node_str = cx.tcx.hir().get(hir_id); if_chain! { @@ -2120,7 +2120,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> { if self.prefer_mutable { self.indexed_mut.insert(seqvar.segments[0].ident.name); } - let res = qpath_res(self.cx, seqpath, seqexpr.hir_id); + let res = self.cx.qpath_res(seqpath, seqexpr.hir_id); match res { Res::Local(hir_id) => { let parent_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); @@ -2184,7 +2184,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { if let QPath::Resolved(None, ref path) = *qpath; if path.segments.len() == 1; then { - if let Res::Local(local_id) = qpath_res(self.cx, qpath, expr.hir_id) { + if let Res::Local(local_id) = self.cx.qpath_res(qpath, expr.hir_id) { if local_id == self.var { self.nonindex = true; } else { @@ -2589,7 +2589,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { fn var_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { if let ExprKind::Path(ref qpath) = expr.kind { - let path_res = qpath_res(cx, qpath, expr.hir_id); + let path_res = cx.qpath_res(qpath, expr.hir_id); if let Res::Local(hir_id) = path_res { return Some(hir_id); } @@ -2819,7 +2819,7 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> { if_chain! { if let ExprKind::Path(ref qpath) = ex.kind; if let QPath::Resolved(None, _) = *qpath; - let res = qpath_res(self.cx, qpath, ex.hir_id); + let res = self.cx.qpath_res(qpath, ex.hir_id); then { match res { Res::Local(hir_id) => { diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs index a0cfe145a301c..42a92104a4919 100644 --- a/src/tools/clippy/clippy_lints/src/manual_strip.rs +++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs @@ -1,7 +1,7 @@ use crate::consts::{constant, Constant}; use crate::utils::usage::mutated_variables; use crate::utils::{ - eq_expr_value, higher, match_def_path, meets_msrv, multispan_sugg, paths, qpath_res, snippet, span_lint_and_then, + eq_expr_value, higher, match_def_path, meets_msrv, multispan_sugg, paths, snippet, span_lint_and_then, }; use if_chain::if_chain; @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { } else { return; }; - let target_res = qpath_res(cx, &target_path, target_arg.hir_id); + let target_res = cx.qpath_res(&target_path, target_arg.hir_id); if target_res == Res::Err { return; }; @@ -221,7 +221,7 @@ fn find_stripping<'tcx>( if let ExprKind::Index(indexed, index) = &unref.kind; if let Some(higher::Range { start, end, .. }) = higher::range(index); if let ExprKind::Path(path) = &indexed.kind; - if qpath_res(self.cx, path, ex.hir_id) == self.target; + if self.cx.qpath_res(path, ex.hir_id) == self.target; then { match (self.strip_kind, start, end) { (StripKind::Prefix, Some(start), None) => { @@ -235,7 +235,7 @@ fn find_stripping<'tcx>( if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, left, right) = end.kind; if let Some(left_arg) = len_arg(self.cx, left); if let ExprKind::Path(left_path) = &left_arg.kind; - if qpath_res(self.cx, left_path, left_arg.hir_id) == self.target; + if self.cx.qpath_res(left_path, left_arg.hir_id) == self.target; if eq_pattern_length(self.cx, self.pattern, right); then { self.results.push(ex.span); diff --git a/src/tools/clippy/clippy_lints/src/mem_forget.rs b/src/tools/clippy/clippy_lints/src/mem_forget.rs index 8c6fd10f98a1e..d34f9761e26f9 100644 --- a/src/tools/clippy/clippy_lints/src/mem_forget.rs +++ b/src/tools/clippy/clippy_lints/src/mem_forget.rs @@ -1,4 +1,4 @@ -use crate::utils::{match_def_path, paths, qpath_res, span_lint}; +use crate::utils::{match_def_path, paths, span_lint}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -29,7 +29,7 @@ impl<'tcx> LateLintPass<'tcx> for MemForget { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Call(ref path_expr, ref args) = e.kind { if let ExprKind::Path(ref qpath) = path_expr.kind { - if let Some(def_id) = qpath_res(cx, qpath, path_expr.hir_id).opt_def_id() { + if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() { if match_def_path(cx, def_id, &paths::MEM_FORGET) { let forgot_ty = cx.typeck_results().expr_ty(&args[0]); diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index b1b5b3439a0e3..69302d695ce0a 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -1,4 +1,4 @@ -use crate::utils::{has_drop, qpath_res, snippet_opt, span_lint, span_lint_and_sugg}; +use crate::utils::{has_drop, snippet_opt, span_lint, span_lint_and_sugg}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource}; @@ -67,7 +67,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { }, ExprKind::Call(ref callee, ref args) => { if let ExprKind::Path(ref qpath) = callee.kind { - let res = qpath_res(cx, qpath, callee.hir_id); + let res = cx.qpath_res(qpath, callee.hir_id); match res { Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) => { !has_drop(cx, cx.typeck_results().expr_ty(expr)) @@ -146,7 +146,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option { if let ExprKind::Path(ref qpath) = callee.kind { - let res = qpath_res(cx, qpath, callee.hir_id); + let res = cx.qpath_res(qpath, callee.hir_id); match res { Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) if !has_drop(cx, cx.typeck_results().expr_ty(expr)) => diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 3a9aa6ced03ba..f57d753631755 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -18,7 +18,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{InnerSpan, Span, DUMMY_SP}; use rustc_typeck::hir_ty_to_ty; -use crate::utils::{in_constant, qpath_res, span_lint_and_then}; +use crate::utils::{in_constant, span_lint_and_then}; use if_chain::if_chain; // FIXME: this is a correctness problem but there's no suitable @@ -339,7 +339,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { } // Make sure it is a const item. - let item_def_id = match qpath_res(cx, qpath, expr.hir_id) { + let item_def_id = match cx.qpath_res(qpath, expr.hir_id) { Res::Def(DefKind::Const | DefKind::AssocConst, did) => did, _ => return, }; diff --git a/src/tools/clippy/clippy_lints/src/to_string_in_display.rs b/src/tools/clippy/clippy_lints/src/to_string_in_display.rs index c53727ba16004..fa508df865e48 100644 --- a/src/tools/clippy/clippy_lints/src/to_string_in_display.rs +++ b/src/tools/clippy/clippy_lints/src/to_string_in_display.rs @@ -1,4 +1,4 @@ -use crate::utils::{match_def_path, match_trait_method, paths, qpath_res, span_lint}; +use crate::utils::{match_def_path, match_trait_method, paths, span_lint}; use if_chain::if_chain; use rustc_hir::def::Res; use rustc_hir::{Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind}; @@ -94,7 +94,7 @@ impl LateLintPass<'_> for ToStringInDisplay { if match_trait_method(cx, expr, &paths::TO_STRING); if self.in_display_impl; if let ExprKind::Path(ref qpath) = args[0].kind; - if let Res::Local(hir_id) = qpath_res(cx, qpath, args[0].hir_id); + if let Res::Local(hir_id) = cx.qpath_res(qpath, args[0].hir_id); if let Some(self_hir_id) = self.self_hir_id; if hir_id == self_hir_id; then { diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs index 3b5a83d2a0bec..624ea16f585d2 100644 --- a/src/tools/clippy/clippy_lints/src/types.rs +++ b/src/tools/clippy/clippy_lints/src/types.rs @@ -34,7 +34,7 @@ use crate::utils::sugg::Sugg; use crate::utils::{ clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant, is_type_diagnostic_item, last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, - multispan_sugg, numeric_literal::NumericLiteral, qpath_res, reindent_multiline, sext, snippet, snippet_opt, + multispan_sugg, numeric_literal::NumericLiteral, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext, }; @@ -298,7 +298,7 @@ fn match_type_parameter(cx: &LateContext<'_>, qpath: &QPath<'_>, path: &[&str]) _ => None, }); if let TyKind::Path(ref qpath) = ty.kind; - if let Some(did) = qpath_res(cx, qpath, ty.hir_id).opt_def_id(); + if let Some(did) = cx.qpath_res(qpath, ty.hir_id).opt_def_id(); if match_def_path(cx, did, path); then { return Some(ty.span); @@ -365,7 +365,7 @@ impl Types { match hir_ty.kind { TyKind::Path(ref qpath) if !is_local => { let hir_id = hir_ty.hir_id; - let res = qpath_res(cx, qpath, hir_id); + let res = cx.qpath_res(qpath, hir_id); if let Some(def_id) = res.opt_def_id() { if Some(def_id) == cx.tcx.lang_items().owned_box() { if let Some(span) = match_borrows_parameter(cx, qpath) { @@ -535,7 +535,7 @@ impl Types { }); // ty is now _ at this point if let TyKind::Path(ref ty_qpath) = ty.kind; - let res = qpath_res(cx, ty_qpath, ty.hir_id); + let res = cx.qpath_res(ty_qpath, ty.hir_id); if let Some(def_id) = res.opt_def_id(); if Some(def_id) == cx.tcx.lang_items().owned_box(); // At this point, we know ty is Box, now get T @@ -652,7 +652,7 @@ impl Types { match mut_ty.ty.kind { TyKind::Path(ref qpath) => { let hir_id = mut_ty.ty.hir_id; - let def = qpath_res(cx, qpath, hir_id); + let def = cx.qpath_res(qpath, hir_id); if_chain! { if let Some(def_id) = def.opt_def_id(); if Some(def_id) == cx.tcx.lang_items().owned_box(); @@ -739,7 +739,7 @@ fn is_any_trait(t: &hir::Ty<'_>) -> bool { fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: HirId) -> Option> { if_chain! { - if let Some(did) = qpath_res(cx, qpath, id).opt_def_id(); + if let Some(did) = cx.qpath_res(qpath, id).opt_def_id(); if let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did); if let GenericParamKind::Type { synthetic, .. } = generic_param.kind; if synthetic == Some(SyntheticTyParamKind::ImplTrait); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs index 7aa17520ba79f..822863ca3e279 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs @@ -1,7 +1,7 @@ use crate::consts::{constant_simple, Constant}; use crate::utils::{ - is_expn_of, match_def_path, match_qpath, match_type, method_calls, path_to_res, paths, qpath_res, run_lints, - snippet, span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq, + is_expn_of, match_def_path, match_qpath, match_type, method_calls, path_to_res, paths, run_lints, snippet, + span_lint, span_lint_and_help, span_lint_and_sugg, SpanlessEq, }; use if_chain::if_chain; use rustc_ast::ast::{Crate as AstCrate, ItemKind, LitKind, NodeId}; @@ -787,7 +787,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option return path_to_matched_type(cx, expr), - ExprKind::Path(qpath) => match qpath_res(cx, qpath, expr.hir_id) { + ExprKind::Path(qpath) => match cx.qpath_res(qpath, expr.hir_id) { Res::Local(hir_id) => { let parent_id = cx.tcx.hir().get_parent_node(hir_id); if let Some(Node::Local(local)) = cx.tcx.hir().find(parent_id) { diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 9b262517a9834..023fb0a7112c1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -370,19 +370,6 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option { } } -pub fn qpath_res(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { - match qpath { - hir::QPath::Resolved(_, path) => path.res, - hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => { - if cx.tcx.has_typeck_results(id.owner.to_def_id()) { - cx.tcx.typeck(id.owner).qpath_res(qpath, id) - } else { - Res::Err - } - }, - } -} - /// Convenience function to get the `DefId` of a trait by path. /// It could be a trait or trait alias. pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option { From e25959b417fe2a08d808f9ddc737c2c9742d6d6a Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 22 Jan 2021 18:07:00 +0100 Subject: [PATCH 12/31] Make more traits of the From/Into family diagnostic items Following traits are now diagnostic items: - `From` (unchanged) - `Into` - `TryFrom` - `TryInto` This also adds symbols for those items: - `into_trait` - `try_from_trait` - `try_into_trait` --- compiler/rustc_span/src/symbol.rs | 3 +++ library/core/src/convert/mod.rs | 3 +++ src/tools/clippy/clippy_lints/src/fallible_impl_from.rs | 7 ++----- src/tools/clippy/clippy_lints/src/utils/paths.rs | 1 - 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7b90e5b611cd1..2e7c9701c0c67 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -622,6 +622,7 @@ symbols! { intel, into_iter, into_result, + into_trait, intra_doc_pointers, intrinsics, irrefutable_let_patterns, @@ -1159,6 +1160,8 @@ symbols! { truncf32, truncf64, try_blocks, + try_from_trait, + try_into_trait, try_trait, tt, tuple, diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 139863bbe7f81..a6d3b5ef813f1 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -267,6 +267,7 @@ pub trait AsMut { /// /// [`String`]: ../../std/string/struct.String.html /// [`Vec`]: ../../std/vec/struct.Vec.html +#[rustc_diagnostic_item = "into_trait"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { /// Performs the conversion. @@ -382,6 +383,7 @@ pub trait From: Sized { /// /// This suffers the same restrictions and reasoning as implementing /// [`Into`], see there for details. +#[rustc_diagnostic_item = "try_into_trait"] #[stable(feature = "try_from", since = "1.34.0")] pub trait TryInto: Sized { /// The type returned in the event of a conversion error. @@ -462,6 +464,7 @@ pub trait TryInto: Sized { /// /// [`try_from`]: TryFrom::try_from /// [`!`]: ../../std/primitive.never.html +#[rustc_diagnostic_item = "try_from_trait"] #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 9f389c8d2f9e7..527905e375d28 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -1,7 +1,4 @@ -use crate::utils::paths::FROM_TRAIT; -use crate::utils::{ - is_expn_of, is_type_diagnostic_item, match_def_path, match_panic_def_id, method_chain_args, span_lint_and_then, -}; +use crate::utils::{is_expn_of, is_type_diagnostic_item, match_panic_def_id, method_chain_args, span_lint_and_then}; use if_chain::if_chain; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -59,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom { if_chain! { if let hir::ItemKind::Impl(impl_) = &item.kind; if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id); - if match_def_path(cx, impl_trait_ref.def_id, &FROM_TRAIT); + if cx.tcx.is_diagnostic_item(sym::from_trait, impl_trait_ref.def_id); then { lint_impl_body(cx, item.span, impl_.items); } diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs index c0b203b5388dc..432cc5b59f684 100644 --- a/src/tools/clippy/clippy_lints/src/utils/paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs @@ -48,7 +48,6 @@ pub const FN_MUT: [&str; 3] = ["core", "ops", "FnMut"]; pub const FN_ONCE: [&str; 3] = ["core", "ops", "FnOnce"]; pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"]; pub const FROM_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "FromIterator"]; -pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"]; pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"]; pub const HASH: [&str; 3] = ["core", "hash", "Hash"]; pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"]; From 435b90970f0028975440c1e32a6a9b99fd8b6ea4 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 22 Jan 2021 16:09:24 -0500 Subject: [PATCH 13/31] Split JSON into separately versioned crate --- Cargo.toml | 1 + src/librustdoc/Cargo.toml | 1 + src/librustdoc/json-types/Cargo.toml | 11 +++ .../{json/types.rs => json-types/lib.rs} | 10 +-- src/librustdoc/json/conversions.rs | 83 +++++++++---------- src/librustdoc/json/mod.rs | 25 ++++-- 6 files changed, 72 insertions(+), 59 deletions(-) create mode 100644 src/librustdoc/json-types/Cargo.toml rename src/librustdoc/{json/types.rs => json-types/lib.rs} (98%) diff --git a/Cargo.toml b/Cargo.toml index 5bd1147cad554..5b58ed8f6a050 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "compiler/rustc", "library/std", "library/test", + "src/librustdoc/json-types", "src/tools/cargotest", "src/tools/clippy", "src/tools/compiletest", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index b0f5bac6abd0f..bc6eba74d2d48 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -17,6 +17,7 @@ smallvec = "1.0" tempfile = "3" itertools = "0.9" regex = "1" +json-types = { path = "./json-types" } [dev-dependencies] expect-test = "1.0" diff --git a/src/librustdoc/json-types/Cargo.toml b/src/librustdoc/json-types/Cargo.toml new file mode 100644 index 0000000000000..b9c97c31c1877 --- /dev/null +++ b/src/librustdoc/json-types/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "json-types" +version = "0.1.0" +authors = ["The Rust Project Developers"] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +serde = { version = "1.0", features = ["derive"] } diff --git a/src/librustdoc/json/types.rs b/src/librustdoc/json-types/lib.rs similarity index 98% rename from src/librustdoc/json/types.rs rename to src/librustdoc/json-types/lib.rs index 66cf12954dd0b..3fb2a32d5a0a3 100644 --- a/src/librustdoc/json/types.rs +++ b/src/librustdoc/json-types/lib.rs @@ -3,9 +3,9 @@ //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] //! struct is the root of the JSON blob and all other items are contained within. +use std::collections::HashMap; use std::path::PathBuf; -use rustc_data_structures::fx::FxHashMap; use serde::{Deserialize, Serialize}; /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information @@ -21,11 +21,11 @@ pub struct Crate { pub includes_private: bool, /// A collection of all items in the local crate as well as some external traits and their /// items that are referenced locally. - pub index: FxHashMap, + pub index: HashMap, /// Maps IDs to fully qualified paths and other info helpful for generating links. - pub paths: FxHashMap, + pub paths: HashMap, /// Maps `crate_id` of items to a crate name and html_root_url if it exists. - pub external_crates: FxHashMap, + pub external_crates: HashMap, /// A single version number to be used in the future when making backwards incompatible changes /// to the JSON output. pub format_version: u32, @@ -72,7 +72,7 @@ pub struct Item { /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`). pub docs: Option, /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs - pub links: FxHashMap, + pub links: HashMap, /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`) pub attrs: Vec, pub deprecation: Option, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bfd2141d9a174..9b0603c4d55ba 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -9,9 +9,10 @@ use rustc_hir::def::CtorKind; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_span::Pos; +use json_types::*; + use crate::clean; use crate::formats::item_type::ItemType; -use crate::json::types::*; use crate::json::JsonRenderer; impl JsonRenderer<'_> { @@ -22,7 +23,7 @@ impl JsonRenderer<'_> { match *kind { clean::StrippedItem(_) => None, kind => Some(Item { - id: def_id.into(), + id: from_def_id(def_id), crate_id: def_id.krate.as_u32(), name: name.map(|sym| sym.to_string()), source: self.convert_span(source), @@ -32,7 +33,7 @@ impl JsonRenderer<'_> { .links .into_iter() .filter_map(|clean::ItemLink { link, did, .. }| { - did.map(|did| (link, did.into())) + did.map(|did| (link, from_def_id(did))) }) .collect(), attrs: attrs @@ -40,7 +41,7 @@ impl JsonRenderer<'_> { .iter() .map(rustc_ast_pretty::pprust::attribute_to_string) .collect(), - deprecation: deprecation.map(Into::into), + deprecation: deprecation.map(from_deprecation), kind: item_type.into(), inner: kind.into(), }), @@ -74,19 +75,17 @@ impl JsonRenderer<'_> { Inherited => Visibility::Default, Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate, Restricted(did) => Visibility::Restricted { - parent: did.into(), + parent: from_def_id(did), path: self.tcx.def_path(did).to_string_no_crate_verbose(), }, } } } -impl From for Deprecation { - fn from(deprecation: rustc_attr::Deprecation) -> Self { - #[rustfmt::skip] - let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation; - Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } - } +crate fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation { + #[rustfmt::skip] + let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation; + Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } } impl From for GenericArgs { @@ -141,10 +140,8 @@ impl From for TypeBindingKind { } } -impl From for Id { - fn from(did: DefId) -> Self { - Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))) - } +crate fn from_def_id(did: DefId) -> Id { + Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))) } impl From for ItemEnum { @@ -199,7 +196,7 @@ impl From for Struct { fn from(struct_: clean::Struct) -> Self { let clean::Struct { struct_type, generics, fields, fields_stripped } = struct_; Struct { - struct_type: struct_type.into(), + struct_type: from_ctor_kind(struct_type), generics: generics.into(), fields_stripped, fields: ids(fields), @@ -221,13 +218,11 @@ impl From for Struct { } } -impl From for StructType { - fn from(struct_type: CtorKind) -> Self { - match struct_type { - CtorKind::Fictive => StructType::Plain, - CtorKind::Fn => StructType::Tuple, - CtorKind::Const => StructType::Unit, - } +crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { + match struct_type { + CtorKind::Fictive => StructType::Plain, + CtorKind::Fn => StructType::Tuple, + CtorKind::Const => StructType::Unit, } } @@ -310,7 +305,7 @@ impl From for GenericBound { GenericBound::TraitBound { trait_: trait_.into(), generic_params: generic_params.into_iter().map(Into::into).collect(), - modifier: modifier.into(), + modifier: from_trait_bound_modifier(modifier), } } Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()), @@ -318,14 +313,12 @@ impl From for GenericBound { } } -impl From for TraitBoundModifier { - fn from(modifier: rustc_hir::TraitBoundModifier) -> Self { - use rustc_hir::TraitBoundModifier::*; - match modifier { - None => TraitBoundModifier::None, - Maybe => TraitBoundModifier::Maybe, - MaybeConst => TraitBoundModifier::MaybeConst, - } +crate fn from_trait_bound_modifier(modifier: rustc_hir::TraitBoundModifier) -> TraitBoundModifier { + use rustc_hir::TraitBoundModifier::*; + match modifier { + None => TraitBoundModifier::None, + Maybe => TraitBoundModifier::Maybe, + MaybeConst => TraitBoundModifier::MaybeConst, } } @@ -335,7 +328,7 @@ impl From for Type { match ty { ResolvedPath { path, param_names, did, is_generic: _ } => Type::ResolvedPath { name: path.whole_name(), - id: did.into(), + id: from_def_id(did), args: path.segments.last().map(|args| Box::new(args.clone().args.into())), param_names: param_names .map(|v| v.into_iter().map(Into::into).collect()) @@ -470,7 +463,7 @@ impl From for Struct { fn from(struct_: clean::VariantStruct) -> Self { let clean::VariantStruct { struct_type, fields, fields_stripped } = struct_; Struct { - struct_type: struct_type.into(), + struct_type: from_ctor_kind(struct_type), generics: Default::default(), fields_stripped, fields: ids(fields), @@ -497,13 +490,13 @@ impl From for Import { Simple(s) => Import { span: import.source.path.whole_name(), name: s.to_string(), - id: import.source.did.map(Into::into), + id: import.source.did.map(from_def_id), glob: false, }, Glob => Import { span: import.source.path.whole_name(), name: import.source.path.last_name().to_string(), - id: import.source.did.map(Into::into), + id: import.source.did.map(from_def_id), glob: true, }, } @@ -513,20 +506,18 @@ impl From for Import { impl From for ProcMacro { fn from(mac: clean::ProcMacro) -> Self { ProcMacro { - kind: mac.kind.into(), + kind: from_macro_kind(mac.kind), helpers: mac.helpers.iter().map(|x| x.to_string()).collect(), } } } -impl From for MacroKind { - fn from(kind: rustc_span::hygiene::MacroKind) -> Self { - use rustc_span::hygiene::MacroKind::*; - match kind { - Bang => MacroKind::Bang, - Attr => MacroKind::Attr, - Derive => MacroKind::Derive, - } +crate fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind { + use rustc_span::hygiene::MacroKind::*; + match kind { + Bang => MacroKind::Bang, + Attr => MacroKind::Attr, + Derive => MacroKind::Derive, } } @@ -599,5 +590,5 @@ impl From for ItemKind { } fn ids(items: impl IntoIterator) -> Vec { - items.into_iter().filter(|x| !x.is_stripped()).map(|i| i.def_id.into()).collect() + items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_def_id(i.def_id)).collect() } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index dc50c8a76b24f..8acfa3cc08a5b 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -5,7 +5,6 @@ //! docs for usage and details. mod conversions; -pub mod types; use std::cell::RefCell; use std::fs::File; @@ -17,12 +16,15 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; +use json_types as types; + use crate::clean; use crate::config::{RenderInfo, RenderOptions}; use crate::error::Error; use crate::formats::cache::Cache; use crate::formats::FormatRenderer; use crate::html::render::cache::ExternalLocation; +use crate::json::conversions::from_def_id; #[derive(Clone)] crate struct JsonRenderer<'tcx> { @@ -53,7 +55,7 @@ impl JsonRenderer<'_> { .map(|i| { let item = &i.impl_item; self.item(item.clone(), cache).unwrap(); - item.def_id.into() + from_def_id(item.def_id) }) .collect() }) @@ -71,7 +73,7 @@ impl JsonRenderer<'_> { let item = &i.impl_item; if item.def_id.is_local() { self.item(item.clone(), cache).unwrap(); - Some(item.def_id.into()) + Some(from_def_id(item.def_id)) } else { None } @@ -90,9 +92,9 @@ impl JsonRenderer<'_> { if !id.is_local() { trait_item.items.clone().into_iter().for_each(|i| self.item(i, cache).unwrap()); Some(( - id.into(), + from_def_id(id), types::Item { - id: id.into(), + id: from_def_id(id), crate_id: id.krate.as_u32(), name: cache .paths @@ -160,7 +162,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { } else if let types::ItemEnum::EnumItem(ref mut e) = new_item.inner { e.impls = self.get_impls(id, cache) } - let removed = self.index.borrow_mut().insert(id.into(), new_item.clone()); + let removed = self.index.borrow_mut().insert(from_def_id(id), new_item.clone()); // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check // to make sure the items are unique. if let Some(old_item) = removed { @@ -208,11 +210,18 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { debug!("Done with crate"); let mut index = (*self.index).clone().into_inner(); index.extend(self.get_trait_items(cache)); + let len = index.len(); let output = types::Crate { root: types::Id(String::from("0:0")), crate_version: krate.version.clone(), includes_private: cache.document_private, - index, + index: index.into_iter().fold( + std::collections::HashMap::with_capacity(len), + |mut acc, (key, val)| { + acc.insert(key, val); + acc + }, + ), paths: cache .paths .clone() @@ -220,7 +229,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { .chain(cache.external_paths.clone().into_iter()) .map(|(k, (path, kind))| { ( - k.into(), + from_def_id(k), types::ItemSummary { crate_id: k.krate.as_u32(), path, kind: kind.into() }, ) }) From bb65513a71e7e052e87b7b91f816d585e0ad8d37 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 22 Jan 2021 16:30:44 -0500 Subject: [PATCH 14/31] Update cargo.lock --- Cargo.lock | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b2ae22b6abd9b..086dd6b4efe5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1636,6 +1636,13 @@ version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92c245af8786f6ac35f95ca14feca9119e71339aaab41e878e7cdd655c97e9e5" +[[package]] +name = "json-types" +version = "0.1.0" +dependencies = [ + "serde", +] + [[package]] name = "jsondocck" version = "0.1.0" @@ -4387,6 +4394,7 @@ version = "0.0.0" dependencies = [ "expect-test", "itertools 0.9.0", + "json-types", "minifier", "pulldown-cmark 0.8.0", "regex", From d6909e11cd0f5e054004a60b22efaad5f43ec929 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 22 Jan 2021 16:46:19 -0500 Subject: [PATCH 15/31] Allow rustc::default_hash_types in the offending statement --- src/librustdoc/json/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 8acfa3cc08a5b..c9d552fe47da6 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -211,6 +211,9 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { let mut index = (*self.index).clone().into_inner(); index.extend(self.get_trait_items(cache)); let len = index.len(); + // This needs to be the default HashMap for compatibility with the public interface for + // rustdoc-json + #[allow(rustc::default_hash_types)] let output = types::Crate { root: types::Id(String::from("0:0")), crate_version: krate.version.clone(), From 1a78a8903868adac497345da50619fabc8a17f0f Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 22 Jan 2021 17:42:15 -0500 Subject: [PATCH 16/31] Move into src/etc --- Cargo.toml | 2 +- src/{librustdoc => etc}/json-types/Cargo.toml | 0 src/{librustdoc => etc}/json-types/lib.rs | 0 src/librustdoc/Cargo.toml | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename src/{librustdoc => etc}/json-types/Cargo.toml (100%) rename src/{librustdoc => etc}/json-types/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 5b58ed8f6a050..34d3718f57db0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = [ "compiler/rustc", "library/std", "library/test", - "src/librustdoc/json-types", + "src/etc/json-types", "src/tools/cargotest", "src/tools/clippy", "src/tools/compiletest", diff --git a/src/librustdoc/json-types/Cargo.toml b/src/etc/json-types/Cargo.toml similarity index 100% rename from src/librustdoc/json-types/Cargo.toml rename to src/etc/json-types/Cargo.toml diff --git a/src/librustdoc/json-types/lib.rs b/src/etc/json-types/lib.rs similarity index 100% rename from src/librustdoc/json-types/lib.rs rename to src/etc/json-types/lib.rs diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index bc6eba74d2d48..560bca8e3d116 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -17,7 +17,7 @@ smallvec = "1.0" tempfile = "3" itertools = "0.9" regex = "1" -json-types = { path = "./json-types" } +json-types = { path = "../etc/json-types" } [dev-dependencies] expect-test = "1.0" From c28427ae8aa21bc329db82a62d0f449a116f01d7 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 22 Jan 2021 18:30:01 -0500 Subject: [PATCH 17/31] Simplify conversion --- src/librustdoc/json/mod.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index c9d552fe47da6..dd9aced3121f3 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -210,21 +210,11 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { debug!("Done with crate"); let mut index = (*self.index).clone().into_inner(); index.extend(self.get_trait_items(cache)); - let len = index.len(); - // This needs to be the default HashMap for compatibility with the public interface for - // rustdoc-json - #[allow(rustc::default_hash_types)] let output = types::Crate { root: types::Id(String::from("0:0")), crate_version: krate.version.clone(), includes_private: cache.document_private, - index: index.into_iter().fold( - std::collections::HashMap::with_capacity(len), - |mut acc, (key, val)| { - acc.insert(key, val); - acc - }, - ), + index: index.into_iter().collect(), paths: cache .paths .clone() From 3b8f1b7883d300bb1a435b994c90433774105cc9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 22 Jan 2021 14:33:21 -0500 Subject: [PATCH 18/31] Make `-Z time-passes` less noisy - Add the module name to `pre_AST_expansion_passes` and don't make it a verbose event (since it normally doesn't take very long, and it's emitted many times) - Don't make the following rustdoc events verbose; they're emitted many times. + build_extern_trait_impl + build_local_trait_impl + build_primitive_trait_impl + get_auto_trait_impls + get_blanket_trait_impls - Remove `get_auto_trait_and_blanket_synthetic_impls`; it's wholly covered by get_{auto,blanket}_trait_impls and not very useful. --- compiler/rustc_expand/src/base.rs | 6 ++++-- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_interface/src/passes.rs | 17 ++++++++++++----- src/librustdoc/clean/utils.rs | 16 ++++++++++------ src/librustdoc/passes/collect_trait_impls.rs | 18 ++++++++---------- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 2f43940a9dcbb..08543d1622a7d 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -929,7 +929,9 @@ pub struct ExtCtxt<'a> { pub force_mode: bool, pub expansions: FxHashMap>, /// Called directly after having parsed an external `mod foo;` in expansion. - pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>, + /// + /// `Ident` is the module name. + pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate, Ident)>, } impl<'a> ExtCtxt<'a> { @@ -937,7 +939,7 @@ impl<'a> ExtCtxt<'a> { sess: &'a Session, ecfg: expand::ExpansionConfig<'a>, resolver: &'a mut dyn ResolverExpand, - extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>, + extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate, Ident)>, ) -> ExtCtxt<'a> { ExtCtxt { sess, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 16913dbb1abf8..edfe2edd3e3b7 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1407,7 +1407,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { proc_macros: vec![], }; if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded { - extern_mod_loaded(&krate); + extern_mod_loaded(&krate, ident); } *old_mod = krate.module; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ead2512d3b2a5..6eba378b689a9 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -33,7 +33,7 @@ use rustc_session::lint; use rustc_session::output::{filename_for_input, filename_for_metadata}; use rustc_session::search_paths::PathKind; use rustc_session::Session; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{FileName, RealFileName}; use rustc_trait_selection::traits; use rustc_typeck as typeck; @@ -211,8 +211,13 @@ pub fn register_plugins<'a>( Ok((krate, lint_store)) } -fn pre_expansion_lint(sess: &Session, lint_store: &LintStore, krate: &ast::Crate) { - sess.time("pre_AST_expansion_lint_checks", || { +fn pre_expansion_lint( + sess: &Session, + lint_store: &LintStore, + krate: &ast::Crate, + crate_name: &str, +) { + sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", crate_name).run(|| { rustc_lint::check_ast_crate( sess, lint_store, @@ -233,7 +238,7 @@ fn configure_and_expand_inner<'a>( metadata_loader: &'a MetadataLoaderDyn, ) -> Result<(ast::Crate, Resolver<'a>)> { tracing::trace!("configure_and_expand_inner"); - pre_expansion_lint(sess, lint_store, &krate); + pre_expansion_lint(sess, lint_store, &krate, crate_name); let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas); rustc_builtin_macros::register_builtin_macros(&mut resolver); @@ -295,7 +300,9 @@ fn configure_and_expand_inner<'a>( ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string()) }; - let extern_mod_loaded = |k: &ast::Crate| pre_expansion_lint(sess, lint_store, k); + let extern_mod_loaded = |k: &ast::Crate, ident: Ident| { + pre_expansion_lint(sess, lint_store, k, &*ident.name.as_str()) + }; let mut ecx = ExtCtxt::new(&sess, cfg, &mut resolver, Some(&extern_mod_loaded)); // Expand macros now! diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 0f5495c831058..60bd3c984b728 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -487,12 +487,16 @@ crate fn get_auto_trait_and_blanket_impls( ty: Ty<'tcx>, param_env_def_id: DefId, ) -> impl Iterator { - let auto_impls = cx.sess().time("get_auto_trait_impls", || { - AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id) - }); - let blanket_impls = cx.sess().time("get_blanket_impls", || { - BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id) - }); + let auto_impls = cx + .sess() + .prof + .generic_activity("get_auto_trait_impls") + .run(|| AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id)); + let blanket_impls = cx + .sess() + .prof + .generic_activity("get_blanket_impls") + .run(|| BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id)); auto_impls.into_iter().chain(blanket_impls) } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 7b5e9e5905f33..6ec6620681bf5 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -30,7 +30,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { for &cnum in cx.tcx.crates().iter() { for &(did, _) in cx.tcx.all_trait_implementations(cnum).iter() { - cx.tcx.sess.time("build_extern_trait_impl", || { + cx.tcx.sess.prof.generic_activity("build_extern_trait_impl").run(|| { inline::build_impl(cx, None, did, None, &mut new_items); }); } @@ -39,7 +39,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { // Also try to inline primitive impls from other crates. for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() { if !def_id.is_local() { - cx.sess().time("build_primitive_trait_impl", || { + cx.tcx.sess.prof.generic_activity("build_primitive_trait_impls").run(|| { inline::build_impl(cx, None, def_id, None, &mut new_items); // FIXME(eddyb) is this `doc(hidden)` check needed? @@ -59,7 +59,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { for &trait_did in cx.tcx.all_traits(LOCAL_CRATE).iter() { for &impl_node in cx.tcx.hir().trait_impls(trait_did) { let impl_did = cx.tcx.hir().local_def_id(impl_node); - cx.tcx.sess.time("build_local_trait_impl", || { + cx.tcx.sess.prof.generic_activity("build_local_trait_impl").run(|| { let mut extra_attrs = Vec::new(); let mut parent = cx.tcx.parent(impl_did.to_def_id()); while let Some(did) = parent { @@ -177,13 +177,11 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> { if i.is_struct() || i.is_enum() || i.is_union() { // FIXME(eddyb) is this `doc(hidden)` check needed? if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) { - self.cx.sess().time("get_auto_trait_and_blanket_synthetic_impls", || { - self.impls.extend(get_auto_trait_and_blanket_impls( - self.cx, - self.cx.tcx.type_of(i.def_id), - i.def_id, - )); - }); + self.impls.extend(get_auto_trait_and_blanket_impls( + self.cx, + self.cx.tcx.type_of(i.def_id), + i.def_id, + )); } } From f241c102230fb1a01fff4712228426ef67171115 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 23 Jan 2021 20:52:59 +0100 Subject: [PATCH 19/31] Improve flatten-fuse tests --- library/core/tests/iter/adapters/flatten.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs index bd2c6fd9252df..4bbae6947bf66 100644 --- a/library/core/tests/iter/adapters/flatten.rs +++ b/library/core/tests/iter/adapters/flatten.rs @@ -64,6 +64,14 @@ fn test_flatten_non_fused_outer() { assert_eq!(iter.next_back(), Some(1)); assert_eq!(iter.next(), Some(0)); assert_eq!(iter.next(), None); + assert_eq!(iter.next(), None); + + let mut iter = NonFused::new(once(0..2)).flatten(); + + assert_eq!(iter.next(), Some(0)); + assert_eq!(iter.next_back(), Some(1)); + assert_eq!(iter.next_back(), None); + assert_eq!(iter.next_back(), None); } #[test] @@ -74,6 +82,15 @@ fn test_flatten_non_fused_inner() { assert_eq!(iter.next(), Some(0)); assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next(), None); + assert_eq!(iter.next(), None); + + let mut iter = once(0..1).chain(once(1..3)).flat_map(NonFused::new); + + assert_eq!(iter.next(), Some(0)); + assert_eq!(iter.next_back(), Some(2)); + assert_eq!(iter.next_back(), Some(1)); + assert_eq!(iter.next_back(), None); + assert_eq!(iter.next_back(), None); } #[test] From 5aa625b903a24a270b2676b2b8c2f99902942b31 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 23 Jan 2021 21:00:00 +0100 Subject: [PATCH 20/31] Manually fuse the inner iterator in FlattenCompat --- library/core/src/iter/adapters/flatten.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 29e191db0f62f..081f282edcf89 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -265,7 +265,13 @@ where } } match self.iter.next() { - None => return self.backiter.as_mut()?.next(), + None => match self.backiter.as_mut()?.next() { + None => { + self.backiter = None; + return None; + } + elt @ Some(_) => return elt, + }, Some(inner) => self.frontiter = Some(inner.into_iter()), } } @@ -353,7 +359,13 @@ where } } match self.iter.next_back() { - None => return self.frontiter.as_mut()?.next_back(), + None => match self.frontiter.as_mut()?.next_back() { + None => { + self.frontiter = None; + return None; + } + elt @ Some(_) => return elt, + }, next => self.backiter = next.map(IntoIterator::into_iter), } } From 8a18fb0f7396ceb1ca18cd82ca3deb795f5e60b2 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Sat, 19 Dec 2020 21:41:20 +0100 Subject: [PATCH 21/31] Stabilize `Seek::stream_position` & change feature of `Seek::stream_len` --- library/std/src/io/buffered/bufreader.rs | 1 - library/std/src/io/mod.rs | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 8bae3da1273eb..987371f50ec22 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -410,7 +410,6 @@ impl Seek for BufReader { /// # Example /// /// ```no_run - /// #![feature(seek_convenience)] /// use std::{ /// io::{self, BufRead, BufReader, Seek}, /// fs::File, diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index c87a56586c65e..db3b0e2628f2a 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1671,7 +1671,7 @@ pub trait Seek { /// # Example /// /// ```no_run - /// #![feature(seek_convenience)] + /// #![feature(seek_stream_len)] /// use std::{ /// io::{self, Seek}, /// fs::File, @@ -1685,7 +1685,7 @@ pub trait Seek { /// Ok(()) /// } /// ``` - #[unstable(feature = "seek_convenience", issue = "59359")] + #[unstable(feature = "seek_stream_len", issue = "59359")] fn stream_len(&mut self) -> Result { let old_pos = self.stream_position()?; let len = self.seek(SeekFrom::End(0))?; @@ -1706,7 +1706,6 @@ pub trait Seek { /// # Example /// /// ```no_run - /// #![feature(seek_convenience)] /// use std::{ /// io::{self, BufRead, BufReader, Seek}, /// fs::File, @@ -1723,7 +1722,7 @@ pub trait Seek { /// Ok(()) /// } /// ``` - #[unstable(feature = "seek_convenience", issue = "59359")] + #[stable(feature = "seek_convenience", since = "1.51.0")] fn stream_position(&mut self) -> Result { self.seek(SeekFrom::Current(0)) } From 48f9dbfd59356f865f81ce674eefdbab2d7c3cbb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 24 Jan 2021 12:50:30 +0100 Subject: [PATCH 22/31] clean up some const error reporting around promoteds --- .../rustc_codegen_cranelift/src/constant.rs | 8 +- .../rustc_codegen_ssa/src/mir/constant.rs | 7 +- .../rustc_mir/src/const_eval/eval_queries.rs | 102 +++++------------- .../defaults-not-assumed-fail.rs | 2 +- .../defaults-not-assumed-fail.stderr | 10 +- .../conditional_array_execution.stderr | 2 +- .../const-eval/const-eval-query-stack.rs | 2 +- .../const-eval/const-eval-query-stack.stderr | 8 +- .../consts/const-eval/const_fn_ptr_fail2.rs | 4 +- .../const-eval/const_fn_ptr_fail2.stderr | 20 ++-- src/test/ui/consts/const-eval/issue-43197.rs | 4 +- .../ui/consts/const-eval/issue-43197.stderr | 4 +- src/test/ui/consts/const-eval/issue-44578.rs | 2 +- .../ui/consts/const-eval/issue-44578.stderr | 2 +- .../ui/consts/const-eval/issue-50814-2.stderr | 8 +- .../ui/consts/const-eval/issue-50814.stderr | 8 +- .../consts/const_unsafe_unreachable_ub.stderr | 10 +- src/test/ui/consts/issue-55878.stderr | 7 +- 18 files changed, 66 insertions(+), 144 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index beff84fb2e217..5702832bcb67d 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -134,11 +134,9 @@ pub(crate) fn codegen_constant<'tcx>( { Ok(const_val) => const_val, Err(_) => { - if promoted.is_none() { - fx.tcx - .sess - .span_err(constant.span, "erroneous constant encountered"); - } + fx.tcx + .sess + .span_err(constant.span, "erroneous constant encountered"); return crate::trap::trap_unreachable_ret_value( fx, fx.layout_of(const_.ty), diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 3a85c268e0ea9..b79a221a0e74a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -30,12 +30,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None) .map_err(|err| { - if promoted.is_none() { - self.cx - .tcx() - .sess - .span_err(constant.span, "erroneous constant encountered"); - } + self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); err }), ty::ConstKind::Value(value) => Ok(value), diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index df163f6562842..252f5e7ef2ff2 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -298,6 +298,8 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx.def_span(def.did), key.param_env, CompileTimeInterpreter::new(tcx.sess.const_eval_limit()), + // Statics (and promoteds inside statics) may access other statics, because unlike consts + // they do not have to behave "as if" they were evaluated at runtime. MemoryExtra { can_access_statics: is_static }, ); @@ -305,83 +307,35 @@ pub fn eval_to_allocation_raw_provider<'tcx>( match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) { Err(error) => { let err = ConstEvalErr::new(&ecx, error, None); - // errors in statics are always emitted as fatal errors - if is_static { - // Ensure that if the above error was either `TooGeneric` or `Reported` - // an error must be reported. - let v = err.report_as_error( - ecx.tcx.at(ecx.cur_span()), - "could not evaluate static initializer", - ); - - // If this is `Reveal:All`, then we need to make sure an error is reported but if - // this is `Reveal::UserFacing`, then it's expected that we could get a - // `TooGeneric` error. When we fall back to `Reveal::All`, then it will either - // succeed or we'll report this error then. - if key.param_env.reveal() == Reveal::All { - tcx.sess.delay_span_bug( - err.span, - &format!("static eval failure did not emit an error: {:#?}", v), - ); - } - - Err(v) - } else if let Some(def) = def.as_local() { - // constant defined in this crate, we can figure out a lint level! - match tcx.def_kind(def.did.to_def_id()) { - // constants never produce a hard error at the definition site. Anything else is - // a backwards compatibility hazard (and will break old versions of winapi for - // sure) - // - // note that validation may still cause a hard error on this very same constant, - // because any code that existed before validation could not have failed - // validation thus preventing such a hard error from being a backwards - // compatibility hazard - DefKind::Const | DefKind::AssocConst => { - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - Err(err.report_as_lint( - tcx.at(tcx.def_span(def.did)), - "any use of this value will cause an error", - hir_id, - Some(err.span), - )) - } - // promoting runtime code is only allowed to error if it references broken - // constants any other kind of error will be reported to the user as a - // deny-by-default lint - _ => { - if let Some(p) = cid.promoted { - let span = tcx.promoted_mir_opt_const_arg(def.to_global())[p].span; - if let err_inval!(ReferencedConstant) = err.error { - Err(err.report_as_error( - tcx.at(span), - "evaluation of constant expression failed", - )) - } else { - Err(err.report_as_lint( - tcx.at(span), - "reaching this expression at runtime will panic or abort", - tcx.hir().local_def_id_to_hir_id(def.did), - Some(err.span), - )) - } - // anything else (array lengths, enum initializers, constant patterns) are - // reported as hard errors - } else { - Err(err.report_as_error( - ecx.tcx.at(ecx.cur_span()), - "evaluation of constant value failed", - )) - } - } - } + // Some CTFE errors raise just a lint, not a hard error; see + // . + let emit_as_lint = if let Some(def) = def.as_local() { + // (Associated) consts only emit a lint, since they might be unused. + matches!(tcx.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) } else { - // use of broken constant from other crate - Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), "could not evaluate constant")) + // use of broken constant from other crate: always an error + false + }; + if emit_as_lint { + let hir_id = tcx.hir().local_def_id_to_hir_id(def.as_local().unwrap().did); + Err(err.report_as_lint( + tcx.at(tcx.def_span(def.did)), + "any use of this value will cause an error", + hir_id, + Some(err.span), + )) + } else { + let msg = if is_static { + "could not evaluate static initializer" + } else { + "evaluation of constant value failed" + }; + Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), msg)) } } Ok(mplace) => { - // Since evaluation had no errors, valiate the resulting constant: + // Since evaluation had no errors, validate the resulting constant. + // This is a separate `try` block to provide more targeted error reporting. let validation = try { let mut ref_tracking = RefTracking::new(mplace); let mut inner = false; @@ -399,7 +353,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( } }; if let Err(error) = validation { - // Validation failed, report an error + // Validation failed, report an error. This is always a hard error. let err = ConstEvalErr::new(&ecx, error, None); Err(err.struct_error( ecx.tcx, diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs index d7a48cbd63ecc..b0a4c7722e3ce 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs @@ -31,7 +31,7 @@ impl Tr for u32 { fn main() { assert_eq!(<() as Tr>::A, 255); assert_eq!(<() as Tr>::B, 0); // causes the error above - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed //~| ERROR erroneous constant used assert_eq!(::A, 254); diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr index 1497633c26af9..cbaaed0508b98 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -8,15 +8,11 @@ LL | const B: u8 = Self::A + 1; | = note: `#[deny(const_err)]` on by default -error[E0080]: evaluation of constant expression failed - --> $DIR/defaults-not-assumed-fail.rs:33:5 +error[E0080]: evaluation of constant value failed + --> $DIR/defaults-not-assumed-fail.rs:33:16 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above - | ^^^^^^^^^^^-------------^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^^^^^^^^^^^ referenced constant has errors error: erroneous constant used --> $DIR/defaults-not-assumed-fail.rs:33:5 diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index 65dfbd8097e76..c2adff116ef20 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(const_err)] | ^^^^^^^^^ -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/conditional_array_execution.rs:11:20 | LL | println!("{}", FOO); diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.rs b/src/test/ui/consts/const-eval/const-eval-query-stack.rs index 39803c8f257e0..cbfeca2402666 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.rs +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.rs @@ -21,6 +21,6 @@ const X: i32 = 1 / 0; //~WARN any use of this value will cause an error fn main() { let x: &'static i32 = &X; - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed println!("x={}", x); } diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 0016d301e598c..3e727b84aed10 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -12,13 +12,11 @@ note: the lint level is defined here LL | #[warn(const_err)] | ^^^^^^^^^ -error[E0080]: evaluation of constant expression failed - --> $DIR/const-eval-query-stack.rs:23:27 +error[E0080]: evaluation of constant value failed + --> $DIR/const-eval-query-stack.rs:23:28 | LL | let x: &'static i32 = &X; - | ^- - | | - | referenced constant has errors + | ^ referenced constant has errors query stack during panic: #0 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]` #1 [optimized_mir] optimizing MIR for `main` diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs index f67871e6142ef..0a2532973f423 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -18,7 +18,7 @@ const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday fn main() { assert_eq!(Y, 4); - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed assert_eq!(Z, 4); - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 822d4af83064e..2afedf30563a6 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -1,22 +1,14 @@ -error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:20:5 +error[E0080]: evaluation of constant value failed + --> $DIR/const_fn_ptr_fail2.rs:20:16 | LL | assert_eq!(Y, 4); - | ^^^^^^^^^^^-^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^ referenced constant has errors -error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:22:5 +error[E0080]: evaluation of constant value failed + --> $DIR/const_fn_ptr_fail2.rs:22:16 | LL | assert_eq!(Z, 4); - | ^^^^^^^^^^^-^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^ referenced constant has errors warning: skipping const checks | diff --git a/src/test/ui/consts/const-eval/issue-43197.rs b/src/test/ui/consts/const-eval/issue-43197.rs index 9109307632b59..7d1d33288a907 100644 --- a/src/test/ui/consts/const-eval/issue-43197.rs +++ b/src/test/ui/consts/const-eval/issue-43197.rs @@ -12,8 +12,8 @@ fn main() { const Y: u32 = foo(0 - 1); //~^ WARN any use of this value will cause println!("{} {}", X, Y); - //~^ ERROR evaluation of constant expression failed - //~| ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed + //~| ERROR evaluation of constant value failed //~| WARN erroneous constant used [const_err] //~| WARN erroneous constant used [const_err] } diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index 27e067cedbb5c..8c72b59141687 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -20,7 +20,7 @@ LL | const Y: u32 = foo(0 - 1); | | | attempt to compute `0_u32 - 1_u32`, which would overflow -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/issue-43197.rs:14:23 | LL | println!("{} {}", X, Y); @@ -32,7 +32,7 @@ warning: erroneous constant used LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/issue-43197.rs:14:26 | LL | println!("{} {}", X, Y); diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs index f9194709dc0b7..79f1301a2f944 100644 --- a/src/test/ui/consts/const-eval/issue-44578.rs +++ b/src/test/ui/consts/const-eval/issue-44578.rs @@ -25,5 +25,5 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ ERROR evaluation of constant expression failed [E0080] + //~^ ERROR evaluation of constant value failed [E0080] } diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index f4323713e682b..bff9f40f82b35 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -1,4 +1,4 @@ -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/issue-44578.rs:27:20 | LL | println!("{}", as Foo>::AMT); diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index ca8885e935090..f929f500cf9fb 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -8,13 +8,11 @@ LL | const BAR: usize = [5, 6, 7][T::BOO]; | = note: `#[deny(const_err)]` on by default -error[E0080]: evaluation of constant expression failed - --> $DIR/issue-50814-2.rs:18:5 +error[E0080]: evaluation of constant value failed + --> $DIR/issue-50814-2.rs:18:6 | LL | & as Foo>::BAR - | ^--------------------- - | | - | referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index 7327138627648..307fb3c8c9de1 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -8,13 +8,11 @@ LL | const MAX: u8 = A::MAX + B::MAX; | = note: `#[deny(const_err)]` on by default -error[E0080]: evaluation of constant expression failed - --> $DIR/issue-50814.rs:20:5 +error[E0080]: evaluation of constant value failed + --> $DIR/issue-50814.rs:20:6 | LL | &Sum::::MAX - | ^----------------- - | | - | referenced constant has errors + | ^^^^^^^^^^^^^^^^^ referenced constant has errors error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr index 31090be090833..6dddc7ff6e9d2 100644 --- a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr +++ b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr @@ -20,15 +20,11 @@ note: the lint level is defined here LL | #[warn(const_err)] | ^^^^^^^^^ -error[E0080]: evaluation of constant expression failed - --> $DIR/const_unsafe_unreachable_ub.rs:17:3 +error[E0080]: evaluation of constant value failed + --> $DIR/const_unsafe_unreachable_ub.rs:17:14 | LL | assert_eq!(BAR, true); - | ^^^^^^^^^^^---^^^^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^ referenced constant has errors error: erroneous constant used --> $DIR/const_unsafe_unreachable_ub.rs:17:3 diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index 924910e9cb6df..ede5487b65d39 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -2,15 +2,12 @@ error[E0080]: values of the type `[u8; SIZE]` are too big for the current archit --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL - | inside `main` at $DIR/issue-55878.rs:7:26 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL | ::: $DIR/issue-55878.rs:7:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ---------------------------------------------- + | ---------------------------------------------- inside `main` at $DIR/issue-55878.rs:7:26 error: erroneous constant used --> $DIR/issue-55878.rs:7:26 From 6d4e03af1e092b469825d998f6ea6b7e27def4d4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 24 Jan 2021 12:12:08 +0100 Subject: [PATCH 23/31] codegen: assume constants cannot fail to evaluate --- compiler/rustc_codegen_ssa/src/mir/mod.rs | 21 ++++++++++++++++ compiler/rustc_codegen_ssa/src/mir/operand.rs | 25 +++---------------- compiler/rustc_mir/src/interpret/operand.rs | 4 +++ 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 285140060be45..8a009b66b593e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -188,8 +188,10 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx); + let mut all_consts_ok = true; for const_ in &mir.required_consts { if let Err(err) = fx.eval_mir_constant(const_) { + all_consts_ok = false; match err { // errored or at least linted ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {} @@ -199,6 +201,25 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } } + if !all_consts_ok { + // There is no delay_span_bug here, we just have to rely on a hard error actually having + // been raised. + bx.abort(); + // `abort` does not terminate the block, so we still need to generate + // an `unreachable` terminator after it. + bx.unreachable(); + // We also have to delete all the other basic blocks again... + for bb in mir.basic_blocks().indices() { + if bb != mir::START_BLOCK { + unsafe { + bx.delete_basic_block(fx.blocks[bb]); + } + } + } + // FIXME: Can we somehow avoid all this by evaluating the consts before creating the basic + // blocks? The tricky part is doing that without duplicating `fx.eval_mir_constant`. + return; + } let memory_locals = analyze::non_ssa_locals(&fx); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 08a4ae3962bee..25e84c38ed315 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -6,9 +6,8 @@ use crate::glue; use crate::traits::*; use crate::MemFlags; -use rustc_errors::ErrorReported; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar}; +use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar}; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::Ty; use rustc_target::abi::{Abi, Align, LayoutOf, Size}; @@ -439,25 +438,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Operand::Constant(ref constant) => { - self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| { - match err { - // errored or at least linted - ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {} - ErrorHandled::TooGeneric => { - bug!("codegen encountered polymorphic constant") - } - } - // Allow RalfJ to sleep soundly knowing that even refactorings that remove - // the above error (or silence it under some conditions) will not cause UB. - bx.abort(); - // We still have to return an operand but it doesn't matter, - // this code is unreachable. - let ty = self.monomorphize(constant.literal.ty); - let layout = bx.cx().layout_of(ty); - bx.load_operand(PlaceRef::new_sized( - bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))), - layout, - )) + // This cannot fail because we checked all required_consts in advance. + self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| { + span_bug!(constant.span, "erroneous constant not captured by required_consts") }) } } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index d9437a312aec0..88236458a213a 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -511,6 +511,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Constant(ref constant) => { let val = self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal); + // This can still fail: + // * During ConstProp, with `TooGeneric` or since the `requried_consts` were not all + // checked yet. + // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail. self.const_to_op(val, layout)? } }; From 77a9e3e8e112e2d33599942cef63b1e22b6e5d27 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 24 Jan 2021 20:08:12 +0100 Subject: [PATCH 24/31] combine: stop eagerly evaluating consts --- compiler/rustc_infer/src/infer/combine.rs | 28 +++++++++++++------ compiler/rustc_middle/src/ty/relate.rs | 11 +------- .../issues/issue-69654-run-pass.rs | 2 +- .../issues/issue-69654-run-pass.stderr | 15 ++++++++++ .../ui/const-generics/issues/issue-69654.rs | 1 + .../const-generics/issues/issue-69654.stderr | 17 +++++++++-- .../occurs-check/unused-substs-1.rs | 3 +- .../occurs-check/unused-substs-1.stderr | 17 +++++++++++ .../occurs-check/unused-substs-2.rs | 3 +- .../occurs-check/unused-substs-2.stderr | 9 ++++++ .../occurs-check/unused-substs-3.rs | 3 +- .../occurs-check/unused-substs-3.stderr | 12 ++++++++ .../occurs-check/unused-substs-4.rs | 3 +- .../occurs-check/unused-substs-4.stderr | 9 ++++++ 14 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-69654-run-pass.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-1.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-2.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-3.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-4.stderr diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index b344086e95e77..718cd6aa8fbdd 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -543,10 +543,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn binders( &mut self, a: ty::Binder, @@ -737,6 +733,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } } + ty::ConstKind::Unevaluated(def, substs, promoted) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); + let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?; + Ok(self.tcx().mk_const(ty::Const { + ty: c.ty, + val: ty::ConstKind::Unevaluated(def, substs, promoted), + })) + } _ => relate::super_relate_consts(self, c, c), } } @@ -822,10 +828,6 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn relate_with_variance>( &mut self, _variance: ty::Variance, @@ -959,6 +961,16 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } } + ty::ConstKind::Unevaluated(def, substs, promoted) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); + let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?; + Ok(self.tcx().mk_const(ty::Const { + ty: c.ty, + val: ty::ConstKind::Unevaluated(def, substs, promoted), + })) + } _ => relate::super_relate_consts(self, c, c), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 293b3c6b0470a..af7fc42971954 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -33,15 +33,6 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; - /// Whether we should look into the substs of unevaluated constants - /// even if `feature(const_evaluatable_checked)` is active. - /// - /// This is needed in `combine` to prevent accidentially creating - /// infinite types as we abuse `TypeRelation` to walk a type there. - fn visit_ct_substs(&self) -> bool { - false - } - fn with_cause(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -588,7 +579,7 @@ pub fn super_relate_consts>( ( ty::ConstKind::Unevaluated(a_def, a_substs, None), ty::ConstKind::Unevaluated(b_def, b_substs, None), - ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => { + ) if tcx.features().const_evaluatable_checked => { if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) { Ok(a.val) } else { diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs index bbfd2183b06e3..8c0398e8a13ea 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs @@ -1,4 +1,3 @@ -// run-pass #![feature(const_generics)] #![allow(incomplete_features, unused_braces)] @@ -15,4 +14,5 @@ where fn main() { Foo::foo(); + //~^ ERROR no function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr new file mode 100644 index 0000000000000..a95cc0f2a1c32 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr @@ -0,0 +1,15 @@ +error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope + --> $DIR/issue-69654-run-pass.rs:16:10 + | +LL | struct Foo {} + | -------------------------- function or associated item `foo` not found for this +... +LL | Foo::foo(); + | ^^^ function or associated item not found in `Foo<{_: usize}>` + | + = note: the method `foo` exists but the following trait bounds were not satisfied: + `[u8; _]: Bar<[(); _]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/const-generics/issues/issue-69654.rs b/src/test/ui/const-generics/issues/issue-69654.rs index 7e775999ebd10..38fca98ad4f06 100644 --- a/src/test/ui/const-generics/issues/issue-69654.rs +++ b/src/test/ui/const-generics/issues/issue-69654.rs @@ -15,4 +15,5 @@ where fn main() { Foo::foo(); + //~^ ERROR no function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654.stderr b/src/test/ui/const-generics/issues/issue-69654.stderr index 70af7bf25d849..69cd0806fcd42 100644 --- a/src/test/ui/const-generics/issues/issue-69654.stderr +++ b/src/test/ui/const-generics/issues/issue-69654.stderr @@ -4,6 +4,19 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error: aborting due to previous error +error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope + --> $DIR/issue-69654.rs:17:10 + | +LL | struct Foo {} + | -------------------------- function or associated item `foo` not found for this +... +LL | Foo::foo(); + | ^^^ function or associated item not found in `Foo<{_: usize}>` + | + = note: the method `foo` exists but the following trait bounds were not satisfied: + `[u8; _]: Bar<[(); _]>` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0423`. +Some errors have detailed explanations: E0423, E0599. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs index f56687ecd9329..6ded9f13bc4fa 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs @@ -1,4 +1,3 @@ -// build-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -10,5 +9,5 @@ where A: Bar; fn main() { - let _ = A; + let _ = A; //~ERROR the trait bound } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr new file mode 100644 index 0000000000000..6830288acc0ad --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied + --> $DIR/unused-substs-1.rs:12:13 + | +LL | / struct A +LL | | where +LL | | A: Bar; + | |_________________- required by `A` +... +LL | let _ = A; + | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>` + | + = help: the following implementations were found: + as Bar> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs index 12444ec5312d9..2d00141fbf70b 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -24,4 +23,6 @@ fn main() { // `t` is `ty::Infer(TyVar(_#1t))` // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs t = foo; + //~^ ERROR mismatched types + //~| NOTE cyclic type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr new file mode 100644 index 0000000000000..9532fc21a31b7 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-2.rs:25:9 + | +LL | t = foo; + | ^^^ cyclic type of infinite size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs index 187e27382fcf2..2e306f8c4c88f 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -15,4 +14,6 @@ fn main() { // `t` is `ty::Infer(TyVar(_#1t))` // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs t = foo; + //~^ ERROR mismatched types + //~| NOTE cyclic type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr new file mode 100644 index 0000000000000..2551d68f97474 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-3.rs:16:9 + | +LL | t = foo; + | ^^^ + | | + | cyclic type of infinite size + | help: try using a conversion method: `foo.to_vec()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs index 8e42ceb6d70e9..9c7f5ab91edb1 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs @@ -1,4 +1,3 @@ -// build-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -8,5 +7,5 @@ fn bind(value: [u8; N]) -> [u8; 3 + 4] { fn main() { let mut arr = Default::default(); - arr = bind(arr); + arr = bind(arr); //~ ERROR mismatched type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr new file mode 100644 index 0000000000000..5685eedbdeca8 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-4.rs:10:11 + | +LL | arr = bind(arr); + | ^^^^^^^^^ encountered a self-referencing constant + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 36284a33f5500a1ff46e02f3f279131e28c871c8 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sun, 24 Jan 2021 15:42:33 -0500 Subject: [PATCH 25/31] `src/etc/json-types` -> `src/rustdoc-json-types` --- Cargo.toml | 2 +- src/librustdoc/Cargo.toml | 2 +- src/{etc/json-types => rustdoc-json-types}/Cargo.toml | 0 src/{etc/json-types => rustdoc-json-types}/lib.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename src/{etc/json-types => rustdoc-json-types}/Cargo.toml (100%) rename src/{etc/json-types => rustdoc-json-types}/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 34d3718f57db0..f3b2e0f740d61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = [ "compiler/rustc", "library/std", "library/test", - "src/etc/json-types", + "src/rustdoc-json-types", "src/tools/cargotest", "src/tools/clippy", "src/tools/compiletest", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 560bca8e3d116..c33482251ed4a 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -17,7 +17,7 @@ smallvec = "1.0" tempfile = "3" itertools = "0.9" regex = "1" -json-types = { path = "../etc/json-types" } +json-types = { path = "../rustdoc-json-types" } [dev-dependencies] expect-test = "1.0" diff --git a/src/etc/json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml similarity index 100% rename from src/etc/json-types/Cargo.toml rename to src/rustdoc-json-types/Cargo.toml diff --git a/src/etc/json-types/lib.rs b/src/rustdoc-json-types/lib.rs similarity index 100% rename from src/etc/json-types/lib.rs rename to src/rustdoc-json-types/lib.rs From 26b4baf46ea66d3651281c8b66d76853e6362c65 Mon Sep 17 00:00:00 2001 From: 1000teslas <47207223+1000teslas@users.noreply.github.com> Date: Mon, 18 Jan 2021 19:04:55 +1100 Subject: [PATCH 26/31] Point to span of upvar making closure FnMut Add expected error Add comment Tweak comment wording Fix after rebase to updated master Fix after rebase to updated master Distinguish mutation in normal and move closures Tweak error message Fix error message for nested closures Refactor code showing mutated upvar in closure Remove debug assert B --- .../diagnostics/mutability_errors.rs | 56 ++++++++++++++++++- .../borrow-raw-address-of-mutability.stderr | 4 +- .../issue-80313-mutable-borrow-in-closure.rs | 7 +++ ...sue-80313-mutable-borrow-in-closure.stderr | 14 +++++ ...ue-80313-mutable-borrow-in-move-closure.rs | 7 +++ ...0313-mutable-borrow-in-move-closure.stderr | 14 +++++ .../issue-80313-mutation-in-closure.rs | 7 +++ .../issue-80313-mutation-in-closure.stderr | 14 +++++ .../issue-80313-mutation-in-move-closure.rs | 7 +++ ...ssue-80313-mutation-in-move-closure.stderr | 14 +++++ ...es-infer-fnmut-calling-fnmut-no-mut.stderr | 4 ++ ...ed-closures-infer-fnmut-missing-mut.stderr | 4 +- ...osures-infer-fnmut-move-missing-mut.stderr | 4 +- 13 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/closures/issue-80313-mutable-borrow-in-closure.rs create mode 100644 src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr create mode 100644 src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.rs create mode 100644 src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr create mode 100644 src/test/ui/closures/issue-80313-mutation-in-closure.rs create mode 100644 src/test/ui/closures/issue-80313-mutation-in-closure.stderr create mode 100644 src/test/ui/closures/issue-80313-mutation-in-move-closure.rs create mode 100644 src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index e1af6fc07cf8f..73196c732f5bb 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -1,9 +1,12 @@ use rustc_hir as hir; use rustc_hir::Node; use rustc_index::vec::Idx; -use rustc_middle::mir::{self, ClearCrossCrate, Local, LocalDecl, LocalInfo, Location}; use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{ + hir::place::PlaceBase, + mir::{self, ClearCrossCrate, Local, LocalDecl, LocalInfo, Location}, +}; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; @@ -241,6 +244,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { format!("mut {}", self.local_names[local].unwrap()), Applicability::MachineApplicable, ); + let tcx = self.infcx.tcx; + if let ty::Closure(id, _) = the_place_err.ty(self.body, tcx).ty.kind() { + self.show_mutating_upvar(tcx, id, the_place_err, &mut err); + } } // Also suggest adding mut for upvars @@ -271,6 +278,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } } + + let tcx = self.infcx.tcx; + if let ty::Ref(_, ty, Mutability::Mut) = the_place_err.ty(self.body, tcx).ty.kind() + { + if let ty::Closure(id, _) = ty.kind() { + self.show_mutating_upvar(tcx, id, the_place_err, &mut err); + } + } } // complete hack to approximate old AST-borrowck @@ -463,6 +478,45 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.buffer(&mut self.errors_buffer); } + // point to span of upvar making closure call require mutable borrow + fn show_mutating_upvar( + &self, + tcx: TyCtxt<'_>, + id: &hir::def_id::DefId, + the_place_err: PlaceRef<'tcx>, + err: &mut DiagnosticBuilder<'_>, + ) { + let id = id.expect_local(); + let tables = tcx.typeck(id); + let hir_id = tcx.hir().local_def_id_to_hir_id(id); + let (span, place) = &tables.closure_kind_origins()[hir_id]; + let reason = if let PlaceBase::Upvar(upvar_id) = place.base { + let upvar = ty::place_to_string_for_capture(tcx, place); + match tables.upvar_capture(upvar_id) { + ty::UpvarCapture::ByRef(ty::UpvarBorrow { + kind: ty::BorrowKind::MutBorrow, + .. + }) => { + format!("mutable borrow of `{}`", upvar) + } + ty::UpvarCapture::ByValue(_) => { + format!("possible mutation of `{}`", upvar) + } + _ => bug!("upvar `{}` borrowed, but not mutably", upvar), + } + } else { + bug!("not an upvar") + }; + err.span_label( + *span, + format!( + "calling `{}` requires mutable binding due to {}", + self.describe_place(the_place_err).unwrap(), + reason + ), + ); + } + /// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected. fn expected_fn_found_fn_mut_call(&self, err: &mut DiagnosticBuilder<'_>, sp: Span, act: &str) { err.span_label(sp, format!("cannot {}", act)); diff --git a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr index 44dde0fd80b0d..ea74fb966846f 100644 --- a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr +++ b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr @@ -20,7 +20,9 @@ error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable | LL | let f = || { | - help: consider changing this to be mutable: `mut f` -... +LL | let y = &raw mut x; + | - calling `f` requires mutable binding due to mutable borrow of `x` +LL | }; LL | f(); | ^ cannot borrow as mutable diff --git a/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.rs b/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.rs new file mode 100644 index 0000000000000..ff210ae06a3bd --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.rs @@ -0,0 +1,7 @@ +fn main() { + let mut my_var = false; + let callback = || { + &mut my_var; + }; + callback(); //~ ERROR E0596 +} diff --git a/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr b/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr new file mode 100644 index 0000000000000..bf9e1febdbba4 --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutable-borrow-in-closure.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable + --> $DIR/issue-80313-mutable-borrow-in-closure.rs:6:5 + | +LL | let callback = || { + | -------- help: consider changing this to be mutable: `mut callback` +LL | &mut my_var; + | ------ calling `callback` requires mutable binding due to mutable borrow of `my_var` +LL | }; +LL | callback(); + | ^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.rs b/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.rs new file mode 100644 index 0000000000000..8f2d8a676302c --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.rs @@ -0,0 +1,7 @@ +fn main() { + let mut my_var = false; + let callback = move || { + &mut my_var; + }; + callback(); //~ ERROR E0596 +} diff --git a/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr b/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr new file mode 100644 index 0000000000000..b67cec6a609f0 --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutable-borrow-in-move-closure.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable + --> $DIR/issue-80313-mutable-borrow-in-move-closure.rs:6:5 + | +LL | let callback = move || { + | -------- help: consider changing this to be mutable: `mut callback` +LL | &mut my_var; + | ------ calling `callback` requires mutable binding due to possible mutation of `my_var` +LL | }; +LL | callback(); + | ^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/closures/issue-80313-mutation-in-closure.rs b/src/test/ui/closures/issue-80313-mutation-in-closure.rs new file mode 100644 index 0000000000000..e082ea562ef22 --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutation-in-closure.rs @@ -0,0 +1,7 @@ +fn main() { + let mut my_var = false; + let callback = || { + my_var = true; + }; + callback(); //~ ERROR E0596 +} diff --git a/src/test/ui/closures/issue-80313-mutation-in-closure.stderr b/src/test/ui/closures/issue-80313-mutation-in-closure.stderr new file mode 100644 index 0000000000000..6e98549f6b84f --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutation-in-closure.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable + --> $DIR/issue-80313-mutation-in-closure.rs:6:5 + | +LL | let callback = || { + | -------- help: consider changing this to be mutable: `mut callback` +LL | my_var = true; + | ------ calling `callback` requires mutable binding due to mutable borrow of `my_var` +LL | }; +LL | callback(); + | ^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/closures/issue-80313-mutation-in-move-closure.rs b/src/test/ui/closures/issue-80313-mutation-in-move-closure.rs new file mode 100644 index 0000000000000..f66bf4e062831 --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutation-in-move-closure.rs @@ -0,0 +1,7 @@ +fn main() { + let mut my_var = false; + let callback = move || { + my_var = true; + }; + callback(); //~ ERROR E0596 +} diff --git a/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr b/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr new file mode 100644 index 0000000000000..edd55422a0bd4 --- /dev/null +++ b/src/test/ui/closures/issue-80313-mutation-in-move-closure.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable + --> $DIR/issue-80313-mutation-in-move-closure.rs:6:5 + | +LL | let callback = move || { + | -------- help: consider changing this to be mutable: `mut callback` +LL | my_var = true; + | ------ calling `callback` requires mutable binding due to possible mutation of `my_var` +LL | }; +LL | callback(); + | ^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr index 5dea424596e9c..a0ed56d4bcf7b 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr @@ -3,6 +3,8 @@ error[E0596]: cannot borrow `tick1` as mutable, as it is not declared as mutable | LL | let tick1 = || { | ----- help: consider changing this to be mutable: `mut tick1` +LL | counter += 1; + | ------- calling `tick1` requires mutable binding due to mutable borrow of `counter` ... LL | tick1(); | ^^^^^ cannot borrow as mutable @@ -12,6 +14,8 @@ error[E0596]: cannot borrow `tick2` as mutable, as it is not declared as mutable | LL | let tick2 = || { | ----- help: consider changing this to be mutable: `mut tick2` +LL | tick1(); + | ----- calling `tick2` requires mutable binding due to mutable borrow of `tick1` ... LL | tick2(); | ^^^^^ cannot borrow as mutable diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr index eb398628846dd..27d23e3fa044b 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.stderr @@ -2,7 +2,9 @@ error[E0596]: cannot borrow `tick` as mutable, as it is not declared as mutable --> $DIR/unboxed-closures-infer-fnmut-missing-mut.rs:7:5 | LL | let tick = || counter += 1; - | ---- help: consider changing this to be mutable: `mut tick` + | ---- ------- calling `tick` requires mutable binding due to mutable borrow of `counter` + | | + | help: consider changing this to be mutable: `mut tick` LL | tick(); | ^^^^ cannot borrow as mutable diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr index b9d76d9a752ce..c00f986c397a7 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.stderr @@ -2,7 +2,9 @@ error[E0596]: cannot borrow `tick` as mutable, as it is not declared as mutable --> $DIR/unboxed-closures-infer-fnmut-move-missing-mut.rs:7:5 | LL | let tick = move || counter += 1; - | ---- help: consider changing this to be mutable: `mut tick` + | ---- ------- calling `tick` requires mutable binding due to possible mutation of `counter` + | | + | help: consider changing this to be mutable: `mut tick` LL | tick(); | ^^^^ cannot borrow as mutable From ef3127dcdfedb6b3b113150f6c84171bd98ab360 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 25 Jan 2021 12:54:25 +0100 Subject: [PATCH 27/31] Completely remove search query parameter when clearing search input --- src/librustdoc/html/static/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 74bd348e9ac1c..5606a1d5170e9 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1925,7 +1925,8 @@ function defocusSearchBar() { clearInputTimeout(); if (search_input.value.length === 0) { if (browserSupportsHistoryApi()) { - history.replaceState("", window.currentCrate + " - Rust", "?search="); + history.replaceState("", window.currentCrate + " - Rust", + window.location.href.split("?")[0]); } hideSearchResults(); } else { From 09518db73e84112922af76f161b803eb90ceb445 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 25 Jan 2021 13:21:12 +0100 Subject: [PATCH 28/31] Improve URL handling when clicking on a menu link while being on the search results and overall --- src/librustdoc/html/static/main.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 5606a1d5170e9..51c62c285073c 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -94,6 +94,11 @@ function getThemePickerElement() { return document.getElementById("theme-picker"); } +// Returns the current URL without any query parameter or hash. +function getNakedUrl() { + return window.location.href.split("?")[0].split("#")[0]; +} + // Sets the focus on the search bar at the top of the page function focusSearchBar() { getSearchInput().focus(); @@ -255,7 +260,9 @@ function defocusSearchBar() { hideSearchResults(search); var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); if (browserSupportsHistoryApi()) { - history.replaceState(hash, "", "?search=#" + hash); + // `window.location.search`` contains all the query parameters, not just `search`. + history.replaceState(hash, "", + getNakedUrl() + window.location.search + "#" + hash); } elem = document.getElementById(hash); if (elem) { @@ -1813,10 +1820,12 @@ function defocusSearchBar() { // Because searching is incremental by character, only the most // recent search query is added to the browser history. if (browserSupportsHistoryApi()) { + var newURL = getNakedUrl() + "?search=" + encodeURIComponent(query.raw) + + window.location.hash; if (!history.state && !params.search) { - history.pushState(query, "", "?search=" + encodeURIComponent(query.raw)); + history.pushState(query, "", newURL); } else { - history.replaceState(query, "", "?search=" + encodeURIComponent(query.raw)); + history.replaceState(query, "", newURL); } } @@ -1926,7 +1935,7 @@ function defocusSearchBar() { if (search_input.value.length === 0) { if (browserSupportsHistoryApi()) { history.replaceState("", window.currentCrate + " - Rust", - window.location.href.split("?")[0]); + getNakedUrl() + window.location.hash); } hideSearchResults(); } else { @@ -2786,9 +2795,9 @@ function defocusSearchBar() { if (search_input.value !== "" && hasClass(search, "hidden")) { showSearchResults(search); if (browserSupportsHistoryApi()) { - history.replaceState(search_input.value, - "", - "?search=" + encodeURIComponent(search_input.value)); + var extra = "?search=" + encodeURIComponent(search_input.value); + history.replaceState(search_input.value, "", + getNakedUrl() + extra + window.location.hash); } document.title = searchTitle; } From 6cbc4c234e8999702a4dc3220d585a849e1dd374 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 25 Jan 2021 16:23:43 -0500 Subject: [PATCH 29/31] Update crate name and add README --- Cargo.lock | 16 ++++++++-------- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/json/conversions.rs | 2 +- src/librustdoc/json/mod.rs | 2 +- src/rustdoc-json-types/Cargo.toml | 2 +- src/rustdoc-json-types/README.md | 12 ++++++++++++ 6 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 src/rustdoc-json-types/README.md diff --git a/Cargo.lock b/Cargo.lock index 086dd6b4efe5a..63afb2a7d73c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1636,13 +1636,6 @@ version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92c245af8786f6ac35f95ca14feca9119e71339aaab41e878e7cdd655c97e9e5" -[[package]] -name = "json-types" -version = "0.1.0" -dependencies = [ - "serde", -] - [[package]] name = "jsondocck" version = "0.1.0" @@ -4394,17 +4387,24 @@ version = "0.0.0" dependencies = [ "expect-test", "itertools 0.9.0", - "json-types", "minifier", "pulldown-cmark 0.8.0", "regex", "rustc-rayon", + "rustdoc-json-types", "serde", "serde_json", "smallvec 1.4.2", "tempfile", ] +[[package]] +name = "rustdoc-json-types" +version = "0.1.0" +dependencies = [ + "serde", +] + [[package]] name = "rustdoc-themes" version = "0.1.0" diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index c33482251ed4a..db64b31f31cfc 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -17,7 +17,7 @@ smallvec = "1.0" tempfile = "3" itertools = "0.9" regex = "1" -json-types = { path = "../rustdoc-json-types" } +rustdoc-json-types = { path = "../rustdoc-json-types" } [dev-dependencies] expect-test = "1.0" diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 9b0603c4d55ba..b2e5c8834b8ff 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -9,7 +9,7 @@ use rustc_hir::def::CtorKind; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_span::Pos; -use json_types::*; +use rustdoc_json_types::*; use crate::clean; use crate::formats::item_type::ItemType; diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index dd9aced3121f3..92ba41c1b3b62 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; -use json_types as types; +use rustdoc_json_types as types; use crate::clean; use crate::config::{RenderInfo, RenderOptions}; diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml index b9c97c31c1877..7bba16a68b96c 100644 --- a/src/rustdoc-json-types/Cargo.toml +++ b/src/rustdoc-json-types/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "json-types" +name = "rustdoc-json-types" version = "0.1.0" authors = ["The Rust Project Developers"] edition = "2018" diff --git a/src/rustdoc-json-types/README.md b/src/rustdoc-json-types/README.md new file mode 100644 index 0000000000000..17894c3c61d03 --- /dev/null +++ b/src/rustdoc-json-types/README.md @@ -0,0 +1,12 @@ +# Rustdoc JSON Types + +This crate exposes the Rustdoc JSON API as a set of types with serde implementations. +These types are part of the public interface of the rustdoc JSON output, and making them +their own crate allows them to be versioned and distributed without having to depend on +any rustc/rustdoc internals. This way, consumers can rely on this crate for both documentation +of the output, and as a way to read the output easily, and its versioning is intended to +follow semver guarantees about the version of the format. JSON format X will always be +compatible with rustdoc-json-types version N. + +Currently, this crate is only used by rustdoc itself. Upon the stabilization of +rustdoc-json, it may be start to be distributed separately for consumers of the API. From cf71d83bd22a9aac4757f9bc144b42f3bbff6aae Mon Sep 17 00:00:00 2001 From: Chris Pardy Date: Tue, 26 Jan 2021 17:39:30 -0500 Subject: [PATCH 30/31] add tests --- .../capture-analysis-3.rs | 35 ++++++++++ .../capture-analysis-3.stderr | 65 +++++++++++++++++++ .../capture-analysis-4.rs | 33 ++++++++++ .../capture-analysis-4.stderr | 62 ++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs new file mode 100644 index 0000000000000..817ade899e2a0 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs @@ -0,0 +1,35 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] + +#[derive(Debug)] +struct Child { + c: String, + d: String, +} + +#[derive(Debug)] +struct Parent { + b: Child, +} + +fn main() { + let mut a = Parent { b: Child {c: String::new(), d: String::new()} }; + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ First Pass analysis includes: + //~| Min Capture analysis includes: + let _x = a.b.c; + //~^ NOTE: Capturing a[(0, 0),(0, 0)] -> ByValue + //~| NOTE: a[(0, 0)] captured as ByValue here + println!("{:?}", a.b); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ByValue + //~| NOTE: a[(0, 0)] used here + }; +} diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr new file mode 100644 index 0000000000000..263e9ca56ebf6 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr @@ -0,0 +1,65 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/capture-analysis-3.rs:21:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-analysis-3.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error: First Pass analysis includes: + --> $DIR/capture-analysis-3.rs:24:5 + | +LL | / || { +LL | | +LL | | +LL | | let _x = a.b.c; +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing a[(0, 0),(0, 0)] -> ByValue + --> $DIR/capture-analysis-3.rs:27:18 + | +LL | let _x = a.b.c; + | ^^^^^ +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/capture-analysis-3.rs:30:26 + | +LL | println!("{:?}", a.b); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/capture-analysis-3.rs:24:5 + | +LL | / || { +LL | | +LL | | +LL | | let _x = a.b.c; +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture a[(0, 0)] -> ByValue + --> $DIR/capture-analysis-3.rs:27:18 + | +LL | let _x = a.b.c; + | ^^^^^ a[(0, 0)] captured as ByValue here +... +LL | println!("{:?}", a.b); + | ^^^ a[(0, 0)] used here + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs new file mode 100644 index 0000000000000..e8401299b30ad --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs @@ -0,0 +1,33 @@ +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] + +#[derive(Debug)] +struct Child { + c: String, + d: String, +} + +#[derive(Debug)] +struct Parent { + b: Child, +} + +fn main() { + let mut a = Parent { b: Child {c: String::new(), d: String::new()} }; + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ First Pass analysis includes: + //~| Min Capture analysis includes: + let _x = a.b; + //~^ NOTE: Capturing a[(0, 0)] -> ByValue + //~| NOTE: Min Capture a[(0, 0)] -> ByValue + println!("{:?}", a.b.c); + //~^ NOTE: Capturing a[(0, 0),(0, 0)] -> ImmBorrow + }; +} diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr new file mode 100644 index 0000000000000..f4605c1d51b76 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr @@ -0,0 +1,62 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/capture-analysis-4.rs:21:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-analysis-4.rs:1:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error: First Pass analysis includes: + --> $DIR/capture-analysis-4.rs:24:5 + | +LL | / || { +LL | | +LL | | +LL | | let _x = a.b; +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing a[(0, 0)] -> ByValue + --> $DIR/capture-analysis-4.rs:27:18 + | +LL | let _x = a.b; + | ^^^ +note: Capturing a[(0, 0),(0, 0)] -> ImmBorrow + --> $DIR/capture-analysis-4.rs:30:26 + | +LL | println!("{:?}", a.b.c); + | ^^^^^ + +error: Min Capture analysis includes: + --> $DIR/capture-analysis-4.rs:24:5 + | +LL | / || { +LL | | +LL | | +LL | | let _x = a.b; +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture a[(0, 0)] -> ByValue + --> $DIR/capture-analysis-4.rs:27:18 + | +LL | let _x = a.b; + | ^^^ + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. From 582a17101dd0ba337f27d4a09feae1a0af6cc1e3 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 27 Jan 2021 12:21:19 +0100 Subject: [PATCH 31/31] add const_evaluatable_checked test --- .../elaborate-trait-pred.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/elaborate-trait-pred.rs diff --git a/src/test/ui/const-generics/const_evaluatable_checked/elaborate-trait-pred.rs b/src/test/ui/const-generics/const_evaluatable_checked/elaborate-trait-pred.rs new file mode 100644 index 0000000000000..4a4fd1e33117f --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/elaborate-trait-pred.rs @@ -0,0 +1,24 @@ +// run-pass +// Test that we use the elaborated predicates from traits +// to satisfy const evaluatable predicates. +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +use std::mem::size_of; + +trait Foo: Sized +where + [(); size_of::()]: Sized, +{ +} + +impl Foo for u64 {} +impl Foo for u32 {} + +fn foo() -> [u8; size_of::()] { + [0; size_of::()] +} + +fn main() { + assert_eq!(foo::(), [0; 4]); + assert_eq!(foo::(), [0; 8]); +}