From 72a2d35f165a94e17cd17e56cb61e3dcbef7eb2d Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 20 May 2020 14:57:16 +0200 Subject: [PATCH 01/25] fix is_const_context --- src/librustc_middle/hir/map/mod.rs | 22 +++++----- .../diagnostics/mutability_errors.rs | 2 +- src/test/ui/consts/enum-discr-type-err.stderr | 8 ---- src/test/ui/discrim/discrim-ill-typed.stderr | 40 ------------------- src/test/ui/issues/issue-31910.stderr | 5 --- src/test/ui/issues/issue-8761.stderr | 10 ----- src/test/ui/repeat_count.stderr | 10 ----- 7 files changed, 12 insertions(+), 85 deletions(-) diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index b823516d64f3b..c5f0acb3f0709 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -374,6 +374,16 @@ impl<'hir> Map<'hir> { } } + pub fn enclosing_body_owner(&self, hir_id: HirId) -> HirId { + for (parent, _) in self.parent_iter(hir_id) { + if let Some(body) = self.maybe_body_owned_by(parent) { + return self.body_owner(body); + } + } + + bug!("no `enclosing_body_owner` for hir_id `{}`", hir_id); + } + /// Returns the `HirId` that corresponds to the definition of /// which this is the body of, i.e., a `fn`, `const` or `static` /// item (possibly associated), a closure, or a `hir::AnonConst`. @@ -577,17 +587,7 @@ impl<'hir> Map<'hir> { /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. /// Used exclusively for diagnostics, to avoid suggestion function calls. pub fn is_const_context(&self, hir_id: HirId) -> bool { - let parent_id = self.get_parent_item(hir_id); - match self.get(parent_id) { - Node::Item(&Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. }) - | Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. }) - | Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. }) - | Node::AnonConst(_) => true, - Node::Item(&Item { kind: ItemKind::Fn(ref sig, ..), .. }) => { - sig.header.constness == Constness::Const - } - _ => false, - } + self.body_const_context(self.local_def_id(self.enclosing_body_owner(hir_id))).is_some() } /// Whether `hir_id` corresponds to a `mod` or a crate. diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 402eac47c462b..ff90748a9d07e 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -495,7 +495,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let closure_id = hir.as_local_hir_id(self.mir_def_id.expect_local()); let fn_call_id = hir.get_parent_node(closure_id); let node = hir.get(fn_call_id); - let item_id = hir.get_parent_item(fn_call_id); + let item_id = hir.enclosing_body_owner(fn_call_id); let mut look_at_return = true; // If we can detect the expression to be an `fn` call where the closure was an argument, // we point at the `fn` definition argument... diff --git a/src/test/ui/consts/enum-discr-type-err.stderr b/src/test/ui/consts/enum-discr-type-err.stderr index 492b79e2e6021..9834a99b79a0e 100644 --- a/src/test/ui/consts/enum-discr-type-err.stderr +++ b/src/test/ui/consts/enum-discr-type-err.stderr @@ -11,10 +11,6 @@ LL | | } | |_- in this macro invocation | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit - | -LL | $( $v = $s::V.try_into().unwrap(), )* - | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/enum-discr-type-err.rs:18:21 @@ -29,10 +25,6 @@ LL | | } | |_- in this macro invocation | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit - | -LL | $( $v = $s::V.try_into().unwrap(), )* - | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/discrim/discrim-ill-typed.stderr b/src/test/ui/discrim/discrim-ill-typed.stderr index 7b9f086151a84..b0e11ee5a6e60 100644 --- a/src/test/ui/discrim/discrim-ill-typed.stderr +++ b/src/test/ui/discrim/discrim-ill-typed.stderr @@ -3,88 +3,48 @@ error[E0308]: mismatched types | LL | OhNo = 0_u8, | ^^^^ expected `i8`, found `u8` - | -help: change the type of the numeric literal from `u8` to `i8` - | -LL | OhNo = 0_i8, - | ^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:30:16 | LL | OhNo = 0_i8, | ^^^^ expected `u8`, found `i8` - | -help: change the type of the numeric literal from `i8` to `u8` - | -LL | OhNo = 0_u8, - | ^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:43:16 | LL | OhNo = 0_u16, | ^^^^^ expected `i16`, found `u16` - | -help: change the type of the numeric literal from `u16` to `i16` - | -LL | OhNo = 0_i16, - | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:56:16 | LL | OhNo = 0_i16, | ^^^^^ expected `u16`, found `i16` - | -help: change the type of the numeric literal from `i16` to `u16` - | -LL | OhNo = 0_u16, - | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:69:16 | LL | OhNo = 0_u32, | ^^^^^ expected `i32`, found `u32` - | -help: change the type of the numeric literal from `u32` to `i32` - | -LL | OhNo = 0_i32, - | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:82:16 | LL | OhNo = 0_i32, | ^^^^^ expected `u32`, found `i32` - | -help: change the type of the numeric literal from `i32` to `u32` - | -LL | OhNo = 0_u32, - | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:95:16 | LL | OhNo = 0_u64, | ^^^^^ expected `i64`, found `u64` - | -help: change the type of the numeric literal from `u64` to `i64` - | -LL | OhNo = 0_i64, - | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:108:16 | LL | OhNo = 0_i64, | ^^^^^ expected `u64`, found `i64` - | -help: change the type of the numeric literal from `i64` to `u64` - | -LL | OhNo = 0_u64, - | ^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/issues/issue-31910.stderr b/src/test/ui/issues/issue-31910.stderr index c5c988cdaa75a..2603c944207d0 100644 --- a/src/test/ui/issues/issue-31910.stderr +++ b/src/test/ui/issues/issue-31910.stderr @@ -3,11 +3,6 @@ error[E0308]: mismatched types | LL | X = Trait::Number, | ^^^^^^^^^^^^^ expected `isize`, found `i32` - | -help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit - | -LL | X = Trait::Number.try_into().unwrap(), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-8761.stderr b/src/test/ui/issues/issue-8761.stderr index 836520a28ef34..6ab74a9e98940 100644 --- a/src/test/ui/issues/issue-8761.stderr +++ b/src/test/ui/issues/issue-8761.stderr @@ -3,22 +3,12 @@ error[E0308]: mismatched types | LL | A = 1i64, | ^^^^ expected `isize`, found `i64` - | -help: change the type of the numeric literal from `i64` to `isize` - | -LL | A = 1isize, - | ^^^^^^ error[E0308]: mismatched types --> $DIR/issue-8761.rs:5:9 | LL | B = 2u8 | ^^^ expected `isize`, found `u8` - | -help: change the type of the numeric literal from `u8` to `isize` - | -LL | B = 2isize - | ^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 4a2d1d9f921cb..963319892d4ca 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -39,22 +39,12 @@ error[E0308]: mismatched types | LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` - | -help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit - | -LL | let f = [0; (-4_isize).try_into().unwrap()]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/repeat_count.rs:22:23 | LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` - | -help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit - | -LL | let f = [0_usize; (-1_isize).try_into().unwrap()]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 8 previous errors From ecb593379c3ab075940a3fbf2e980ec5260b6ca4 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 20 May 2020 15:59:57 +0200 Subject: [PATCH 02/25] refactor check_for_cast --- src/librustc_typeck/check/demand.rs | 396 +++++++++---------- src/test/ui/discrim/discrim-ill-typed.stderr | 40 ++ src/test/ui/issues/issue-8761.stderr | 10 + src/test/ui/numeric/const-scope.stderr | 10 + src/test/ui/repeat_count.rs | 3 + src/test/ui/repeat_count.stderr | 15 +- 6 files changed, 265 insertions(+), 209 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 9694ce9450c27..6e93f2273ab86 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -16,6 +16,8 @@ use rustc_span::Span; use super::method::probe; +use std::fmt; + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn emit_coerce_suggestions( &self, @@ -689,16 +691,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { checked_ty: Ty<'tcx>, expected_ty: Ty<'tcx>, ) -> bool { - if self.tcx.hir().is_const_context(expr.hir_id) { - // Shouldn't suggest `.into()` on `const`s. - // FIXME(estebank): modify once we decide to suggest `as` casts - return false; - } if self.tcx.sess.source_map().is_imported(expr.span) { // Ignore if span is from within a macro. return false; } + let src = if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) { + src + } else { + return false; + }; + // If casting this expression to a given numeric type would be appropriate in case of a type // mismatch. // @@ -727,6 +730,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { String::new() }; + if let hir::ExprKind::Call(path, args) = &expr.kind { if let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) = (&path.kind, args.len()) @@ -768,222 +772,200 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { checked_ty, expected_ty, ); - let needs_paren = expr.precedence().order() < (PREC_POSTFIX as i8); - - if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) { - let cast_suggestion = format!( - "{}{}{}{} as {}", - prefix, - if needs_paren { "(" } else { "" }, - src, - if needs_paren { ")" } else { "" }, - expected_ty, - ); - let try_into_suggestion = format!( - "{}{}{}{}.try_into().unwrap()", - prefix, - if needs_paren { "(" } else { "" }, - src, - if needs_paren { ")" } else { "" }, - ); - let into_suggestion = format!( - "{}{}{}{}.into()", - prefix, - if needs_paren { "(" } else { "" }, - src, - if needs_paren { ")" } else { "" }, - ); - let suffix_suggestion = format!( - "{}{}{}{}", - if needs_paren { "(" } else { "" }, - if let (ty::Int(_) | ty::Uint(_), ty::Float(_)) = - (&expected_ty.kind, &checked_ty.kind,) - { - // Remove fractional part from literal, for example `42.0f32` into `42` - let src = src.trim_end_matches(&checked_ty.to_string()); - src.split('.').next().unwrap() + let with_opt_paren: fn(&dyn fmt::Display) -> String = + if expr.precedence().order() < PREC_POSTFIX { + |s| format!("({})", s) + } else { + |s| s.to_string() + }; + + let cast_suggestion = format!("{}{} as {}", prefix, with_opt_paren(&src), expected_ty); + let try_into_suggestion = format!("{}{}.try_into().unwrap()", prefix, with_opt_paren(&src)); + let into_suggestion = format!("{}{}.into()", prefix, with_opt_paren(&src)); + let suffix_suggestion = with_opt_paren(&format_args!( + "{}{}", + if matches!( + (&expected_ty.kind, &checked_ty.kind), + (ty::Int(_) | ty::Uint(_), ty::Float(_)) + ) { + // Remove fractional part from literal, for example `42.0f32` into `42` + let src = src.trim_end_matches(&checked_ty.to_string()); + src.split('.').next().unwrap() + } else { + src.trim_end_matches(&checked_ty.to_string()) + }, + expected_ty, + )); + let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| { + if let hir::ExprKind::Lit(lit) = &expr.kind { lit.node.is_suffixed() } else { false } + }; + + let is_const_context = self.tcx.hir().is_const_context(expr.hir_id); + let suggest_to_change_suffix_or_into = + |err: &mut DiagnosticBuilder<'_>, is_fallible: bool| { + let msg = if literal_is_ty_suffixed(expr) { + &lit_msg + } else if is_const_context { + // Do not recommend `into` or `try_into` in const contexts. + return; + } else if is_fallible { + &try_msg } else { - src.trim_end_matches(&checked_ty.to_string()) - }, - expected_ty, - if needs_paren { ")" } else { "" }, - ); - let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| { - if let hir::ExprKind::Lit(lit) = &expr.kind { - lit.node.is_suffixed() + &msg + }; + let suggestion = if literal_is_ty_suffixed(expr) { + suffix_suggestion.clone() + } else if is_fallible { + try_into_suggestion } else { - false - } + into_suggestion.clone() + }; + err.span_suggestion(expr.span, msg, suggestion, Applicability::MachineApplicable); }; - let suggest_to_change_suffix_or_into = - |err: &mut DiagnosticBuilder<'_>, is_fallible: bool| { + match (&expected_ty.kind, &checked_ty.kind) { + (&ty::Int(ref exp), &ty::Int(ref found)) => { + let is_fallible = match (exp.bit_width(), found.bit_width()) { + (Some(exp), Some(found)) if exp < found => true, + (None, Some(8 | 16)) => false, + (None, _) | (_, None) => true, + _ => false, + }; + suggest_to_change_suffix_or_into(err, is_fallible); + true + } + (&ty::Uint(ref exp), &ty::Uint(ref found)) => { + let is_fallible = match (exp.bit_width(), found.bit_width()) { + (Some(exp), Some(found)) if exp < found => true, + (None, Some(8 | 16)) => false, + (None, _) | (_, None) => true, + _ => false, + }; + suggest_to_change_suffix_or_into(err, is_fallible); + true + } + (&ty::Int(exp), &ty::Uint(found)) => { + let is_fallible = match (exp.bit_width(), found.bit_width()) { + (Some(exp), Some(found)) if found < exp => false, + (None, Some(8)) => false, + _ => true, + }; + suggest_to_change_suffix_or_into(err, is_fallible); + true + } + (&ty::Uint(_), &ty::Int(_)) => { + suggest_to_change_suffix_or_into(err, true); + true + } + (&ty::Float(ref exp), &ty::Float(ref found)) => { + if found.bit_width() < exp.bit_width() { + suggest_to_change_suffix_or_into(err, false); + } else if literal_is_ty_suffixed(expr) { err.span_suggestion( expr.span, - if literal_is_ty_suffixed(expr) { - &lit_msg - } else if is_fallible { - &try_msg - } else { - &msg - }, - if literal_is_ty_suffixed(expr) { - suffix_suggestion.clone() - } else if is_fallible { - try_into_suggestion - } else { - into_suggestion.clone() - }, + &lit_msg, + suffix_suggestion, Applicability::MachineApplicable, ); - }; - - match (&expected_ty.kind, &checked_ty.kind) { - (&ty::Int(ref exp), &ty::Int(ref found)) => { - let is_fallible = match (exp.bit_width(), found.bit_width()) { - (Some(exp), Some(found)) if exp < found => true, - (None, Some(8 | 16)) => false, - (None, _) | (_, None) => true, - _ => false, - }; - suggest_to_change_suffix_or_into(err, is_fallible); - true - } - (&ty::Uint(ref exp), &ty::Uint(ref found)) => { - let is_fallible = match (exp.bit_width(), found.bit_width()) { - (Some(exp), Some(found)) if exp < found => true, - (None, Some(8 | 16)) => false, - (None, _) | (_, None) => true, - _ => false, - }; - suggest_to_change_suffix_or_into(err, is_fallible); - true - } - (&ty::Int(exp), &ty::Uint(found)) => { - let is_fallible = match (exp.bit_width(), found.bit_width()) { - (Some(exp), Some(found)) if found < exp => false, - (None, Some(8)) => false, - _ => true, - }; - suggest_to_change_suffix_or_into(err, is_fallible); - true - } - (&ty::Uint(_), &ty::Int(_)) => { - suggest_to_change_suffix_or_into(err, true); - true - } - (&ty::Float(ref exp), &ty::Float(ref found)) => { - if found.bit_width() < exp.bit_width() { - suggest_to_change_suffix_or_into(err, false); - } else if literal_is_ty_suffixed(expr) { - err.span_suggestion( - expr.span, - &lit_msg, - suffix_suggestion, - Applicability::MachineApplicable, - ); - } else if can_cast { - // Missing try_into implementation for `f64` to `f32` - err.span_suggestion( - expr.span, - &format!("{}, producing the closest possible value", cast_msg), - cast_suggestion, - Applicability::MaybeIncorrect, // lossy conversion - ); - } - true + } else if can_cast { + // Missing try_into implementation for `f64` to `f32` + err.span_suggestion( + expr.span, + &format!("{}, producing the closest possible value", cast_msg), + cast_suggestion, + Applicability::MaybeIncorrect, // lossy conversion + ); } - (&ty::Uint(_) | &ty::Int(_), &ty::Float(_)) => { - if literal_is_ty_suffixed(expr) { - err.span_suggestion( - expr.span, - &lit_msg, - suffix_suggestion, - Applicability::MachineApplicable, - ); - } else if can_cast { - // Missing try_into implementation for `{float}` to `{integer}` - err.span_suggestion( - expr.span, - &format!("{}, rounding the float towards zero", msg), - cast_suggestion, - Applicability::MaybeIncorrect, // lossy conversion - ); - } - true + true + } + (&ty::Uint(_) | &ty::Int(_), &ty::Float(_)) => { + if literal_is_ty_suffixed(expr) { + err.span_suggestion( + expr.span, + &lit_msg, + suffix_suggestion, + Applicability::MachineApplicable, + ); + } else if can_cast { + // Missing try_into implementation for `{float}` to `{integer}` + err.span_suggestion( + expr.span, + &format!("{}, rounding the float towards zero", msg), + cast_suggestion, + Applicability::MaybeIncorrect, // lossy conversion + ); } - (&ty::Float(ref exp), &ty::Uint(ref found)) => { - // if `found` is `None` (meaning found is `usize`), don't suggest `.into()` - if exp.bit_width() > found.bit_width().unwrap_or(256) { - err.span_suggestion( - expr.span, - &format!( - "{}, producing the floating point representation of the integer", - msg, - ), - into_suggestion, - Applicability::MachineApplicable, - ); - } else if literal_is_ty_suffixed(expr) { - err.span_suggestion( - expr.span, - &lit_msg, - suffix_suggestion, - Applicability::MachineApplicable, - ); - } else { - // Missing try_into implementation for `{integer}` to `{float}` - err.span_suggestion( - expr.span, - &format!( - "{}, producing the floating point representation of the integer, + true + } + (&ty::Float(ref exp), &ty::Uint(ref found)) => { + // if `found` is `None` (meaning found is `usize`), don't suggest `.into()` + if exp.bit_width() > found.bit_width().unwrap_or(256) { + err.span_suggestion( + expr.span, + &format!( + "{}, producing the floating point representation of the integer", + msg, + ), + into_suggestion, + Applicability::MachineApplicable, + ); + } else if literal_is_ty_suffixed(expr) { + err.span_suggestion( + expr.span, + &lit_msg, + suffix_suggestion, + Applicability::MachineApplicable, + ); + } else { + // Missing try_into implementation for `{integer}` to `{float}` + err.span_suggestion( + expr.span, + &format!( + "{}, producing the floating point representation of the integer, rounded if necessary", - cast_msg, - ), - cast_suggestion, - Applicability::MaybeIncorrect, // lossy conversion - ); - } - true + cast_msg, + ), + cast_suggestion, + Applicability::MaybeIncorrect, // lossy conversion + ); } - (&ty::Float(ref exp), &ty::Int(ref found)) => { - // if `found` is `None` (meaning found is `isize`), don't suggest `.into()` - if exp.bit_width() > found.bit_width().unwrap_or(256) { - err.span_suggestion( - expr.span, - &format!( - "{}, producing the floating point representation of the integer", - &msg, - ), - into_suggestion, - Applicability::MachineApplicable, - ); - } else if literal_is_ty_suffixed(expr) { - err.span_suggestion( - expr.span, - &lit_msg, - suffix_suggestion, - Applicability::MachineApplicable, - ); - } else { - // Missing try_into implementation for `{integer}` to `{float}` - err.span_suggestion( - expr.span, - &format!( - "{}, producing the floating point representation of the integer, \ - rounded if necessary", - &msg, - ), - cast_suggestion, - Applicability::MaybeIncorrect, // lossy conversion - ); - } - true + true + } + (&ty::Float(ref exp), &ty::Int(ref found)) => { + // if `found` is `None` (meaning found is `isize`), don't suggest `.into()` + if exp.bit_width() > found.bit_width().unwrap_or(256) { + err.span_suggestion( + expr.span, + &format!( + "{}, producing the floating point representation of the integer", + &msg, + ), + into_suggestion, + Applicability::MachineApplicable, + ); + } else if literal_is_ty_suffixed(expr) { + err.span_suggestion( + expr.span, + &lit_msg, + suffix_suggestion, + Applicability::MachineApplicable, + ); + } else { + // Missing try_into implementation for `{integer}` to `{float}` + err.span_suggestion( + expr.span, + &format!( + "{}, producing the floating point representation of the integer, \ + rounded if necessary", + &msg, + ), + cast_suggestion, + Applicability::MaybeIncorrect, // lossy conversion + ); } - _ => false, + true } - } else { - false + _ => false, } } } diff --git a/src/test/ui/discrim/discrim-ill-typed.stderr b/src/test/ui/discrim/discrim-ill-typed.stderr index b0e11ee5a6e60..7b9f086151a84 100644 --- a/src/test/ui/discrim/discrim-ill-typed.stderr +++ b/src/test/ui/discrim/discrim-ill-typed.stderr @@ -3,48 +3,88 @@ error[E0308]: mismatched types | LL | OhNo = 0_u8, | ^^^^ expected `i8`, found `u8` + | +help: change the type of the numeric literal from `u8` to `i8` + | +LL | OhNo = 0_i8, + | ^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:30:16 | LL | OhNo = 0_i8, | ^^^^ expected `u8`, found `i8` + | +help: change the type of the numeric literal from `i8` to `u8` + | +LL | OhNo = 0_u8, + | ^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:43:16 | LL | OhNo = 0_u16, | ^^^^^ expected `i16`, found `u16` + | +help: change the type of the numeric literal from `u16` to `i16` + | +LL | OhNo = 0_i16, + | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:56:16 | LL | OhNo = 0_i16, | ^^^^^ expected `u16`, found `i16` + | +help: change the type of the numeric literal from `i16` to `u16` + | +LL | OhNo = 0_u16, + | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:69:16 | LL | OhNo = 0_u32, | ^^^^^ expected `i32`, found `u32` + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | OhNo = 0_i32, + | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:82:16 | LL | OhNo = 0_i32, | ^^^^^ expected `u32`, found `i32` + | +help: change the type of the numeric literal from `i32` to `u32` + | +LL | OhNo = 0_u32, + | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:95:16 | LL | OhNo = 0_u64, | ^^^^^ expected `i64`, found `u64` + | +help: change the type of the numeric literal from `u64` to `i64` + | +LL | OhNo = 0_i64, + | ^^^^^ error[E0308]: mismatched types --> $DIR/discrim-ill-typed.rs:108:16 | LL | OhNo = 0_i64, | ^^^^^ expected `u64`, found `i64` + | +help: change the type of the numeric literal from `i64` to `u64` + | +LL | OhNo = 0_u64, + | ^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/issues/issue-8761.stderr b/src/test/ui/issues/issue-8761.stderr index 6ab74a9e98940..836520a28ef34 100644 --- a/src/test/ui/issues/issue-8761.stderr +++ b/src/test/ui/issues/issue-8761.stderr @@ -3,12 +3,22 @@ error[E0308]: mismatched types | LL | A = 1i64, | ^^^^ expected `isize`, found `i64` + | +help: change the type of the numeric literal from `i64` to `isize` + | +LL | A = 1isize, + | ^^^^^^ error[E0308]: mismatched types --> $DIR/issue-8761.rs:5:9 | LL | B = 2u8 | ^^^ expected `isize`, found `u8` + | +help: change the type of the numeric literal from `u8` to `isize` + | +LL | B = 2isize + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/numeric/const-scope.stderr b/src/test/ui/numeric/const-scope.stderr index 6e1990e3a7222..d7f18e19b41bd 100644 --- a/src/test/ui/numeric/const-scope.stderr +++ b/src/test/ui/numeric/const-scope.stderr @@ -3,6 +3,11 @@ error[E0308]: mismatched types | LL | const C: i32 = 1i8; | ^^^ expected `i32`, found `i8` + | +help: change the type of the numeric literal from `i8` to `i32` + | +LL | const C: i32 = 1i32; + | ^^^^ error[E0308]: mismatched types --> $DIR/const-scope.rs:2:15 @@ -17,6 +22,11 @@ LL | let c: i32 = 1i8; | --- ^^^ expected `i32`, found `i8` | | | expected due to this + | +help: change the type of the numeric literal from `i8` to `i32` + | +LL | let c: i32 = 1i32; + | ^^^^ error[E0308]: mismatched types --> $DIR/const-scope.rs:6:17 diff --git a/src/test/ui/repeat_count.rs b/src/test/ui/repeat_count.rs index aca7af144a934..7e30491f0bdbc 100644 --- a/src/test/ui/repeat_count.rs +++ b/src/test/ui/repeat_count.rs @@ -22,6 +22,9 @@ fn main() { let f = [0_usize; -1_isize]; //~^ ERROR mismatched types //~| expected `usize`, found `isize` + let f = [0; 4u8]; + //~^ ERROR mismatched types + //~| expected `usize`, found `u8` struct G { g: (), } diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 963319892d4ca..6a081e23d9d37 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -29,7 +29,7 @@ LL | let e = [0; "foo"]; | ^^^^^ expected `usize`, found `&str` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:28:17 + --> $DIR/repeat_count.rs:31:17 | LL | let g = [0; G { g: () }]; | ^^^^^^^^^^^ expected `usize`, found struct `main::G` @@ -46,7 +46,18 @@ error[E0308]: mismatched types LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` -error: aborting due to 8 previous errors +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:25:17 + | +LL | let f = [0; 4u8]; + | ^^^ expected `usize`, found `u8` + | +help: change the type of the numeric literal from `u8` to `usize` + | +LL | let f = [0; 4usize]; + | ^^^^^^ + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0435. For more information about an error, try `rustc --explain E0308`. From 6da17d244b08e5f14edd1645fbd07d1f042d00b7 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 20 May 2020 20:10:04 +0200 Subject: [PATCH 03/25] `is_const_context` -> `is_inside_const_context` --- src/librustc_middle/hir/map/mod.rs | 2 +- src/librustc_typeck/check/demand.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index c5f0acb3f0709..a5b388f410ddf 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -586,7 +586,7 @@ impl<'hir> Map<'hir> { /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. /// Used exclusively for diagnostics, to avoid suggestion function calls. - pub fn is_const_context(&self, hir_id: HirId) -> bool { + pub fn is_inside_const_context(&self, hir_id: HirId) -> bool { self.body_const_context(self.local_def_id(self.enclosing_body_owner(hir_id))).is_some() } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 6e93f2273ab86..44d7be4124f5d 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -800,12 +800,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::Lit(lit) = &expr.kind { lit.node.is_suffixed() } else { false } }; - let is_const_context = self.tcx.hir().is_const_context(expr.hir_id); + let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id); let suggest_to_change_suffix_or_into = |err: &mut DiagnosticBuilder<'_>, is_fallible: bool| { let msg = if literal_is_ty_suffixed(expr) { &lit_msg - } else if is_const_context { + } else if in_const_context { // Do not recommend `into` or `try_into` in const contexts. return; } else if is_fallible { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d72c74e4188ee..69252046ad1bb 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5097,7 +5097,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, ) { - if self.tcx.hir().is_const_context(expr.hir_id) { + if self.tcx.hir().is_inside_const_context(expr.hir_id) { // Do not suggest `Box::new` in const context. return; } @@ -5134,7 +5134,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { // Handle #68197. - if self.tcx.hir().is_const_context(expr.hir_id) { + if self.tcx.hir().is_inside_const_context(expr.hir_id) { // Do not suggest `Box::new` in const context. return false; } From c183c3f4d167121fb6dc5bff7587647217a2ec75 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Jun 2020 13:03:50 +0200 Subject: [PATCH 04/25] Clean up E0642 explanation --- src/librustc_error_codes/error_codes/E0642.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0642.md b/src/librustc_error_codes/error_codes/E0642.md index 592ada6ecadc7..c790aa154bde9 100644 --- a/src/librustc_error_codes/error_codes/E0642.md +++ b/src/librustc_error_codes/error_codes/E0642.md @@ -1,6 +1,6 @@ Trait methods currently cannot take patterns as arguments. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0642 trait Foo { From 2650c5fc6c8aac7f802b05490d0755cfda7f85cc Mon Sep 17 00:00:00 2001 From: Sean Wilson Date: Sat, 6 Jun 2020 17:20:06 -0700 Subject: [PATCH 05/25] doc/rustdoc: Fix incorrect external_doc feature flag --- src/doc/rustdoc/src/documentation-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index efadae1c5fb9d..18010bebcf0e7 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -416,7 +416,7 @@ without including it in your main documentation. For example, you could write th `lib.rs` to test your README as part of your doctests: ```rust,ignore -#![feature(extern_doc)] +#![feature(external_doc)] #[doc(include="../README.md")] #[cfg(doctest)] From bd949ed3568c2f3e06a936a492e3cd3a4267a63e Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 11:25:23 +0100 Subject: [PATCH 06/25] Check associated opaque types in check_opaque_types --- .../type_check/free_region_relations.rs | 8 ++++++- src/librustc_typeck/check/wfcheck.rs | 23 ++++++++++++------- .../impl-with-unconstrained-param.rs | 18 +++++++++++++++ .../impl-with-unconstrained-param.stderr | 15 ++++++++++++ .../ui/type-alias-impl-trait/issue-60564.rs | 7 ++---- .../type-alias-impl-trait/issue-60564.stderr | 14 +---------- 6 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs create mode 100644 src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index f97dff146450c..5707127340d87 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -259,7 +259,13 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .param_env .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) - .unwrap_or_else(|_| bug!("failed to normalize {:?}", ty)); + .unwrap_or_else(|_| { + self.infcx + .tcx + .sess + .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); + (self.infcx.tcx.types.err, None) + }); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); constraints1.into_iter().chain(constraints2) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7d9bf975c6913..8a83952c4fc7f 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -806,7 +806,11 @@ fn check_where_clauses<'tcx, 'fcx>( let mut predicates = predicates.instantiate_identity(fcx.tcx); - if let Some((return_ty, span)) = return_ty { + if let Some((mut return_ty, span)) = return_ty { + if return_ty.has_infer_types_or_consts() { + fcx.select_obligations_where_possible(false, |_| {}); + return_ty = fcx.resolve_vars_if_possible(&return_ty); + } let opaque_types = check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); for _ in 0..opaque_types.len() { predicates.spans.push(span); @@ -893,10 +897,16 @@ fn check_opaque_types<'fcx, 'tcx>( trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs); let generics = tcx.generics_of(def_id); // Only check named `impl Trait` types defined in this crate. - // FIXME(eddyb) is `generics.parent.is_none()` correct? It seems - // potentially risky wrt associated types in `impl`s. - if generics.parent.is_none() && def_id.is_local() { + if !def_id.is_local() { + return ty; + } let opaque_hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) = + tcx.hir().expect_item(opaque_hir_id).kind + { + // Don't check return position impl trait. + return ty; + } if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { trace!("check_opaque_types: may define, generics={:#?}", generics); let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); @@ -924,9 +934,7 @@ fn check_opaque_types<'fcx, 'tcx>( true } - GenericArgKind::Const(ct) => { - matches!(ct.val, ty::ConstKind::Param(_)) - } + GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)), }; if arg_is_param { @@ -988,7 +996,6 @@ fn check_opaque_types<'fcx, 'tcx>( substituted_predicates.push(substituted_pred); } } - } // if is_named_opaque_type } // if let Opaque ty }, diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs new file mode 100644 index 0000000000000..bc6543a9229db --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -0,0 +1,18 @@ +// Ensure that we don't ICE if associated type impl trait is used in an impl +// with an unconstrained type parameter. + +#![feature(type_alias_impl_trait)] + +trait X { + type I; + fn f() -> Self::I; +} + +impl X for () { + type I = impl Sized; + //~^ ERROR could not find defining uses + fn f() -> Self::I {} + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr new file mode 100644 index 0000000000000..e8b677113dba7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/impl-with-unconstrained-param.rs:14:23 + | +LL | fn f() -> Self::I {} + | ^^ cannot infer type for type parameter `T` + +error: could not find defining uses + --> $DIR/impl-with-unconstrained-param.rs:12:14 + | +LL | type I = impl Sized; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 4eb7f7836d869..78def0d1136de 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -17,11 +17,8 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ ERROR non-defining opaque type use in defining scope - //~| ERROR non-defining opaque type use in defining scope - (0u8..n) - .rev() - .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + //~^ ERROR non-defining opaque type use in defining scope + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) } } diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index 55984609437b0..66fa862ef9d7a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,15 +1,3 @@ -error: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:19:34 - | -LL | fn iter_bits(self, n: u8) -> Self::BitsIter { - | ^^^^^^^^^^^^^^ - | -note: used non-generic type `_` for generic parameter - --> $DIR/issue-60564.rs:8:22 - | -LL | type IterBitsIter = impl std::iter::Iterator; - | ^ - error: non-defining opaque type use in defining scope --> $DIR/issue-60564.rs:19:34 | @@ -22,5 +10,5 @@ note: used non-generic type `u8` for generic parameter LL | type IterBitsIter = impl std::iter::Iterator; | ^ -error: aborting due to 2 previous errors +error: aborting due to previous error From 627b4697b74405f9027500f48ba489df69eb9968 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 12:06:01 +0100 Subject: [PATCH 07/25] Make pretty printing `TyKind::Def` do something --- src/librustc_hir_pretty/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index e642915b86a5e..c1b6857038798 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -385,7 +385,7 @@ impl<'a> State<'a> { &f.param_names[..], ); } - hir::TyKind::Def(..) => {} + hir::TyKind::Def(..) => self.s.word("/*impl Trait*/"), hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false), hir::TyKind::TraitObject(bounds, ref lifetime) => { let mut first = true; From 973e5726411756c4b9cff20ab9a6bb99f24e17f8 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 11:57:58 +0100 Subject: [PATCH 08/25] Stop special casing top level TAIT --- src/librustc_ast/ast.rs | 9 - src/librustc_ast_lowering/item.rs | 56 ++--- src/librustc_ast_lowering/lib.rs | 9 +- src/librustc_lint/builtin.rs | 4 + src/librustc_middle/hir/map/mod.rs | 8 +- src/librustc_passes/layout_test.rs | 7 +- src/librustc_resolve/build_reduced_graph.rs | 11 +- src/librustc_resolve/late/lifetimes.rs | 29 +-- src/librustc_trait_selection/opaque_types.rs | 69 +++--- src/librustc_typeck/astconv.rs | 22 +- src/librustc_typeck/check/writeback.rs | 2 +- src/librustc_typeck/collect.rs | 17 +- .../ui/associated-type-bounds/duplicate.rs | 6 - .../associated-type-bounds/duplicate.stderr | 198 +++++++----------- .../feature-gate-type_alias_impl_trait.rs | 24 ++- .../feature-gate-type_alias_impl_trait.stderr | 70 ++----- src/test/ui/impl-trait/auto-trait.rs | 14 +- src/test/ui/impl-trait/auto-trait.stderr | 8 +- src/test/ui/impl-trait/issue-55872-1.stderr | 8 +- src/test/ui/impl-trait/issue-55872-2.stderr | 4 +- src/test/ui/impl-trait/negative-reasoning.rs | 15 +- .../ui/impl-trait/negative-reasoning.stderr | 10 +- src/test/ui/impl-trait/where-allowed.stderr | 12 +- src/test/ui/issues/issue-60662.stdout | 2 +- .../inline-trait-and-foreign-items.stderr | 4 +- src/test/ui/lint/opaque-ty-ffi-unsafe.rs | 3 +- src/test/ui/lint/opaque-ty-ffi-unsafe.stderr | 6 +- .../ui/privacy/private-in-public-assoc-ty.rs | 9 +- .../privacy/private-in-public-assoc-ty.stderr | 25 +-- src/test/ui/save-analysis/issue-68621.stderr | 4 +- .../bound_reduction2.stderr | 4 +- .../declared_but_never_defined.stderr | 4 +- .../declared_but_not_defined_in_scope.stderr | 4 +- ...eric_type_does_not_live_long_enough.stderr | 8 +- .../generic_underconstrained.stderr | 4 +- .../generic_underconstrained2.stderr | 8 +- .../issue-57611-trait-alias.stderr | 8 +- .../type-alias-impl-trait/issue-60371.stderr | 8 +- .../type-alias-impl-trait/issue-63279.stderr | 6 +- .../never_reveal_concrete_type.stderr | 6 +- .../no_inferrable_concrete_type.stderr | 4 +- ...o_revealing_outside_defining_module.stderr | 10 +- ...e-alias-impl-trait-with-cycle-error.stderr | 4 +- ...-alias-impl-trait-with-cycle-error2.stderr | 4 +- 44 files changed, 323 insertions(+), 424 deletions(-) diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index efcf95ec706b8..d08b92aadd91f 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -1849,15 +1849,6 @@ impl TyKind { pub fn is_unit(&self) -> bool { if let TyKind::Tup(ref tys) = *self { tys.is_empty() } else { false } } - - /// HACK(type_alias_impl_trait, Centril): A temporary crutch used - /// in lowering to avoid making larger changes there and beyond. - pub fn opaque_top_hack(&self) -> Option<&GenericBounds> { - match self { - Self::ImplTrait(_, bounds) => Some(bounds), - _ => None, - } - } } /// Syntax used to declare a trait object. diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 47d10f86d03e2..f8a5120b72a18 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -1,5 +1,5 @@ use super::{AnonymousLifetimeMode, LoweringContext, ParamMode}; -use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor}; +use super::{ImplTraitContext, ImplTraitPosition}; use crate::Arena; use rustc_ast::ast::*; @@ -165,13 +165,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::MacroDef(..) => SmallVec::new(), ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id], - ItemKind::Static(ref ty, ..) | ItemKind::Const(_, ref ty, ..) => { - let mut ids = smallvec![i.id]; - if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitTypeIdVisitor { ids: &mut ids }.visit_ty(ty); - } - ids - } _ => smallvec![i.id], }; @@ -292,23 +285,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)), ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)), ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)), - ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => match ty.kind.opaque_top_hack() { - None => { - let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); - let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); - hir::ItemKind::TyAlias(ty, generics) - } - Some(bounds) => { - let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc); - let ty = hir::OpaqueTy { - generics: self.lower_generics(gen, ctx()), - bounds: self.lower_param_bounds(bounds, ctx()), - impl_trait_fn: None, - origin: hir::OpaqueTyOrigin::TypeAlias, - }; - hir::ItemKind::OpaqueTy(ty) - } - }, + ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => { + let ty = + self.lower_ty(ty, ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)); + let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); + hir::ItemKind::TyAlias(ty, generics) + } ItemKind::TyAlias(_, ref generics, _, None) => { let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err)); let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); @@ -844,16 +826,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err)); hir::ImplItemKind::TyAlias(ty) } - Some(ty) => match ty.kind.opaque_top_hack() { - None => { - let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); - hir::ImplItemKind::TyAlias(ty) - } - Some(bs) => { - let bs = self.lower_param_bounds(bs, ImplTraitContext::disallowed()); - hir::ImplItemKind::OpaqueTy(bs) - } - }, + Some(ty) => { + let ty = self.lower_ty( + ty, + ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc), + ); + hir::ImplItemKind::TyAlias(ty) + } }; (generics, kind) } @@ -887,12 +866,7 @@ impl<'hir> LoweringContext<'_, 'hir> { defaultness, kind: match &i.kind { AssocItemKind::Const(..) => hir::AssocItemKind::Const, - AssocItemKind::TyAlias(.., ty) => { - match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { - None => hir::AssocItemKind::Type, - Some(_) => hir::AssocItemKind::OpaqueTy, - } - } + AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type, AssocItemKind::Fn(_, sig, ..) => { hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 1f8c68f75e943..0154e10112b49 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1371,8 +1371,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds); - let (lifetimes, lifetime_defs) = - self.lifetimes_from_impl_trait_bounds(opaque_ty_node_id, opaque_ty_def_id, &hir_bounds); + let (lifetimes, lifetime_defs): (&[_], &[_]) = if fn_def_id.is_some() { + self.lifetimes_from_impl_trait_bounds(opaque_ty_node_id, opaque_ty_def_id, &hir_bounds) + } else { + // Non return-position impl trait captures all of the lifetimes of + // the parent item. + (&[], &[]) + }; debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes,); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e17e8b7b9640e..e9f5956a41692 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1102,6 +1102,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { hir::ItemKind::TyAlias(ref ty, ref generics) => (&*ty, generics), _ => return, }; + if let hir::TyKind::Def(..) = ty.kind { + // Bounds are respected for `type X = impl Trait` + return; + } let mut suggested_changing_assoc_types = false; // There must not be a where clause if !type_alias_generics.where_clause.predicates.is_empty() { diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index 53e88787323f4..5281c51a8b811 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -672,6 +672,8 @@ impl<'hir> Map<'hir> { if let Node::Item(Item { kind: ItemKind::Fn(..) + | ItemKind::Const(..) + | ItemKind::Static(..) | ItemKind::Mod(..) | ItemKind::Enum(..) | ItemKind::Struct(..) @@ -700,11 +702,7 @@ impl<'hir> Map<'hir> { return CRATE_HIR_ID; } match self.get(scope) { - Node::Item(Item { - kind: ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }), - .. - }) - | Node::Block(_) => {} + Node::Block(_) => {} _ => break, } } diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index c0826f8cc605f..2419e6965968e 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -27,8 +27,7 @@ impl ItemLikeVisitor<'tcx> for LayoutTest<'tcx> { ItemKind::TyAlias(..) | ItemKind::Enum(..) | ItemKind::Struct(..) - | ItemKind::Union(..) - | ItemKind::OpaqueTy(..) => { + | ItemKind::Union(..) => { for attr in self.tcx.get_attrs(item_def_id.to_def_id()).iter() { if attr.check_name(sym::rustc_layout) { self.dump_layout_of(item_def_id, item, attr); @@ -83,9 +82,11 @@ impl LayoutTest<'tcx> { } sym::debug => { + let normalized_ty = + self.tcx.normalize_erasing_regions(param_env.with_reveal_all(), ty); self.tcx.sess.span_err( item.span, - &format!("layout_of({:?}) = {:#?}", ty, *ty_layout), + &format!("layout_of({:?}) = {:#?}", normalized_ty, *ty_layout), ); } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 9ee3d989bf3f1..c4ceb50018aac 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -740,12 +740,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // These items live in the type namespace. - ItemKind::TyAlias(_, _, _, ref ty) => { - let def_kind = match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { - None => DefKind::TyAlias, - Some(_) => DefKind::OpaqueTy, - }; - let res = Res::Def(def_kind, self.r.definitions.local_def_id(item.id).to_def_id()); + ItemKind::TyAlias(..) => { + let res = Res::Def( + DefKind::TyAlias, + self.r.definitions.local_def_id(item.id).to_def_id(), + ); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index a3fbb28f22a56..02193dcec901e 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -396,15 +396,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE }; self.with(scope, |_, this| intravisit::walk_item(this, item)); } - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => { - // Currently opaque type declarations are just generated from `impl Trait` - // items. Doing anything on this node is irrelevant, as we currently don't need - // it. + hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { + // Opaque types are visited when we visit the `TyKind::Def`, so + // that they have the lifetimes from their parent opaque_ty in + // scope. } hir::ItemKind::TyAlias(_, ref generics) - | hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: None, ref generics, .. - }) | hir::ItemKind::Enum(_, ref generics) | hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Union(_, ref generics) @@ -563,17 +560,22 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // `type MyAnonTy<'b> = impl MyTrait<'b>;` // ^ ^ this gets resolved in the scope of // the opaque_ty generics - let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).kind { + let opaque_ty = self.tcx.hir().expect_item(item_id.id); + let (generics, bounds) = match opaque_ty.kind { // Named opaque `impl Trait` types are reached via `TyKind::Path`. // This arm is for `impl Trait` in the types of statics, constants and locals. hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { intravisit::walk_ty(self, ty); + intravisit::walk_item(this, opaque_ty); return; } // RPIT (return position impl trait) - hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, bounds, .. }) => { - (generics, bounds) - } + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + impl_trait_fn: Some(_), + ref generics, + bounds, + .. + }) => (generics, bounds), ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), }; @@ -2667,8 +2669,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // going to make a fresh name, so we cannot // necessarily replace a single-use lifetime with // `'_`. - Scope::Elision { elide: Elide::Exact(_), .. } => break false, - Scope::Elision { elide: Elide::Error(_), .. } => break false, + Scope::Elision { + elide: Elide::Exact(_) | Elide::Error(_) | Elide::Forbid, .. + } => break false, Scope::ObjectLifetimeDefault { s, .. } => scope = s, } diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index 19caf64c63f1e..51b1db390b927 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -133,9 +133,9 @@ pub trait InferCtxtExt<'tcx> { fn generate_member_constraint( &self, concrete_ty: Ty<'tcx>, - opaque_type_generics: &ty::Generics, opaque_defn: &OpaqueTypeDecl<'tcx>, opaque_type_def_id: DefId, + first_own_region_index: usize, ); /*private*/ @@ -405,7 +405,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); - let opaque_type_generics = tcx.generics_of(def_id); + let first_own_region = match opaque_defn.origin { + hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { + // For these opaque types, only the item's own lifetime + // parameters are considered. + tcx.generics_of(def_id).parent_count + } + // These opaque type inherit all lifetime parameters from their + // parent. + hir::OpaqueTyOrigin::Misc => 0, + }; let span = tcx.def_span(def_id); @@ -427,12 +436,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); } if let GenerateMemberConstraints::IfNoStaticBound = mode { - self.generate_member_constraint( - concrete_ty, - opaque_type_generics, - opaque_defn, - def_id, - ); + self.generate_member_constraint(concrete_ty, opaque_defn, def_id, first_own_region); } return; } @@ -445,29 +449,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // `['a]` for the first impl trait and `'b` for the // second. let mut least_region = None; - for param in &opaque_type_generics.params { - match param.kind { - GenericParamDefKind::Lifetime => {} - _ => continue, - } - // Get the value supplied for this region from the substs. - let subst_arg = opaque_defn.substs.region_at(param.index as usize); + for subst_arg in &opaque_defn.substs[first_own_region..] { + let subst_region = match subst_arg.unpack() { + GenericArgKind::Lifetime(r) => r, + GenericArgKind::Type(_) | GenericArgKind::Const(_) => continue, + }; // Compute the least upper bound of it with the other regions. debug!("constrain_opaque_types: least_region={:?}", least_region); - debug!("constrain_opaque_types: subst_arg={:?}", subst_arg); + debug!("constrain_opaque_types: subst_region={:?}", subst_region); match least_region { - None => least_region = Some(subst_arg), + None => least_region = Some(subst_region), Some(lr) => { - if free_region_relations.sub_free_regions(self.tcx, lr, subst_arg) { + if free_region_relations.sub_free_regions(self.tcx, lr, subst_region) { // keep the current least region - } else if free_region_relations.sub_free_regions(self.tcx, subst_arg, lr) { - // switch to `subst_arg` - least_region = Some(subst_arg); + } else if free_region_relations.sub_free_regions(self.tcx, subst_region, lr) { + // switch to `subst_region` + least_region = Some(subst_region); } else { // There are two regions (`lr` and - // `subst_arg`) which are not relatable. We + // `subst_region`) which are not relatable. We // can't find a best choice. Therefore, // instead of creating a single bound like // `'r: 'a` (which is our preferred choice), @@ -476,13 +478,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // regions that appear in the impl trait. // For now, enforce a feature gate outside of async functions. - self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_arg); + self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_region); return self.generate_member_constraint( concrete_ty, - opaque_type_generics, opaque_defn, def_id, + first_own_region, ); } } @@ -494,12 +496,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let GenerateMemberConstraints::IfNoStaticBound = mode { if least_region != tcx.lifetimes.re_static { - self.generate_member_constraint( - concrete_ty, - opaque_type_generics, - opaque_defn, - def_id, - ); + self.generate_member_constraint(concrete_ty, opaque_defn, def_id, first_own_region); } } concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { @@ -518,22 +515,20 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn generate_member_constraint( &self, concrete_ty: Ty<'tcx>, - opaque_type_generics: &ty::Generics, opaque_defn: &OpaqueTypeDecl<'tcx>, opaque_type_def_id: DefId, + first_own_region: usize, ) { // Create the set of choice regions: each region in the hidden // type can be equal to any of the region parameters of the // opaque type definition. let choice_regions: Lrc>> = Lrc::new( - opaque_type_generics - .params + opaque_defn.substs[first_own_region..] .iter() - .filter(|param| match param.kind { - GenericParamDefKind::Lifetime => true, - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => false, + .filter_map(|arg| match arg.unpack() { + GenericArgKind::Lifetime(r) => Some(r), + GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, }) - .map(|param| opaque_defn.substs.region_at(param.index as usize)) .chain(std::iter::once(self.tcx.lifetimes.re_static)) .collect(), ); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f1dc7e5390629..24e38cc42ef6c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2839,8 +2839,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.res_to_ty(opt_self_ty, path, false) } hir::TyKind::Def(item_id, ref lifetimes) => { - let did = tcx.hir().local_def_id(item_id.id); - self.impl_trait_ty_to_ty(did.to_def_id(), lifetimes) + let opaque_ty = tcx.hir().expect_item(item_id.id); + let def_id = tcx.hir().local_def_id(item_id.id).to_def_id(); + + match opaque_ty.kind { + // RPIT (return position impl trait) + // Only lifetimes mentioned in the impl Trait predicate are + // captured by the opaque type, so the lifetime parameters + // from the parent item need to be replaced with `'static`. + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => { + self.impl_trait_ty_to_ty(def_id, lifetimes) + } + // This arm is for `impl Trait` in the types of statics, + // constants, locals and type aliases. These capture all + // parent lifetimes, so they can use their identity subst. + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { + let substs = InternalSubsts::identity_for_item(tcx, def_id); + tcx.mk_opaque(def_id, substs) + } + ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), + } } hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 3473dc7a58d04..159d3d7a538a6 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -460,7 +460,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let mut skip_add = false; if let ty::Opaque(defin_ty_def_id, _substs) = definition_ty.kind { - if let hir::OpaqueTyOrigin::TypeAlias = opaque_defn.origin { + if let hir::OpaqueTyOrigin::Misc = opaque_defn.origin { if def_id == defin_ty_def_id { debug!( "skipping adding concrete definition for opaque type {:?} {:?}", diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 355b4fc413f42..7038caf4367e6 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1202,22 +1202,11 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { impl_trait_fn.or_else(|| { let parent_id = tcx.hir().get_parent_item(hir_id); - if parent_id != hir_id && parent_id != CRATE_HIR_ID { + assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID); debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); - // If this 'impl Trait' is nested inside another 'impl Trait' - // (e.g. `impl Foo>`), we need to use the 'parent' - // 'impl Trait' for its generic parameters, since we can reference them - // from the 'child' 'impl Trait' - if let Node::Item(hir::Item { kind: ItemKind::OpaqueTy(..), .. }) = - tcx.hir().get(parent_id) - { + // Opaque types are always nested within another item, and + // inherit the generics of the item. Some(tcx.hir().local_def_id(parent_id).to_def_id()) - } else { - None - } - } else { - None - } }) } _ => None, diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index 8b396f23efd54..8b5c5219430b6 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -108,18 +108,12 @@ type TAW3 where T: Iterator = T; type ETAI1> = impl Copy; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses -//~| ERROR could not find defining uses -//~| ERROR could not find defining uses type ETAI2> = impl Copy; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses -//~| ERROR could not find defining uses -//~| ERROR could not find defining uses type ETAI3> = impl Copy; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses -//~| ERROR could not find defining uses -//~| ERROR could not find defining uses type ETAI4 = impl Iterator; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index 71f6e4ff8b62d..712211e60cbac 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -223,30 +223,6 @@ LL | fn FAPIT3(_: impl Iterator) {} | | | `Item` bound here first -error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:62:42 - | -LL | fn FRPIT1() -> impl Iterator { iter::empty() } - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:64:42 - | -LL | fn FRPIT2() -> impl Iterator { iter::empty() } - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:66:45 - | -LL | fn FRPIT3() -> impl Iterator { iter::empty() } - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:75:39 | @@ -367,12 +343,6 @@ LL | type TAW3 where T: Iterator = T; | | | `Item` bound here first -error: could not find defining uses - --> $DIR/duplicate.rs:108:1 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:108:36 | @@ -381,14 +351,38 @@ LL | type ETAI1> = impl Copy; | | | `Item` bound here first +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:62:42 + | +LL | fn FRPIT1() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:64:42 + | +LL | fn FRPIT2() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:66:45 + | +LL | fn FRPIT3() -> impl Iterator { iter::empty() } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + error: could not find defining uses - --> $DIR/duplicate.rs:113:1 + --> $DIR/duplicate.rs:108:51 | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI1> = impl Copy; + | ^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:113:36 + --> $DIR/duplicate.rs:111:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -396,13 +390,13 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:118:1 + --> $DIR/duplicate.rs:111:51 | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI2> = impl Copy; + | ^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:118:39 + --> $DIR/duplicate.rs:114:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -410,13 +404,19 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:123:1 + --> $DIR/duplicate.rs:114:57 + | +LL | type ETAI3> = impl Copy; + | ^^^^^^^^^ + +error: could not find defining uses + --> $DIR/duplicate.rs:117:14 | LL | type ETAI4 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:123:40 + --> $DIR/duplicate.rs:117:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -424,13 +424,13 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:128:1 + --> $DIR/duplicate.rs:122:14 | LL | type ETAI5 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:128:40 + --> $DIR/duplicate.rs:122:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -438,13 +438,13 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:133:1 + --> $DIR/duplicate.rs:127:14 | LL | type ETAI6 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:133:43 + --> $DIR/duplicate.rs:127:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -452,7 +452,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:139:36 + --> $DIR/duplicate.rs:133:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -460,7 +460,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:141:36 + --> $DIR/duplicate.rs:135:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -468,7 +468,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:143:39 + --> $DIR/duplicate.rs:137:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -476,7 +476,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:145:34 + --> $DIR/duplicate.rs:139:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -484,7 +484,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:147:34 + --> $DIR/duplicate.rs:141:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -492,7 +492,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:149:37 + --> $DIR/duplicate.rs:143:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -500,7 +500,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:151:45 + --> $DIR/duplicate.rs:145:45 | LL | trait TRW1 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -508,7 +508,7 @@ LL | trait TRW1 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:153:45 + --> $DIR/duplicate.rs:147:45 | LL | trait TRW2 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -516,7 +516,7 @@ LL | trait TRW2 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:155:48 + --> $DIR/duplicate.rs:149:48 | LL | trait TRW3 where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -524,7 +524,7 @@ LL | trait TRW3 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:157:46 + --> $DIR/duplicate.rs:151:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -532,7 +532,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:157:46 + --> $DIR/duplicate.rs:151:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -540,7 +540,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:160:46 + --> $DIR/duplicate.rs:154:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -548,7 +548,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:160:46 + --> $DIR/duplicate.rs:154:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -556,7 +556,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:163:49 + --> $DIR/duplicate.rs:157:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -564,7 +564,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:163:49 + --> $DIR/duplicate.rs:157:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -572,7 +572,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:166:43 + --> $DIR/duplicate.rs:160:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -580,7 +580,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:168:43 + --> $DIR/duplicate.rs:162:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -588,7 +588,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:170:46 + --> $DIR/duplicate.rs:164:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -596,7 +596,7 @@ LL | trait TRA3 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:173:40 + --> $DIR/duplicate.rs:167:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -604,7 +604,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:177:44 + --> $DIR/duplicate.rs:171:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -612,7 +612,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:181:43 + --> $DIR/duplicate.rs:175:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -620,113 +620,77 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:108:24 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:108:36 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:113:24 - | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:113:36 - | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:118:24 - | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:118:39 - | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:123:28 + --> $DIR/duplicate.rs:117:28 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:123:40 + --> $DIR/duplicate.rs:117:40 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:128:28 + --> $DIR/duplicate.rs:122:28 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:128:40 + --> $DIR/duplicate.rs:122:40 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:133:28 + --> $DIR/duplicate.rs:127:28 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:133:43 + --> $DIR/duplicate.rs:127:43 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:173:28 + --> $DIR/duplicate.rs:167:28 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:173:40 + --> $DIR/duplicate.rs:167:40 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:177:32 + --> $DIR/duplicate.rs:171:32 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:177:44 + --> $DIR/duplicate.rs:171:44 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:181:28 + --> $DIR/duplicate.rs:175:28 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:181:43 + --> $DIR/duplicate.rs:175:43 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ -error: aborting due to 96 previous errors; 1 warning emitted +error: aborting due to 90 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 6088331cded77..3b6c9791722bb 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -9,10 +9,14 @@ trait Bar { impl Bar for () { type Baa = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable - fn define() -> Self::Baa { 0 } + fn define() -> Self::Baa { + 0 + } } -fn define() -> Foo { 0 } +fn define() -> Foo { + 0 +} trait TraitWithDefault { type Assoc = impl Debug; @@ -26,20 +30,20 @@ type NestedFree = (Vec, impl Debug, impl Iterator //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable -//~| ERROR `impl Trait` not allowed outside of function -//~| ERROR `impl Trait` not allowed outside of function -//~| ERROR `impl Trait` not allowed outside of function + +fn define_multiple() -> NestedFree { + (vec![true], 0u8, 0i32..1) +} impl Bar for u8 { - type Baa = (Vec, impl Debug, impl Iterator); + type Baa = (Vec, impl Debug, impl Iterator + Debug); //~^ ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable - //~| ERROR `impl Trait` not allowed outside of function - //~| ERROR `impl Trait` not allowed outside of function - //~| ERROR `impl Trait` not allowed outside of function - fn define() -> Self::Baa { (vec![true], 0u8, 0i32..1) } + fn define() -> Self::Baa { + (vec![true], 0u8, 0i32..1) + } } fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr index 55cd2984ab665..8bab0d0c4a95c 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -17,7 +17,7 @@ LL | type Baa = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: associated type defaults are unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:18:5 + --> $DIR/feature-gate-type_alias_impl_trait.rs:22:5 | LL | type Assoc = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Assoc = impl Debug; = help: add `#![feature(associated_type_defaults)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:18:18 + --> $DIR/feature-gate-type_alias_impl_trait.rs:22:18 | LL | type Assoc = impl Debug; | ^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type Assoc = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:24 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:24 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:24:37 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:37 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^ @@ -53,7 +53,7 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:24:49 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:49 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:24:70 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:70 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^ @@ -71,84 +71,48 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:34:21 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:21 | -LL | type Baa = (Vec, impl Debug, impl Iterator); +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); | ^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:34 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:34 | -LL | type Baa = (Vec, impl Debug, impl Iterator); +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); | ^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:46 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:46 | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:67 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:67 | -LL | type Baa = (Vec, impl Debug, impl Iterator); +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); | ^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:18:18 + --> $DIR/feature-gate-type_alias_impl_trait.rs:22:18 | LL | type Assoc = impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:24 - | -LL | type NestedFree = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:37 - | -LL | type NestedFree = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:49 - | -LL | type NestedFree = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:21 - | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:34 - | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:46 - | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 19 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0562, E0658. For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/impl-trait/auto-trait.rs b/src/test/ui/impl-trait/auto-trait.rs index c767578120883..cf2773f4ef59d 100644 --- a/src/test/ui/impl-trait/auto-trait.rs +++ b/src/test/ui/impl-trait/auto-trait.rs @@ -2,22 +2,24 @@ // the purposes of coherence checking #![feature(type_alias_impl_trait)] -trait OpaqueTrait { } -impl OpaqueTrait for T { } +trait OpaqueTrait {} +impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; -fn mk_opaque() -> OpaqueType { () } +fn mk_opaque() -> OpaqueType { + () +} #[derive(Debug)] struct D(T); -trait AnotherTrait { } -impl AnotherTrait for T { } +trait AnotherTrait {} +impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Send`. // (We treat opaque types as "foreign types" that could grow more impls // in the future.) impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` } fn main() {} diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr index 5e72ca7a47ba1..16fe1b56b50c6 100644 --- a/src/test/ui/impl-trait/auto-trait.stderr +++ b/src/test/ui/impl-trait/auto-trait.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: - --> $DIR/auto-trait.rs:19:1 +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: + --> $DIR/auto-trait.rs:21:1 | -LL | impl AnotherTrait for T { } +LL | impl AnotherTrait for T {} | -------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr index 6cb2c9fb892f3..5131509cdf03e 100644 --- a/src/test/ui/impl-trait/issue-55872-1.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:12:5 + --> $DIR/issue-55872-1.rs:12:14 | LL | type E = impl Copy; - | ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S` + | ^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S` | = note: required because it appears within the type `(S, T)` = note: the return type of a function must have a statically known size @@ -12,10 +12,10 @@ LL | impl Bar for S { | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:12:5 + --> $DIR/issue-55872-1.rs:12:14 | LL | type E = impl Copy; - | ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T` + | ^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T` | = note: required because it appears within the type `(S, T)` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 01371b4d5c61f..649109e4c9324 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied - --> $DIR/issue-55872-2.rs:13:5 + --> $DIR/issue-55872-2.rs:13:14 | LL | type E = impl Copy; - | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` + | ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/impl-trait/negative-reasoning.rs b/src/test/ui/impl-trait/negative-reasoning.rs index 4977f9bdbacd9..d173fe83fb791 100644 --- a/src/test/ui/impl-trait/negative-reasoning.rs +++ b/src/test/ui/impl-trait/negative-reasoning.rs @@ -2,21 +2,22 @@ // other trait #![feature(type_alias_impl_trait)] -trait OpaqueTrait { } -impl OpaqueTrait for T { } +trait OpaqueTrait {} +impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; -fn mk_opaque() -> OpaqueType { () } +fn mk_opaque() -> OpaqueType { + () +} #[derive(Debug)] struct D(T); -trait AnotherTrait { } -impl AnotherTrait for T { } - +trait AnotherTrait {} +impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Debug` impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` } fn main() {} diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr index 526a664726ac2..e43d8c857b257 100644 --- a/src/test/ui/impl-trait/negative-reasoning.stderr +++ b/src/test/ui/impl-trait/negative-reasoning.stderr @@ -1,13 +1,13 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: - --> $DIR/negative-reasoning.rs:18:1 +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: + --> $DIR/negative-reasoning.rs:19:1 | -LL | impl AnotherTrait for T { } +LL | impl AnotherTrait for T {} | ------------------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` | - = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions + = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `impl OpaqueTrait` in future versions error: aborting due to previous error diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index 5d9ae6a03018f..7addc006e1900 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -256,16 +256,16 @@ LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ error: could not find defining uses - --> $DIR/where-allowed.rs:155:1 + --> $DIR/where-allowed.rs:119:16 | -LL | type InTypeAlias = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Out = impl Debug; + | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/where-allowed.rs:119:5 + --> $DIR/where-allowed.rs:155:23 | -LL | type Out = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | type InTypeAlias = impl Debug; + | ^^^^^^^^^^ error: aborting due to 42 previous errors diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout index 5a4b49cfa1e76..cebe834824a61 100644 --- a/src/test/ui/issues/issue-60662.stdout +++ b/src/test/ui/issues/issue-60662.stdout @@ -10,5 +10,5 @@ extern crate std; trait Animal { } fn main() { - pub type ServeFut = impl Animal; + pub type ServeFut = /*impl Trait*/; } diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr index 15aaf8961b7b1..ae04612a4dd69 100644 --- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr +++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr @@ -62,10 +62,10 @@ LL | type U = impl Trait; | -------------------- not a function or closure error: could not find defining uses - --> $DIR/inline-trait-and-foreign-items.rs:26:5 + --> $DIR/inline-trait-and-foreign-items.rs:26:14 | LL | type U = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to 6 previous errors; 2 warnings emitted diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs index 25d5f8ec68aa0..3cbc084ecae7c 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs @@ -1,5 +1,4 @@ #![feature(type_alias_impl_trait)] - #![deny(improper_ctypes)] type A = impl Fn(); @@ -10,7 +9,7 @@ pub fn ret_closure() -> A { extern "C" { pub fn a(_: A); - //~^ ERROR `extern` block uses type `A`, which is not FFI-safe +//~^ ERROR `extern` block uses type `impl std::ops::Fn<()>`, which is not FFI-safe } fn main() {} diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index 712095e3208bd..06dfb7b8fbeca 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -1,11 +1,11 @@ -error: `extern` block uses type `A`, which is not FFI-safe - --> $DIR/opaque-ty-ffi-unsafe.rs:12:17 +error: `extern` block uses type `impl std::ops::Fn<()>`, which is not FFI-safe + --> $DIR/opaque-ty-ffi-unsafe.rs:11:17 | LL | pub fn a(_: A); | ^ not FFI-safe | note: the lint level is defined here - --> $DIR/opaque-ty-ffi-unsafe.rs:3:9 + --> $DIR/opaque-ty-ffi-unsafe.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.rs b/src/test/ui/privacy/private-in-public-assoc-ty.rs index 62faae1f399e8..cd7c37cb04b22 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.rs +++ b/src/test/ui/privacy/private-in-public-assoc-ty.rs @@ -9,7 +9,9 @@ mod m { trait PrivTr {} impl PrivTr for Priv {} pub trait PubTrAux1 {} - pub trait PubTrAux2 { type A; } + pub trait PubTrAux2 { + type A; + } impl PubTrAux1 for u8 {} impl PubTrAux2 for u8 { type A = Priv; @@ -41,8 +43,9 @@ mod m { type Exist = impl PrivTr; //~^ ERROR private trait `m::PrivTr` in public interface - //~| ERROR private trait `m::PrivTr` in public interface - fn infer_exist() -> Self::Exist { Priv } + fn infer_exist() -> Self::Exist { + Priv + } } } diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr index dd2ea7481f331..1a3ca3f16ed4c 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr +++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr @@ -1,5 +1,5 @@ error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:15:9 + --> $DIR/private-in-public-assoc-ty.rs:17:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -8,7 +8,7 @@ LL | type A = Priv; | ^^^^^^^^^^^^^^ can't leak private type warning: private trait `m::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-assoc-ty.rs:21:5 + --> $DIR/private-in-public-assoc-ty.rs:23:5 | LL | / pub trait PubTr { LL | | @@ -24,7 +24,7 @@ LL | | } = note: for more information, see issue #34537 warning: private type `m::Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:21:5 + --> $DIR/private-in-public-assoc-ty.rs:23:5 | LL | / pub trait PubTr { LL | | @@ -39,7 +39,7 @@ LL | | } = note: for more information, see issue #34537 warning: private type `m::Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:21:5 + --> $DIR/private-in-public-assoc-ty.rs:23:5 | LL | / pub trait PubTr { LL | | @@ -54,7 +54,7 @@ LL | | } = note: for more information, see issue #34537 error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:32:9 + --> $DIR/private-in-public-assoc-ty.rs:34:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -63,7 +63,7 @@ LL | type Alias4 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:39:9 + --> $DIR/private-in-public-assoc-ty.rs:41:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -72,7 +72,7 @@ LL | type Alias1 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0445]: private trait `m::PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:42:9 + --> $DIR/private-in-public-assoc-ty.rs:44:9 | LL | trait PrivTr {} | - `m::PrivTr` declared as private @@ -80,16 +80,7 @@ LL | trait PrivTr {} LL | type Exist = impl PrivTr; | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait -error[E0445]: private trait `m::PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:42:9 - | -LL | trait PrivTr {} - | - `m::PrivTr` declared as private -... -LL | type Exist = impl PrivTr; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait - -error: aborting due to 5 previous errors; 3 warnings emitted +error: aborting due to 4 previous errors; 3 warnings emitted Some errors have detailed explanations: E0445, E0446. For more information about an error, try `rustc --explain E0445`. diff --git a/src/test/ui/save-analysis/issue-68621.stderr b/src/test/ui/save-analysis/issue-68621.stderr index 2c5bbd7782b35..3af6d0a3e076e 100644 --- a/src/test/ui/save-analysis/issue-68621.stderr +++ b/src/test/ui/save-analysis/issue-68621.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/issue-68621.rs:14:5 + --> $DIR/issue-68621.rs:14:19 | LL | type Future = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr index b871f79aa1dc5..9ebf63468e773 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `T: TraitWithAssoc` is not satisfied - --> $DIR/bound_reduction2.rs:10:1 + --> $DIR/bound_reduction2.rs:10:15 | LL | type Foo = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitWithAssoc` is not implemented for `T` + | ^^^^^^^^^^^^^ the trait `TraitWithAssoc` is not implemented for `T` | help: consider further restricting this bound | diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr index ae0fee4333b5b..21c2e8a9db618 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/declared_but_never_defined.rs:6:1 + --> $DIR/declared_but_never_defined.rs:6:12 | LL | type Bar = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr index 0642407aba3cd..c0cb94b15d033 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/declared_but_not_defined_in_scope.rs:7:5 + --> $DIR/declared_but_not_defined_in_scope.rs:7:20 | LL | pub type Boo = impl ::std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index e2540e424cb19..18d8daa05e63d 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -13,16 +13,16 @@ LL | let z: i32 = x; | expected due to this ... LL | type WrongGeneric = impl 'static; - | ------------------------------------ the found opaque type + | ------------ the found opaque type | = note: expected type `i32` - found opaque type `WrongGeneric::<&{integer}>` + found opaque type `impl Sized` error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:9:1 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:24 | LL | type WrongGeneric = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds ... LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound...: `T: 'static` diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr index f7a04263259f6..911f592f73f27 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr @@ -5,10 +5,10 @@ LL | type Underconstrained = impl 'static; | ^^^^^^^^^^^^ error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/generic_underconstrained.rs:6:1 + --> $DIR/generic_underconstrained.rs:6:35 | LL | type Underconstrained = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | ^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` | = note: the return type of a function must have a statically known size help: consider restricting type parameter `T` diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr index ad160abcbd573..247d68ef2a1f0 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -11,10 +11,10 @@ LL | type Underconstrained2 = impl 'static; | ^^^^^^^^^^^^ error[E0277]: `U` doesn't implement `std::fmt::Debug` - --> $DIR/generic_underconstrained2.rs:5:1 + --> $DIR/generic_underconstrained2.rs:5:45 | LL | type Underconstrained = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` ... LL | 5u32 | ---- this returned value is of type `u32` @@ -27,10 +27,10 @@ LL | fn underconstrained(_: U) -> Underconstrained { | ^^^^^^^^^^^^^^^^^ error[E0277]: `V` doesn't implement `std::fmt::Debug` - --> $DIR/generic_underconstrained2.rs:14:1 + --> $DIR/generic_underconstrained2.rs:14:46 | LL | type Underconstrained2 = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` ... LL | 5u32 | ---- this returned value is of type `u32` diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr index f648b7bfc991d..cc121ac89fb8d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -1,8 +1,8 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/issue-57611-trait-alias.rs:17:5 + --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _` + | ^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _` ... LL | |x| x | ----- found signature of `fn(_) -> _` @@ -10,10 +10,10 @@ LL | |x| x = note: the return type of a function must have a statically known size error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-57611-trait-alias.rs:21:9: 21:14] as std::ops::FnOnce<(&'r X,)>>::Output == &'r X` - --> $DIR/issue-57611-trait-alias.rs:17:5 + --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime + | ^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr index 2796c77baa1c4..bf2d612fcdb41 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -8,20 +8,20 @@ LL | type Item = impl Bug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0277]: the trait bound `(): Bug` is not satisfied - --> $DIR/issue-60371.rs:8:5 + --> $DIR/issue-60371.rs:8:17 | LL | type Item = impl Bug; - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Bug` is not implemented for `()` + | ^^^^^^^^ the trait `Bug` is not implemented for `()` | = help: the following implementations were found: <&() as Bug> = note: the return type of a function must have a statically known size error: could not find defining uses - --> $DIR/issue-60371.rs:8:5 + --> $DIR/issue-60371.rs:8:17 | LL | type Item = impl Bug; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr index bef4d01093c62..d07f64c3312d3 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -1,10 +1,10 @@ error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:8:5: 8:28] as std::ops::FnOnce<()>>::Output == ()` - --> $DIR/issue-63279.rs:5:1 + --> $DIR/issue-63279.rs:5:16 | LL | type Closure = impl FnOnce(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()` + | ^^^^^^^^^^^^^ expected opaque type, found `()` | - = note: expected opaque type `Closure` + = note: expected opaque type `impl std::ops::FnOnce<()>` found unit type `()` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr index 70c99c944d654..4fbbf34752803 100644 --- a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/never_reveal_concrete_type.rs:13:27 | LL | type NoReveal = impl std::fmt::Debug; - | ------------------------------------- the found opaque type + | -------------------- the found opaque type ... LL | let _: &'static str = x; | ------------ ^ expected `&str`, found opaque type @@ -10,9 +10,9 @@ LL | let _: &'static str = x; | expected due to this | = note: expected reference `&'static str` - found opaque type `NoReveal` + found opaque type `impl std::fmt::Debug` -error[E0605]: non-primitive cast: `NoReveal` as `&'static str` +error[E0605]: non-primitive cast: `impl std::fmt::Debug` as `&'static str` --> $DIR/never_reveal_concrete_type.rs:14:13 | LL | let _ = x as &'static str; diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index 444e6e8214ff2..61025e846921e 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/no_inferrable_concrete_type.rs:6:1 + --> $DIR/no_inferrable_concrete_type.rs:6:12 | LL | type Foo = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index 375c0bc7fe2ed..d237cc6238ae1 100644 --- a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:15:19 | LL | pub type Boo = impl ::std::fmt::Debug; - | -------------------------------------- the found opaque type + | ---------------------- the found opaque type ... LL | let _: &str = bomp(); | ---- ^^^^^^ expected `&str`, found opaque type @@ -10,20 +10,20 @@ LL | let _: &str = bomp(); | expected due to this | = note: expected reference `&str` - found opaque type `Boo` + found opaque type `impl std::fmt::Debug` error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:19:5 | LL | pub type Boo = impl ::std::fmt::Debug; - | -------------------------------------- the expected opaque type + | ---------------------- the expected opaque type ... LL | fn bomp() -> boo::Boo { - | -------- expected `Boo` because of return type + | -------- expected `impl std::fmt::Debug` because of return type LL | "" | ^^ expected opaque type, found `&str` | - = note: expected opaque type `Boo` + = note: expected opaque type `impl std::fmt::Debug` found reference `&'static str` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr index 02ab3399ea6fa..726f4ea6e00f7 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:1 + --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12 | LL | type Foo = impl Fn() -> Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr index e9abb79588683..3947cc4d27055 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:1 + --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12 | LL | type Foo = impl Bar; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error From 556fa95306823b780a6e5e0c3b8e6718f2c48bdf Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 12:15:51 +0100 Subject: [PATCH 09/25] Remove associated opaque types They're unused now. --- src/librustc_hir/def.rs | 8 +- src/librustc_hir/hir.rs | 7 +- src/librustc_hir/intravisit.rs | 4 - src/librustc_hir_pretty/lib.rs | 6 - .../persist/dirty_clean.rs | 1 - .../infer/error_reporting/mod.rs | 4 +- src/librustc_metadata/rmeta/decoder.rs | 2 - src/librustc_metadata/rmeta/encoder.rs | 7 +- src/librustc_metadata/rmeta/mod.rs | 1 - src/librustc_middle/hir/map/mod.rs | 4 - .../traits/specialization_graph.rs | 17 +- src/librustc_middle/ty/error.rs | 4 +- src/librustc_middle/ty/mod.rs | 20 +-- src/librustc_passes/check_attr.rs | 2 +- src/librustc_passes/dead.rs | 2 +- src/librustc_passes/reachable.rs | 4 +- src/librustc_privacy/lib.rs | 14 +- src/librustc_resolve/build_reduced_graph.rs | 3 +- src/librustc_resolve/late/lifetimes.rs | 37 ---- src/librustc_save_analysis/dump_visitor.rs | 1 - src/librustc_save_analysis/lib.rs | 1 - src/librustc_trait_selection/opaque_types.rs | 17 +- .../traits/project.rs | 11 +- src/librustc_ty/ty.rs | 2 - src/librustc_typeck/check/compare_method.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 4 +- src/librustc_typeck/check/mod.rs | 5 +- src/librustc_typeck/check/wfcheck.rs | 167 +++++++++--------- src/librustc_typeck/collect.rs | 32 +--- src/librustc_typeck/collect/type_of.rs | 7 - src/librustc_typeck/impl_wf_check.rs | 7 - src/librustdoc/clean/mod.rs | 5 - .../clippy/clippy_lints/src/lifetimes.rs | 2 +- .../clippy_lints/src/manual_async_fn.rs | 2 +- .../clippy_lints/src/utils/hir_utils.rs | 2 +- 36 files changed, 116 insertions(+), 300 deletions(-) diff --git a/src/librustc_hir/def.rs b/src/librustc_hir/def.rs index 88049f85f45e4..af1860ca6bfea 100644 --- a/src/librustc_hir/def.rs +++ b/src/librustc_hir/def.rs @@ -54,15 +54,11 @@ pub enum DefKind { /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists. Variant, Trait, - /// `type Foo = impl Bar;` - OpaqueTy, /// `type Foo = Bar;` TyAlias, ForeignTy, TraitAlias, AssocTy, - /// `type Foo = impl Bar;` - AssocOpaqueTy, TyParam, // Value namespace @@ -83,6 +79,7 @@ pub enum DefKind { Use, ForeignMod, AnonConst, + OpaqueTy, Field, LifetimeParam, GlobalAsm, @@ -115,7 +112,6 @@ impl DefKind { DefKind::TyAlias => "type alias", DefKind::TraitAlias => "trait alias", DefKind::AssocTy => "associated type", - DefKind::AssocOpaqueTy => "associated opaque type", DefKind::Union => "union", DefKind::Trait => "trait", DefKind::ForeignTy => "foreign type", @@ -143,7 +139,6 @@ impl DefKind { match *self { DefKind::AssocTy | DefKind::AssocConst - | DefKind::AssocOpaqueTy | DefKind::AssocFn | DefKind::Enum | DefKind::OpaqueTy @@ -168,7 +163,6 @@ impl DefKind { | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy - | DefKind::AssocOpaqueTy | DefKind::TyParam => ns == Namespace::TypeNS, DefKind::Fn diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 1e305c6d32d6a..122b8f2ac1612 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1919,14 +1919,12 @@ pub enum ImplItemKind<'hir> { Fn(FnSig<'hir>, BodyId), /// An associated type. TyAlias(&'hir Ty<'hir>), - /// An associated `type = impl Trait`. - OpaqueTy(GenericBounds<'hir>), } impl ImplItemKind<'_> { pub fn namespace(&self) -> Namespace { match self { - ImplItemKind::OpaqueTy(..) | ImplItemKind::TyAlias(..) => Namespace::TypeNS, + ImplItemKind::TyAlias(..) => Namespace::TypeNS, ImplItemKind::Const(..) | ImplItemKind::Fn(..) => Namespace::ValueNS, } } @@ -2016,8 +2014,6 @@ pub struct OpaqueTy<'hir> { /// From whence the opaque type came. #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum OpaqueTyOrigin { - /// `type Foo = impl Trait;` - TypeAlias, /// `-> impl Trait` FnReturn, /// `async fn` @@ -2614,7 +2610,6 @@ pub enum AssocItemKind { Const, Fn { has_self: bool }, Type, - OpaqueTy, } #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 97601a3e1ac7b..8d7bba7dbd578 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -1007,10 +1007,6 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_id(impl_item.hir_id); visitor.visit_ty(ty); } - ImplItemKind::OpaqueTy(bounds) => { - visitor.visit_id(impl_item.hir_id); - walk_list!(visitor, visit_param_bound, bounds); - } } } diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index c1b6857038798..cf153840a04ba 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -981,12 +981,6 @@ impl<'a> State<'a> { hir::ImplItemKind::TyAlias(ref ty) => { self.print_associated_type(ii.ident, &ii.generics, None, Some(ty)); } - hir::ImplItemKind::OpaqueTy(bounds) => { - self.word_space("type"); - self.print_ident(ii.ident); - self.print_bounds("= impl", bounds); - self.s.word(";"); - } } self.ann.post(self, AnnNode::SubItem(ii.hir_id)) } diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 9bf992537dfaf..2ee95174dffe6 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -336,7 +336,6 @@ impl DirtyCleanVisitor<'tcx> { ImplItemKind::Fn(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL), ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), ImplItemKind::TyAlias(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), - ImplItemKind::OpaqueTy(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), }, _ => self.tcx.sess.span_fatal( attr.span, diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index a59a91e3005aa..12f7a9c0ca502 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -224,9 +224,7 @@ fn trait_item_scope_tag(item: &hir::TraitItem<'_>) -> &'static str { fn impl_item_scope_tag(item: &hir::ImplItem<'_>) -> &'static str { match item.kind { hir::ImplItemKind::Fn(..) => "method body", - hir::ImplItemKind::Const(..) - | hir::ImplItemKind::OpaqueTy(..) - | hir::ImplItemKind::TyAlias(..) => "associated item", + hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(..) => "associated item", } } diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index f5a9dceb78295..44944a9fb265a 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -579,7 +579,6 @@ impl EntryKind { EntryKind::ConstParam => DefKind::ConstParam, EntryKind::OpaqueTy => DefKind::OpaqueTy, EntryKind::AssocType(_) => DefKind::AssocTy, - EntryKind::AssocOpaqueTy(_) => DefKind::AssocOpaqueTy, EntryKind::Mod(_) => DefKind::Mod, EntryKind::Variant(_) => DefKind::Variant, EntryKind::Trait(_) => DefKind::Trait, @@ -1145,7 +1144,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { (ty::AssocKind::Fn, data.container, data.has_self) } EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false), - EntryKind::AssocOpaqueTy(container) => (ty::AssocKind::OpaqueTy, container, false), _ => bug!("cannot get associated-item of `{:?}`", def_key), }; diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 9964c9c94c951..9430d7f342ddb 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -865,7 +865,6 @@ impl EncodeContext<'tcx> { })) } ty::AssocKind::Type => EntryKind::AssocType(container), - ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"), }); record!(self.tables.visibility[def_id] <- trait_item.vis); record!(self.tables.span[def_id] <- ast_item.span); @@ -883,7 +882,6 @@ impl EncodeContext<'tcx> { self.encode_item_type(def_id); } } - ty::AssocKind::OpaqueTy => unreachable!(), } if trait_item.kind == ty::AssocKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); @@ -948,7 +946,6 @@ impl EncodeContext<'tcx> { has_self: impl_item.fn_has_self_parameter, })) } - ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container), ty::AssocKind::Type => EntryKind::AssocType(container) }); record!(self.tables.visibility[def_id] <- impl_item.vis); @@ -980,7 +977,7 @@ impl EncodeContext<'tcx> { let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; needs_inline || is_const_fn || always_encode_mir } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => false, + hir::ImplItemKind::TyAlias(..) => false, }; if mir { self.encode_optimized_mir(def_id.expect_local()); @@ -1777,7 +1774,7 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { self.prefetch_mir(def_id) } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => (), + hir::ImplItemKind::TyAlias(..) => (), } } } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 89d525eb80b8c..626a436b40060 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -308,7 +308,6 @@ enum EntryKind { Impl(Lazy), AssocFn(Lazy), AssocType(AssocContainer), - AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, mir::ConstQualifs, Lazy), TraitAlias, } diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index 5281c51a8b811..2b7cc9bc056b4 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -228,7 +228,6 @@ impl<'hir> Map<'hir> { ImplItemKind::Const(..) => DefKind::AssocConst, ImplItemKind::Fn(..) => DefKind::AssocFn, ImplItemKind::TyAlias(..) => DefKind::AssocTy, - ImplItemKind::OpaqueTy(..) => DefKind::AssocOpaqueTy, }, Node::Variant(_) => DefKind::Variant, Node::Ctor(variant_data) => { @@ -1023,9 +1022,6 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { ImplItemKind::TyAlias(_) => { format!("assoc type {} in {}{}", ii.ident, path_str(), id_str) } - ImplItemKind::OpaqueTy(_) => { - format!("assoc opaque type {} in {}{}", ii.ident, path_str(), id_str) - } }, Some(Node::TraitItem(ti)) => { let kind = match ti.kind { diff --git a/src/librustc_middle/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs index 4f02aaa96acd3..f4961617b81c6 100644 --- a/src/librustc_middle/traits/specialization_graph.rs +++ b/src/librustc_middle/traits/specialization_graph.rs @@ -100,24 +100,11 @@ impl<'tcx> Node { trait_item_kind: ty::AssocKind, trait_def_id: DefId, ) -> Option { - use crate::ty::AssocKind::*; - tcx.associated_items(self.def_id()) .filter_by_name_unhygienic(trait_item_name.name) .find(move |impl_item| { - match (trait_item_kind, impl_item.kind) { - | (Const, Const) - | (Fn, Fn) - | (Type, Type) - | (Type, OpaqueTy) // assoc. types can be made opaque in impls - => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), - - | (Const, _) - | (Fn, _) - | (Type, _) - | (OpaqueTy, _) - => false, - } + trait_item_kind == impl_item.kind + && tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id) }) .copied() } diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs index 480420dfdcf5e..be3bf748225b9 100644 --- a/src/librustc_middle/ty/error.rs +++ b/src/librustc_middle/ty/error.rs @@ -814,7 +814,7 @@ fn foo(&self) -> Self::T { String::new() } // FIXME: account for `#![feature(specialization)]` for item in &items[..] { match item.kind { - hir::AssocItemKind::Type | hir::AssocItemKind::OpaqueTy => { + hir::AssocItemKind::Type => { // FIXME: account for returning some type in a trait fn impl that has // an assoc type as a return type (#72076). if let hir::Defaultness::Default { has_value: true } = item.defaultness @@ -838,7 +838,7 @@ fn foo(&self) -> Self::T { String::new() } })) => { for item in &items[..] { match item.kind { - hir::AssocItemKind::Type | hir::AssocItemKind::OpaqueTy => { + hir::AssocItemKind::Type => { if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found { db.span_label(item.span, "expected this associated type"); return true; diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 00c00a63b6b5d..5ba5cc33340e3 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -198,14 +198,13 @@ pub struct AssocItem { pub enum AssocKind { Const, Fn, - OpaqueTy, Type, } impl AssocKind { pub fn namespace(&self) -> Namespace { match *self { - ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::TypeNS, + ty::AssocKind::Type => Namespace::TypeNS, ty::AssocKind::Const | ty::AssocKind::Fn => Namespace::ValueNS, } } @@ -215,22 +214,11 @@ impl AssocKind { AssocKind::Const => DefKind::AssocConst, AssocKind::Fn => DefKind::AssocFn, AssocKind::Type => DefKind::AssocTy, - AssocKind::OpaqueTy => DefKind::AssocOpaqueTy, } } } impl AssocItem { - /// Tests whether the associated item admits a non-trivial implementation - /// for ! - pub fn relevant_for_never(&self) -> bool { - match self.kind { - AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true, - // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. - AssocKind::Fn => !self.fn_has_self_parameter, - } - } - pub fn signature(&self, tcx: TyCtxt<'_>) -> String { match self.kind { ty::AssocKind::Fn => { @@ -241,8 +229,6 @@ impl AssocItem { tcx.fn_sig(self.def_id).skip_binder().to_string() } ty::AssocKind::Type => format!("type {};", self.ident), - // FIXME(type_alias_impl_trait): we should print bounds here too. - ty::AssocKind::OpaqueTy => format!("type {};", self.ident), ty::AssocKind::Const => { format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id)) } @@ -2558,10 +2544,6 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) } - pub fn trait_relevant_for_never(self, did: DefId) -> bool { - self.associated_items(did).in_definition_order().any(|item| item.relevant_for_never()) - } - pub fn opt_item_name(self, def_id: DefId) -> Option { def_id .as_local() diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index b54731d8881d1..80681c143750f 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -37,7 +37,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) Target::Method(MethodKind::Inherent) } } - hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::OpaqueTy(..) => Target::AssocTy, + hir::ImplItemKind::TyAlias(..) => Target::AssocTy, } } diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 1dcf0e7c7a98a..419bbda78271a 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -668,7 +668,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } self.visit_nested_body(body_id) } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => {} + hir::ImplItemKind::TyAlias(..) => {} } } diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index cac71b3836c54..c9a4428c007aa 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -180,7 +180,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => false, + hir::ImplItemKind::TyAlias(_) => false, } } Some(_) => false, @@ -289,7 +289,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { self.visit_nested_body(body) } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {} + hir::ImplItemKind::TyAlias(_) => {} }, Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., body, _, _), .. }) => { self.visit_nested_body(body); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index cb896810951ba..9778626212242 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -615,7 +615,6 @@ impl EmbargoVisitor<'tcx> { // public, or are not namespaced at all. DefKind::AssocConst | DefKind::AssocTy - | DefKind::AssocOpaqueTy | DefKind::ConstParam | DefKind::Ctor(_, _) | DefKind::Enum @@ -1333,11 +1332,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { _ => None, }; let def = def.filter(|(kind, _)| match kind { - DefKind::AssocFn - | DefKind::AssocConst - | DefKind::AssocTy - | DefKind::AssocOpaqueTy - | DefKind::Static => true, + DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Static => true, _ => false, }); if let Some((kind, def_id)) = def { @@ -1602,9 +1597,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => { self.access_levels.is_reachable(impl_item_ref.id.hir_id) } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => { - false - } + hir::ImplItemKind::TyAlias(_) => false, } }); @@ -1952,9 +1945,6 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { let (check_ty, is_assoc_ty) = match assoc_item_kind { AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), AssocItemKind::Type => (defaultness.has_value(), true), - // `ty()` for opaque types is the underlying type, - // it's not a part of interface, so we skip it. - AssocItemKind::OpaqueTy => (false, true), }; check.in_assoc_ty = is_assoc_ty; check.generics().predicates(); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c4ceb50018aac..30d79d4be9477 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -910,8 +910,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { | DefKind::ForeignTy | DefKind::OpaqueTy | DefKind::TraitAlias - | DefKind::AssocTy - | DefKind::AssocOpaqueTy, + | DefKind::AssocTy, _, ) | Res::PrimTy(..) diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 02193dcec901e..aa3e04121435f 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -799,43 +799,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.visit_ty(ty); }); } - OpaqueTy(bounds) => { - let generics = &impl_item.generics; - let mut index = self.next_early_index(); - let mut next_early_index = index; - debug!("visit_ty: index = {}", index); - let lifetimes = generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - Some(Region::early(&self.tcx.hir(), &mut index, param)) - } - GenericParamKind::Type { .. } => { - next_early_index += 1; - None - } - GenericParamKind::Const { .. } => { - next_early_index += 1; - None - } - }) - .collect(); - - let scope = Scope::Binder { - lifetimes, - next_early_index, - s: self.scope, - track_lifetime_uses: true, - opaque_type_parent: true, - }; - self.with(scope, |_old_scope, this| { - this.visit_generics(generics); - for bound in bounds { - this.visit_param_bound(bound); - } - }); - } Const(_, _) => { // Only methods and types support generics. assert!(impl_item.generics.params.is_empty()); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index a5e61ab9ab033..c7f4d670a4fc8 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1083,7 +1083,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { impl_item.span, ); } - hir::ImplItemKind::OpaqueTy(..) => {} hir::ImplItemKind::TyAlias(ref ty) => { // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 8c7731c18e9c4..e703dd069ed5b 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -667,7 +667,6 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { | HirDefKind::TyAlias | HirDefKind::ForeignTy | HirDefKind::TraitAlias - | HirDefKind::AssocOpaqueTy | HirDefKind::AssocTy | HirDefKind::Trait | HirDefKind::OpaqueTy diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index 51b1db390b927..af2fa783c93bd 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -11,7 +11,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_infer::infer::{self, InferCtxt, InferOk}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::nightly_options; use rustc_span::Span; @@ -1059,21 +1059,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { ), origin, ), - _ => (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias), - }, - Some(Node::ImplItem(item)) => match item.kind { - hir::ImplItemKind::OpaqueTy(_) => ( - may_define_opaque_type( - tcx, - self.parent_def_id.expect_local(), - opaque_hir_id, - ), - hir::OpaqueTyOrigin::TypeAlias, - ), - _ => (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias), + _ => (def_scope_default(), hir::OpaqueTyOrigin::Misc), }, _ => bug!( - "expected (impl) item, found {}", + "expected item, found {}", tcx.hir().node_to_string(opaque_hir_id), ), }; diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 1126480b02a0d..16367fcd3638f 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -25,7 +25,7 @@ use rustc_errors::ErrorReported; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::{FnOnceTraitLangItem, GeneratorTraitLangItem}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; -use rustc_middle::ty::subst::{InternalSubsts, Subst}; +use rustc_middle::ty::subst::Subst; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_span::symbol::{sym, Ident}; @@ -1474,12 +1474,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node); - let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind { - let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); - tcx.mk_opaque(assoc_ty.item.def_id, item_substs) - } else { - tcx.type_of(assoc_ty.item.def_id) - }; + let ty = tcx.type_of(assoc_ty.item.def_id); if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { tcx.sess .delay_span_bug(DUMMY_SP, "impl item and trait item have different parameter counts"); @@ -1512,7 +1507,7 @@ fn assoc_ty_def( // cycle error if the specialization graph is currently being built. let impl_node = specialization_graph::Node::Impl(impl_def_id); for item in impl_node.items(tcx) { - if matches!(item.kind, ty::AssocKind::Type | ty::AssocKind::OpaqueTy) + if matches!(item.kind, ty::AssocKind::Type) && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id) { return Ok(specialization_graph::LeafDef { diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 3da5da2d9efb8..99094246a6378 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -85,7 +85,6 @@ fn associated_item_from_trait_item_ref( hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), }; ty::AssocItem { @@ -110,7 +109,6 @@ fn associated_item_from_impl_item_ref( hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), }; ty::AssocItem { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 29cd9681295be..5f8fcaadfdb0b 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -1165,6 +1165,6 @@ fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { match impl_item.kind { ty::AssocKind::Const => "const", ty::AssocKind::Fn => "method", - ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "type", + ty::AssocKind::Type => "type", } } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 91562d576ea80..0551ca0ba16ca 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1556,7 +1556,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { match self.mode { Mode::MethodCall => item.fn_has_self_parameter, Mode::Path => match item.kind { - ty::AssocKind::OpaqueTy | ty::AssocKind::Type => false, + ty::AssocKind::Type => false, ty::AssocKind::Fn | ty::AssocKind::Const => true, }, } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 7ca3eb884d88f..67bdd04d3715c 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -158,9 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let path = self.tcx.def_path_str(trait_ref.def_id); let ty = match item.kind { - ty::AssocKind::Const - | ty::AssocKind::Type - | ty::AssocKind::OpaqueTy => rcvr_ty, + ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty, ty::AssocKind::Fn => self .tcx .fn_sig(item.def_id) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e5bca3746771c..728c3d4856ca1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1946,7 +1946,6 @@ fn check_specialization_validity<'tcx>( let kind = match impl_item.kind { hir::ImplItemKind::Const(..) => ty::AssocKind::Const, hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn, - hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy, hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type, }; @@ -2117,7 +2116,7 @@ fn check_impl_items_against_trait<'tcx>( err.emit() } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => { + hir::ImplItemKind::TyAlias(_) => { let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssocKind::Type { compare_ty_impl( @@ -2370,8 +2369,6 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String { ) } ty::AssocKind::Type => format!("type {} = Type;", assoc.ident), - // FIXME(type_alias_impl_trait): we should print bounds here too. - ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident), ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id); let val = expr::ty_kind_suggestion(ty).unwrap_or("value"); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 8a83952c4fc7f..c0be1d42d134c 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -316,9 +316,6 @@ fn check_associated_item( fcx.register_wf_obligation(ty.into(), span, code.clone()); } } - ty::AssocKind::OpaqueTy => { - // Do nothing: opaque types check themselves. - } } implied_bounds @@ -900,102 +897,102 @@ fn check_opaque_types<'fcx, 'tcx>( if !def_id.is_local() { return ty; } - let opaque_hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + let opaque_hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) = tcx.hir().expect_item(opaque_hir_id).kind { // Don't check return position impl trait. return ty; } - if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { - trace!("check_opaque_types: may define, generics={:#?}", generics); - let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); - for (i, arg) in substs.iter().enumerate() { - let arg_is_param = match arg.unpack() { - GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)), - - GenericArgKind::Lifetime(region) => { - if let ty::ReStatic = region { - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_label( - tcx.def_span(generics.param_at(i, tcx).def_id), - "cannot use static lifetime; use a bound lifetime \ + if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { + trace!("check_opaque_types: may define, generics={:#?}", generics); + let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); + for (i, arg) in substs.iter().enumerate() { + let arg_is_param = match arg.unpack() { + GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)), + + GenericArgKind::Lifetime(region) => { + if let ty::ReStatic = region { + tcx.sess + .struct_span_err( + span, + "non-defining opaque type use in defining scope", + ) + .span_label( + tcx.def_span(generics.param_at(i, tcx).def_id), + "cannot use static lifetime; use a bound lifetime \ instead or remove the lifetime parameter from the \ opaque type", - ) - .emit(); - continue; - } - - true + ) + .emit(); + continue; } - GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)), - }; - - if arg_is_param { - seen_params.entry(arg).or_default().push(i); - } else { - // Prevent `fn foo() -> Foo` from being defining. - let opaque_param = generics.param_at(i, tcx); - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_note( - tcx.def_span(opaque_param.def_id), - &format!( - "used non-generic {} `{}` for generic parameter", - opaque_param.kind.descr(), - arg, - ), - ) - .emit(); - } - } // for (arg, param) - - for (_, indices) in seen_params { - if indices.len() > 1 { - let descr = generics.param_at(indices[0], tcx).kind.descr(); - let spans: Vec<_> = indices - .into_iter() - .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id)) - .collect(); - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_note(spans, &format!("{} used multiple times", descr)) - .emit(); + true } + + GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)), + }; + + if arg_is_param { + seen_params.entry(arg).or_default().push(i); + } else { + // Prevent `fn foo() -> Foo` from being defining. + let opaque_param = generics.param_at(i, tcx); + tcx.sess + .struct_span_err( + span, + "non-defining opaque type use in defining scope", + ) + .span_note( + tcx.def_span(opaque_param.def_id), + &format!( + "used non-generic {} `{}` for generic parameter", + opaque_param.kind.descr(), + arg, + ), + ) + .emit(); } - } // if may_define_opaque_type - - // Now register the bounds on the parameters of the opaque type - // so the parameters given by the function need to fulfill them. - // - // type Foo = impl Baz + 'static; - // fn foo() -> Foo { .. *} - // - // becomes - // - // type Foo = impl Baz + 'static; - // fn foo() -> Foo { .. *} - let predicates = tcx.predicates_of(def_id); - trace!("check_opaque_types: may define, predicates={:#?}", predicates,); - for &(pred, _) in predicates.predicates { - let substituted_pred = pred.subst(fcx.tcx, substs); - // Avoid duplication of predicates that contain no parameters, for example. - if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { - substituted_predicates.push(substituted_pred); + } // for (arg, param) + + for (_, indices) in seen_params { + if indices.len() > 1 { + let descr = generics.param_at(indices[0], tcx).kind.descr(); + let spans: Vec<_> = indices + .into_iter() + .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id)) + .collect(); + tcx.sess + .struct_span_err( + span, + "non-defining opaque type use in defining scope", + ) + .span_note(spans, &format!("{} used multiple times", descr)) + .emit(); } } + } // if may_define_opaque_type + + // Now register the bounds on the parameters of the opaque type + // so the parameters given by the function need to fulfill them. + // + // type Foo = impl Baz + 'static; + // fn foo() -> Foo { .. *} + // + // becomes + // + // type Foo = impl Baz + 'static; + // fn foo() -> Foo { .. *} + let predicates = tcx.predicates_of(def_id); + trace!("check_opaque_types: may define, predicates={:#?}", predicates,); + for &(pred, _) in predicates.predicates { + let substituted_pred = pred.subst(fcx.tcx, substs); + // Avoid duplication of predicates that contain no parameters, for example. + if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { + substituted_predicates.push(substituted_pred); + } + } } // if let Opaque ty }, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7038caf4367e6..191244e41c80c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -742,7 +742,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { hir::ImplItemKind::Fn(..) => { tcx.ensure().fn_sig(def_id); } - hir::ImplItemKind::TyAlias(_) | hir::ImplItemKind::OpaqueTy(_) => { + hir::ImplItemKind::TyAlias(_) => { // Account for `type T = _;` let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_impl_item(impl_item); @@ -1203,10 +1203,10 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { impl_trait_fn.or_else(|| { let parent_id = tcx.hir().get_parent_item(hir_id); assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID); - debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); + debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); // Opaque types are always nested within another item, and // inherit the generics of the item. - Some(tcx.hir().local_def_id(parent_id).to_def_id()) + Some(tcx.hir().local_def_id(parent_id).to_def_id()) }) } _ => None, @@ -1704,31 +1704,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat let ast_generics = match node { Node::TraitItem(item) => &item.generics, - Node::ImplItem(item) => match item.kind { - ImplItemKind::OpaqueTy(ref bounds) => { - ty::print::with_no_queries(|| { - let substs = InternalSubsts::identity_for_item(tcx, def_id); - let opaque_ty = tcx.mk_opaque(def_id, substs); - debug!( - "explicit_predicates_of({:?}): created opaque type {:?}", - def_id, opaque_ty - ); - - // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. - let bounds = AstConv::compute_bounds( - &icx, - opaque_ty, - bounds, - SizedByDefault::Yes, - tcx.def_span(def_id), - ); - - predicates.extend(bounds.predicates(tcx, opaque_ty)); - &item.generics - }) - } - _ => &item.generics, - }, + Node::ImplItem(item) => &item.generics, Node::Item(item) => { match item.kind { diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index cf0e3f9cdf592..f9bc7389b070d 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -64,13 +64,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { icx.to_ty(ty) } } - ImplItemKind::OpaqueTy(_) => { - if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id).to_def_id()).is_none() { - report_assoc_ty_on_inherent_impl(tcx, item.span); - } - - find_opaque_ty_constraints(tcx, def_id.expect_local()) - } ImplItemKind::TyAlias(ref ty) => { if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id).to_def_id()).is_none() { report_assoc_ty_on_inherent_impl(tcx, item.span); diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index e13d9ea2b2626..37d383db68ab6 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -140,13 +140,6 @@ fn enforce_impl_params_are_constrained( Vec::new() } } - ty::AssocKind::OpaqueTy => { - // We don't know which lifetimes appear in the actual - // opaque type, so use all of the lifetimes that appear - // in the type's predicates. - let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); - cgp::parameters_for(&predicates, true) - } ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(), } }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dd4df11b1df38..92bf6b564cf8a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1138,10 +1138,6 @@ impl Clean for hir::ImplItem<'_> { let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } - hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( - OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, - true, - ), }; let local_did = cx.tcx.hir().local_def_id(self.hir_id); Item { @@ -1308,7 +1304,6 @@ impl Clean for ty::AssocItem { ) } } - ty::AssocKind::OpaqueTy => unimplemented!(), }; let visibility = match self.container { diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index d80ad47ab2468..318d0b69d57b7 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -379,7 +379,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { TyKind::Path(ref path) => { self.collect_anonymous_lifetimes(path, ty); }, - TyKind::Def(item, _) => { + TyKind::OpaqueDef(item, _) => { let map = self.cx.tcx.hir(); if let ItemKind::OpaqueTy(ref exist_ty) = map.expect_item(item.id).kind { for bound in exist_ty.bounds { diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index cb72a24058234..03ab274d9ca9c 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ManualAsyncFn { fn future_trait_ref<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &'tcx Ty<'tcx>) -> Option<&'tcx TraitRef<'tcx>> { if_chain! { - if let TyKind::Def(item_id, _) = ty.kind; + if let TyKind::OpaqueDef(item_id, _) = ty.kind; let item = cx.tcx.hir().item(item_id.id); if let ItemKind::OpaqueTy(opaque) = &item.kind; if opaque.bounds.len() == 1; diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs index 92c27e79452ab..7f7a3f2c34e39 100644 --- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs @@ -716,7 +716,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { segment.ident.name.hash(&mut self.s); }, }, - TyKind::Def(_, arg_list) => { + TyKind::OpaqueDef(_, arg_list) => { for arg in *arg_list { match arg { GenericArg::Lifetime(ref l) => self.hash_lifetime(l), From 9489d326f3a2746845570dafc2f92e7c96df7fc5 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 12:18:55 +0100 Subject: [PATCH 10/25] Forbid lifetime elision in let position impl Trait This is consistent with types. --- src/librustc_ast_lowering/lib.rs | 6 +- src/librustc_hir/hir.rs | 4 +- src/librustc_resolve/late/lifetimes.rs | 13 +++- src/librustc_trait_selection/opaque_types.rs | 4 +- src/librustc_typeck/collect/type_of.rs | 74 ++++++++++++++------ src/test/ui/impl-trait/issue-60473.rs | 10 ++- src/test/ui/impl-trait/issue-60473.stderr | 16 +++-- src/test/ui/impl-trait/issue-67166.rs | 4 +- src/test/ui/impl-trait/issue-67166.stderr | 16 +++-- 9 files changed, 95 insertions(+), 52 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 0154e10112b49..39546c861bd08 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1619,15 +1619,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { visitor.visit_ty(ty); } } - let parent_def_id = self.current_hir_id_owner.last().unwrap().0; let ty = l.ty.as_ref().map(|t| { self.lower_ty( t, if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitContext::OpaqueTy( - Some(parent_def_id.to_def_id()), - hir::OpaqueTyOrigin::Misc, - ) + ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Binding) } else { ImplTraitContext::Disallowed(ImplTraitPosition::Binding) }, diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 122b8f2ac1612..1190c90cd17ee 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2018,7 +2018,9 @@ pub enum OpaqueTyOrigin { FnReturn, /// `async fn` AsyncFn, - /// Impl trait in bindings, consts, statics, bounds. + /// `let _: impl Trait = ...` + Binding, + /// Impl trait in type aliases, consts, statics, bounds. Misc, } diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index aa3e04121435f..72fe4355814ee 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -258,6 +258,9 @@ enum Elide { Exact(Region), /// Less or more than one lifetime were found, error on unspecified. Error(Vec), + /// Forbid lifetime elision inside of a larger scope that does. For + /// example, in let position impl trait. + Forbid, } #[derive(Clone, Debug)] @@ -566,7 +569,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // This arm is for `impl Trait` in the types of statics, constants and locals. hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { intravisit::walk_ty(self, ty); - intravisit::walk_item(this, opaque_ty); + + // Elided lifetimes are not allowed in non-return + // position impl Trait + let scope = Scope::Elision { elide: Elide::Forbid, s: self.scope }; + self.with(scope, |_, this| { + intravisit::walk_item(this, opaque_ty); + }); + return; } // RPIT (return position impl trait) @@ -2332,6 +2342,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } break Some(e); } + Elide::Forbid => break None, }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index af2fa783c93bd..e1f0c579a3c36 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -413,7 +413,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } // These opaque type inherit all lifetime parameters from their // parent. - hir::OpaqueTyOrigin::Misc => 0, + hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::Misc => 0, }; let span = tcx.def_span(def_id); @@ -569,7 +569,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { hir::OpaqueTyOrigin::AsyncFn => return false, // Otherwise, generate the label we'll use in the error message. - hir::OpaqueTyOrigin::TypeAlias + hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::Misc => "impl Trait", }; diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index f9bc7389b070d..0ef561fdbbb29 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -100,26 +100,17 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_adt(def, substs) } + ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }) => { + let_position_impl_trait_type(tcx, def_id.expect_local()) + } ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => { find_opaque_ty_constraints(tcx, def_id.expect_local()) } // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), origin, .. }) => { - let concrete_types = match origin { - OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => { - &tcx.mir_borrowck(owner.expect_local()).concrete_opaque_types - } - OpaqueTyOrigin::Misc => { - // We shouldn't leak borrowck results through impl trait in bindings. - // For example, we shouldn't be able to tell if `x` in - // `let x: impl Sized + 'a = &()` has type `&'static ()` or `&'a ()`. - &tcx.typeck_tables_of(owner.expect_local()).concrete_opaque_types - } - OpaqueTyOrigin::TypeAlias => { - span_bug!(item.span, "Type alias impl trait shouldn't have an owner") - } - }; - let concrete_ty = concrete_types + ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => { + let concrete_ty = tcx + .mir_borrowck(owner.expect_local()) + .concrete_opaque_types .get(&def_id) .map(|opaque| opaque.concrete_type) .unwrap_or_else(|| { @@ -148,13 +139,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } }); debug!("concrete_ty = {:?}", concrete_ty); - if concrete_ty.has_erased_regions() { - // FIXME(impl_trait_in_bindings) Handle this case. - tcx.sess.span_fatal( - item.span, - "lifetimes in impl Trait types in bindings are not currently supported", - ); - } concrete_ty } ItemKind::Trait(..) @@ -589,6 +573,50 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } } +fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty<'_> { + let scope = tcx.hir().get_defining_scope(tcx.hir().as_local_hir_id(opaque_ty_id)); + let scope_def_id = tcx.hir().local_def_id(scope); + + let opaque_ty_def_id = opaque_ty_id.to_def_id(); + + let owner_tables = tcx.typeck_tables_of(scope_def_id); + let concrete_ty = owner_tables + .concrete_opaque_types + .get(&opaque_ty_def_id) + .map(|opaque| opaque.concrete_type) + .unwrap_or_else(|| { + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "owner {:?} has no opaque type for {:?} in its tables", + scope_def_id, opaque_ty_id + ), + ); + if let Some(ErrorReported) = owner_tables.tainted_by_errors { + // Some error in the owner fn prevented us from populating the + // `concrete_opaque_types` table. + tcx.types.err + } else { + // We failed to resolve the opaque type or it resolves to + // itself. Return the non-revealed type, which should result in + // E0720. + tcx.mk_opaque( + opaque_ty_def_id, + InternalSubsts::identity_for_item(tcx, opaque_ty_def_id), + ) + } + }); + debug!("concrete_ty = {:?}", concrete_ty); + if concrete_ty.has_erased_regions() { + // FIXME(impl_trait_in_bindings) Handle this case. + tcx.sess.span_fatal( + tcx.hir().span(tcx.hir().as_local_hir_id(opaque_ty_id)), + "lifetimes in impl Trait types in bindings are not currently supported", + ); + } + concrete_ty +} + fn infer_placeholder_type( tcx: TyCtxt<'_>, def_id: LocalDefId, diff --git a/src/test/ui/impl-trait/issue-60473.rs b/src/test/ui/impl-trait/issue-60473.rs index 50cf0c8c6d641..2ef86f03d340c 100644 --- a/src/test/ui/impl-trait/issue-60473.rs +++ b/src/test/ui/impl-trait/issue-60473.rs @@ -5,13 +5,11 @@ struct A<'a>(&'a ()); -trait Trait { -} +trait Trait {} -impl Trait for () { -} +impl Trait for () {} fn main() { - let x: impl Trait = (); // FIXME: The error doesn't seem correct. - //~^ ERROR: opaque type expands to a recursive type + let x: impl Trait = (); + //~^ ERROR: missing lifetime specifier } diff --git a/src/test/ui/impl-trait/issue-60473.stderr b/src/test/ui/impl-trait/issue-60473.stderr index 2d95be4e52c61..367b5db5d2dce 100644 --- a/src/test/ui/impl-trait/issue-60473.stderr +++ b/src/test/ui/impl-trait/issue-60473.stderr @@ -1,11 +1,15 @@ -error[E0720]: opaque type expands to a recursive type - --> $DIR/issue-60473.rs:15:12 +error[E0106]: missing lifetime specifier + --> $DIR/issue-60473.rs:13:23 | -LL | let x: impl Trait = (); // FIXME: The error doesn't seem correct. - | ^^^^^^^^^^^^^ expands to a recursive type +LL | let x: impl Trait = (); + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | fn main<'a>() { +LL | let x: impl Trait> = (); | - = note: type resolves to itself error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/impl-trait/issue-67166.rs b/src/test/ui/impl-trait/issue-67166.rs index de7433a9bfc4c..efa67558bd7c1 100644 --- a/src/test/ui/impl-trait/issue-67166.rs +++ b/src/test/ui/impl-trait/issue-67166.rs @@ -4,8 +4,8 @@ #![allow(incomplete_features)] pub fn run() { - let _foo: Box = Box::new(()); // FIXME: The error doesn't much make sense. - //~^ ERROR: opaque type expands to a recursive type + let _foo: Box = Box::new(()); + //~^ ERROR: missing lifetime specifier } fn main() {} diff --git a/src/test/ui/impl-trait/issue-67166.stderr b/src/test/ui/impl-trait/issue-67166.stderr index 56cba3cff0b55..14c78684e3e2f 100644 --- a/src/test/ui/impl-trait/issue-67166.stderr +++ b/src/test/ui/impl-trait/issue-67166.stderr @@ -1,11 +1,15 @@ -error[E0720]: opaque type expands to a recursive type - --> $DIR/issue-67166.rs:7:19 +error[E0106]: missing lifetime specifier + --> $DIR/issue-67166.rs:7:31 | -LL | let _foo: Box = Box::new(()); // FIXME: The error doesn't much make sense. - | ^^^^^^^^^^^^^^ expands to a recursive type +LL | let _foo: Box = Box::new(()); + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | pub fn run<'a>() { +LL | let _foo: Box = Box::new(()); | - = note: type resolves to itself error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0106`. From aef9b1a8dbff3627f5d5c8bb6acaf6045240e45d Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 12:22:45 +0100 Subject: [PATCH 11/25] Add more tests for type alias impl Trait --- src/test/rustdoc/auxiliary/issue-73061.rs | 17 +++++++++ ...sue-73061-cross-crate-opaque-assoc-type.rs | 14 +++++++ .../issue-57188-associate-impl-capture.rs | 24 ++++++++++++ ...ue-62000-associate-impl-trait-lifetimes.rs | 38 +++++++++++++++++++ ...ssue-69136-inner-lifetime-resolve-error.rs | 22 +++++++++++ ...-69136-inner-lifetime-resolve-error.stderr | 11 ++++++ .../issue-69136-inner-lifetime-resolve-ok.rs | 23 +++++++++++ .../type-alias-nested-impl-trait.rs | 14 +++++++ 8 files changed, 163 insertions(+) create mode 100644 src/test/rustdoc/auxiliary/issue-73061.rs create mode 100644 src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs diff --git a/src/test/rustdoc/auxiliary/issue-73061.rs b/src/test/rustdoc/auxiliary/issue-73061.rs new file mode 100644 index 0000000000000..e05a3bc6d9180 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-73061.rs @@ -0,0 +1,17 @@ +//edition:2018 + +#![feature(type_alias_impl_trait)] + +pub trait Foo { + type X: std::future::Future; + fn x(&self) -> Self::X; +} + +pub struct F; + +impl Foo for F { + type X = impl std::future::Future; + fn x(&self) -> Self::X { + async {} + } +} diff --git a/src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs b/src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs new file mode 100644 index 0000000000000..2700f2370eec8 --- /dev/null +++ b/src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs @@ -0,0 +1,14 @@ +// Regression test for ICE #73061 + +// aux-build:issue-73061.rs + +extern crate issue_73061; + +pub struct Z; + +impl issue_73061::Foo for Z { + type X = ::X; + fn x(&self) -> Self::X { + issue_73061::F.x() + } +} diff --git a/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs new file mode 100644 index 0000000000000..3a7a5da075f11 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs @@ -0,0 +1,24 @@ +// Regression test for #57188 + +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Baz<'a> { + source: &'a str, +} + +trait Foo<'a> { + type T: Iterator> + 'a; + fn foo(source: &'a str) -> Self::T; +} + +struct Bar; +impl<'a> Foo<'a> for Bar { + type T = impl Iterator> + 'a; + fn foo(source: &'a str) -> Self::T { + std::iter::once(Baz { source }) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs new file mode 100644 index 0000000000000..36779a0ce89c3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs @@ -0,0 +1,38 @@ +// Regression test for #62988 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait MyTrait { + type AssocType: Send; + fn ret(&self) -> Self::AssocType; +} + +impl MyTrait for () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +impl<'a> MyTrait for &'a () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +trait MyLifetimeTrait<'a> { + type AssocType: Send + 'a; + fn ret(&self) -> Self::AssocType; +} + +impl<'a> MyLifetimeTrait<'a> for &'a () { + type AssocType = impl Send + 'a; + fn ret(&self) -> Self::AssocType { + *self + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs new file mode 100644 index 0000000000000..6732902c09a50 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs @@ -0,0 +1,22 @@ +// Regression test for #69136 + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return = impl WithAssoc; +//~^ ERROR use of undeclared lifetime name `'a` + +fn my_fun() -> Return<()> {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr new file mode 100644 index 0000000000000..fe45e39d938f0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr @@ -0,0 +1,11 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:65 + | +LL | type Return = impl WithAssoc; + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `'a,` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs new file mode 100644 index 0000000000000..a6916eda8b093 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs @@ -0,0 +1,23 @@ +// Test-pass variant of #69136 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return<'a> = impl WithAssoc; + +fn my_fun<'a>() -> Return<'a> {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs new file mode 100644 index 0000000000000..fd954801dc047 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(type_alias_impl_trait)] + +use std::iter::{once, Chain}; + +type I = Chain>; +fn test2>(x: A) -> I { + x.chain(once("5")) +} + +fn main() { + assert_eq!(vec!["1", "3", "5"], test2(["1", "3"].iter().cloned()).collect::>()); +} From 10441a2d80c59c2a94a080035b8916aebe1e9689 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 15:05:06 +0100 Subject: [PATCH 12/25] Remove ImplItemKind::OpaqueTy from clippy --- src/tools/clippy/clippy_lints/src/missing_doc.rs | 1 - src/tools/clippy/clippy_lints/src/missing_inline.rs | 2 +- src/tools/clippy/clippy_lints/src/utils/inspector.rs | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 2eefb6bbaf424..0fd1e87f9e415 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -187,7 +187,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::ImplItemKind::Const(..) => "an associated constant", hir::ImplItemKind::Fn(..) => "a method", hir::ImplItemKind::TyAlias(_) => "an associated type", - hir::ImplItemKind::OpaqueTy(_) => "an existential type", }; self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, desc); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 3ad3d5aee4d4a..1802470b1841e 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -142,7 +142,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline { let desc = match impl_item.kind { hir::ImplItemKind::Fn(..) => "a method", - hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) | hir::ImplItemKind::OpaqueTy(_) => return, + hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) => return, }; let def_id = cx.tcx.hir().local_def_id(impl_item.hir_id); diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index 9b672b9ec225b..9a4689631cca0 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -63,7 +63,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { }, hir::ImplItemKind::Fn(..) => println!("method"), hir::ImplItemKind::TyAlias(_) => println!("associated type"), - hir::ImplItemKind::OpaqueTy(_) => println!("existential type"), } } // fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx From 4696907f3f44cd5ee5cb689247fd2cf3ea2240dc Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 7 Jun 2020 18:56:17 +0100 Subject: [PATCH 13/25] Rename `TyKind::Def` to `OpaqueDef` --- src/librustc_ast_lowering/lib.rs | 2 +- src/librustc_hir/hir.rs | 10 +++++----- src/librustc_hir/intravisit.rs | 2 +- src/librustc_hir_pretty/lib.rs | 2 +- .../nice_region_error/named_anon_conflict.rs | 3 ++- src/librustc_lint/builtin.rs | 2 +- src/librustc_passes/dead.rs | 2 +- src/librustc_resolve/late/lifetimes.rs | 8 ++++---- src/librustc_save_analysis/sig.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- 13 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 39546c861bd08..7d335fc608a7f 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1400,7 +1400,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lctx.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span); // `impl Trait` now just becomes `Foo<'a, 'b, ..>`. - hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, lifetimes) + hir::TyKind::OpaqueDef(hir::ItemId { id: opaque_ty_id }, lifetimes) }) } diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 1190c90cd17ee..6facaf400a731 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2046,12 +2046,12 @@ pub enum TyKind<'hir> { /// /// Type parameters may be stored in each `PathSegment`. Path(QPath<'hir>), - /// A type definition itself. This is currently only used for the `type Foo = impl Trait` - /// item that `impl Trait` in return position desugars to. + /// A opaque type definition itself. This is currently only used for the + /// `opaque type Foo: Trait` item that `impl Trait` in desugars to. /// - /// The generic argument list contains the lifetimes (and in the future possibly parameters) - /// that are actually bound on the `impl Trait`. - Def(ItemId, &'hir [GenericArg<'hir>]), + /// The generic argument list contains the lifetimes (and in the future + /// possibly parameters) that are actually bound on the `impl Trait`. + OpaqueDef(ItemId, &'hir [GenericArg<'hir>]), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime), diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 8d7bba7dbd578..a8e7f5e295212 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -690,7 +690,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { TyKind::Path(ref qpath) => { visitor.visit_qpath(qpath, typ.hir_id, typ.span); } - TyKind::Def(item_id, lifetimes) => { + TyKind::OpaqueDef(item_id, lifetimes) => { visitor.visit_nested_item(item_id); walk_list!(visitor, visit_generic_arg, lifetimes); } diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index cf153840a04ba..7a403d07c8859 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -385,7 +385,7 @@ impl<'a> State<'a> { &f.param_names[..], ); } - hir::TyKind::Def(..) => self.s.word("/*impl Trait*/"), + hir::TyKind::OpaqueDef(..) => self.s.word("/*impl Trait*/"), hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false), hir::TyKind::TraitObject(bounds, ref lifetime) => { let mut first = true; diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs index acaf474699276..a56401ebb90f0 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -84,7 +84,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { rustc_hir::intravisit::walk_ty(&mut v, ty); debug!("try_report_named_anon_conflict: ret ty {:?}", ty); - if sub == &ty::ReStatic && (matches!(ty.kind, TyKind::Def(_, _)) || v.0.len() == 1) + if sub == &ty::ReStatic + && (matches!(ty.kind, TyKind::OpaqueDef(_, _)) || v.0.len() == 1) { debug!("try_report_named_anon_conflict: impl Trait + 'static"); // This is an `impl Trait` or `dyn Trait` return that evaluates de need of diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e9f5956a41692..e5daf88c81e2e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1102,7 +1102,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { hir::ItemKind::TyAlias(ref ty, ref generics) => (&*ty, generics), _ => return, }; - if let hir::TyKind::Def(..) = ty.kind { + if let hir::TyKind::OpaqueDef(..) = ty.kind { // Bounds are respected for `type X = impl Trait` return; } diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 419bbda78271a..503fbb64db83d 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -304,7 +304,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { - if let TyKind::Def(item_id, _) = ty.kind { + if let TyKind::OpaqueDef(item_id, _) = ty.kind { let item = self.tcx.hir().expect_item(item_id.id); intravisit::walk_item(self, item); } diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 72fe4355814ee..0af49075c6758 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -400,9 +400,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.with(scope, |_, this| intravisit::walk_item(this, item)); } hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { - // Opaque types are visited when we visit the `TyKind::Def`, so - // that they have the lifetimes from their parent opaque_ty in - // scope. + // Opaque types are visited when we visit the + // `TyKind::OpaqueDef`, so that they have the lifetimes from + // their parent opaque_ty in scope. } hir::ItemKind::TyAlias(_, ref generics) | hir::ItemKind::Enum(_, ref generics) @@ -557,7 +557,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.with(scope, |_, this| this.visit_ty(&mt.ty)); } - hir::TyKind::Def(item_id, lifetimes) => { + hir::TyKind::OpaqueDef(item_id, lifetimes) => { // Resolve the lifetimes in the bounds to the lifetime defs in the generics. // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to // `type MyAnonTy<'b> = impl MyTrait<'b>;` diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 6fec5cdba8b59..01a617d746583 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -310,7 +310,7 @@ impl<'hir> Sig for hir::Ty<'hir> { } hir::TyKind::Typeof(_) | hir::TyKind::Infer - | hir::TyKind::Def(..) + | hir::TyKind::OpaqueDef(..) | hir::TyKind::Path(..) | hir::TyKind::Err => Err("Ty"), } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 24e38cc42ef6c..ecbb5f81b0360 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2838,7 +2838,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself)); self.res_to_ty(opt_self_ty, path, false) } - hir::TyKind::Def(item_id, ref lifetimes) => { + hir::TyKind::OpaqueDef(item_id, ref lifetimes) => { let opaque_ty = tcx.hir().expect_item(item_id.id); let def_id = tcx.hir().local_def_id(item_id.id).to_def_id(); diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index a324bd03eca8f..d95d9190b0b6a 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1494,7 +1494,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut is_object_safe = false; if let hir::FnRetTy::Return(ty) = fn_output { // Get the return type. - if let hir::TyKind::Def(..) = ty.kind { + if let hir::TyKind::OpaqueDef(..) = ty.kind { let ty = AstConv::ast_ty_to_ty(fcx, ty); // Get the `impl Trait`'s `DefId`. if let ty::Opaque(def_id, _) = ty.kind { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 191244e41c80c..1d59d749634ee 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1417,7 +1417,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty), Tup(tys) => tys.iter().any(is_suggestable_infer_ty), Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), - Def(_, generic_args) => are_suggestable_generic_args(generic_args), + OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args), Path(hir::QPath::TypeRelative(ty, segment)) => { is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.generic_args().args) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 92bf6b564cf8a..adb2ae9a5d660 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1351,7 +1351,7 @@ impl Clean for hir::Ty<'_> { Array(box ty.clean(cx), length) } TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), - TyKind::Def(item_id, _) => { + TyKind::OpaqueDef(item_id, _) => { let item = cx.tcx.hir().expect_item(item_id.id); if let hir::ItemKind::OpaqueTy(ref ty) = item.kind { ImplTrait(ty.bounds.clean(cx)) From ea998cb59ab42b26f82bfb86ab6c613c14862b26 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 7 Jun 2020 19:42:08 +0100 Subject: [PATCH 14/25] Allow all impl trait types to capture bound lifetimes --- src/librustc_ast_lowering/item.rs | 30 +++++- src/librustc_ast_lowering/lib.rs | 147 ++++++++++++++++++++++++------ src/librustc_typeck/astconv.rs | 29 +++--- 3 files changed, 159 insertions(+), 47 deletions(-) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index f8a5120b72a18..8cfbd408e22b3 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -7,6 +7,7 @@ use rustc_ast::attr; use rustc_ast::node_id::NodeMap; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, Visitor}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -286,8 +287,21 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)), ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)), ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => { - let ty = - self.lower_ty(ty, ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)); + // We lower + // + // type Foo = impl Trait + // + // to + // + // type Foo = Foo1 + // opaque type Foo1: Trait + let ty = self.lower_ty( + ty, + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin: hir::OpaqueTyOrigin::Misc, + }, + ); let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); hir::ItemKind::TyAlias(ty, generics) } @@ -420,8 +434,13 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, body: Option<&Expr>, ) -> (&'hir hir::Ty<'hir>, hir::BodyId) { + let mut capturable_lifetimes; let itctx = if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc) + capturable_lifetimes = FxHashSet::default(); + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut capturable_lifetimes, + origin: hir::OpaqueTyOrigin::Misc, + } } else { ImplTraitContext::Disallowed(ImplTraitPosition::Binding) }; @@ -829,7 +848,10 @@ impl<'hir> LoweringContext<'_, 'hir> { Some(ty) => { let ty = self.lower_ty( ty, - ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc), + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin: hir::OpaqueTyOrigin::Misc, + }, ); hir::ImplItemKind::TyAlias(ty) } diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 7d335fc608a7f..d7946ad009415 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -224,11 +224,30 @@ enum ImplTraitContext<'b, 'a> { /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`. /// - /// We optionally store a `DefId` for the parent item here so we can look up necessary - /// information later. It is `None` when no information about the context should be stored - /// (e.g., for consts and statics). - OpaqueTy(Option /* fn def-ID */, hir::OpaqueTyOrigin), - + ReturnPositionOpaqueTy { + /// `DefId` for the parent function, used to look up necessary + /// information later. + fn_def_id: DefId, + /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn, + origin: hir::OpaqueTyOrigin, + }, + /// Impl trait in type aliases, consts and statics. + OtherOpaqueTy { + /// Set of lifetimes that this opaque type can capture, if it uses + /// them. This includes lifetimes bound since we entered this context. + /// For example, in + /// + /// type A<'b> = impl for<'a> Trait<'a, Out = impl Sized + 'a>; + /// + /// the inner opaque type captures `'a` because it uses it. It doesn't + /// need to capture `'b` because it already inherits the lifetime + /// parameter from `A`. + // FIXME(impl_trait): but `required_region_bounds` will ICE later + // anyway. + capturable_lifetimes: &'b mut FxHashSet, + /// Origin: Either OpaqueTyOrigin::Misc or OpaqueTyOrigin::Binding, + origin: hir::OpaqueTyOrigin, + }, /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -253,7 +272,12 @@ impl<'a> ImplTraitContext<'_, 'a> { use self::ImplTraitContext::*; match self { Universal(params) => Universal(params), - OpaqueTy(fn_def_id, origin) => OpaqueTy(*fn_def_id, *origin), + ReturnPositionOpaqueTy { fn_def_id, origin } => { + ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin } + } + OtherOpaqueTy { capturable_lifetimes, origin } => { + OtherOpaqueTy { capturable_lifetimes, origin: *origin } + } Disallowed(pos) => Disallowed(*pos), } } @@ -1001,6 +1025,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) } } AssocTyConstraintKind::Bound { ref bounds } => { + let mut capturable_lifetimes; // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: @@ -1010,7 +1035,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo() -> impl Iterator - ImplTraitContext::OpaqueTy(..) => (true, itctx), + ImplTraitContext::ReturnPositionOpaqueTy { .. } + | ImplTraitContext::OtherOpaqueTy { .. } => (true, itctx), // We are in the argument position, but within a dyn type: // @@ -1028,7 +1054,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // FIXME: this is only needed until `impl Trait` is allowed in type aliases. ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => { - (true, ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)) + capturable_lifetimes = FxHashSet::default(); + ( + true, + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut capturable_lifetimes, + origin: hir::OpaqueTyOrigin::Misc, + }, + ) } // We are in the parameter position, but not within a dyn type: @@ -1270,10 +1303,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::ImplTrait(def_node_id, ref bounds) => { let span = t.span; match itctx { - ImplTraitContext::OpaqueTy(fn_def_id, origin) => { - self.lower_opaque_impl_trait(span, fn_def_id, origin, def_node_id, |this| { - this.lower_param_bounds(bounds, itctx) - }) + ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin } => self + .lower_opaque_impl_trait( + span, + Some(fn_def_id), + origin, + def_node_id, + None, + |this| this.lower_param_bounds(bounds, itctx), + ), + ImplTraitContext::OtherOpaqueTy { ref capturable_lifetimes, origin } => { + // Reset capturable lifetimes, any nested impl trait + // types will inherit lifetimes from this opaque type, + // so don't need to capture them again. + let nested_itctx = ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin, + }; + self.lower_opaque_impl_trait( + span, + None, + origin, + def_node_id, + Some(capturable_lifetimes), + |this| this.lower_param_bounds(bounds, nested_itctx), + ) } ImplTraitContext::Universal(in_band_ty_params) => { // Add a definition for the in-band `Param`. @@ -1351,6 +1405,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn_def_id: Option, origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, + capturable_lifetimes: Option<&FxHashSet>, lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>, ) -> hir::TyKind<'hir> { debug!( @@ -1371,17 +1426,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds); - let (lifetimes, lifetime_defs): (&[_], &[_]) = if fn_def_id.is_some() { - self.lifetimes_from_impl_trait_bounds(opaque_ty_node_id, opaque_ty_def_id, &hir_bounds) - } else { - // Non return-position impl trait captures all of the lifetimes of - // the parent item. - (&[], &[]) - }; + let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds( + opaque_ty_node_id, + opaque_ty_def_id, + &hir_bounds, + capturable_lifetimes, + ); - debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes,); + debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes); - debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs,); + debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs); self.with_hir_id_owner(opaque_ty_node_id, move |lctx| { let opaque_ty_item = hir::OpaqueTy { @@ -1438,6 +1492,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_id: NodeId, parent_def_id: LocalDefId, bounds: hir::GenericBounds<'hir>, + lifetimes_to_include: Option<&FxHashSet>, ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) { debug!( "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \ @@ -1458,6 +1513,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { already_defined_lifetimes: FxHashSet, output_lifetimes: Vec>, output_lifetime_params: Vec>, + lifetimes_to_include: Option<&'r FxHashSet>, } impl<'r, 'a, 'v, 'hir> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> { @@ -1543,6 +1599,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if !self.currently_bound_lifetimes.contains(&name) && !self.already_defined_lifetimes.contains(&name) + && self.lifetimes_to_include.map_or(true, |lifetimes| lifetimes.contains(&name)) { self.already_defined_lifetimes.insert(name); @@ -1596,6 +1653,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { already_defined_lifetimes: FxHashSet::default(), output_lifetimes: Vec::new(), output_lifetime_params: Vec::new(), + lifetimes_to_include, }; for bound in bounds { @@ -1620,10 +1678,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } let ty = l.ty.as_ref().map(|t| { + let mut capturable_lifetimes; self.lower_ty( t, if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Binding) + capturable_lifetimes = FxHashSet::default(); + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut capturable_lifetimes, + origin: hir::OpaqueTyOrigin::Binding, + } } else { ImplTraitContext::Disallowed(ImplTraitPosition::Binding) }, @@ -1726,7 +1789,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { FnRetTy::Ty(ref ty) => { let context = match in_band_ty_params { Some((def_id, _)) if impl_trait_return_allow => { - ImplTraitContext::OpaqueTy(Some(def_id), hir::OpaqueTyOrigin::FnReturn) + ImplTraitContext::ReturnPositionOpaqueTy { + fn_def_id: def_id, + origin: hir::OpaqueTyOrigin::FnReturn, + } } _ => ImplTraitContext::disallowed(), }; @@ -1945,7 +2011,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Foo = impl Trait` is, internally, created as a child of the // async fn, so the *type parameters* are inherited. It's // only the lifetime parameters that we must supply. - let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args); + let opaque_ty_ref = hir::TyKind::OpaqueDef(hir::ItemId { id: opaque_ty_id }, generic_args); let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref); hir::FnRetTy::Return(self.arena.alloc(opaque_ty)) } @@ -1963,8 +2029,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the // `impl Future` opaque type that `async fn` implicitly // generates. - let context = - ImplTraitContext::OpaqueTy(Some(fn_def_id), hir::OpaqueTyOrigin::FnReturn); + let context = ImplTraitContext::ReturnPositionOpaqueTy { + fn_def_id, + origin: hir::OpaqueTyOrigin::FnReturn, + }; self.lower_ty(ty, context) } FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])), @@ -2114,7 +2182,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { default: default.as_ref().map(|x| { self.lower_ty( x, - ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc), + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin: hir::OpaqueTyOrigin::Misc, + }, ) }), synthetic: param @@ -2170,8 +2241,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &NodeMap::default(), itctx.reborrow(), ); + let trait_ref = self.with_in_scope_lifetime_defs(&p.bound_generic_params, |this| { - this.lower_trait_ref(&p.trait_ref, itctx) + // Any impl Trait types defined within this scope can capture + // lifetimes bound on this predicate. + let lt_def_names = p.bound_generic_params.iter().filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(hir::LifetimeName::Param( + ParamName::Plain(param.ident.normalize_to_macros_2_0()), + )), + _ => None, + }); + if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx { + capturable_lifetimes.extend(lt_def_names.clone()); + } + + let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow()); + + if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx { + for param in lt_def_names { + capturable_lifetimes.remove(¶m); + } + } + res }); hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ecbb5f81b0360..267f3d9f3ef6e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2843,19 +2843,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let def_id = tcx.hir().local_def_id(item_id.id).to_def_id(); match opaque_ty.kind { - // RPIT (return position impl trait) - // Only lifetimes mentioned in the impl Trait predicate are - // captured by the opaque type, so the lifetime parameters - // from the parent item need to be replaced with `'static`. - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => { - self.impl_trait_ty_to_ty(def_id, lifetimes) - } - // This arm is for `impl Trait` in the types of statics, - // constants, locals and type aliases. These capture all - // parent lifetimes, so they can use their identity subst. - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { - let substs = InternalSubsts::identity_for_item(tcx, def_id); - tcx.mk_opaque(def_id, substs) + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { + self.impl_trait_ty_to_ty(def_id, lifetimes, impl_trait_fn.is_some()) } ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), } @@ -2911,6 +2900,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, def_id: DefId, lifetimes: &[hir::GenericArg<'_>], + replace_parent_lifetimes: bool, ) -> Ty<'tcx> { debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes); let tcx = self.tcx(); @@ -2932,9 +2922,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { _ => bug!(), } } else { - // Replace all parent lifetimes with `'static`. match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(), + // For RPIT (return position impl trait), only lifetimes + // mentioned in the impl Trait predicate are captured by + // the opaque type, so the lifetime parameters from the + // parent item need to be replaced with `'static`. + // + // For `impl Trait` in the types of statics, constants, + // locals and type aliases. These capture all parent + // lifetimes, so they can use their identity subst. + GenericParamDefKind::Lifetime if replace_parent_lifetimes => { + tcx.lifetimes.re_static.into() + } _ => tcx.mk_param_from_def(param), } } From 51a65503e3e66e64a9522b2a2ab1b275d569542b Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 7 Jun 2020 19:52:05 +0100 Subject: [PATCH 15/25] Document some opaque types code --- src/librustc_resolve/late/lifetimes.rs | 4 +- src/librustc_trait_selection/opaque_types.rs | 14 +- src/librustc_typeck/check/wfcheck.rs | 181 +++++++++---------- src/librustc_typeck/collect/type_of.rs | 10 + 4 files changed, 109 insertions(+), 100 deletions(-) diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 0af49075c6758..5bbf8703f0b60 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -258,8 +258,8 @@ enum Elide { Exact(Region), /// Less or more than one lifetime were found, error on unspecified. Error(Vec), - /// Forbid lifetime elision inside of a larger scope that does. For - /// example, in let position impl trait. + /// Forbid lifetime elision inside of a larger scope where it would be + /// permitted. For example, in let position impl trait. Forbid, } diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index e1f0c579a3c36..d53a0ec9ef884 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -407,12 +407,20 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let first_own_region = match opaque_defn.origin { hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { - // For these opaque types, only the item's own lifetime - // parameters are considered. + // We lower + // + // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> + // + // into + // + // type foo::<'p0..'pn>::Foo<'q0..'qm> + // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. + // + // For these types we onlt iterate over `'l0..lm` below. tcx.generics_of(def_id).parent_count } // These opaque type inherit all lifetime parameters from their - // parent. + // parent, so we have to check them all. hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::Misc => 0, }; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index c0be1d42d134c..f3297ed674347 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -801,18 +801,14 @@ fn check_where_clauses<'tcx, 'fcx>( traits::Obligation::new(cause, fcx.param_env, pred) }); - let mut predicates = predicates.instantiate_identity(fcx.tcx); + let predicates = predicates.instantiate_identity(fcx.tcx); if let Some((mut return_ty, span)) = return_ty { if return_ty.has_infer_types_or_consts() { fcx.select_obligations_where_possible(false, |_| {}); return_ty = fcx.resolve_vars_if_possible(&return_ty); } - let opaque_types = check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); - for _ in 0..opaque_types.len() { - predicates.spans.push(span); - } - predicates.predicates.extend(opaque_types); + check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); } let predicates = fcx.normalize_associated_types_in(span, &predicates); @@ -884,113 +880,109 @@ fn check_opaque_types<'fcx, 'tcx>( fn_def_id: LocalDefId, span: Span, ty: Ty<'tcx>, -) -> Vec> { +) { trace!("check_opaque_types(ty={:?})", ty); - let mut substituted_predicates = Vec::new(); ty.fold_with(&mut ty::fold::BottomUpFolder { tcx: fcx.tcx, ty_op: |ty| { if let ty::Opaque(def_id, substs) = ty.kind { trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs); let generics = tcx.generics_of(def_id); - // Only check named `impl Trait` types defined in this crate. - if !def_id.is_local() { + + let opaque_hir_id = if let Some(local_id) = def_id.as_local() { + tcx.hir().as_local_hir_id(local_id) + } else { + // Opaque types from other crates won't have defining uses in this crate. return ty; - } - let opaque_hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + }; if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) = tcx.hir().expect_item(opaque_hir_id).kind { - // Don't check return position impl trait. + // No need to check return position impl trait (RPIT) + // because for type and const parameters they are correct + // by construction: we convert + // + // fn foo() -> impl Trait + // + // into + // + // type Foo + // fn foo() -> Foo. + // + // For lifetime parameters we convert + // + // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> + // + // into + // + // type foo::<'p0..'pn>::Foo<'q0..'qm> + // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. + // + // which would error here on all of the `'static` args. + return ty; + } + if !may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { return ty; } - if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { - trace!("check_opaque_types: may define, generics={:#?}", generics); - let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); - for (i, arg) in substs.iter().enumerate() { - let arg_is_param = match arg.unpack() { - GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)), - - GenericArgKind::Lifetime(region) => { - if let ty::ReStatic = region { - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_label( - tcx.def_span(generics.param_at(i, tcx).def_id), - "cannot use static lifetime; use a bound lifetime \ + trace!("check_opaque_types: may define, generics={:#?}", generics); + let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); + for (i, arg) in substs.iter().enumerate() { + let arg_is_param = match arg.unpack() { + GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)), + + GenericArgKind::Lifetime(region) => { + if let ty::ReStatic = region { + tcx.sess + .struct_span_err( + span, + "non-defining opaque type use in defining scope", + ) + .span_label( + tcx.def_span(generics.param_at(i, tcx).def_id), + "cannot use static lifetime; use a bound lifetime \ instead or remove the lifetime parameter from the \ opaque type", - ) - .emit(); - continue; - } - - true + ) + .emit(); + continue; } - GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)), - }; - - if arg_is_param { - seen_params.entry(arg).or_default().push(i); - } else { - // Prevent `fn foo() -> Foo` from being defining. - let opaque_param = generics.param_at(i, tcx); - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_note( - tcx.def_span(opaque_param.def_id), - &format!( - "used non-generic {} `{}` for generic parameter", - opaque_param.kind.descr(), - arg, - ), - ) - .emit(); - } - } // for (arg, param) - - for (_, indices) in seen_params { - if indices.len() > 1 { - let descr = generics.param_at(indices[0], tcx).kind.descr(); - let spans: Vec<_> = indices - .into_iter() - .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id)) - .collect(); - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_note(spans, &format!("{} used multiple times", descr)) - .emit(); + true } + + GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)), + }; + + if arg_is_param { + seen_params.entry(arg).or_default().push(i); + } else { + // Prevent `fn foo() -> Foo` from being defining. + let opaque_param = generics.param_at(i, tcx); + tcx.sess + .struct_span_err(span, "non-defining opaque type use in defining scope") + .span_note( + tcx.def_span(opaque_param.def_id), + &format!( + "used non-generic {} `{}` for generic parameter", + opaque_param.kind.descr(), + arg, + ), + ) + .emit(); } - } // if may_define_opaque_type - - // Now register the bounds on the parameters of the opaque type - // so the parameters given by the function need to fulfill them. - // - // type Foo = impl Baz + 'static; - // fn foo() -> Foo { .. *} - // - // becomes - // - // type Foo = impl Baz + 'static; - // fn foo() -> Foo { .. *} - let predicates = tcx.predicates_of(def_id); - trace!("check_opaque_types: may define, predicates={:#?}", predicates,); - for &(pred, _) in predicates.predicates { - let substituted_pred = pred.subst(fcx.tcx, substs); - // Avoid duplication of predicates that contain no parameters, for example. - if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { - substituted_predicates.push(substituted_pred); + } // for (arg, param) + + for (_, indices) in seen_params { + if indices.len() > 1 { + let descr = generics.param_at(indices[0], tcx).kind.descr(); + let spans: Vec<_> = indices + .into_iter() + .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id)) + .collect(); + tcx.sess + .struct_span_err(span, "non-defining opaque type use in defining scope") + .span_note(spans, &format!("{} used multiple times", descr)) + .emit(); } } } // if let Opaque @@ -999,7 +991,6 @@ fn check_opaque_types<'fcx, 'tcx>( lt_op: |lt| lt, ct_op: |ct| ct, }); - substituted_predicates } const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 0ef561fdbbb29..549a20531e299 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -573,6 +573,16 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } } +/// Retrieve the inferred concrete type for let position impl trait. +/// +/// This is different to other kinds of impl trait because: +/// +/// 1. We know which function contains the defining use (the function that +/// contains the let statement) +/// 2. We do not currently allow (free) lifetimes in the return type. `let` +/// statements in some statically unreachable code are removed from the MIR +/// by the time we borrow check, and it's not clear how we should handle +/// those. fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty<'_> { let scope = tcx.hir().get_defining_scope(tcx.hir().as_local_hir_id(opaque_ty_id)); let scope_def_id = tcx.hir().local_def_id(scope); From c9f2cbf215870049fe9ffe312f7cc2bd78ce1744 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Tue, 9 Jun 2020 22:58:32 +0200 Subject: [PATCH 16/25] Automatically prioritize unsoundness issues --- triagebot.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index e43cff5538659..9c5464c9fc535 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -38,10 +38,16 @@ label = "ICEBreaker-Cleanup-Crew" [prioritize] label = "I-prioritize" -prioritize_on = ["regression-from-stable-to-stable", "regression-from-stable-to-beta", "regression-from-stable-to-nightly"] +prioritize_on = [ + "regression-from-stable-to-stable", + "regression-from-stable-to-beta", + "regression-from-stable-to-nightly", + "I-unsound 💥", +] exclude_labels = [ "P-*", "T-infra", "T-release", + "requires-nightly", ] zulip_stream = 227806 From fff822fead6249671cbcb090b24bce58fab38de0 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Tue, 2 Jun 2020 07:59:11 +0000 Subject: [PATCH 17/25] Migrate to numeric associated consts --- src/liballoc/rc.rs | 4 +- src/liballoc/rc/tests.rs | 4 +- src/liballoc/sync/tests.rs | 4 +- src/liballoc/tests/str.rs | 4 +- src/liballoc/tests/vec.rs | 18 +- src/libcore/cell.rs | 10 +- src/libcore/convert/num.rs | 6 +- src/libcore/num/mod.rs | 66 +++---- src/libcore/num/wrapping.rs | 7 +- src/libcore/ptr/const_ptr.rs | 4 +- src/libcore/ptr/mod.rs | 4 +- src/libcore/slice/mod.rs | 12 +- src/libcore/str/mod.rs | 18 +- src/libcore/tests/num/mod.rs | 32 +-- src/libcore/tests/ptr.rs | 2 +- src/libcore/tests/slice.rs | 4 +- src/librustc_apfloat/lib.rs | 6 +- src/librustc_apfloat/tests/ieee.rs | 4 +- src/librustc_data_structures/base_n/tests.rs | 4 +- src/librustc_expand/proc_macro_server.rs | 8 +- src/librustc_lexer/src/unescape.rs | 2 +- src/librustc_lint/types.rs | 24 +-- src/librustc_metadata/creader.rs | 2 +- .../build/matches/simplify.rs | 4 +- src/librustc_mir_build/hair/pattern/_match.rs | 2 +- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_session/config.rs | 2 +- src/librustc_span/lib.rs | 2 +- src/librustc_span/source_map.rs | 4 +- src/libstd/f32.rs | 57 +++--- src/libstd/f64.rs | 183 +++++++++--------- src/libstd/io/buffered.rs | 10 +- src/libstd/io/cursor.rs | 2 +- src/libstd/num.rs | 37 ++-- src/libstd/sync/condvar.rs | 1 - src/libstd/sync/mpsc/mod.rs | 3 +- src/libstd/sys/cloudabi/condvar.rs | 2 +- src/libstd/sys/hermit/condvar.rs | 2 +- src/libstd/sys/unix/android.rs | 2 +- src/libstd/sys/unix/condvar.rs | 8 +- src/libstd/sys/unix/ext/net.rs | 2 +- src/libstd/sys/unix/fd.rs | 10 +- src/libstd/sys/unix/fs.rs | 2 +- src/libstd/sys/unix/net.rs | 6 +- src/libstd/sys/unix/thread.rs | 2 +- src/libstd/sys/vxworks/condvar.rs | 8 +- src/libstd/sys/vxworks/fd.rs | 6 +- src/libstd/sys/vxworks/net.rs | 6 +- src/libstd/sys/vxworks/thread.rs | 2 +- src/libstd/sys/wasi/mod.rs | 2 +- src/libstd/sys/wasi/thread.rs | 2 +- src/libstd/sys/wasm/condvar_atomics.rs | 4 +- src/libstd/sys/wasm/thread.rs | 2 +- src/libstd/sys/windows/handle.rs | 10 +- src/libstd/sys/windows/io.rs | 4 +- src/libstd/sys/windows/mod.rs | 2 +- src/libstd/sys/windows/net.rs | 8 +- src/libstd/sys_common/net.rs | 6 +- src/libstd/thread/mod.rs | 1 - src/libstd/time.rs | 4 +- src/test/rustdoc/show-const-contents.rs | 8 +- .../ui/consts/const-eval/shift_overflow.rs | 2 +- .../consts/const-eval/shift_overflow.stderr | 4 +- src/test/ui/consts/const-int-arithmetic.rs | 24 +-- .../ui/consts/const-int-conversion-rpass.rs | 4 +- src/test/ui/consts/const-int-conversion.rs | 2 +- .../ui/consts/const-int-conversion.stderr | 4 +- .../ui/consts/const-int-overflowing-rpass.rs | 8 +- src/test/ui/consts/const-int-pow-rpass.rs | 6 +- .../ui/consts/const-int-saturating-arith.rs | 32 +-- src/test/ui/consts/const-int-unchecked.rs | 4 +- src/test/ui/consts/const-int-unchecked.stderr | 8 +- .../ui/consts/const-int-wrapping-rpass.rs | 8 +- .../issue-70509-partial_eq.rs | 2 +- src/test/ui/enum-discriminant/repr128.rs | 16 +- src/test/ui/issues/issue-44216-add-instant.rs | 2 +- .../ui/issues/issue-44216-add-system-time.rs | 2 +- src/test/ui/issues/issue-44216-sub-instant.rs | 2 +- .../ui/issues/issue-44216-sub-system-time.rs | 2 +- src/test/ui/issues/issue-8460.rs | 20 +- .../ui/iterators/iter-step-overflow-debug.rs | 4 +- .../ui/iterators/iter-step-overflow-ndebug.rs | 8 +- .../ui/iterators/iter-sum-overflow-debug.rs | 8 +- .../ui/iterators/iter-sum-overflow-ndebug.rs | 16 +- .../iter-sum-overflow-overflow-checks.rs | 8 +- src/test/ui/iterators/skip-count-overflow.rs | 2 +- src/test/ui/numbers-arithmetic/i128.rs | 2 +- .../ui/numbers-arithmetic/int-abs-overflow.rs | 10 +- .../next-power-of-two-overflow-debug.rs | 4 +- .../promoted_overflow_opt.rs | 2 +- src/test/ui/numbers-arithmetic/u128.rs | 4 +- ...intrinsic-generic-arithmetic-saturating.rs | 6 +- .../ui/simd/simd-intrinsic-generic-bitmask.rs | 2 +- .../simd/simd-intrinsic-generic-reduction.rs | 2 +- src/tools/clippy/clippy_lints/src/consts.rs | 10 +- .../clippy/clippy_lints/src/enum_clike.rs | 2 +- src/tools/clippy/clippy_lints/src/types.rs | 52 ++--- src/tools/clippy/tests/ui/cast.rs | 10 +- .../tests/ui/implicit_saturating_sub.rs | 14 +- .../tests/ui/implicit_saturating_sub.stderr | 14 +- .../src/raw_emitter.rs | 2 +- 101 files changed, 485 insertions(+), 518 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 925bc7d3c024e..0327a9f9a96e5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -2034,7 +2034,7 @@ trait RcBoxPtr { // The reference count will never be zero when this is called; // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. - if strong == 0 || strong == usize::max_value() { + if strong == 0 || strong == usize::MAX { abort(); } self.inner().strong.set(strong + 1); @@ -2058,7 +2058,7 @@ trait RcBoxPtr { // The reference count will never be zero when this is called; // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. - if weak == 0 || weak == usize::max_value() { + if weak == 0 || weak == usize::MAX { abort(); } self.inner().weak.set(weak + 1); diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs index 56788bb56d550..e88385faf4fd4 100644 --- a/src/liballoc/rc/tests.rs +++ b/src/liballoc/rc/tests.rs @@ -407,14 +407,14 @@ fn test_from_vec() { fn test_downcast() { use std::any::Any; - let r1: Rc = Rc::new(i32::max_value()); + let r1: Rc = Rc::new(i32::MAX); let r2: Rc = Rc::new("abc"); assert!(r1.clone().downcast::().is_err()); let r1i32 = r1.downcast::(); assert!(r1i32.is_ok()); - assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); + assert_eq!(r1i32.unwrap(), Rc::new(i32::MAX)); assert!(r2.clone().downcast::().is_err()); diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs index a2bb651e2b778..6f08cd7f123be 100644 --- a/src/liballoc/sync/tests.rs +++ b/src/liballoc/sync/tests.rs @@ -465,14 +465,14 @@ fn test_from_vec() { fn test_downcast() { use std::any::Any; - let r1: Arc = Arc::new(i32::max_value()); + let r1: Arc = Arc::new(i32::MAX); let r2: Arc = Arc::new("abc"); assert!(r1.clone().downcast::().is_err()); let r1i32 = r1.downcast::(); assert!(r1i32.is_ok()); - assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value())); + assert_eq!(r1i32.unwrap(), Arc::new(i32::MAX)); assert!(r2.clone().downcast::().is_err()); diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b703df6f3cb7d..eee98d4534042 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -566,13 +566,13 @@ mod slice_index { data: "hello"; // note: using 0 specifically ensures that the result of overflowing is 0..0, // so that `get` doesn't simply return None for the wrong reason. - bad: data[0..=usize::max_value()]; + bad: data[0..=usize::MAX]; message: "maximum usize"; } in mod rangetoinclusive { data: "hello"; - bad: data[..=usize::max_value()]; + bad: data[..=usize::MAX]; message: "maximum usize"; } } diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index b73fd95ab6a86..a9813a8704f30 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -68,7 +68,7 @@ fn test_reserve() { #[test] fn test_zst_capacity() { - assert_eq!(Vec::<()>::new().capacity(), usize::max_value()); + assert_eq!(Vec::<()>::new().capacity(), usize::MAX); } #[test] @@ -563,19 +563,19 @@ fn test_drain_inclusive_range() { #[test] fn test_drain_max_vec_size() { - let mut v = Vec::<()>::with_capacity(usize::max_value()); + let mut v = Vec::<()>::with_capacity(usize::MAX); unsafe { - v.set_len(usize::max_value()); + v.set_len(usize::MAX); } - for _ in v.drain(usize::max_value() - 1..) {} - assert_eq!(v.len(), usize::max_value() - 1); + for _ in v.drain(usize::MAX - 1..) {} + assert_eq!(v.len(), usize::MAX - 1); - let mut v = Vec::<()>::with_capacity(usize::max_value()); + let mut v = Vec::<()>::with_capacity(usize::MAX); unsafe { - v.set_len(usize::max_value()); + v.set_len(usize::MAX); } - for _ in v.drain(usize::max_value() - 1..=usize::max_value() - 1) {} - assert_eq!(v.len(), usize::max_value() - 1); + for _ in v.drain(usize::MAX - 1..=usize::MAX - 1) {} + assert_eq!(v.len(), usize::MAX - 1); } #[test] diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c4c1d2824b098..cadc2e631b0fa 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1163,8 +1163,8 @@ impl<'b> BorrowRef<'b> { // Incrementing borrow can result in a non-reading value (<= 0) in these cases: // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow // due to Rust's reference aliasing rules - // 2. It was isize::max_value() (the max amount of reading borrows) and it overflowed - // into isize::min_value() (the max amount of writing borrows) so we can't allow + // 2. It was isize::MAX (the max amount of reading borrows) and it overflowed + // into isize::MIN (the max amount of writing borrows) so we can't allow // an additional read borrow because isize can't represent so many read borrows // (this can only happen if you mem::forget more than a small constant amount of // `Ref`s, which is not good practice) @@ -1172,7 +1172,7 @@ impl<'b> BorrowRef<'b> { } else { // Incrementing borrow can result in a reading value (> 0) in these cases: // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow - // 2. It was > 0 and < isize::max_value(), i.e. there were read borrows, and isize + // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize // is large enough to represent having one more read borrow borrow.set(b); Some(BorrowRef { borrow }) @@ -1198,7 +1198,7 @@ impl Clone for BorrowRef<'_> { debug_assert!(is_reading(borrow)); // Prevent the borrow counter from overflowing into // a writing borrow. - assert!(borrow != isize::max_value()); + assert!(borrow != isize::MAX); self.borrow.set(borrow + 1); BorrowRef { borrow: self.borrow } } @@ -1489,7 +1489,7 @@ impl<'b> BorrowRefMut<'b> { let borrow = self.borrow.get(); debug_assert!(is_writing(borrow)); // Prevent the borrow counter from underflowing. - assert!(borrow != isize::min_value()); + assert!(borrow != isize::MIN); self.borrow.set(borrow - 1); BorrowRefMut { borrow: self.borrow } } diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs index 6dd0522f7f610..5ff52a9a11b5a 100644 --- a/src/libcore/convert/num.rs +++ b/src/libcore/convert/num.rs @@ -217,7 +217,7 @@ macro_rules! try_from_upper_bounded { /// is outside of the range of the target type. #[inline] fn try_from(u: $source) -> Result { - if u > (Self::max_value() as $source) { + if u > (Self::MAX as $source) { Err(TryFromIntError(())) } else { Ok(u as Self) @@ -239,8 +239,8 @@ macro_rules! try_from_both_bounded { /// is outside of the range of the target type. #[inline] fn try_from(u: $source) -> Result { - let min = Self::min_value() as $source; - let max = Self::max_value() as $source; + let min = Self::MIN as $source; + let max = Self::MAX as $source; if u < min || u > max { Err(TryFromIntError(())) } else { diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index c164e893b4fbf..3e5114f336119 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -750,9 +750,9 @@ $EndFeature, " } doc_comment! { - concat!("Unchecked integer addition. Computes `self + rhs, assuming overflow + concat!("Unchecked integer addition. Computes `self + rhs`, assuming overflow cannot occur. This results in undefined behavior when `self + rhs > ", stringify!($SelfT), -"::max_value()` or `self + rhs < ", stringify!($SelfT), "::min_value()`."), +"::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`."), #[unstable( feature = "unchecked_math", reason = "niche optimization path", @@ -792,9 +792,9 @@ $EndFeature, " } doc_comment! { - concat!("Unchecked integer subtraction. Computes `self - rhs, assuming overflow + concat!("Unchecked integer subtraction. Computes `self - rhs`, assuming overflow cannot occur. This results in undefined behavior when `self - rhs > ", stringify!($SelfT), -"::max_value()` or `self - rhs < ", stringify!($SelfT), "::min_value()`."), +"::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`."), #[unstable( feature = "unchecked_math", reason = "niche optimization path", @@ -834,9 +834,9 @@ $EndFeature, " } doc_comment! { - concat!("Unchecked integer multiplication. Computes `self * rhs, assuming overflow + concat!("Unchecked integer multiplication. Computes `self * rhs`, assuming overflow cannot occur. This results in undefined behavior when `self * rhs > ", stringify!($SelfT), -"::max_value()` or `self * rhs < ", stringify!($SelfT), "::min_value()`."), +"::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`."), #[unstable( feature = "unchecked_math", reason = "niche optimization path", @@ -871,7 +871,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn checked_div(self, rhs: Self) -> Option { - if rhs == 0 || (self == Self::min_value() && rhs == -1) { + if rhs == 0 || (self == Self::MIN && rhs == -1) { None } else { // SAFETY: div by zero and by INT_MIN have been checked above @@ -900,7 +900,7 @@ assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None); without modifying the original"] #[inline] pub const fn checked_div_euclid(self, rhs: Self) -> Option { - if rhs == 0 || (self == Self::min_value() && rhs == -1) { + if rhs == 0 || (self == Self::MIN && rhs == -1) { None } else { Some(self.div_euclid(rhs)) @@ -929,7 +929,7 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn checked_rem(self, rhs: Self) -> Option { - if rhs == 0 || (self == Self::min_value() && rhs == -1) { + if rhs == 0 || (self == Self::MIN && rhs == -1) { None } else { // SAFETY: div by zero and by INT_MIN have been checked above @@ -957,7 +957,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None); without modifying the original"] #[inline] pub const fn checked_rem_euclid(self, rhs: Self) -> Option { - if rhs == 0 || (self == Self::min_value() && rhs == -1) { + if rhs == 0 || (self == Self::MIN && rhs == -1) { None } else { Some(self.rem_euclid(rhs)) @@ -1236,9 +1236,9 @@ $EndFeature, " match self.checked_mul(rhs) { Some(x) => x, None => if (self < 0) == (rhs < 0) { - Self::max_value() + Self::MAX } else { - Self::min_value() + Self::MIN } } } @@ -1267,8 +1267,8 @@ $EndFeature, " pub const fn saturating_pow(self, exp: u32) -> Self { match self.checked_pow(exp) { Some(x) => x, - None if self < 0 && exp % 2 == 1 => Self::min_value(), - None => Self::max_value(), + None if self < 0 && exp % 2 == 1 => Self::MIN, + None => Self::MAX, } } } @@ -1738,7 +1738,7 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { - if self == Self::min_value() && rhs == -1 { + if self == Self::MIN && rhs == -1 { (self, true) } else { (self / rhs, false) @@ -1771,7 +1771,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { - if self == Self::min_value() && rhs == -1 { + if self == Self::MIN && rhs == -1 { (self, true) } else { (self.div_euclid(rhs), false) @@ -1805,7 +1805,7 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { - if self == Self::min_value() && rhs == -1 { + if self == Self::MIN && rhs == -1 { (0, true) } else { (self % rhs, false) @@ -1838,7 +1838,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true)); without modifying the original"] #[inline] pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { - if self == Self::min_value() && rhs == -1 { + if self == Self::MIN && rhs == -1 { (0, true) } else { (self.rem_euclid(rhs), false) @@ -1869,8 +1869,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($Self #[allow(unused_attributes)] #[allow_internal_unstable(const_if_match)] pub const fn overflowing_neg(self) -> (Self, bool) { - if self == Self::min_value() { - (Self::min_value(), true) + if self == Self::MIN { + (Self::MIN, true) } else { (-self, false) } @@ -1952,7 +1952,7 @@ $EndFeature, " #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] #[inline] pub const fn overflowing_abs(self) -> (Self, bool) { - (self.wrapping_abs(), self == Self::min_value()) + (self.wrapping_abs(), self == Self::MIN) } } @@ -2986,9 +2986,9 @@ assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);", $EndFeat } doc_comment! { - concat!("Unchecked integer addition. Computes `self + rhs, assuming overflow + concat!("Unchecked integer addition. Computes `self + rhs`, assuming overflow cannot occur. This results in undefined behavior when `self + rhs > ", stringify!($SelfT), -"::max_value()` or `self + rhs < ", stringify!($SelfT), "::min_value()`."), +"::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`."), #[unstable( feature = "unchecked_math", reason = "niche optimization path", @@ -3026,9 +3026,9 @@ assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, " } doc_comment! { - concat!("Unchecked integer subtraction. Computes `self - rhs, assuming overflow + concat!("Unchecked integer subtraction. Computes `self - rhs`, assuming overflow cannot occur. This results in undefined behavior when `self - rhs > ", stringify!($SelfT), -"::max_value()` or `self - rhs < ", stringify!($SelfT), "::min_value()`."), +"::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`."), #[unstable( feature = "unchecked_math", reason = "niche optimization path", @@ -3066,9 +3066,9 @@ assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);", $EndFeature, " } doc_comment! { - concat!("Unchecked integer multiplication. Computes `self * rhs, assuming overflow + concat!("Unchecked integer multiplication. Computes `self * rhs`, assuming overflow cannot occur. This results in undefined behavior when `self * rhs > ", stringify!($SelfT), -"::max_value()` or `self * rhs < ", stringify!($SelfT), "::min_value()`."), +"::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`."), #[unstable( feature = "unchecked_math", reason = "niche optimization path", @@ -3366,7 +3366,7 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se pub const fn saturating_mul(self, rhs: Self) -> Self { match self.checked_mul(rhs) { Some(x) => x, - None => Self::max_value(), + None => Self::MAX, } } } @@ -3393,7 +3393,7 @@ $EndFeature, " pub const fn saturating_pow(self, exp: u32) -> Self { match self.checked_pow(exp) { Some(x) => x, - None => Self::max_value(), + None => Self::MAX, } } } @@ -4080,7 +4080,7 @@ Basic usage: } } - doc_comment! { + doc_comment! { concat!("Performs Euclidean division. Since, for the positive integers, all common @@ -4178,7 +4178,7 @@ assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, " // (such as intel pre-haswell) have more efficient ctlz // intrinsics when the argument is non-zero. let z = unsafe { intrinsics::ctlz_nonzero(p) }; - <$SelfT>::max_value() >> z + <$SelfT>::MAX >> z } doc_comment! { @@ -5160,9 +5160,9 @@ trait FromStrRadixHelper: PartialOrd + Copy { macro_rules! doit { ($($t:ty)*) => ($(impl FromStrRadixHelper for $t { #[inline] - fn min_value() -> Self { Self::min_value() } + fn min_value() -> Self { Self::MIN } #[inline] - fn max_value() -> Self { Self::max_value() } + fn max_value() -> Self { Self::MAX } #[inline] fn from_u32(u: u32) -> Self { u as Self } #[inline] diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index bb648ba8c25de..f6acb8f8b9a92 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -694,7 +694,7 @@ Basic usage: #![feature(wrapping_int_impl)] use std::num::Wrapping; -let n = Wrapping(", stringify!($t), "::max_value()) >> 2; +let n = Wrapping(", stringify!($t), "::MAX) >> 2; assert_eq!(n.leading_zeros(), 3); ```"), @@ -723,8 +723,7 @@ use std::num::Wrapping; assert_eq!(Wrapping(100", stringify!($t), ").abs(), Wrapping(100)); assert_eq!(Wrapping(-100", stringify!($t), ").abs(), Wrapping(100)); -assert_eq!(Wrapping(", stringify!($t), "::min_value()).abs(), Wrapping(", stringify!($t), -"::min_value())); +assert_eq!(Wrapping(", stringify!($t), "::MIN).abs(), Wrapping(", stringify!($t), "::MIN)); assert_eq!(Wrapping(-128i8).abs().0 as u8, 128u8); ```"), #[inline] @@ -823,7 +822,7 @@ Basic usage: #![feature(wrapping_int_impl)] use std::num::Wrapping; -let n = Wrapping(", stringify!($t), "::max_value()) >> 2; +let n = Wrapping(", stringify!($t), "::MAX) >> 2; assert_eq!(n.leading_zeros(), 2); ```"), diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index 835183d171a79..e39d18d7733a2 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -291,7 +291,7 @@ impl *const T { T: Sized, { let pointee_size = mem::size_of::(); - assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize); + assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); intrinsics::ptr_offset_from(self, origin) } @@ -336,7 +336,7 @@ impl *const T { T: Sized, { let pointee_size = mem::size_of::(); - assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize); + assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); let d = isize::wrapping_sub(self as _, origin as _); d.wrapping_div(pointee_size as _) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index ecc70adda4111..57d0008e6f8a2 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -1128,7 +1128,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { // // Note, that we use wrapping operations here intentionally – the original formula // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod - // usize::max_value()` instead, because we take the result `mod n` at the end + // usize::MAX` instead, because we take the result `mod n` at the end // anyway. inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse))); if going_mod >= m { @@ -1193,7 +1193,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { } // Cannot be aligned at all. - usize::max_value() + usize::MAX } /// Compares raw pointers for equality. diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ff333f77334f7..8f0b662aa28e9 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3043,16 +3043,12 @@ impl SliceIndex<[T]> for ops::RangeInclusive { #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { - if *self.end() == usize::max_value() { - None - } else { - (*self.start()..self.end() + 1).get(slice) - } + if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) } } #[inline] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get_mut(slice) @@ -3071,7 +3067,7 @@ impl SliceIndex<[T]> for ops::RangeInclusive { #[inline] fn index(self, slice: &[T]) -> &[T] { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { slice_index_overflow_fail(); } (*self.start()..self.end() + 1).index(slice) @@ -3079,7 +3075,7 @@ impl SliceIndex<[T]> for ops::RangeInclusive { #[inline] fn index_mut(self, slice: &mut [T]) -> &mut [T] { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { slice_index_overflow_fail(); } (*self.start()..self.end() + 1).index_mut(slice) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 316c2cd55acea..6c4b28499a60b 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1651,7 +1651,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // Ascii case, try to skip forward quickly. // When the pointer is aligned, read 2 words of data per iteration // until we find a word containing a non-ascii byte. - if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 { + if align != usize::MAX && align.wrapping_sub(index) % usize_bytes == 0 { let ptr = v.as_ptr(); while index < blocks_end { // SAFETY: since `align - index` and `ascii_block_size` are @@ -2083,7 +2083,7 @@ mod traits { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) @@ -2091,7 +2091,7 @@ mod traits { } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get_mut(slice) @@ -2107,14 +2107,14 @@ mod traits { } #[inline] fn index(self, slice: &str) -> &Self::Output { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { str_index_overflow_fail(); } (*self.start()..self.end() + 1).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - if *self.end() == usize::max_value() { + if *self.end() == usize::MAX { str_index_overflow_fail(); } (*self.start()..self.end() + 1).index_mut(slice) @@ -2140,11 +2140,11 @@ mod traits { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.end == usize::max_value() { None } else { (..self.end + 1).get(slice) } + if self.end == usize::MAX { None } else { (..self.end + 1).get(slice) } } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.end == usize::max_value() { None } else { (..self.end + 1).get_mut(slice) } + if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) } } #[inline] unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { @@ -2156,14 +2156,14 @@ mod traits { } #[inline] fn index(self, slice: &str) -> &Self::Output { - if self.end == usize::max_value() { + if self.end == usize::MAX { str_index_overflow_fail(); } (..self.end + 1).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - if self.end == usize::max_value() { + if self.end == usize::MAX { str_index_overflow_fail(); } (..self.end + 1).index_mut(slice) diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index 181bbb8e18784..939f1325c8499 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -140,8 +140,8 @@ macro_rules! test_impl_from { ($fn_name: ident, $Small: ty, $Large: ty) => { #[test] fn $fn_name() { - let small_max = <$Small>::max_value(); - let small_min = <$Small>::min_value(); + let small_max = <$Small>::MAX; + let small_min = <$Small>::MIN; let large_max: $Large = small_max.into(); let large_min: $Large = small_min.into(); assert_eq!(large_max as $Small, small_max); @@ -248,8 +248,8 @@ macro_rules! test_impl_try_from_always_ok { ($fn_name:ident, $source:ty, $target: ty) => { #[test] fn $fn_name() { - let max = <$source>::max_value(); - let min = <$source>::min_value(); + let max = <$source>::MAX; + let min = <$source>::MIN; let zero: $source = 0; assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), max as $target); assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), min as $target); @@ -361,8 +361,8 @@ macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok { ($fn_name:ident, $source:ty, $target:ty) => { #[test] fn $fn_name() { - let max = <$source>::max_value(); - let min = <$source>::min_value(); + let max = <$source>::MAX; + let min = <$source>::MIN; let zero: $source = 0; let neg_one: $source = -1; assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), max as $target); @@ -426,8 +426,8 @@ macro_rules! test_impl_try_from_unsigned_to_signed_upper_err { ($fn_name:ident, $source:ty, $target:ty) => { #[test] fn $fn_name() { - let max = <$source>::max_value(); - let min = <$source>::min_value(); + let max = <$source>::MAX; + let min = <$source>::MIN; let zero: $source = 0; assert!(<$target as TryFrom<$source>>::try_from(max).is_err()); assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), min as $target); @@ -487,11 +487,11 @@ macro_rules! test_impl_try_from_same_sign_err { ($fn_name:ident, $source:ty, $target:ty) => { #[test] fn $fn_name() { - let max = <$source>::max_value(); - let min = <$source>::min_value(); + let max = <$source>::MAX; + let min = <$source>::MIN; let zero: $source = 0; - let t_max = <$target>::max_value(); - let t_min = <$target>::min_value(); + let t_max = <$target>::MAX; + let t_min = <$target>::MIN; assert!(<$target as TryFrom<$source>>::try_from(max).is_err()); if min != 0 { assert!(<$target as TryFrom<$source>>::try_from(min).is_err()); @@ -576,11 +576,11 @@ macro_rules! test_impl_try_from_signed_to_unsigned_err { ($fn_name:ident, $source:ty, $target:ty) => { #[test] fn $fn_name() { - let max = <$source>::max_value(); - let min = <$source>::min_value(); + let max = <$source>::MAX; + let min = <$source>::MIN; let zero: $source = 0; - let t_max = <$target>::max_value(); - let t_min = <$target>::min_value(); + let t_max = <$target>::MAX; + let t_min = <$target>::MIN; assert!(<$target as TryFrom<$source>>::try_from(max).is_err()); assert!(<$target as TryFrom<$source>>::try_from(min).is_err()); assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target); diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index a008b3319f39a..9fea34d668fcc 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -357,7 +357,7 @@ fn align_offset_weird_strides() { unsafe fn test_weird_stride(ptr: *const T, align: usize) -> bool { let numptr = ptr as usize; - let mut expected = usize::max_value(); + let mut expected = usize::MAX; // Naive but definitely correct way to find the *first* aligned element of stride::. for el in 0..align { if (numptr + el * ::std::mem::size_of::()) % align == 0 { diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 54a585415bce2..cd46117f76322 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1691,8 +1691,8 @@ fn test_copy_within_panics_src_inverted() { #[should_panic(expected = "attempted to index slice up to maximum usize")] fn test_copy_within_panics_src_out_of_bounds() { let mut bytes = *b"Hello, World!"; - // an inclusive range ending at usize::max_value() would make src_end overflow - bytes.copy_within(usize::max_value()..=usize::max_value(), 0); + // an inclusive range ending at usize::MAX would make src_end overflow + bytes.copy_within(usize::MAX..=usize::MAX, 0); } #[test] diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 09a069ab3136d..ba3adc4a135cb 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -133,9 +133,9 @@ impl Neg for Round { pub type ExpInt = i16; // \c ilogb error results. -pub const IEK_INF: ExpInt = ExpInt::max_value(); -pub const IEK_NAN: ExpInt = ExpInt::min_value(); -pub const IEK_ZERO: ExpInt = ExpInt::min_value() + 1; +pub const IEK_INF: ExpInt = ExpInt::MAX; +pub const IEK_NAN: ExpInt = ExpInt::MIN; +pub const IEK_ZERO: ExpInt = ExpInt::MIN + 1; #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct ParseError(pub &'static str); diff --git a/src/librustc_apfloat/tests/ieee.rs b/src/librustc_apfloat/tests/ieee.rs index e5b06cf225d16..2d8bb7d1e8e03 100644 --- a/src/librustc_apfloat/tests/ieee.rs +++ b/src/librustc_apfloat/tests/ieee.rs @@ -2997,8 +2997,8 @@ fn scalbn() { assert!(smallest_f64.scalbn(2099).is_infinite()); // Test for integer overflows when adding to exponent. - assert!(smallest_f64.scalbn(-ExpInt::max_value()).is_pos_zero()); - assert!(largest_f64.scalbn(ExpInt::max_value()).is_infinite()); + assert!(smallest_f64.scalbn(-ExpInt::MAX).is_pos_zero()); + assert!(largest_f64.scalbn(ExpInt::MAX).is_infinite()); assert!(largest_denormal_f64.bitwise_eq(largest_denormal_f64.scalbn(0),)); assert!(neg_largest_denormal_f64.bitwise_eq(neg_largest_denormal_f64.scalbn(0),)); diff --git a/src/librustc_data_structures/base_n/tests.rs b/src/librustc_data_structures/base_n/tests.rs index a86f991cd0e0d..b68ef1eb7f4c4 100644 --- a/src/librustc_data_structures/base_n/tests.rs +++ b/src/librustc_data_structures/base_n/tests.rs @@ -12,8 +12,8 @@ fn test_encode() { test(35, base); test(36, base); test(37, base); - test(u64::max_value() as u128, base); - test(u128::max_value(), base); + test(u64::MAX as u128, base); + test(u128::MAX, base); for i in 0..1_000 { test(i * 983, base); diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 79fa091ba1808..ea55674045c0f 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -582,10 +582,10 @@ impl server::Literal for Rustc<'_> { }; // Bounds check the values, preventing addition overflow and OOB spans. - if start > u32::max_value() as usize - || end > u32::max_value() as usize - || (u32::max_value() - start as u32) < span.lo().to_u32() - || (u32::max_value() - end as u32) < span.lo().to_u32() + if start > u32::MAX as usize + || end > u32::MAX as usize + || (u32::MAX - start as u32) < span.lo().to_u32() + || (u32::MAX - end as u32) < span.lo().to_u32() || start >= end || end > length { diff --git a/src/librustc_lexer/src/unescape.rs b/src/librustc_lexer/src/unescape.rs index 2a9e1b7cbc346..697d25fdb585b 100644 --- a/src/librustc_lexer/src/unescape.rs +++ b/src/librustc_lexer/src/unescape.rs @@ -335,7 +335,7 @@ where fn byte_from_char(c: char) -> u8 { let res = c as u32; - assert!(res <= u8::max_value() as u32, "guaranteed because of Mode::ByteStr"); + assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr"); res as u8 } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 703c2a7a443a9..a67c09b892379 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -108,23 +108,23 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>( // warnings are consistent between 32- and 64-bit platforms. fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) { match int_ty { - ast::IntTy::Isize => (i64::min_value() as i128, i64::max_value() as i128), - ast::IntTy::I8 => (i8::min_value() as i64 as i128, i8::max_value() as i128), - ast::IntTy::I16 => (i16::min_value() as i64 as i128, i16::max_value() as i128), - ast::IntTy::I32 => (i32::min_value() as i64 as i128, i32::max_value() as i128), - ast::IntTy::I64 => (i64::min_value() as i128, i64::max_value() as i128), - ast::IntTy::I128 => (i128::min_value() as i128, i128::max_value()), + ast::IntTy::Isize => (i64::MIN as i128, i64::MAX as i128), + ast::IntTy::I8 => (i8::MIN as i64 as i128, i8::MAX as i128), + ast::IntTy::I16 => (i16::MIN as i64 as i128, i16::MAX as i128), + ast::IntTy::I32 => (i32::MIN as i64 as i128, i32::MAX as i128), + ast::IntTy::I64 => (i64::MIN as i128, i64::MAX as i128), + ast::IntTy::I128 => (i128::MIN as i128, i128::MAX), } } fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) { match uint_ty { - ast::UintTy::Usize => (u64::min_value() as u128, u64::max_value() as u128), - ast::UintTy::U8 => (u8::min_value() as u128, u8::max_value() as u128), - ast::UintTy::U16 => (u16::min_value() as u128, u16::max_value() as u128), - ast::UintTy::U32 => (u32::min_value() as u128, u32::max_value() as u128), - ast::UintTy::U64 => (u64::min_value() as u128, u64::max_value() as u128), - ast::UintTy::U128 => (u128::min_value(), u128::max_value()), + ast::UintTy::Usize => (u64::MIN as u128, u64::MAX as u128), + ast::UintTy::U8 => (u8::MIN as u128, u8::MAX as u128), + ast::UintTy::U16 => (u16::MIN as u128, u16::MAX as u128), + ast::UintTy::U32 => (u32::MIN as u128, u32::MAX as u128), + ast::UintTy::U64 => (u64::MIN as u128, u64::MAX as u128), + ast::UintTy::U128 => (u128::MIN, u128::MAX), } } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7e902f0ade2ef..b8ebcd6c8a8ff 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -934,7 +934,7 @@ impl<'a> CrateLoader<'a> { src: ExternCrateSource::Path, span, // to have the least priority in `update_extern_crate` - path_len: usize::max_value(), + path_len: usize::MAX, dependency_of: LOCAL_CRATE, }, ); diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index 09543cd1ce4e6..2917a771a2cf8 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -160,13 +160,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ty::Int(ity) => { let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); - let max = truncate(u128::max_value(), size); + let max = truncate(u128::MAX, size); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); - let max = truncate(u128::max_value(), size); + let max = truncate(u128::MAX, size); (Some((0, max, size)), 0) } _ => (None, 0), diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index 2de6d9fe3d480..dc7d8098e5542 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -1519,7 +1519,7 @@ fn all_constructors<'a, 'tcx>( } ty::Uint(uty) => { let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); - let max = truncate(u128::max_value(), size); + let max = truncate(u128::MAX, size); vec![make_range(0, max)] } _ => { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 0341b54252661..69e3758941929 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1088,7 +1088,7 @@ fn id_from_hir_id(id: hir::HirId, scx: &SaveContext<'_, '_>) -> rls_data::Id { } fn null_id() -> rls_data::Id { - rls_data::Id { krate: u32::max_value(), index: u32::max_value() } + rls_data::Id { krate: u32::MAX, index: u32::MAX } } fn lower_attributes( diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 5bdd7b67723b8..411a6eecbba15 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1031,7 +1031,7 @@ pub fn get_cmd_lint_options( // HACK: forbid is always specified last, so it can't be overridden. // FIXME: remove this once is // fixed and `forbid` works as expected. - usize::max_value() + usize::MAX } else { passed_arg_pos }; diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index fbab99b2f8f20..743b7eca4e29b 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -1250,7 +1250,7 @@ impl SourceFile { hasher.finish::() }; let end_pos = start_pos.to_usize() + src.len(); - assert!(end_pos <= u32::max_value() as usize); + assert!(end_pos <= u32::MAX as usize); let (lines, multibyte_chars, non_narrow_chars) = analyze_source_file::analyze_source_file(&src[..], start_pos); diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index c33c1dd29cb72..4b5bce1db2628 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -819,9 +819,7 @@ impl SourceMap { // Disregard indexes that are at the start or end of their spans, they can't fit bigger // characters. - if (!forwards && end_index == usize::min_value()) - || (forwards && start_index == usize::max_value()) - { + if (!forwards && end_index == usize::MIN) || (forwards && start_index == usize::MAX) { debug!("find_width_of_character_at_span: start or end of span, cannot be multibyte"); return 1; } diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 8ff19557a3063..d752ba89a276d 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -916,8 +916,7 @@ impl f32 { #[cfg(test)] mod tests { - use crate::f32; - use crate::f32::*; + use crate::f32::consts; use crate::num::FpCategory as Fp; use crate::num::*; @@ -928,14 +927,14 @@ mod tests { #[test] fn test_min_nan() { - assert_eq!(NAN.min(2.0), 2.0); - assert_eq!(2.0f32.min(NAN), 2.0); + assert_eq!(f32::NAN.min(2.0), 2.0); + assert_eq!(2.0f32.min(f32::NAN), 2.0); } #[test] fn test_max_nan() { - assert_eq!(NAN.max(2.0), 2.0); - assert_eq!(2.0f32.max(NAN), 2.0); + assert_eq!(f32::NAN.max(2.0), 2.0); + assert_eq!(2.0f32.max(f32::NAN), 2.0); } #[test] @@ -1158,52 +1157,52 @@ mod tests { #[test] fn test_abs() { - assert_eq!(INFINITY.abs(), INFINITY); + assert_eq!(f32::INFINITY.abs(), f32::INFINITY); assert_eq!(1f32.abs(), 1f32); assert_eq!(0f32.abs(), 0f32); assert_eq!((-0f32).abs(), 0f32); assert_eq!((-1f32).abs(), 1f32); - assert_eq!(NEG_INFINITY.abs(), INFINITY); - assert_eq!((1f32 / NEG_INFINITY).abs(), 0f32); - assert!(NAN.abs().is_nan()); + assert_eq!(f32::NEG_INFINITY.abs(), f32::INFINITY); + assert_eq!((1f32 / f32::NEG_INFINITY).abs(), 0f32); + assert!(f32::NAN.abs().is_nan()); } #[test] fn test_signum() { - assert_eq!(INFINITY.signum(), 1f32); + assert_eq!(f32::INFINITY.signum(), 1f32); assert_eq!(1f32.signum(), 1f32); assert_eq!(0f32.signum(), 1f32); assert_eq!((-0f32).signum(), -1f32); assert_eq!((-1f32).signum(), -1f32); - assert_eq!(NEG_INFINITY.signum(), -1f32); - assert_eq!((1f32 / NEG_INFINITY).signum(), -1f32); - assert!(NAN.signum().is_nan()); + assert_eq!(f32::NEG_INFINITY.signum(), -1f32); + assert_eq!((1f32 / f32::NEG_INFINITY).signum(), -1f32); + assert!(f32::NAN.signum().is_nan()); } #[test] fn test_is_sign_positive() { - assert!(INFINITY.is_sign_positive()); + assert!(f32::INFINITY.is_sign_positive()); assert!(1f32.is_sign_positive()); assert!(0f32.is_sign_positive()); assert!(!(-0f32).is_sign_positive()); assert!(!(-1f32).is_sign_positive()); - assert!(!NEG_INFINITY.is_sign_positive()); - assert!(!(1f32 / NEG_INFINITY).is_sign_positive()); - assert!(NAN.is_sign_positive()); - assert!(!(-NAN).is_sign_positive()); + assert!(!f32::NEG_INFINITY.is_sign_positive()); + assert!(!(1f32 / f32::NEG_INFINITY).is_sign_positive()); + assert!(f32::NAN.is_sign_positive()); + assert!(!(-f32::NAN).is_sign_positive()); } #[test] fn test_is_sign_negative() { - assert!(!INFINITY.is_sign_negative()); + assert!(!f32::INFINITY.is_sign_negative()); assert!(!1f32.is_sign_negative()); assert!(!0f32.is_sign_negative()); assert!((-0f32).is_sign_negative()); assert!((-1f32).is_sign_negative()); - assert!(NEG_INFINITY.is_sign_negative()); - assert!((1f32 / NEG_INFINITY).is_sign_negative()); - assert!(!NAN.is_sign_negative()); - assert!((-NAN).is_sign_negative()); + assert!(f32::NEG_INFINITY.is_sign_negative()); + assert!((1f32 / f32::NEG_INFINITY).is_sign_negative()); + assert!(!f32::NAN.is_sign_negative()); + assert!((-f32::NAN).is_sign_negative()); } #[test] @@ -1268,13 +1267,13 @@ mod tests { #[test] fn test_sqrt_domain() { - assert!(NAN.sqrt().is_nan()); - assert!(NEG_INFINITY.sqrt().is_nan()); + assert!(f32::NAN.sqrt().is_nan()); + assert!(f32::NEG_INFINITY.sqrt().is_nan()); assert!((-1.0f32).sqrt().is_nan()); assert_eq!((-0.0f32).sqrt(), -0.0); assert_eq!(0.0f32.sqrt(), 0.0); assert_eq!(1.0f32.sqrt(), 1.0); - assert_eq!(INFINITY.sqrt(), INFINITY); + assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY); } #[test] @@ -1523,13 +1522,13 @@ mod tests { #[test] #[should_panic] fn test_clamp_min_is_nan() { - let _ = 1.0f32.clamp(NAN, 1.0); + let _ = 1.0f32.clamp(f32::NAN, 1.0); } #[test] #[should_panic] fn test_clamp_max_is_nan() { - let _ = 1.0f32.clamp(3.0, NAN); + let _ = 1.0f32.clamp(3.0, f32::NAN); } #[test] diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index d7845fd2c4ddc..9cd60d846a707 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -943,8 +943,7 @@ impl f64 { #[cfg(test)] mod tests { - use crate::f64; - use crate::f64::*; + use crate::f64::consts; use crate::num::FpCategory as Fp; use crate::num::*; @@ -955,19 +954,19 @@ mod tests { #[test] fn test_min_nan() { - assert_eq!(NAN.min(2.0), 2.0); - assert_eq!(2.0f64.min(NAN), 2.0); + assert_eq!(f64::NAN.min(2.0), 2.0); + assert_eq!(2.0f64.min(f64::NAN), 2.0); } #[test] fn test_max_nan() { - assert_eq!(NAN.max(2.0), 2.0); - assert_eq!(2.0f64.max(NAN), 2.0); + assert_eq!(f64::NAN.max(2.0), 2.0); + assert_eq!(2.0f64.max(f64::NAN), 2.0); } #[test] fn test_nan() { - let nan: f64 = NAN; + let nan: f64 = f64::NAN; assert!(nan.is_nan()); assert!(!nan.is_infinite()); assert!(!nan.is_finite()); @@ -979,7 +978,7 @@ mod tests { #[test] fn test_infinity() { - let inf: f64 = INFINITY; + let inf: f64 = f64::INFINITY; assert!(inf.is_infinite()); assert!(!inf.is_finite()); assert!(inf.is_sign_positive()); @@ -991,7 +990,7 @@ mod tests { #[test] fn test_neg_infinity() { - let neg_inf: f64 = NEG_INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert!(neg_inf.is_infinite()); assert!(!neg_inf.is_finite()); assert!(!neg_inf.is_sign_positive()); @@ -1043,9 +1042,9 @@ mod tests { #[test] fn test_is_nan() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert!(nan.is_nan()); assert!(!0.0f64.is_nan()); assert!(!5.3f64.is_nan()); @@ -1056,9 +1055,9 @@ mod tests { #[test] fn test_is_infinite() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert!(!nan.is_infinite()); assert!(inf.is_infinite()); assert!(neg_inf.is_infinite()); @@ -1069,9 +1068,9 @@ mod tests { #[test] fn test_is_finite() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert!(!nan.is_finite()); assert!(!inf.is_finite()); assert!(!neg_inf.is_finite()); @@ -1083,9 +1082,9 @@ mod tests { #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 #[test] fn test_is_normal() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; let zero: f64 = 0.0f64; let neg_zero: f64 = -0.0; assert!(!nan.is_normal()); @@ -1101,9 +1100,9 @@ mod tests { #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 #[test] fn test_classify() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; let zero: f64 = 0.0f64; let neg_zero: f64 = -0.0; assert_eq!(nan.classify(), Fp::Nan); @@ -1187,59 +1186,59 @@ mod tests { #[test] fn test_abs() { - assert_eq!(INFINITY.abs(), INFINITY); + assert_eq!(f64::INFINITY.abs(), f64::INFINITY); assert_eq!(1f64.abs(), 1f64); assert_eq!(0f64.abs(), 0f64); assert_eq!((-0f64).abs(), 0f64); assert_eq!((-1f64).abs(), 1f64); - assert_eq!(NEG_INFINITY.abs(), INFINITY); - assert_eq!((1f64 / NEG_INFINITY).abs(), 0f64); - assert!(NAN.abs().is_nan()); + assert_eq!(f64::NEG_INFINITY.abs(), f64::INFINITY); + assert_eq!((1f64 / f64::NEG_INFINITY).abs(), 0f64); + assert!(f64::NAN.abs().is_nan()); } #[test] fn test_signum() { - assert_eq!(INFINITY.signum(), 1f64); + assert_eq!(f64::INFINITY.signum(), 1f64); assert_eq!(1f64.signum(), 1f64); assert_eq!(0f64.signum(), 1f64); assert_eq!((-0f64).signum(), -1f64); assert_eq!((-1f64).signum(), -1f64); - assert_eq!(NEG_INFINITY.signum(), -1f64); - assert_eq!((1f64 / NEG_INFINITY).signum(), -1f64); - assert!(NAN.signum().is_nan()); + assert_eq!(f64::NEG_INFINITY.signum(), -1f64); + assert_eq!((1f64 / f64::NEG_INFINITY).signum(), -1f64); + assert!(f64::NAN.signum().is_nan()); } #[test] fn test_is_sign_positive() { - assert!(INFINITY.is_sign_positive()); + assert!(f64::INFINITY.is_sign_positive()); assert!(1f64.is_sign_positive()); assert!(0f64.is_sign_positive()); assert!(!(-0f64).is_sign_positive()); assert!(!(-1f64).is_sign_positive()); - assert!(!NEG_INFINITY.is_sign_positive()); - assert!(!(1f64 / NEG_INFINITY).is_sign_positive()); - assert!(NAN.is_sign_positive()); - assert!(!(-NAN).is_sign_positive()); + assert!(!f64::NEG_INFINITY.is_sign_positive()); + assert!(!(1f64 / f64::NEG_INFINITY).is_sign_positive()); + assert!(f64::NAN.is_sign_positive()); + assert!(!(-f64::NAN).is_sign_positive()); } #[test] fn test_is_sign_negative() { - assert!(!INFINITY.is_sign_negative()); + assert!(!f64::INFINITY.is_sign_negative()); assert!(!1f64.is_sign_negative()); assert!(!0f64.is_sign_negative()); assert!((-0f64).is_sign_negative()); assert!((-1f64).is_sign_negative()); - assert!(NEG_INFINITY.is_sign_negative()); - assert!((1f64 / NEG_INFINITY).is_sign_negative()); - assert!(!NAN.is_sign_negative()); - assert!((-NAN).is_sign_negative()); + assert!(f64::NEG_INFINITY.is_sign_negative()); + assert!((1f64 / f64::NEG_INFINITY).is_sign_negative()); + assert!(!f64::NAN.is_sign_negative()); + assert!((-f64::NAN).is_sign_negative()); } #[test] fn test_mul_add() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05); assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65); assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2); @@ -1253,9 +1252,9 @@ mod tests { #[test] fn test_recip() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(1.0f64.recip(), 1.0); assert_eq!(2.0f64.recip(), 0.5); assert_eq!((-0.4f64).recip(), -2.5); @@ -1267,9 +1266,9 @@ mod tests { #[test] fn test_powi() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(1.0f64.powi(1), 1.0); assert_approx_eq!((-3.1f64).powi(2), 9.61); assert_approx_eq!(5.9f64.powi(-2), 0.028727); @@ -1281,9 +1280,9 @@ mod tests { #[test] fn test_powf() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(1.0f64.powf(1.0), 1.0); assert_approx_eq!(3.4f64.powf(4.5), 246.408183); assert_approx_eq!(2.7f64.powf(-3.2), 0.041652); @@ -1297,13 +1296,13 @@ mod tests { #[test] fn test_sqrt_domain() { - assert!(NAN.sqrt().is_nan()); - assert!(NEG_INFINITY.sqrt().is_nan()); + assert!(f64::NAN.sqrt().is_nan()); + assert!(f64::NEG_INFINITY.sqrt().is_nan()); assert!((-1.0f64).sqrt().is_nan()); assert_eq!((-0.0f64).sqrt(), -0.0); assert_eq!(0.0f64.sqrt(), 0.0); assert_eq!(1.0f64.sqrt(), 1.0); - assert_eq!(INFINITY.sqrt(), INFINITY); + assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY); } #[test] @@ -1312,9 +1311,9 @@ mod tests { assert_approx_eq!(2.718282, 1.0f64.exp()); assert_approx_eq!(148.413159, 5.0f64.exp()); - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; - let nan: f64 = NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; assert_eq!(inf, inf.exp()); assert_eq!(0.0, neg_inf.exp()); assert!(nan.exp().is_nan()); @@ -1325,9 +1324,9 @@ mod tests { assert_eq!(32.0, 5.0f64.exp2()); assert_eq!(1.0, 0.0f64.exp2()); - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; - let nan: f64 = NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; assert_eq!(inf, inf.exp2()); assert_eq!(0.0, neg_inf.exp2()); assert!(nan.exp2().is_nan()); @@ -1335,9 +1334,9 @@ mod tests { #[test] fn test_ln() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_approx_eq!(1.0f64.exp().ln(), 1.0); assert!(nan.ln().is_nan()); assert_eq!(inf.ln(), inf); @@ -1350,9 +1349,9 @@ mod tests { #[test] fn test_log() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(10.0f64.log(10.0), 1.0); assert_approx_eq!(2.3f64.log(3.5), 0.664858); assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0); @@ -1368,9 +1367,9 @@ mod tests { #[test] fn test_log2() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_approx_eq!(10.0f64.log2(), 3.321928); assert_approx_eq!(2.3f64.log2(), 1.201634); assert_approx_eq!(1.0f64.exp().log2(), 1.442695); @@ -1384,9 +1383,9 @@ mod tests { #[test] fn test_log10() { - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(10.0f64.log10(), 1.0); assert_approx_eq!(2.3f64.log10(), 0.361728); assert_approx_eq!(1.0f64.exp().log10(), 0.434294); @@ -1402,9 +1401,9 @@ mod tests { #[test] fn test_to_degrees() { let pi: f64 = consts::PI; - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(0.0f64.to_degrees(), 0.0); assert_approx_eq!((-5.8f64).to_degrees(), -332.315521); assert_eq!(pi.to_degrees(), 180.0); @@ -1416,9 +1415,9 @@ mod tests { #[test] fn test_to_radians() { let pi: f64 = consts::PI; - let nan: f64 = NAN; - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; assert_eq!(0.0f64.to_radians(), 0.0); assert_approx_eq!(154.6f64.to_radians(), 2.698279); assert_approx_eq!((-332.31f64).to_radians(), -5.799903); @@ -1433,9 +1432,9 @@ mod tests { assert_eq!(0.0f64.asinh(), 0.0f64); assert_eq!((-0.0f64).asinh(), -0.0f64); - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; - let nan: f64 = NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; assert_eq!(inf.asinh(), inf); assert_eq!(neg_inf.asinh(), neg_inf); assert!(nan.asinh().is_nan()); @@ -1450,9 +1449,9 @@ mod tests { assert_eq!(1.0f64.acosh(), 0.0f64); assert!(0.999f64.acosh().is_nan()); - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; - let nan: f64 = NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; assert_eq!(inf.acosh(), inf); assert!(neg_inf.acosh().is_nan()); assert!(nan.acosh().is_nan()); @@ -1465,9 +1464,9 @@ mod tests { assert_eq!(0.0f64.atanh(), 0.0f64); assert_eq!((-0.0f64).atanh(), -0.0f64); - let inf: f64 = INFINITY; - let neg_inf: f64 = NEG_INFINITY; - let nan: f64 = NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; assert_eq!(1.0f64.atanh(), inf); assert_eq!((-1.0f64).atanh(), neg_inf); assert!(2f64.atanh().atanh().is_nan()); @@ -1546,13 +1545,13 @@ mod tests { #[test] #[should_panic] fn test_clamp_min_is_nan() { - let _ = 1.0f64.clamp(NAN, 1.0); + let _ = 1.0f64.clamp(f64::NAN, 1.0); } #[test] #[should_panic] fn test_clamp_max_is_nan() { - let _ = 1.0f64.clamp(3.0, NAN); + let _ = 1.0f64.clamp(3.0, f64::NAN); } #[test] diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index e986a39eb03e0..0737008a94c9a 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -366,7 +366,7 @@ impl Seek for BufReader { // it should be safe to assume that remainder fits within an i64 as the alternative // means we managed to allocate 8 exbibytes and that's absurd. // But it's not out of the realm of possibility for some weird underlying reader to - // support seeking by i64::min_value() so we need to handle underflow when subtracting + // support seeking by i64::MIN so we need to handle underflow when subtracting // remainder. if let Some(offset) = n.checked_sub(remainder) { result = self.inner.seek(SeekFrom::Current(offset))?; @@ -1268,7 +1268,7 @@ mod tests { self.pos = self.pos.wrapping_add(n as u64); } SeekFrom::End(n) => { - self.pos = u64::max_value().wrapping_add(n as u64); + self.pos = u64::MAX.wrapping_add(n as u64); } } Ok(self.pos) @@ -1277,11 +1277,11 @@ mod tests { let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 }); assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..])); - assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::max_value() - 5)); + assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5)); assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); // the following seek will require two underlying seeks let expected = 9223372036854775802; - assert_eq!(reader.seek(SeekFrom::Current(i64::min_value())).ok(), Some(expected)); + assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected)); assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); // seeking to 0 should empty the buffer. assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected)); @@ -1319,7 +1319,7 @@ mod tests { // The following seek will require two underlying seeks. The first will // succeed but the second will fail. This should still invalidate the // buffer. - assert!(reader.seek(SeekFrom::Current(i64::min_value())).is_err()); + assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err()); assert_eq!(reader.buffer().len(), 0); } diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index f3e3fc81a5d82..f4db5f8145060 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -963,7 +963,7 @@ mod tests { #[cfg(target_pointer_width = "32")] fn vec_seek_and_write_past_usize_max() { let mut c = Cursor::new(Vec::new()); - c.set_position(::max_value() as u64 + 1); + c.set_position(usize::MAX as u64 + 1); assert!(c.write_all(&[1, 2, 3]).is_err()); } diff --git a/src/libstd/num.rs b/src/libstd/num.rs index de8acf8d9d472..b496c16a749cf 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -52,52 +52,43 @@ where #[cfg(test)] mod tests { use crate::ops::Mul; - use crate::u16; - use crate::u32; - use crate::u64; - use crate::u8; - use crate::usize; #[test] fn test_saturating_add_uint() { - use crate::usize::MAX; assert_eq!(3_usize.saturating_add(5_usize), 8_usize); - assert_eq!(3_usize.saturating_add(MAX - 1), MAX); - assert_eq!(MAX.saturating_add(MAX), MAX); - assert_eq!((MAX - 2).saturating_add(1), MAX - 1); + assert_eq!(3_usize.saturating_add(usize::MAX - 1), usize::MAX); + assert_eq!(usize::MAX.saturating_add(usize::MAX), usize::MAX); + assert_eq!((usize::MAX - 2).saturating_add(1), usize::MAX - 1); } #[test] fn test_saturating_sub_uint() { - use crate::usize::MAX; assert_eq!(5_usize.saturating_sub(3_usize), 2_usize); assert_eq!(3_usize.saturating_sub(5_usize), 0_usize); assert_eq!(0_usize.saturating_sub(1_usize), 0_usize); - assert_eq!((MAX - 1).saturating_sub(MAX), 0); + assert_eq!((usize::MAX - 1).saturating_sub(usize::MAX), 0); } #[test] fn test_saturating_add_int() { - use crate::isize::{MAX, MIN}; assert_eq!(3i32.saturating_add(5), 8); - assert_eq!(3isize.saturating_add(MAX - 1), MAX); - assert_eq!(MAX.saturating_add(MAX), MAX); - assert_eq!((MAX - 2).saturating_add(1), MAX - 1); + assert_eq!(3isize.saturating_add(isize::MAX - 1), isize::MAX); + assert_eq!(isize::MAX.saturating_add(isize::MAX), isize::MAX); + assert_eq!((isize::MAX - 2).saturating_add(1), isize::MAX - 1); assert_eq!(3i32.saturating_add(-5), -2); - assert_eq!(MIN.saturating_add(-1), MIN); - assert_eq!((-2isize).saturating_add(-MAX), MIN); + assert_eq!(isize::MIN.saturating_add(-1), isize::MIN); + assert_eq!((-2isize).saturating_add(-isize::MAX), isize::MIN); } #[test] fn test_saturating_sub_int() { - use crate::isize::{MAX, MIN}; assert_eq!(3i32.saturating_sub(5), -2); - assert_eq!(MIN.saturating_sub(1), MIN); - assert_eq!((-2isize).saturating_sub(MAX), MIN); + assert_eq!(isize::MIN.saturating_sub(1), isize::MIN); + assert_eq!((-2isize).saturating_sub(isize::MAX), isize::MIN); assert_eq!(3i32.saturating_sub(-5), 8); - assert_eq!(3isize.saturating_sub(-(MAX - 1)), MAX); - assert_eq!(MAX.saturating_sub(-MAX), MAX); - assert_eq!((MAX - 2).saturating_sub(-1), MAX - 1); + assert_eq!(3isize.saturating_sub(-(isize::MAX - 1)), isize::MAX); + assert_eq!(isize::MAX.saturating_sub(-isize::MAX), isize::MAX); + assert_eq!((isize::MAX - 2).saturating_sub(-1), isize::MAX - 1); } #[test] diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 77e521eae9afe..2250c0d4203ef 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -609,7 +609,6 @@ mod tests { use crate::sync::{Arc, Condvar, Mutex}; use crate::thread; use crate::time::Duration; - use crate::u64; #[test] fn smoke() { diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index e70204d6839fc..d6cc811154f11 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -2176,8 +2176,7 @@ mod tests { #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn very_long_recv_timeout_wont_panic() { let (tx, rx) = channel::<()>(); - let join_handle = - thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::max_value()))); + let join_handle = thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::MAX))); thread::sleep(Duration::from_secs(1)); assert!(tx.send(()).is_ok()); assert_eq!(join_handle.join().unwrap(), Ok(())); diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs index 3ba51d77494d4..dabdc0c9b510a 100644 --- a/src/libstd/sys/cloudabi/condvar.rs +++ b/src/libstd/sys/cloudabi/condvar.rs @@ -42,7 +42,7 @@ impl Condvar { let ret = abi::condvar_signal( condvar as *mut abi::condvar, abi::scope::PRIVATE, - abi::nthreads::max_value(), + abi::nthreads::MAX, ); assert_eq!(ret, abi::errno::SUCCESS, "Failed to broadcast on condition variable"); } diff --git a/src/libstd/sys/hermit/condvar.rs b/src/libstd/sys/hermit/condvar.rs index 94e3275448ae9..132e579b3a5cb 100644 --- a/src/libstd/sys/hermit/condvar.rs +++ b/src/libstd/sys/hermit/condvar.rs @@ -35,7 +35,7 @@ impl Condvar { pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { let nanos = dur.as_nanos(); - let nanos = cmp::min(i64::max_value() as u128, nanos); + let nanos = cmp::min(i64::MAX as u128, nanos); // add current task to the wait queue let _ = abi::add_queue(self.id(), nanos as i64); diff --git a/src/libstd/sys/unix/android.rs b/src/libstd/sys/unix/android.rs index 8fc2599f0d762..ea05ee3d7cedf 100644 --- a/src/libstd/sys/unix/android.rs +++ b/src/libstd/sys/unix/android.rs @@ -95,7 +95,7 @@ pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> { match ftruncate64.get() { Some(f) => cvt_r(|| f(fd, size as i64)).map(drop), None => { - if size > i32::max_value() as u64 { + if size > i32::MAX as u64 { Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot truncate >2GB")) } else { cvt_r(|| ftruncate(fd, size as i32)).map(drop) diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index b4896b7ad7476..9f1847943f326 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -10,14 +10,10 @@ unsafe impl Send for Condvar {} unsafe impl Sync for Condvar {} const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: ::max_value(), tv_nsec: 1_000_000_000 - 1 }; + libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; fn saturating_cast_to_time_t(value: u64) -> libc::time_t { - if value > ::max_value() as u64 { - ::max_value() - } else { - value as libc::time_t - } + if value > ::MAX as u64 { ::MAX } else { value as libc::time_t } } impl Condvar { diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 32c2ac43129bf..cd24605ec7ab7 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -1090,7 +1090,7 @@ impl<'a> Iterator for Incoming<'a> { } fn size_hint(&self) -> (usize, Option) { - (usize::max_value(), None) + (usize::MAX, None) } } diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 1ef7ffacfcf14..c481ca8961f86 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -23,11 +23,7 @@ fn max_len() -> usize { // intentionally showing odd behavior by rejecting any read with a size // larger than or equal to INT_MAX. To handle both of these the read // size is capped on both platforms. - if cfg!(target_os = "macos") { - ::max_value() as usize - 1 - } else { - ::max_value() as usize - } + if cfg!(target_os = "macos") { ::MAX as usize - 1 } else { ::MAX as usize } } impl FileDesc { @@ -58,7 +54,7 @@ impl FileDesc { libc::readv( self.fd, bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::max_value() as usize) as c_int, + cmp::min(bufs.len(), c_int::MAX as usize) as c_int, ) })?; Ok(ret as usize) @@ -115,7 +111,7 @@ impl FileDesc { libc::writev( self.fd, bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::max_value() as usize) as c_int, + cmp::min(bufs.len(), c_int::MAX as usize) as c_int, ) })?; Ok(ret as usize) diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 80cf6a5dbc27b..29cdbf05354fb 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -1196,7 +1196,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { let mut written = 0u64; while written < len { let copy_result = if has_copy_file_range { - let bytes_to_copy = cmp::min(len - written, usize::max_value() as u64) as usize; + let bytes_to_copy = cmp::min(len - written, usize::MAX as u64) as usize; let copy_result = unsafe { // We actually don't have to adjust the offsets, // because copy_file_range adjusts the file offset automatically diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index f062bc012f7ef..3717c660b575d 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -148,7 +148,7 @@ impl Socket { timeout = 1; } - let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int; + let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; match unsafe { libc::poll(&mut pollfd, 1, timeout) } { -1 => { @@ -283,8 +283,8 @@ impl Socket { )); } - let secs = if dur.as_secs() > libc::time_t::max_value() as u64 { - libc::time_t::max_value() + let secs = if dur.as_secs() > libc::time_t::MAX as u64 { + libc::time_t::MAX } else { dur.as_secs() as libc::time_t }; diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 895ea48e2b43e..7b3d69dcaa015 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,7 +171,7 @@ impl Thread { unsafe { while secs > 0 || nsecs > 0 { let mut ts = libc::timespec { - tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t, + tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t, tv_nsec: nsecs, }; secs -= ts.tv_sec as u64; diff --git a/src/libstd/sys/vxworks/condvar.rs b/src/libstd/sys/vxworks/condvar.rs index f2a1d6815290d..5a77966d97468 100644 --- a/src/libstd/sys/vxworks/condvar.rs +++ b/src/libstd/sys/vxworks/condvar.rs @@ -10,14 +10,10 @@ unsafe impl Send for Condvar {} unsafe impl Sync for Condvar {} const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: ::max_value(), tv_nsec: 1_000_000_000 - 1 }; + libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; fn saturating_cast_to_time_t(value: u64) -> libc::time_t { - if value > ::max_value() as u64 { - ::max_value() - } else { - value as libc::time_t - } + if value > ::MAX as u64 { ::MAX } else { value as libc::time_t } } impl Condvar { diff --git a/src/libstd/sys/vxworks/fd.rs b/src/libstd/sys/vxworks/fd.rs index 23e9dc428ce23..7fa86f0db043f 100644 --- a/src/libstd/sys/vxworks/fd.rs +++ b/src/libstd/sys/vxworks/fd.rs @@ -17,7 +17,7 @@ fn max_len() -> usize { // The maximum read limit on most posix-like systems is `SSIZE_MAX`, // with the man page quoting that if the count of bytes to read is // greater than `SSIZE_MAX` the result is "unspecified". - ::max_value() as usize + ::MAX as usize } impl FileDesc { @@ -48,7 +48,7 @@ impl FileDesc { libc::readv( self.fd, bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::max_value() as usize) as c_int, + cmp::min(bufs.len(), c_int::MAX as usize) as c_int, ) })?; Ok(ret as usize) @@ -98,7 +98,7 @@ impl FileDesc { libc::writev( self.fd, bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::max_value() as usize) as c_int, + cmp::min(bufs.len(), c_int::MAX as usize) as c_int, ) })?; Ok(ret as usize) diff --git a/src/libstd/sys/vxworks/net.rs b/src/libstd/sys/vxworks/net.rs index de0b15b43a2e2..32c27ab6e9e8d 100644 --- a/src/libstd/sys/vxworks/net.rs +++ b/src/libstd/sys/vxworks/net.rs @@ -107,7 +107,7 @@ impl Socket { timeout = 1; } - let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int; + let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; match unsafe { libc::poll(&mut pollfd, 1, timeout) } { -1 => { @@ -220,8 +220,8 @@ impl Socket { )); } - let secs = if dur.as_secs() > libc::time_t::max_value() as u64 { - libc::time_t::max_value() + let secs = if dur.as_secs() > libc::time_t::MAX as u64 { + libc::time_t::MAX } else { dur.as_secs() as libc::time_t }; diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs index 4d0196e4b4de5..24a2e0f965d28 100644 --- a/src/libstd/sys/vxworks/thread.rs +++ b/src/libstd/sys/vxworks/thread.rs @@ -96,7 +96,7 @@ impl Thread { unsafe { while secs > 0 || nsecs > 0 { let mut ts = libc::timespec { - tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t, + tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t, tv_nsec: nsecs, }; secs -= ts.tv_sec as u64; diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 29fafaaa0b94f..4fe9661421b03 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -64,7 +64,7 @@ pub fn unsupported_err() -> std_io::Error { pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { use std_io::ErrorKind::*; - if errno > u16::max_value() as i32 || errno < 0 { + if errno > u16::MAX as i32 || errno < 0 { return Other; } match errno as u16 { diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 0986759b89b7c..0d39b1cec328c 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -25,7 +25,7 @@ impl Thread { pub fn sleep(dur: Duration) { let nanos = dur.as_nanos(); - assert!(nanos <= u64::max_value() as u128); + assert!(nanos <= u64::MAX as u128); const USERDATA: wasi::Userdata = 0x0123_45678; diff --git a/src/libstd/sys/wasm/condvar_atomics.rs b/src/libstd/sys/wasm/condvar_atomics.rs index a4021c0ee8380..1859cdd5a0ed8 100644 --- a/src/libstd/sys/wasm/condvar_atomics.rs +++ b/src/libstd/sys/wasm/condvar_atomics.rs @@ -48,7 +48,7 @@ impl Condvar { #[inline] pub unsafe fn notify_all(&self) { self.cnt.fetch_add(1, SeqCst); - wasm32::atomic_notify(self.ptr(), u32::max_value()); // -1 == "wake everyone" + wasm32::atomic_notify(self.ptr(), u32::MAX); // -1 == "wake everyone" } pub unsafe fn wait(&self, mutex: &Mutex) { @@ -72,7 +72,7 @@ impl Condvar { let ticket = self.cnt.load(SeqCst) as i32; mutex.unlock(); let nanos = dur.as_nanos(); - let nanos = cmp::min(i64::max_value() as u128, nanos); + let nanos = cmp::min(i64::MAX as u128, nanos); // If the return value is 2 then a timeout happened, so we return // `false` as we weren't actually notified. diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 0e0e78a827670..0a11896a0048f 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -38,7 +38,7 @@ impl Thread { // 2). let mut nanos = dur.as_nanos(); while nanos > 0 { - let amt = cmp::min(i64::max_value() as u128, nanos); + let amt = cmp::min(i64::MAX as u128, nanos); let mut x = 0; let val = unsafe { wasm32::i32_atomic_wait(&mut x, 0, amt as i64) }; debug_assert_eq!(val, 2); diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs index 2131cfc2c94bc..0d4baa3b340df 100644 --- a/src/libstd/sys/windows/handle.rs +++ b/src/libstd/sys/windows/handle.rs @@ -70,7 +70,7 @@ impl RawHandle { pub fn read(&self, buf: &mut [u8]) -> io::Result { let mut read = 0; - let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; + let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; let res = cvt(unsafe { c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, ptr::null_mut()) }); @@ -99,7 +99,7 @@ impl RawHandle { pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { let mut read = 0; - let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; + let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; let res = unsafe { let mut overlapped: c::OVERLAPPED = mem::zeroed(); overlapped.Offset = offset as u32; @@ -118,7 +118,7 @@ impl RawHandle { buf: &mut [u8], overlapped: *mut c::OVERLAPPED, ) -> io::Result> { - let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; + let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; let mut amt = 0; let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped)); match res { @@ -165,7 +165,7 @@ impl RawHandle { pub fn write(&self, buf: &[u8]) -> io::Result { let mut amt = 0; - let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; + let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; cvt(unsafe { c::WriteFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, ptr::null_mut()) })?; @@ -183,7 +183,7 @@ impl RawHandle { pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { let mut written = 0; - let len = cmp::min(buf.len(), ::max_value() as usize) as c::DWORD; + let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; unsafe { let mut overlapped: c::OVERLAPPED = mem::zeroed(); overlapped.Offset = offset as u32; diff --git a/src/libstd/sys/windows/io.rs b/src/libstd/sys/windows/io.rs index 5525d2832526f..fb06df1f80cda 100644 --- a/src/libstd/sys/windows/io.rs +++ b/src/libstd/sys/windows/io.rs @@ -12,7 +12,7 @@ pub struct IoSlice<'a> { impl<'a> IoSlice<'a> { #[inline] pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - assert!(buf.len() <= c::ULONG::max_value() as usize); + assert!(buf.len() <= c::ULONG::MAX as usize); IoSlice { vec: c::WSABUF { len: buf.len() as c::ULONG, @@ -49,7 +49,7 @@ pub struct IoSliceMut<'a> { impl<'a> IoSliceMut<'a> { #[inline] pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - assert!(buf.len() <= c::ULONG::max_value() as usize); + assert!(buf.len() <= c::ULONG::MAX as usize); IoSliceMut { vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() as *mut c::CHAR }, _p: PhantomData, diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 69877e68ba8fe..d63139d8052c2 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -295,7 +295,7 @@ pub fn dur2timeout(dur: Duration) -> c::DWORD { .checked_mul(1000) .and_then(|ms| ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000)) .and_then(|ms| ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 { 1 } else { 0 })) - .map(|ms| if ms > ::max_value() as u64 { c::INFINITE } else { ms as c::DWORD }) + .map(|ms| if ms > ::MAX as u64 { c::INFINITE } else { ms as c::DWORD }) .unwrap_or(c::INFINITE) } diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index a15ded92f08c4..9e74454bc2335 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -228,7 +228,7 @@ impl Socket { fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. - let len = cmp::min(buf.len(), i32::max_value() as usize) as i32; + let len = cmp::min(buf.len(), i32::MAX as usize) as i32; unsafe { match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, flags) { -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0), @@ -245,7 +245,7 @@ impl Socket { pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. - let len = cmp::min(bufs.len(), c::DWORD::max_value() as usize) as c::DWORD; + let len = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD; let mut nread = 0; let mut flags = 0; unsafe { @@ -282,7 +282,7 @@ impl Socket { ) -> io::Result<(usize, SocketAddr)> { let mut storage: c::SOCKADDR_STORAGE_LH = unsafe { mem::zeroed() }; let mut addrlen = mem::size_of_val(&storage) as c::socklen_t; - let len = cmp::min(buf.len(), ::max_value() as usize) as wrlen_t; + let len = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. @@ -313,7 +313,7 @@ impl Socket { } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - let len = cmp::min(bufs.len(), c::DWORD::max_value() as usize) as c::DWORD; + let len = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD; let mut nwritten = 0; unsafe { cvt(c::WSASend( diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 1c03bc9234448..81a5ef95e82dc 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -271,7 +271,7 @@ impl TcpStream { } pub fn write(&self, buf: &[u8]) -> io::Result { - let len = cmp::min(buf.len(), ::max_value() as usize) as wrlen_t; + let len = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; let ret = cvt(unsafe { c::send(*self.inner.as_inner(), buf.as_ptr() as *const c_void, len, MSG_NOSIGNAL) })?; @@ -502,7 +502,7 @@ impl UdpSocket { } pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result { - let len = cmp::min(buf.len(), ::max_value() as usize) as wrlen_t; + let len = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; let (dstp, dstlen) = dst.into_inner(); let ret = cvt(unsafe { c::sendto( @@ -641,7 +641,7 @@ impl UdpSocket { } pub fn send(&self, buf: &[u8]) -> io::Result { - let len = cmp::min(buf.len(), ::max_value() as usize) as wrlen_t; + let len = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; let ret = cvt(unsafe { c::send(*self.inner.as_inner(), buf.as_ptr() as *const c_void, len, MSG_NOSIGNAL) })?; diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 3134a5967566b..d435ca6842518 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -1530,7 +1530,6 @@ mod tests { use crate::sync::mpsc::{channel, Sender}; use crate::thread::{self, ThreadId}; use crate::time::Duration; - use crate::u32; // !!! These tests are dangerous. If something is buggy, they will hang, !!! // !!! instead of exiting cleanly. This might wedge the buildbots. !!! diff --git a/src/libstd/time.rs b/src/libstd/time.rs index c36e78b1d004e..bc3bfde6d7559 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -686,7 +686,7 @@ mod tests { // checked_add_duration will not panic on overflow let mut maybe_t = Some(Instant::now()); - let max_duration = Duration::from_secs(u64::max_value()); + let max_duration = Duration::from_secs(u64::MAX); // in case `Instant` can store `>= now + max_duration`. for _ in 0..2 { maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); @@ -766,7 +766,7 @@ mod tests { // checked_add_duration will not panic on overflow let mut maybe_t = Some(SystemTime::UNIX_EPOCH); - let max_duration = Duration::from_secs(u64::max_value()); + let max_duration = Duration::from_secs(u64::MAX); // in case `SystemTime` can store `>= UNIX_EPOCH + max_duration`. for _ in 0..2 { maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); diff --git a/src/test/rustdoc/show-const-contents.rs b/src/test/rustdoc/show-const-contents.rs index b35f67ef91243..814339e198f95 100644 --- a/src/test/rustdoc/show-const-contents.rs +++ b/src/test/rustdoc/show-const-contents.rs @@ -28,8 +28,8 @@ pub const CONST_CALC_I32: i32 = 42 + 1; // @!has show_const_contents/constant.CONST_REF_I32.html '; //' pub const CONST_REF_I32: &'static i32 = &42; -// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::max_value(); // 2_147_483_647i32' -pub const CONST_I32_MAX: i32 = i32::max_value(); +// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32' +pub const CONST_I32_MAX: i32 = i32::MAX; // @!has show_const_contents/constant.UNIT.html '= ();' // @!has show_const_contents/constant.UNIT.html '; //' @@ -56,11 +56,11 @@ pub use std::i32::MAX; macro_rules! int_module { ($T:ident) => ( - pub const MIN: $T = $T::min_value(); + pub const MIN: $T = $T::MIN; ) } -// @has show_const_contents/constant.MIN.html '= i16::min_value(); // -32_768i16' +// @has show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16' int_module!(i16); // @has show_const_contents/constant.ESCAPE.html //pre '= r#""#;' diff --git a/src/test/ui/consts/const-eval/shift_overflow.rs b/src/test/ui/consts/const-eval/shift_overflow.rs index f7d0f6bd96144..e843584b69bb5 100644 --- a/src/test/ui/consts/const-eval/shift_overflow.rs +++ b/src/test/ui/consts/const-eval/shift_overflow.rs @@ -1,6 +1,6 @@ enum Foo { // test that we detect overflows for non-u32 discriminants - X = 1 << ((u32::max_value() as u64) + 1), //~ ERROR E0080 + X = 1 << ((u32::MAX as u64) + 1), //~ ERROR E0080 Y = 42, } diff --git a/src/test/ui/consts/const-eval/shift_overflow.stderr b/src/test/ui/consts/const-eval/shift_overflow.stderr index 5db231cd5b0df..f4840e9ac96bd 100644 --- a/src/test/ui/consts/const-eval/shift_overflow.stderr +++ b/src/test/ui/consts/const-eval/shift_overflow.stderr @@ -1,8 +1,8 @@ error[E0080]: evaluation of constant value failed --> $DIR/shift_overflow.rs:3:9 | -LL | X = 1 << ((u32::max_value() as u64) + 1), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to shift left with overflow +LL | X = 1 << ((u32::MAX as u64) + 1), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to shift left with overflow error: aborting due to previous error diff --git a/src/test/ui/consts/const-int-arithmetic.rs b/src/test/ui/consts/const-int-arithmetic.rs index ab24abeba32fe..9c94551f7440e 100644 --- a/src/test/ui/consts/const-int-arithmetic.rs +++ b/src/test/ui/consts/const-int-arithmetic.rs @@ -34,8 +34,8 @@ suite!( C6: 5i8.checked_mul(122), None; C7: (-127i8).checked_mul(-99), None; - C8: (i8::min_value() + 1).checked_div(-1), Some(127); - C9: i8::min_value().checked_div(-1), None; + C8: (i8::MIN + 1).checked_div(-1), Some(127); + C9: i8::MIN.checked_div(-1), None; C10: 1i8.checked_div(0), None; C11: 5i8.checked_rem(2), Some(1); @@ -56,8 +56,8 @@ suite!( C21: i8::MIN.checked_abs(), None; // `const_euclidean_int_methods` - C22: (i8::min_value() + 1).checked_div_euclid(-1), Some(127); - C23: i8::min_value().checked_div_euclid(-1), None; + C22: (i8::MIN + 1).checked_div_euclid(-1), Some(127); + C23: i8::MIN.checked_div_euclid(-1), None; C24: (1i8).checked_div_euclid(0), None; C25: 5i8.checked_rem_euclid(2), Some(1); @@ -72,12 +72,12 @@ suite!( saturating_and_wrapping -> i8 { // `const_saturating_int_methods` C28: 100i8.saturating_add(1), 101; - C29: i8::max_value().saturating_add(100), i8::max_value(); - C30: i8::min_value().saturating_add(-1), i8::min_value(); + C29: i8::MAX.saturating_add(100), i8::MAX; + C30: i8::MIN.saturating_add(-1), i8::MIN; C31: 100i8.saturating_sub(127), -27; - C32: i8::min_value().saturating_sub(100), i8::min_value(); - C33: i8::max_value().saturating_sub(-1), i8::max_value(); + C32: i8::MIN.saturating_sub(100), i8::MIN; + C33: i8::MAX.saturating_sub(-1), i8::MAX; C34: 10i8.saturating_mul(12), 120; C35: i8::MAX.saturating_mul(10), i8::MAX; @@ -85,13 +85,13 @@ suite!( C37: 100i8.saturating_neg(), -100; C38: (-100i8).saturating_neg(), 100; - C39: i8::min_value().saturating_neg(), i8::max_value(); - C40: i8::max_value().saturating_neg(), i8::min_value() + 1; + C39: i8::MIN.saturating_neg(), i8::MAX; + C40: i8::MAX.saturating_neg(), i8::MIN + 1; C57: 100i8.saturating_abs(), 100; C58: (-100i8).saturating_abs(), 100; - C59: i8::min_value().saturating_abs(), i8::max_value(); - C60: (i8::min_value() + 1).saturating_abs(), i8::max_value(); + C59: i8::MIN.saturating_abs(), i8::MAX; + C60: (i8::MIN + 1).saturating_abs(), i8::MAX; // `const_wrapping_int_methods` C41: 100i8.wrapping_div(10), 10; diff --git a/src/test/ui/consts/const-int-conversion-rpass.rs b/src/test/ui/consts/const-int-conversion-rpass.rs index 6484169dd9ae1..4aaeeaa38853d 100644 --- a/src/test/ui/consts/const-int-conversion-rpass.rs +++ b/src/test/ui/consts/const-int-conversion-rpass.rs @@ -6,13 +6,13 @@ const FROM_LE_BYTES: i32 = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]); const FROM_NE_BYTES: i32 = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])); const TO_BE_BYTES: [u8; 4] = 0x12_34_56_78_i32.to_be_bytes(); const TO_LE_BYTES: [u8; 4] = 0x12_34_56_78_i32.to_le_bytes(); -const TO_NE_BYTES: [u8; 4] = i32::min_value().to_be().to_ne_bytes(); +const TO_NE_BYTES: [u8; 4] = i32::MIN.to_be().to_ne_bytes(); fn main() { assert_eq!(REVERSE, 0x1e6a2c48); assert_eq!(FROM_BE_BYTES, 0x12_34_56_78); assert_eq!(FROM_LE_BYTES, 0x78_56_34_12); - assert_eq!(FROM_NE_BYTES, i32::min_value()); + assert_eq!(FROM_NE_BYTES, i32::MIN); assert_eq!(TO_BE_BYTES, [0x12, 0x34, 0x56, 0x78]); assert_eq!(TO_LE_BYTES, [0x78, 0x56, 0x34, 0x12]); assert_eq!(TO_NE_BYTES, [0x80, 0, 0, 0]); diff --git a/src/test/ui/consts/const-int-conversion.rs b/src/test/ui/consts/const-int-conversion.rs index b80e616eae77e..5a05a2b35937a 100644 --- a/src/test/ui/consts/const-int-conversion.rs +++ b/src/test/ui/consts/const-int-conversion.rs @@ -11,6 +11,6 @@ fn main() { //~^ ERROR temporary value dropped while borrowed let c: &'static [u8] = &(0x12_34_56_78_i32.to_le_bytes()); //~^ ERROR temporary value dropped while borrowed - let d: &'static [u8] = &(i32::min_value().to_be().to_ne_bytes()); + let d: &'static [u8] = &(i32::MIN.to_be().to_ne_bytes()); //~^ ERROR temporary value dropped while borrowed } diff --git a/src/test/ui/consts/const-int-conversion.stderr b/src/test/ui/consts/const-int-conversion.stderr index 237f9627219bd..61162a792262b 100644 --- a/src/test/ui/consts/const-int-conversion.stderr +++ b/src/test/ui/consts/const-int-conversion.stderr @@ -67,8 +67,8 @@ LL | } error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:14:29 | -LL | let d: &'static [u8] = &(i32::min_value().to_be().to_ne_bytes()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use +LL | let d: &'static [u8] = &(i32::MIN.to_be().to_ne_bytes()); + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-int-overflowing-rpass.rs b/src/test/ui/consts/const-int-overflowing-rpass.rs index 9be87a6447cda..eecb88becabca 100644 --- a/src/test/ui/consts/const-int-overflowing-rpass.rs +++ b/src/test/ui/consts/const-int-overflowing-rpass.rs @@ -1,7 +1,7 @@ // run-pass const ADD_A: (u32, bool) = 5u32.overflowing_add(2); -const ADD_B: (u32, bool) = u32::max_value().overflowing_add(1); +const ADD_B: (u32, bool) = u32::MAX.overflowing_add(1); const SUB_A: (u32, bool) = 5u32.overflowing_sub(2); const SUB_B: (u32, bool) = 0u32.overflowing_sub(1); @@ -20,14 +20,14 @@ const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg(); const ABS_POS: (i32, bool) = 10i32.overflowing_abs(); const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs(); -const ABS_MIN: (i32, bool) = i32::min_value().overflowing_abs(); +const ABS_MIN: (i32, bool) = i32::MIN.overflowing_abs(); fn main() { assert_eq!(ADD_A, (7, false)); assert_eq!(ADD_B, (0, true)); assert_eq!(SUB_A, (3, false)); - assert_eq!(SUB_B, (u32::max_value(), true)); + assert_eq!(SUB_B, (u32::MAX, true)); assert_eq!(MUL_A, (10, false)); assert_eq!(MUL_B, (1410065408, true)); @@ -43,5 +43,5 @@ fn main() { assert_eq!(ABS_POS, (10, false)); assert_eq!(ABS_NEG, (10, false)); - assert_eq!(ABS_MIN, (i32::min_value(), true)); + assert_eq!(ABS_MIN, (i32::MIN, true)); } diff --git a/src/test/ui/consts/const-int-pow-rpass.rs b/src/test/ui/consts/const-int-pow-rpass.rs index b0fba19455ba8..4f936236dbb20 100644 --- a/src/test/ui/consts/const-int-pow-rpass.rs +++ b/src/test/ui/consts/const-int-pow-rpass.rs @@ -20,10 +20,10 @@ const NEXT_POWER_OF_TWO: u32 = 3u32.next_power_of_two(); const CHECKED_NEXT_POWER_OF_TWO_OK: Option = 3u32.checked_next_power_of_two(); const CHECKED_NEXT_POWER_OF_TWO_OVERFLOW: Option = - u32::max_value().checked_next_power_of_two(); + u32::MAX.checked_next_power_of_two(); const WRAPPING_NEXT_POWER_OF_TWO: u32 = - u32::max_value().wrapping_next_power_of_two(); + u32::MAX.wrapping_next_power_of_two(); fn main() { assert!(!IS_POWER_OF_TWO_A); @@ -37,7 +37,7 @@ fn main() { assert_eq!(WRAPPING_POW, 217); assert_eq!(OVERFLOWING_POW, (217, true)); - assert_eq!(SATURATING_POW, u8::max_value()); + assert_eq!(SATURATING_POW, u8::MAX); assert_eq!(NEXT_POWER_OF_TWO, 4); diff --git a/src/test/ui/consts/const-int-saturating-arith.rs b/src/test/ui/consts/const-int-saturating-arith.rs index d0a3eccd17763..4718120a51bd3 100644 --- a/src/test/ui/consts/const-int-saturating-arith.rs +++ b/src/test/ui/consts/const-int-saturating-arith.rs @@ -2,33 +2,33 @@ #![feature(const_saturating_int_methods)] const INT_U32_NO: u32 = (42 as u32).saturating_add(2); -const INT_U32: u32 = u32::max_value().saturating_add(1); -const INT_U128: u128 = u128::max_value().saturating_add(1); -const INT_I128: i128 = i128::max_value().saturating_add(1); -const INT_I128_NEG: i128 = i128::min_value().saturating_add(-1); +const INT_U32: u32 = u32::MAX.saturating_add(1); +const INT_U128: u128 = u128::MAX.saturating_add(1); +const INT_I128: i128 = i128::MAX.saturating_add(1); +const INT_I128_NEG: i128 = i128::MIN.saturating_add(-1); const INT_U32_NO_SUB: u32 = (42 as u32).saturating_sub(2); const INT_U32_SUB: u32 = (1 as u32).saturating_sub(2); const INT_I32_NO_SUB: i32 = (-42 as i32).saturating_sub(2); -const INT_I32_NEG_SUB: i32 = i32::min_value().saturating_sub(1); -const INT_I32_POS_SUB: i32 = i32::max_value().saturating_sub(-1); +const INT_I32_NEG_SUB: i32 = i32::MIN.saturating_sub(1); +const INT_I32_POS_SUB: i32 = i32::MAX.saturating_sub(-1); const INT_U128_SUB: u128 = (0 as u128).saturating_sub(1); -const INT_I128_NEG_SUB: i128 = i128::min_value().saturating_sub(1); -const INT_I128_POS_SUB: i128 = i128::max_value().saturating_sub(-1); +const INT_I128_NEG_SUB: i128 = i128::MIN.saturating_sub(1); +const INT_I128_POS_SUB: i128 = i128::MAX.saturating_sub(-1); fn main() { assert_eq!(INT_U32_NO, 44); - assert_eq!(INT_U32, u32::max_value()); - assert_eq!(INT_U128, u128::max_value()); - assert_eq!(INT_I128, i128::max_value()); - assert_eq!(INT_I128_NEG, i128::min_value()); + assert_eq!(INT_U32, u32::MAX); + assert_eq!(INT_U128, u128::MAX); + assert_eq!(INT_I128, i128::MAX); + assert_eq!(INT_I128_NEG, i128::MIN); assert_eq!(INT_U32_NO_SUB, 40); assert_eq!(INT_U32_SUB, 0); assert_eq!(INT_I32_NO_SUB, -44); - assert_eq!(INT_I32_NEG_SUB, i32::min_value()); - assert_eq!(INT_I32_POS_SUB, i32::max_value()); + assert_eq!(INT_I32_NEG_SUB, i32::MIN); + assert_eq!(INT_I32_POS_SUB, i32::MAX); assert_eq!(INT_U128_SUB, 0); - assert_eq!(INT_I128_NEG_SUB, i128::min_value()); - assert_eq!(INT_I128_POS_SUB, i128::max_value()); + assert_eq!(INT_I128_NEG_SUB, i128::MIN); + assert_eq!(INT_I128_POS_SUB, i128::MAX); } diff --git a/src/test/ui/consts/const-int-unchecked.rs b/src/test/ui/consts/const-int-unchecked.rs index fb09f62854d61..1596093b2c14b 100644 --- a/src/test/ui/consts/const-int-unchecked.rs +++ b/src/test/ui/consts/const-int-unchecked.rs @@ -131,12 +131,12 @@ const _: u16 = unsafe { std::intrinsics::unchecked_mul(300u16, 250u16) }; const _: i32 = unsafe { std::intrinsics::unchecked_div(1, 0) }; //~^ ERROR any use of this value will cause an error -const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::min_value(), -1) }; +const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) }; //~^ ERROR any use of this value will cause an error const _: i32 = unsafe { std::intrinsics::unchecked_rem(1, 0) }; //~^ ERROR any use of this value will cause an error -const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::min_value(), -1) }; +const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::MIN, -1) }; //~^ ERROR any use of this value will cause an error fn main() {} diff --git a/src/test/ui/consts/const-int-unchecked.stderr b/src/test/ui/consts/const-int-unchecked.stderr index cf70454b6bf9e..0287b404e7d46 100644 --- a/src/test/ui/consts/const-int-unchecked.stderr +++ b/src/test/ui/consts/const-int-unchecked.stderr @@ -355,8 +355,8 @@ LL | const _: i32 = unsafe { std::intrinsics::unchecked_div(1, 0) }; error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:134:25 | -LL | const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::min_value(), -1) }; - | ------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- +LL | const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) }; + | ------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | | overflow executing `unchecked_div` @@ -371,8 +371,8 @@ LL | const _: i32 = unsafe { std::intrinsics::unchecked_rem(1, 0) }; error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:139:25 | -LL | const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::min_value(), -1) }; - | ------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- +LL | const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::MIN, -1) }; + | ------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | | overflow executing `unchecked_rem` diff --git a/src/test/ui/consts/const-int-wrapping-rpass.rs b/src/test/ui/consts/const-int-wrapping-rpass.rs index 2bbad99a52a90..225d1e9393db4 100644 --- a/src/test/ui/consts/const-int-wrapping-rpass.rs +++ b/src/test/ui/consts/const-int-wrapping-rpass.rs @@ -1,10 +1,10 @@ // run-pass const ADD_A: u32 = 200u32.wrapping_add(55); -const ADD_B: u32 = 200u32.wrapping_add(u32::max_value()); +const ADD_B: u32 = 200u32.wrapping_add(u32::MAX); const SUB_A: u32 = 100u32.wrapping_sub(100); -const SUB_B: u32 = 100u32.wrapping_sub(u32::max_value()); +const SUB_B: u32 = 100u32.wrapping_sub(u32::MAX); const MUL_A: u8 = 10u8.wrapping_mul(12); const MUL_B: u8 = 25u8.wrapping_mul(12); @@ -20,7 +20,7 @@ const NEG_B: u32 = 1234567890u32.wrapping_neg(); const ABS_POS: i32 = 10i32.wrapping_abs(); const ABS_NEG: i32 = (-10i32).wrapping_abs(); -const ABS_MIN: i32 = i32::min_value().wrapping_abs(); +const ABS_MIN: i32 = i32::MIN.wrapping_abs(); fn main() { assert_eq!(ADD_A, 255); @@ -43,5 +43,5 @@ fn main() { assert_eq!(ABS_POS, 10); assert_eq!(ABS_NEG, 10); - assert_eq!(ABS_MIN, i32::min_value()); + assert_eq!(ABS_MIN, i32::MIN); } diff --git a/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs b/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs index e9c6104e3875a..4e2cc89948a01 100644 --- a/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs +++ b/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs @@ -5,7 +5,7 @@ #[repr(i128)] enum Test { A(Box) = 0, - B(usize) = u64::max_value() as i128 + 1, + B(usize) = u64::MAX as i128 + 1, } fn main() { diff --git a/src/test/ui/enum-discriminant/repr128.rs b/src/test/ui/enum-discriminant/repr128.rs index 420b6007c6d85..eefbc44f585b2 100644 --- a/src/test/ui/enum-discriminant/repr128.rs +++ b/src/test/ui/enum-discriminant/repr128.rs @@ -8,9 +8,9 @@ use std::marker::DiscriminantKind; enum Signed { Zero = 0, Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f, - U64Limit = u64::max_value() as i128 + 1, + U64Limit = u64::MAX as i128 + 1, SmallNegative = -1, - BigNegative = i128::min_value(), + BigNegative = i128::MIN, Next, } @@ -18,7 +18,7 @@ enum Signed { enum Unsigned { Zero = 0, Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f, - U64Limit = u64::max_value() as u128 + 1, + U64Limit = u64::MAX as u128 + 1, Next, } @@ -32,13 +32,13 @@ where fn main() { discr(Signed::Zero, 0); discr(Signed::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f); - discr(Signed::U64Limit, u64::max_value() as i128 + 1); + discr(Signed::U64Limit, u64::MAX as i128 + 1); discr(Signed::SmallNegative, -1); - discr(Signed::BigNegative, i128::min_value()); - discr(Signed::Next, i128::min_value() + 1); + discr(Signed::BigNegative, i128::MIN); + discr(Signed::Next, i128::MIN + 1); discr(Unsigned::Zero, 0); discr(Unsigned::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f); - discr(Unsigned::U64Limit, u64::max_value() as u128 + 1); - discr(Unsigned::Next, u64::max_value() as u128 + 2); + discr(Unsigned::U64Limit, u64::MAX as u128 + 1); + discr(Unsigned::Next, u64::MAX as u128 + 2); } diff --git a/src/test/ui/issues/issue-44216-add-instant.rs b/src/test/ui/issues/issue-44216-add-instant.rs index c2f3598f645bb..78cfecf2f32f0 100644 --- a/src/test/ui/issues/issue-44216-add-instant.rs +++ b/src/test/ui/issues/issue-44216-add-instant.rs @@ -6,5 +6,5 @@ use std::time::{Instant, Duration}; fn main() { let now = Instant::now(); - let _ = now + Duration::from_secs(u64::max_value()); + let _ = now + Duration::from_secs(u64::MAX); } diff --git a/src/test/ui/issues/issue-44216-add-system-time.rs b/src/test/ui/issues/issue-44216-add-system-time.rs index 9a88cb7c18916..7e9a3f802ec89 100644 --- a/src/test/ui/issues/issue-44216-add-system-time.rs +++ b/src/test/ui/issues/issue-44216-add-system-time.rs @@ -6,5 +6,5 @@ use std::time::{Duration, SystemTime}; fn main() { let now = SystemTime::now(); - let _ = now + Duration::from_secs(u64::max_value()); + let _ = now + Duration::from_secs(u64::MAX); } diff --git a/src/test/ui/issues/issue-44216-sub-instant.rs b/src/test/ui/issues/issue-44216-sub-instant.rs index 2decd88bbc06b..e40f80d449d96 100644 --- a/src/test/ui/issues/issue-44216-sub-instant.rs +++ b/src/test/ui/issues/issue-44216-sub-instant.rs @@ -6,5 +6,5 @@ use std::time::{Instant, Duration}; fn main() { let now = Instant::now(); - let _ = now - Duration::from_secs(u64::max_value()); + let _ = now - Duration::from_secs(u64::MAX); } diff --git a/src/test/ui/issues/issue-44216-sub-system-time.rs b/src/test/ui/issues/issue-44216-sub-system-time.rs index e58a31a41a5e9..2c5a000fab692 100644 --- a/src/test/ui/issues/issue-44216-sub-system-time.rs +++ b/src/test/ui/issues/issue-44216-sub-system-time.rs @@ -6,5 +6,5 @@ use std::time::{Duration, SystemTime}; fn main() { let now = SystemTime::now(); - let _ = now - Duration::from_secs(u64::max_value()); + let _ = now - Duration::from_secs(u64::MAX); } diff --git a/src/test/ui/issues/issue-8460.rs b/src/test/ui/issues/issue-8460.rs index 3fd576a8d3580..a7de4bd74aae4 100644 --- a/src/test/ui/issues/issue-8460.rs +++ b/src/test/ui/issues/issue-8460.rs @@ -27,21 +27,21 @@ macro_rules! check { fn main() { check![ - isize::min_value() / -isize::one(), - i8::min_value() / -i8::one(), - i16::min_value() / -i16::one(), - i32::min_value() / -i32::one(), - i64::min_value() / -i64::one(), + isize::MIN / -isize::one(), + i8::MIN / -i8::one(), + i16::MIN / -i16::one(), + i32::MIN / -i32::one(), + i64::MIN / -i64::one(), 1isize / isize::zero(), 1i8 / i8::zero(), 1i16 / i16::zero(), 1i32 / i32::zero(), 1i64 / i64::zero(), - isize::min_value() % -isize::one(), - i8::min_value() % -i8::one(), - i16::min_value() % -i16::one(), - i32::min_value() % -i32::one(), - i64::min_value() % -i64::one(), + isize::MIN % -isize::one(), + i8::MIN % -i8::one(), + i16::MIN % -i16::one(), + i32::MIN % -i32::one(), + i64::MIN % -i64::one(), 1isize % isize::zero(), 1i8 % i8::zero(), 1i16 % i16::zero(), diff --git a/src/test/ui/iterators/iter-step-overflow-debug.rs b/src/test/ui/iterators/iter-step-overflow-debug.rs index 5d67c7cbb4256..67605d2fcc253 100644 --- a/src/test/ui/iterators/iter-step-overflow-debug.rs +++ b/src/test/ui/iterators/iter-step-overflow-debug.rs @@ -6,14 +6,14 @@ use std::panic; fn main() { let r = panic::catch_unwind(|| { - let mut it = u8::max_value()..; + let mut it = u8::MAX..; it.next().unwrap(); // 255 it.next().unwrap(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - let mut it = i8::max_value()..; + let mut it = i8::MAX..; it.next().unwrap(); // 127 it.next().unwrap(); }); diff --git a/src/test/ui/iterators/iter-step-overflow-ndebug.rs b/src/test/ui/iterators/iter-step-overflow-ndebug.rs index a0ad92071b66c..33e708769badb 100644 --- a/src/test/ui/iterators/iter-step-overflow-ndebug.rs +++ b/src/test/ui/iterators/iter-step-overflow-ndebug.rs @@ -2,11 +2,11 @@ // compile-flags: -C debug_assertions=no fn main() { - let mut it = u8::max_value()..; + let mut it = u8::MAX..; assert_eq!(it.next().unwrap(), 255); - assert_eq!(it.next().unwrap(), u8::min_value()); + assert_eq!(it.next().unwrap(), u8::MIN); - let mut it = i8::max_value()..; + let mut it = i8::MAX..; assert_eq!(it.next().unwrap(), 127); - assert_eq!(it.next().unwrap(), i8::min_value()); + assert_eq!(it.next().unwrap(), i8::MIN); } diff --git a/src/test/ui/iterators/iter-sum-overflow-debug.rs b/src/test/ui/iterators/iter-sum-overflow-debug.rs index ee4ab4d24c6ab..b7667d1bbf6d9 100644 --- a/src/test/ui/iterators/iter-sum-overflow-debug.rs +++ b/src/test/ui/iterators/iter-sum-overflow-debug.rs @@ -6,22 +6,22 @@ use std::panic; fn main() { let r = panic::catch_unwind(|| { - [1, i32::max_value()].iter().sum::(); + [1, i32::MAX].iter().sum::(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().product::(); + [2, i32::MAX].iter().product::(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - [1, i32::max_value()].iter().cloned().sum::(); + [1, i32::MAX].iter().cloned().sum::(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().cloned().product::(); + [2, i32::MAX].iter().cloned().product::(); }); assert!(r.is_err()); } diff --git a/src/test/ui/iterators/iter-sum-overflow-ndebug.rs b/src/test/ui/iterators/iter-sum-overflow-ndebug.rs index 61d63d41fb87e..69f4744cc2a1a 100644 --- a/src/test/ui/iterators/iter-sum-overflow-ndebug.rs +++ b/src/test/ui/iterators/iter-sum-overflow-ndebug.rs @@ -2,13 +2,13 @@ // compile-flags: -C debug_assertions=no fn main() { - assert_eq!([1i32, i32::max_value()].iter().sum::(), - 1i32.wrapping_add(i32::max_value())); - assert_eq!([2i32, i32::max_value()].iter().product::(), - 2i32.wrapping_mul(i32::max_value())); + assert_eq!([1i32, i32::MAX].iter().sum::(), + 1i32.wrapping_add(i32::MAX)); + assert_eq!([2i32, i32::MAX].iter().product::(), + 2i32.wrapping_mul(i32::MAX)); - assert_eq!([1i32, i32::max_value()].iter().cloned().sum::(), - 1i32.wrapping_add(i32::max_value())); - assert_eq!([2i32, i32::max_value()].iter().cloned().product::(), - 2i32.wrapping_mul(i32::max_value())); + assert_eq!([1i32, i32::MAX].iter().cloned().sum::(), + 1i32.wrapping_add(i32::MAX)); + assert_eq!([2i32, i32::MAX].iter().cloned().product::(), + 2i32.wrapping_mul(i32::MAX)); } diff --git a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs index 429f8e0bc9648..04ca7f8a31534 100644 --- a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs +++ b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs @@ -6,22 +6,22 @@ use std::panic; fn main() { let r = panic::catch_unwind(|| { - [1, i32::max_value()].iter().sum::(); + [1, i32::MAX].iter().sum::(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().product::(); + [2, i32::MAX].iter().product::(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - [1, i32::max_value()].iter().cloned().sum::(); + [1, i32::MAX].iter().cloned().sum::(); }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - [2, i32::max_value()].iter().cloned().product::(); + [2, i32::MAX].iter().cloned().product::(); }); assert!(r.is_err()); } diff --git a/src/test/ui/iterators/skip-count-overflow.rs b/src/test/ui/iterators/skip-count-overflow.rs index d8efc948664ff..64dee3e3c8b20 100644 --- a/src/test/ui/iterators/skip-count-overflow.rs +++ b/src/test/ui/iterators/skip-count-overflow.rs @@ -3,6 +3,6 @@ // compile-flags: -C overflow-checks -C opt-level=3 fn main() { - let i = (0..usize::max_value()).chain(0..10).skip(usize::max_value()); + let i = (0..usize::MAX).chain(0..10).skip(usize::MAX); assert_eq!(i.count(), 10); } diff --git a/src/test/ui/numbers-arithmetic/i128.rs b/src/test/ui/numbers-arithmetic/i128.rs index ef558c0aa0c02..d61a1ab03b6b3 100644 --- a/src/test/ui/numbers-arithmetic/i128.rs +++ b/src/test/ui/numbers-arithmetic/i128.rs @@ -87,7 +87,7 @@ fn main() { assert_eq!((-z).checked_mul(-z), Some(0x734C_C2F2_A521)); assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); assert_eq!((k).checked_mul(k), None); - let l: i128 = b(i128::min_value()); + let l: i128 = b(i128::MIN); let o: i128 = b(17); assert_eq!(l.checked_sub(b(2)), None); assert_eq!(l.checked_add(l), None); diff --git a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs index 2bc018445db9e..10ec3f0c6624e 100644 --- a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs +++ b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs @@ -5,9 +5,9 @@ use std::thread; fn main() { - assert!(thread::spawn(|| i8::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| i16::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| i32::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| i64::min_value().abs()).join().is_err()); - assert!(thread::spawn(|| isize::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i8::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| i16::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| i32::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| i64::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| isize::MIN.abs()).join().is_err()); } diff --git a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs index e9927304f23f8..101c5d50b20b9 100644 --- a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs +++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs @@ -9,12 +9,12 @@ fn main() { macro_rules! overflow_test { ($t:ident) => ( let r = panic::catch_unwind(|| { - ($t::max_value()).next_power_of_two() + ($t::MAX).next_power_of_two() }); assert!(r.is_err()); let r = panic::catch_unwind(|| { - (($t::max_value() >> 1) + 2).next_power_of_two() + (($t::MAX >> 1) + 2).next_power_of_two() }); assert!(r.is_err()); ) diff --git a/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs index a3b8ff58a7359..4785abbc55470 100644 --- a/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs +++ b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs @@ -5,5 +5,5 @@ fn main() { let x = &(0u32 - 1); - assert_eq!(*x, u32::max_value()) + assert_eq!(*x, u32::MAX) } diff --git a/src/test/ui/numbers-arithmetic/u128.rs b/src/test/ui/numbers-arithmetic/u128.rs index 0b2305c6e8b1a..d7e28055b2154 100644 --- a/src/test/ui/numbers-arithmetic/u128.rs +++ b/src/test/ui/numbers-arithmetic/u128.rs @@ -53,14 +53,14 @@ fn main() { assert_eq!("10000000000000000000000000000000000000000000000000000000000000000000", format!("{:b}", j)); assert_eq!("340282366920938463463374607431768211455", - format!("{}", u128::max_value())); + format!("{}", u128::MAX)); assert_eq!("147573952589676412928", format!("{:?}", j)); // common traits assert_eq!(x, b(x.clone())); // overflow checks assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); assert_eq!((k).checked_mul(k), None); - let l: u128 = b(u128::max_value() - 10); + let l: u128 = b(u128::MAX - 10); let o: u128 = b(17); assert_eq!(l.checked_add(b(11)), None); assert_eq!(l.checked_sub(l), Some(0)); diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs index e664ecadda259..b7b3ec997810e 100644 --- a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs @@ -20,7 +20,7 @@ extern "platform-intrinsic" { fn main() { // unsigned { - const M: u32 = u32::max_value(); + const M: u32 = u32::MAX; let a = u32x4(1, 2, 3, 4); let b = u32x4(2, 4, 6, 8); @@ -48,8 +48,8 @@ fn main() { // signed { - const MIN: i32 = i32::min_value(); - const MAX: i32 = i32::max_value(); + const MIN: i32 = i32::MIN; + const MAX: i32 = i32::MAX; let a = i32x4(1, 2, 3, 4); let b = i32x4(2, 4, 6, 8); diff --git a/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs index b28f742a92e94..a323bd9e82b4a 100644 --- a/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs @@ -39,7 +39,7 @@ fn main() { let e = 0b_1101; // Check usize / isize - let msize: Tx4 = Tx4(usize::max_value(), 0, usize::max_value(), usize::max_value()); + let msize: Tx4 = Tx4(usize::MAX, 0, usize::MAX, usize::MAX); unsafe { let r: u8 = simd_bitmask(z); diff --git a/src/test/ui/simd/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs index 4195444a73f67..8b5afeac0bc2d 100644 --- a/src/test/ui/simd/simd-intrinsic-generic-reduction.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs @@ -100,7 +100,7 @@ fn main() { let r: u32 = simd_reduce_max(x); assert_eq!(r, 4_u32); - let t = u32::max_value(); + let t = u32::MAX; let x = u32x4(t, t, t, t); let r: u32 = simd_reduce_and(x); assert_eq!(r, t); diff --git a/src/tools/clippy/clippy_lints/src/consts.rs b/src/tools/clippy/clippy_lints/src/consts.rs index 81ddc8c0067c7..22c5acca064e9 100644 --- a/src/tools/clippy/clippy_lints/src/consts.rs +++ b/src/tools/clippy/clippy_lints/src/consts.rs @@ -254,11 +254,11 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { if let ["core", "num", int_impl, "max_value"] = *def_path; then { let value = match int_impl { - "" => i8::max_value() as u128, - "" => i16::max_value() as u128, - "" => i32::max_value() as u128, - "" => i64::max_value() as u128, - "" => i128::max_value() as u128, + "" => i8::MAX as u128, + "" => i16::MAX as u128, + "" => i32::MAX as u128, + "" => i64::MAX as u128, + "" => i128::MAX as u128, _ => return None, }; Some(Constant::Int(value)) diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index a1fed3fb6e205..12b62f5cf9789 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -65,7 +65,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant { continue; } }, - ty::Uint(UintTy::Usize) if val > u128::from(u32::max_value()) => {}, + ty::Uint(UintTy::Usize) if val > u128::from(u32::MAX) => {}, _ => continue, } span_lint( diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs index bc5fe44b30f8f..a9d8c66f26189 100644 --- a/src/tools/clippy/clippy_lints/src/types.rs +++ b/src/tools/clippy/clippy_lints/src/types.rs @@ -1946,18 +1946,18 @@ fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ let which = match (&ty.kind, cv) { (&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => Minimum, (&ty::Int(ity), Constant::Int(i)) - if i == unsext(cx.tcx, i128::min_value() >> (128 - int_bits(cx.tcx, ity)), ity) => + if i == unsext(cx.tcx, i128::MIN >> (128 - int_bits(cx.tcx, ity)), ity) => { Minimum }, (&ty::Bool, Constant::Bool(true)) => Maximum, (&ty::Int(ity), Constant::Int(i)) - if i == unsext(cx.tcx, i128::max_value() >> (128 - int_bits(cx.tcx, ity)), ity) => + if i == unsext(cx.tcx, i128::MAX >> (128 - int_bits(cx.tcx, ity)), ity) => { Maximum }, - (&ty::Uint(uty), Constant::Int(i)) if clip(cx.tcx, u128::max_value(), uty) == i => Maximum, + (&ty::Uint(uty), Constant::Int(i)) if clip(cx.tcx, u128::MAX, uty) == i => Maximum, _ => return None, }; @@ -2039,7 +2039,7 @@ impl FullInt { fn cmp_s_u(s: i128, u: u128) -> Ordering { if s < 0 { Ordering::Less - } else if u > (i128::max_value() as u128) { + } else if u > (i128::MAX as u128) { Ordering::Greater } else { (s as u128).cmp(&u) @@ -2084,48 +2084,48 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) match pre_cast_ty.kind { ty::Int(int_ty) => Some(match int_ty { IntTy::I8 => ( - FullInt::S(i128::from(i8::min_value())), - FullInt::S(i128::from(i8::max_value())), + FullInt::S(i128::from(i8::MIN)), + FullInt::S(i128::from(i8::MAX)), ), IntTy::I16 => ( - FullInt::S(i128::from(i16::min_value())), - FullInt::S(i128::from(i16::max_value())), + FullInt::S(i128::from(i16::MIN)), + FullInt::S(i128::from(i16::MAX)), ), IntTy::I32 => ( - FullInt::S(i128::from(i32::min_value())), - FullInt::S(i128::from(i32::max_value())), + FullInt::S(i128::from(i32::MIN)), + FullInt::S(i128::from(i32::MAX)), ), IntTy::I64 => ( - FullInt::S(i128::from(i64::min_value())), - FullInt::S(i128::from(i64::max_value())), + FullInt::S(i128::from(i64::MIN)), + FullInt::S(i128::from(i64::MAX)), ), - IntTy::I128 => (FullInt::S(i128::min_value()), FullInt::S(i128::max_value())), + IntTy::I128 => (FullInt::S(i128::MIN), FullInt::S(i128::MAX)), IntTy::Isize => ( - FullInt::S(isize::min_value() as i128), - FullInt::S(isize::max_value() as i128), + FullInt::S(isize::MIN as i128), + FullInt::S(isize::MAX as i128), ), }), ty::Uint(uint_ty) => Some(match uint_ty { UintTy::U8 => ( - FullInt::U(u128::from(u8::min_value())), - FullInt::U(u128::from(u8::max_value())), + FullInt::U(u128::from(u8::MIN)), + FullInt::U(u128::from(u8::MAX)), ), UintTy::U16 => ( - FullInt::U(u128::from(u16::min_value())), - FullInt::U(u128::from(u16::max_value())), + FullInt::U(u128::from(u16::MIN)), + FullInt::U(u128::from(u16::MAX)), ), UintTy::U32 => ( - FullInt::U(u128::from(u32::min_value())), - FullInt::U(u128::from(u32::max_value())), + FullInt::U(u128::from(u32::MIN)), + FullInt::U(u128::from(u32::MAX)), ), UintTy::U64 => ( - FullInt::U(u128::from(u64::min_value())), - FullInt::U(u128::from(u64::max_value())), + FullInt::U(u128::from(u64::MIN)), + FullInt::U(u128::from(u64::MAX)), ), - UintTy::U128 => (FullInt::U(u128::min_value()), FullInt::U(u128::max_value())), + UintTy::U128 => (FullInt::U(u128::MIN), FullInt::U(u128::MAX)), UintTy::Usize => ( - FullInt::U(usize::min_value() as u128), - FullInt::U(usize::max_value() as u128), + FullInt::U(usize::MIN as u128), + FullInt::U(usize::MAX as u128), ), }), _ => None, diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs index 7e0b211d862ca..8ee0969b0f076 100644 --- a/src/tools/clippy/tests/ui/cast.rs +++ b/src/tools/clippy/tests/ui/cast.rs @@ -37,11 +37,11 @@ fn main() { 1isize as usize; -1isize as usize; 0i8 as u8; - i8::max_value() as u8; - i16::max_value() as u16; - i32::max_value() as u32; - i64::max_value() as u64; - i128::max_value() as u128; + i8::MAX as u8; + i16::MAX as u16; + i32::MAX as u32; + i64::MAX as u64; + i128::MAX as u128; (-1i8).abs() as u8; (-1i16).abs() as u16; diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs index 24cb216e79bf3..2f32a7b157821 100644 --- a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs +++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs @@ -110,7 +110,7 @@ fn main() { } // Lint - if i_8 > i8::min_value() { + if i_8 > i8::MIN { i_8 -= 1; } @@ -120,7 +120,7 @@ fn main() { } // Lint - if i_8 != i8::min_value() { + if i_8 != i8::MIN { i_8 -= 1; } @@ -135,7 +135,7 @@ fn main() { } // Lint - if i_16 > i16::min_value() { + if i_16 > i16::MIN { i_16 -= 1; } @@ -145,7 +145,7 @@ fn main() { } // Lint - if i_16 != i16::min_value() { + if i_16 != i16::MIN { i_16 -= 1; } @@ -160,7 +160,7 @@ fn main() { } // Lint - if i_32 > i32::min_value() { + if i_32 > i32::MIN { i_32 -= 1; } @@ -170,7 +170,7 @@ fn main() { } // Lint - if i_32 != i32::min_value() { + if i_32 != i32::MIN { i_32 -= 1; } @@ -180,7 +180,7 @@ fn main() { let mut i_64: i64 = endi_64 - starti_64; // Lint - if i64::min_value() < i_64 { + if i64::MIN < i_64 { i_64 -= 1; } diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr index a8ba870b1dda6..2eb2023b3b9ef 100644 --- a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr +++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr @@ -75,7 +75,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:113:5 | -LL | / if i_8 > i8::min_value() { +LL | / if i_8 > i8::MIN { LL | | i_8 -= 1; LL | | } | |_____^ help: try: `i_8 = i_8.saturating_sub(1);` @@ -91,7 +91,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:123:5 | -LL | / if i_8 != i8::min_value() { +LL | / if i_8 != i8::MIN { LL | | i_8 -= 1; LL | | } | |_____^ help: try: `i_8 = i_8.saturating_sub(1);` @@ -107,7 +107,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:138:5 | -LL | / if i_16 > i16::min_value() { +LL | / if i_16 > i16::MIN { LL | | i_16 -= 1; LL | | } | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` @@ -123,7 +123,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:148:5 | -LL | / if i_16 != i16::min_value() { +LL | / if i_16 != i16::MIN { LL | | i_16 -= 1; LL | | } | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` @@ -139,7 +139,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:163:5 | -LL | / if i_32 > i32::min_value() { +LL | / if i_32 > i32::MIN { LL | | i_32 -= 1; LL | | } | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` @@ -155,7 +155,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:173:5 | -LL | / if i_32 != i32::min_value() { +LL | / if i_32 != i32::MIN { LL | | i_32 -= 1; LL | | } | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` @@ -163,7 +163,7 @@ LL | | } error: Implicitly performing saturating subtraction --> $DIR/implicit_saturating_sub.rs:183:5 | -LL | / if i64::min_value() < i_64 { +LL | / if i64::MIN < i_64 { LL | | i_64 -= 1; LL | | } | |_____^ help: try: `i_64 = i_64.saturating_sub(1);` diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs index 95b63aca1549b..63cc29b670f6b 100644 --- a/src/tools/unicode-table-generator/src/raw_emitter.rs +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -43,7 +43,7 @@ impl RawEmitter { words.push(0); let unique_words = words.iter().cloned().collect::>().into_iter().collect::>(); - if unique_words.len() > u8::max_value() as usize { + if unique_words.len() > u8::MAX as usize { panic!("cannot pack {} into 8 bits", unique_words.len()); } // needed for the chunk mapping to work From 50a42fe5134fd8dbd5bc6df110654a31ee059a62 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Jun 2020 11:53:57 +0200 Subject: [PATCH 18/25] Create new error code E0762 for unterminated char literals --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0762.md | 13 +++++++++++++ src/librustc_parse/lexer/mod.rs | 10 +++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/librustc_error_codes/error_codes/E0762.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index ec5b3251e6883..285242647b38d 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -440,6 +440,7 @@ E0754: include_str!("./error_codes/E0754.md"), E0758: include_str!("./error_codes/E0758.md"), E0760: include_str!("./error_codes/E0760.md"), E0761: include_str!("./error_codes/E0761.md"), +E0762: include_str!("./error_codes/E0762.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0762.md b/src/librustc_error_codes/error_codes/E0762.md new file mode 100644 index 0000000000000..b01ded4a86616 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0762.md @@ -0,0 +1,13 @@ +A character literal wasn't ended with a quote. + +Erroneous code example: + +```compile_fail,E0762 +static C: char = '●; // error! +``` + +To fix this error, add the missing quote: + +``` +static C: char = '●'; // ok! +``` diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index 9bc6a50acad04..d135f713478a0 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -325,7 +325,15 @@ impl<'a> StringReader<'a> { let (lit_kind, mode, prefix_len, postfix_len) = match kind { rustc_lexer::LiteralKind::Char { terminated } => { if !terminated { - self.fatal_span_(start, suffix_start, "unterminated character literal").raise() + self.sess + .span_diagnostic + .struct_span_fatal_with_code( + self.mk_sp(start, suffix_start), + "unterminated character literal", + error_code!(E0762), + ) + .emit(); + FatalError.raise(); } (token::Char, Mode::Char, 1, 1) // ' ' } From 7bd87cfac2ca4c2c19b04018774b1fb1a9b39e48 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Jun 2020 11:55:50 +0200 Subject: [PATCH 19/25] Add tests for E0762 --- src/test/ui/parser/lex-bad-char-literals-4.stderr | 3 ++- src/test/ui/parser/lex-bad-char-literals-7.stderr | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/ui/parser/lex-bad-char-literals-4.stderr b/src/test/ui/parser/lex-bad-char-literals-4.stderr index 8f8f806f6cf61..fec4421c48a7c 100644 --- a/src/test/ui/parser/lex-bad-char-literals-4.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-4.stderr @@ -1,4 +1,4 @@ -error: unterminated character literal +error[E0762]: unterminated character literal --> $DIR/lex-bad-char-literals-4.rs:4:5 | LL | '● @@ -6,3 +6,4 @@ LL | '● error: aborting due to previous error +For more information about this error, try `rustc --explain E0762`. diff --git a/src/test/ui/parser/lex-bad-char-literals-7.stderr b/src/test/ui/parser/lex-bad-char-literals-7.stderr index ee9aa86935299..70ee8087b5163 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-7.stderr @@ -10,7 +10,7 @@ error: empty unicode escape (must have at least 1 hex digit) LL | let _: char = '\u{}'; | ^^^^ -error: unterminated character literal +error[E0762]: unterminated character literal --> $DIR/lex-bad-char-literals-7.rs:11:13 | LL | let _ = ' hello // here's a comment @@ -18,3 +18,4 @@ LL | let _ = ' hello // here's a comment error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0762`. From 5859f6e4f792afb663ac2dc98191cca08ac9b4ae Mon Sep 17 00:00:00 2001 From: Mihail Malo Date: Wed, 10 Jun 2020 13:55:40 +0300 Subject: [PATCH 20/25] Fix doctest template `saturating_add` example was not parameterized, but passed because the `u8` would saturate successfully --- src/libcore/num/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index c164e893b4fbf..b43994868dea2 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3309,7 +3309,8 @@ Basic usage: ``` ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101); -assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, " +assert_eq!((", stringify!($SelfT), "::MAX).saturating_add(127), ", stringify!($SelfT), +"::MAX);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] From f507748ce49f8e9ce5dc76bb7811a374c814923f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 10 Jun 2020 18:59:48 +0200 Subject: [PATCH 21/25] x.py: with --json-output, forward cargo's JSON --- src/bootstrap/compile.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b3999118e3de4..c09b73b042013 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -983,7 +983,13 @@ pub fn stream_cargo( for line in stdout.lines() { let line = t!(line); match serde_json::from_str::>(&line) { - Ok(msg) => cb(msg), + Ok(msg) => { + if builder.config.json_output { + // Forward JSON to stdout. + println!("{}", line); + } + cb(msg) + } // If this was informational, just print it out and continue Err(_) => println!("{}", line), } From c29b3fa1484c625bd34cb4d94fc76f36c6233447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 09:24:59 -0700 Subject: [PATCH 22/25] On recursive ADT, provide indirection structured suggestion --- src/librustc_errors/diagnostic.rs | 23 +++++++ src/librustc_errors/diagnostic_builder.rs | 13 ++++ src/librustc_middle/ty/util.rs | 10 ++- .../traits/error_reporting/mod.rs | 66 +++++++++++++++---- src/librustc_typeck/check/mod.rs | 6 +- .../infinite-tag-type-recursion.stderr | 9 ++- src/test/ui/issues/issue-17431-1.stderr | 11 +++- src/test/ui/issues/issue-17431-2.stderr | 22 +++++-- src/test/ui/issues/issue-17431-3.stderr | 11 +++- src/test/ui/issues/issue-17431-4.stderr | 11 +++- src/test/ui/issues/issue-17431-5.stderr | 11 +++- src/test/ui/issues/issue-17431-6.stderr | 9 ++- src/test/ui/issues/issue-17431-7.stderr | 9 ++- src/test/ui/issues/issue-2718-a.stderr | 9 ++- src/test/ui/issues/issue-3008-1.stderr | 9 ++- src/test/ui/issues/issue-3008-2.stderr | 11 +++- src/test/ui/issues/issue-3008-3.stderr | 9 ++- src/test/ui/issues/issue-32326.stderr | 5 +- src/test/ui/issues/issue-3779.stderr | 11 +++- src/test/ui/issues/issue-57271.stderr | 18 ++++- src/test/ui/recursion/recursive-enum.stderr | 9 ++- src/test/ui/sized-cycle-note.stderr | 22 +++++-- src/test/ui/span/E0072.stderr | 11 +++- src/test/ui/span/multiline-span-E0072.stderr | 11 +++- src/test/ui/span/recursive-type-field.stderr | 23 ++++--- src/test/ui/type/type-recursive.stderr | 11 +++- .../ui/union/union-nonrepresentable.stderr | 11 +++- 27 files changed, 315 insertions(+), 66 deletions(-) diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index cff83c3d5cda2..acaa26c6ad2fc 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -296,6 +296,29 @@ impl Diagnostic { self } + pub fn multipart_suggestions( + &mut self, + msg: &str, + suggestions: Vec>, + applicability: Applicability, + ) -> &mut Self { + self.suggestions.push(CodeSuggestion { + substitutions: suggestions + .into_iter() + .map(|suggestion| Substitution { + parts: suggestion + .into_iter() + .map(|(span, snippet)| SubstitutionPart { snippet, span }) + .collect(), + }) + .collect(), + msg: msg.to_owned(), + style: SuggestionStyle::ShowCode, + applicability, + }); + self + } + /// Prints out a message with for a multipart suggestion without showing the suggested code. /// /// This is intended to be used for suggestions that are obvious in what the changes need to diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 2dbd9f4e52fad..22bf8fe34aa15 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -260,6 +260,19 @@ impl<'a> DiagnosticBuilder<'a> { self } + pub fn multipart_suggestions( + &mut self, + msg: &str, + suggestions: Vec>, + applicability: Applicability, + ) -> &mut Self { + if !self.0.allow_suggestions { + return self; + } + self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability); + self + } + pub fn tool_only_multipart_suggestion( &mut self, msg: &str, diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index c2b794ca4bdd9..5cdfa6f90128d 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -827,7 +827,15 @@ impl<'tcx> ty::TyS<'tcx> { // Find non representable fields with their spans fold_repr(def.all_fields().map(|field| { let ty = field.ty(tcx, substs); - let span = tcx.hir().span_if_local(field.did).unwrap_or(sp); + let span = match field + .did + .as_local() + .map(|id| tcx.hir().as_local_hir_id(id)) + .and_then(|id| tcx.hir().find(id)) + { + Some(hir::Node::Field(field)) => field.ty.span, + _ => sp, + }; match is_type_structurally_recursive( tcx, span, diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index 1b72a4bf84f19..3457f7b4580c5 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -1747,24 +1747,62 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { pub fn recursive_type_with_infinite_size_error( tcx: TyCtxt<'tcx>, type_def_id: DefId, -) -> DiagnosticBuilder<'tcx> { + spans: Vec, +) { assert!(type_def_id.is_local()); let span = tcx.hir().span_if_local(type_def_id).unwrap(); let span = tcx.sess.source_map().guess_head_span(span); - let mut err = struct_span_err!( - tcx.sess, - span, - E0072, - "recursive type `{}` has infinite size", - tcx.def_path_str(type_def_id) - ); + let path = tcx.def_path_str(type_def_id); + let mut err = + struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", path); err.span_label(span, "recursive type has infinite size"); - err.help(&format!( - "insert indirection (e.g., a `Box`, `Rc`, or `&`) \ - at some point to make `{}` representable", - tcx.def_path_str(type_def_id) - )); - err + for &span in &spans { + err.span_label(span, "recursive without indirection"); + } + let short_msg = format!("insert some indirection to make `{}` representable", path); + let msg = format!( + "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable", + path, + ); + match &spans[..] { + [span] => { + err.multipart_suggestions( + &short_msg, + vec![ + vec![ + (span.shrink_to_lo(), "Box<".to_string()), + (span.shrink_to_hi(), ">".to_string()), + ], + vec![ + (span.shrink_to_lo(), "Rc<".to_string()), + (span.shrink_to_hi(), ">".to_string()), + ], + vec![(span.shrink_to_lo(), "&".to_string())], + ], + Applicability::HasPlaceholders, + ); + } + _ if spans.len() <= 4 => { + err.multipart_suggestion( + &msg, + spans + .iter() + .flat_map(|&span| { + vec![ + (span.shrink_to_lo(), "Box<".to_string()), + (span.shrink_to_hi(), ">".to_string()), + ] + .into_iter() + }) + .collect(), + Applicability::HasPlaceholders, + ); + } + _ => { + err.help(&msg); + } + } + err.emit(); } /// Summarizes information diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f2aeed4f1e465..1e8a149d7d9ec 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2390,11 +2390,7 @@ fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bo // caught by case 1. match rty.is_representable(tcx, sp) { Representability::SelfRecursive(spans) => { - let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id()); - for span in spans { - err.span_label(span, "recursive without indirection"); - } - err.emit(); + recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans); return false; } Representability::Representable | Representability::ContainsRecursive => (), diff --git a/src/test/ui/infinite/infinite-tag-type-recursion.stderr b/src/test/ui/infinite/infinite-tag-type-recursion.stderr index 11f82b842ba6f..b6a4d8f4cf563 100644 --- a/src/test/ui/infinite/infinite-tag-type-recursion.stderr +++ b/src/test/ui/infinite/infinite-tag-type-recursion.stderr @@ -6,7 +6,14 @@ LL | enum MList { Cons(isize, MList), Nil } | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `MList` representable +help: insert some indirection to make `MList` representable + | +LL | enum MList { Cons(isize, Box), Nil } + | ^^^^ ^ +LL | enum MList { Cons(isize, Rc), Nil } + | ^^^ ^ +LL | enum MList { Cons(isize, &MList), Nil } + | ^ error[E0391]: cycle detected when computing drop-check constraints for `MList` --> $DIR/infinite-tag-type-recursion.rs:1:1 diff --git a/src/test/ui/issues/issue-17431-1.stderr b/src/test/ui/issues/issue-17431-1.stderr index eb5a1366e8953..8d44154650e04 100644 --- a/src/test/ui/issues/issue-17431-1.stderr +++ b/src/test/ui/issues/issue-17431-1.stderr @@ -2,11 +2,18 @@ error[E0072]: recursive type `Foo` has infinite size --> $DIR/issue-17431-1.rs:1:1 | LL | struct Foo { foo: Option> } - | ^^^^^^^^^^ ------------------------ recursive without indirection + | ^^^^^^^^^^ ------------------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | struct Foo { foo: Box>> } + | ^^^^ ^ +LL | struct Foo { foo: Rc>> } + | ^^^ ^ +LL | struct Foo { foo: &Option> } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-2.stderr b/src/test/ui/issues/issue-17431-2.stderr index 3a7b0e9ce7997..b06184e84da28 100644 --- a/src/test/ui/issues/issue-17431-2.stderr +++ b/src/test/ui/issues/issue-17431-2.stderr @@ -2,21 +2,35 @@ error[E0072]: recursive type `Baz` has infinite size --> $DIR/issue-17431-2.rs:1:1 | LL | struct Baz { q: Option } - | ^^^^^^^^^^ -------------- recursive without indirection + | ^^^^^^^^^^ ----------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Baz` representable +help: insert some indirection to make `Baz` representable + | +LL | struct Baz { q: Box> } + | ^^^^ ^ +LL | struct Baz { q: Rc> } + | ^^^ ^ +LL | struct Baz { q: &Option } + | ^ error[E0072]: recursive type `Foo` has infinite size --> $DIR/issue-17431-2.rs:4:1 | LL | struct Foo { q: Option } - | ^^^^^^^^^^ -------------- recursive without indirection + | ^^^^^^^^^^ ----------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | struct Foo { q: Box> } + | ^^^^ ^ +LL | struct Foo { q: Rc> } + | ^^^ ^ +LL | struct Foo { q: &Option } + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-17431-3.stderr b/src/test/ui/issues/issue-17431-3.stderr index 675a2e2714209..f32bd70fd6d94 100644 --- a/src/test/ui/issues/issue-17431-3.stderr +++ b/src/test/ui/issues/issue-17431-3.stderr @@ -2,11 +2,18 @@ error[E0072]: recursive type `Foo` has infinite size --> $DIR/issue-17431-3.rs:3:1 | LL | struct Foo { foo: Mutex> } - | ^^^^^^^^^^ ----------------------- recursive without indirection + | ^^^^^^^^^^ ------------------ recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | struct Foo { foo: Box>> } + | ^^^^ ^ +LL | struct Foo { foo: Rc>> } + | ^^^ ^ +LL | struct Foo { foo: &Mutex> } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-4.stderr b/src/test/ui/issues/issue-17431-4.stderr index aff9071095ca0..372c5e975c844 100644 --- a/src/test/ui/issues/issue-17431-4.stderr +++ b/src/test/ui/issues/issue-17431-4.stderr @@ -2,11 +2,18 @@ error[E0072]: recursive type `Foo` has infinite size --> $DIR/issue-17431-4.rs:3:1 | LL | struct Foo { foo: Option>>, marker: marker::PhantomData } - | ^^^^^^^^^^^^^ --------------------------- recursive without indirection + | ^^^^^^^^^^^^^ ---------------------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | struct Foo { foo: Box>>>, marker: marker::PhantomData } + | ^^^^ ^ +LL | struct Foo { foo: Rc>>>, marker: marker::PhantomData } + | ^^^ ^ +LL | struct Foo { foo: &Option>>, marker: marker::PhantomData } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-5.stderr b/src/test/ui/issues/issue-17431-5.stderr index 537f9f34f55ca..01b850ac33694 100644 --- a/src/test/ui/issues/issue-17431-5.stderr +++ b/src/test/ui/issues/issue-17431-5.stderr @@ -2,11 +2,18 @@ error[E0072]: recursive type `Bar` has infinite size --> $DIR/issue-17431-5.rs:5:1 | LL | struct Bar { x: Bar , marker: marker::PhantomData } - | ^^^^^^^^^^^^^ ----------- recursive without indirection + | ^^^^^^^^^^^^^ -------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable +help: insert some indirection to make `Bar` representable + | +LL | struct Bar { x: Box> , marker: marker::PhantomData } + | ^^^^ ^ +LL | struct Bar { x: Rc> , marker: marker::PhantomData } + | ^^^ ^ +LL | struct Bar { x: &Bar , marker: marker::PhantomData } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-6.stderr b/src/test/ui/issues/issue-17431-6.stderr index cb2dab9501488..ce6c2db07fb6d 100644 --- a/src/test/ui/issues/issue-17431-6.stderr +++ b/src/test/ui/issues/issue-17431-6.stderr @@ -6,7 +6,14 @@ LL | enum Foo { X(Mutex>) } | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | enum Foo { X(Box>>) } + | ^^^^ ^ +LL | enum Foo { X(Rc>>) } + | ^^^ ^ +LL | enum Foo { X(&Mutex>) } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-7.stderr b/src/test/ui/issues/issue-17431-7.stderr index de70851da4b5f..4fb563ba502f2 100644 --- a/src/test/ui/issues/issue-17431-7.stderr +++ b/src/test/ui/issues/issue-17431-7.stderr @@ -6,7 +6,14 @@ LL | enum Foo { Voo(Option>) } | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | enum Foo { Voo(Box>>) } + | ^^^^ ^ +LL | enum Foo { Voo(Rc>>) } + | ^^^ ^ +LL | enum Foo { Voo(&Option>) } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2718-a.stderr b/src/test/ui/issues/issue-2718-a.stderr index 0f52c79192843..48b7a61e059ea 100644 --- a/src/test/ui/issues/issue-2718-a.stderr +++ b/src/test/ui/issues/issue-2718-a.stderr @@ -7,7 +7,14 @@ LL | pub struct Pong(SendPacket); | | recursive without indirection | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `pingpong::Pong` representable +help: insert some indirection to make `pingpong::Pong` representable + | +LL | pub struct Pong(Box>); + | ^^^^ ^ +LL | pub struct Pong(Rc>); + | ^^^ ^ +LL | pub struct Pong(&SendPacket); + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3008-1.stderr b/src/test/ui/issues/issue-3008-1.stderr index f12274134ee05..d1173a4b3334c 100644 --- a/src/test/ui/issues/issue-3008-1.stderr +++ b/src/test/ui/issues/issue-3008-1.stderr @@ -7,7 +7,14 @@ LL | enum Bar { LL | BarSome(Bar) | --- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable +help: insert some indirection to make `Bar` representable + | +LL | BarSome(Box) + | ^^^^ ^ +LL | BarSome(Rc) + | ^^^ ^ +LL | BarSome(&Bar) + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3008-2.stderr b/src/test/ui/issues/issue-3008-2.stderr index acc15f4b57c73..4fd60639b21a8 100644 --- a/src/test/ui/issues/issue-3008-2.stderr +++ b/src/test/ui/issues/issue-3008-2.stderr @@ -2,11 +2,18 @@ error[E0072]: recursive type `Bar` has infinite size --> $DIR/issue-3008-2.rs:2:1 | LL | struct Bar { x: Bar } - | ^^^^^^^^^^ ------ recursive without indirection + | ^^^^^^^^^^ --- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable +help: insert some indirection to make `Bar` representable + | +LL | struct Bar { x: Box } + | ^^^^ ^ +LL | struct Bar { x: Rc } + | ^^^ ^ +LL | struct Bar { x: &Bar } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3008-3.stderr b/src/test/ui/issues/issue-3008-3.stderr index d08a3d9708db3..e6efad9188300 100644 --- a/src/test/ui/issues/issue-3008-3.stderr +++ b/src/test/ui/issues/issue-3008-3.stderr @@ -6,7 +6,14 @@ LL | enum E2 { V2(E2, marker::PhantomData), } | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `E2` representable +help: insert some indirection to make `E2` representable + | +LL | enum E2 { V2(Box>, marker::PhantomData), } + | ^^^^ ^ +LL | enum E2 { V2(Rc>, marker::PhantomData), } + | ^^^ ^ +LL | enum E2 { V2(&E2, marker::PhantomData), } + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32326.stderr b/src/test/ui/issues/issue-32326.stderr index 5967627e51a4b..0f3d3690b732e 100644 --- a/src/test/ui/issues/issue-32326.stderr +++ b/src/test/ui/issues/issue-32326.stderr @@ -8,7 +8,10 @@ LL | Plus(Expr, Expr), | | | recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Expr` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Expr` representable + | +LL | Plus(Box, Box), + | ^^^^ ^ ^^^^ ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3779.stderr b/src/test/ui/issues/issue-3779.stderr index ba1e842c610ba..9b50ddec12a44 100644 --- a/src/test/ui/issues/issue-3779.stderr +++ b/src/test/ui/issues/issue-3779.stderr @@ -5,9 +5,16 @@ LL | struct S { | ^^^^^^^^ recursive type has infinite size LL | LL | element: Option - | ------------------ recursive without indirection + | --------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `S` representable +help: insert some indirection to make `S` representable + | +LL | element: Box> + | ^^^^ ^ +LL | element: Rc> + | ^^^ ^ +LL | element: &Option + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57271.stderr b/src/test/ui/issues/issue-57271.stderr index 4f164624f7a53..a6fe83a9b5636 100644 --- a/src/test/ui/issues/issue-57271.stderr +++ b/src/test/ui/issues/issue-57271.stderr @@ -7,7 +7,14 @@ LL | Class(ClassTypeSignature), LL | Array(TypeSignature), | ------------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ObjectType` representable +help: insert some indirection to make `ObjectType` representable + | +LL | Array(Box), + | ^^^^ ^ +LL | Array(Rc), + | ^^^ ^ +LL | Array(&TypeSignature), + | ^ error[E0072]: recursive type `TypeSignature` has infinite size --> $DIR/issue-57271.rs:19:1 @@ -18,7 +25,14 @@ LL | Base(BaseType), LL | Object(ObjectType), | ---------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `TypeSignature` representable +help: insert some indirection to make `TypeSignature` representable + | +LL | Object(Box), + | ^^^^ ^ +LL | Object(Rc), + | ^^^ ^ +LL | Object(&ObjectType), + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/recursion/recursive-enum.stderr b/src/test/ui/recursion/recursive-enum.stderr index e4674b57a6d21..c68badd458bce 100644 --- a/src/test/ui/recursion/recursive-enum.stderr +++ b/src/test/ui/recursion/recursive-enum.stderr @@ -6,7 +6,14 @@ LL | enum List { Cons(T, List), Nil } | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable +help: insert some indirection to make `List` representable + | +LL | enum List { Cons(T, Box>), Nil } + | ^^^^ ^ +LL | enum List { Cons(T, Rc>), Nil } + | ^^^ ^ +LL | enum List { Cons(T, &List), Nil } + | ^ error: aborting due to previous error diff --git a/src/test/ui/sized-cycle-note.stderr b/src/test/ui/sized-cycle-note.stderr index 95bdc34942645..99d8cfd0a05c9 100644 --- a/src/test/ui/sized-cycle-note.stderr +++ b/src/test/ui/sized-cycle-note.stderr @@ -2,21 +2,35 @@ error[E0072]: recursive type `Baz` has infinite size --> $DIR/sized-cycle-note.rs:9:1 | LL | struct Baz { q: Option } - | ^^^^^^^^^^ -------------- recursive without indirection + | ^^^^^^^^^^ ----------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Baz` representable +help: insert some indirection to make `Baz` representable + | +LL | struct Baz { q: Box> } + | ^^^^ ^ +LL | struct Baz { q: Rc> } + | ^^^ ^ +LL | struct Baz { q: &Option } + | ^ error[E0072]: recursive type `Foo` has infinite size --> $DIR/sized-cycle-note.rs:11:1 | LL | struct Foo { q: Option } - | ^^^^^^^^^^ -------------- recursive without indirection + | ^^^^^^^^^^ ----------- recursive without indirection | | | recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | struct Foo { q: Box> } + | ^^^^ ^ +LL | struct Foo { q: Rc> } + | ^^^ ^ +LL | struct Foo { q: &Option } + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr index d4a5e7400d2a4..855e4facb7b8c 100644 --- a/src/test/ui/span/E0072.stderr +++ b/src/test/ui/span/E0072.stderr @@ -5,9 +5,16 @@ LL | struct ListNode { | ^^^^^^^^^^^^^^^ recursive type has infinite size LL | head: u8, LL | tail: Option, - | ---------------------- recursive without indirection + | ---------------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable +help: insert some indirection to make `ListNode` representable + | +LL | tail: Box>, + | ^^^^ ^ +LL | tail: Rc>, + | ^^^ ^ +LL | tail: &Option, + | ^ error: aborting due to previous error diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr index dd322fe833b49..260c2157e96b7 100644 --- a/src/test/ui/span/multiline-span-E0072.stderr +++ b/src/test/ui/span/multiline-span-E0072.stderr @@ -6,11 +6,18 @@ LL | | ListNode LL | | { LL | | head: u8, LL | | tail: Option, - | | ---------------------- recursive without indirection + | | ---------------- recursive without indirection LL | | } | |_^ recursive type has infinite size | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable +help: insert some indirection to make `ListNode` representable + | +LL | tail: Box>, + | ^^^^ ^ +LL | tail: Rc>, + | ^^^ ^ +LL | tail: &Option, + | ^ error: aborting due to previous error diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr index d240872647e50..c1a3270d0a567 100644 --- a/src/test/ui/span/recursive-type-field.stderr +++ b/src/test/ui/span/recursive-type-field.stderr @@ -4,9 +4,16 @@ error[E0072]: recursive type `Foo` has infinite size LL | struct Foo<'a> { | ^^^^^^^^^^^^^^ recursive type has infinite size LL | bar: Bar<'a>, - | ------------ recursive without indirection + | ------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable +help: insert some indirection to make `Foo` representable + | +LL | bar: Box>, + | ^^^^ ^ +LL | bar: Rc>, + | ^^^ ^ +LL | bar: &Bar<'a>, + | ^ error[E0072]: recursive type `Bar` has infinite size --> $DIR/recursive-type-field.rs:8:1 @@ -14,18 +21,18 @@ error[E0072]: recursive type `Bar` has infinite size LL | struct Bar<'a> { | ^^^^^^^^^^^^^^ recursive type has infinite size LL | y: (Foo<'a>, Foo<'a>), - | --------------------- recursive without indirection + | ------------------ recursive without indirection LL | z: Option>, - | ------------------ recursive without indirection + | --------------- recursive without indirection ... LL | d: [Bar<'a>; 1], - | --------------- recursive without indirection + | ------------ recursive without indirection LL | e: Foo<'a>, - | ---------- recursive without indirection + | ------- recursive without indirection LL | x: Bar<'a>, - | ---------- recursive without indirection + | ------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable + = help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Bar` representable error: aborting due to 2 previous errors diff --git a/src/test/ui/type/type-recursive.stderr b/src/test/ui/type/type-recursive.stderr index 72bf372e561d6..b98a6eac49e04 100644 --- a/src/test/ui/type/type-recursive.stderr +++ b/src/test/ui/type/type-recursive.stderr @@ -5,9 +5,16 @@ LL | struct T1 { | ^^^^^^^^^ recursive type has infinite size LL | foo: isize, LL | foolish: T1 - | ----------- recursive without indirection + | -- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `T1` representable +help: insert some indirection to make `T1` representable + | +LL | foolish: Box + | ^^^^ ^ +LL | foolish: Rc + | ^^^ ^ +LL | foolish: &T1 + | ^ error: aborting due to previous error diff --git a/src/test/ui/union/union-nonrepresentable.stderr b/src/test/ui/union/union-nonrepresentable.stderr index 746c1033ea348..70863a549ad25 100644 --- a/src/test/ui/union/union-nonrepresentable.stderr +++ b/src/test/ui/union/union-nonrepresentable.stderr @@ -5,9 +5,16 @@ LL | union U { | ^^^^^^^ recursive type has infinite size LL | a: u8, LL | b: U, - | ---- recursive without indirection + | - recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `U` representable +help: insert some indirection to make `U` representable + | +LL | b: Box, + | ^^^^ ^ +LL | b: Rc, + | ^^^ ^ +LL | b: &U, + | ^ error: aborting due to previous error From 7cde07e5cc5cfc1665dd64e4c06482c2f10b693a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 30 May 2020 19:58:49 -0700 Subject: [PATCH 23/25] review comments: only suggest one substitution --- .../traits/error_reporting/mod.rs | 49 ++++++------------- .../infinite-tag-type-recursion.stderr | 6 +-- src/test/ui/issues/issue-17431-1.stderr | 6 +-- src/test/ui/issues/issue-17431-2.stderr | 12 +---- src/test/ui/issues/issue-17431-3.stderr | 6 +-- src/test/ui/issues/issue-17431-4.stderr | 6 +-- src/test/ui/issues/issue-17431-5.stderr | 6 +-- src/test/ui/issues/issue-17431-6.stderr | 6 +-- src/test/ui/issues/issue-17431-7.stderr | 6 +-- src/test/ui/issues/issue-2718-a.stderr | 6 +-- src/test/ui/issues/issue-3008-1.stderr | 6 +-- src/test/ui/issues/issue-3008-2.stderr | 6 +-- src/test/ui/issues/issue-3008-3.stderr | 6 +-- src/test/ui/issues/issue-3779.stderr | 6 +-- src/test/ui/issues/issue-57271.stderr | 12 +---- src/test/ui/recursion/recursive-enum.stderr | 6 +-- src/test/ui/sized-cycle-note.stderr | 12 +---- src/test/ui/span/E0072.stderr | 6 +-- src/test/ui/span/multiline-span-E0072.stderr | 6 +-- src/test/ui/span/recursive-type-field.stderr | 6 +-- src/test/ui/type/type-recursive.stderr | 6 +-- .../ui/union/union-nonrepresentable.stderr | 6 +-- 22 files changed, 38 insertions(+), 155 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index 3457f7b4580c5..d31e04cffd55f 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -1759,48 +1759,27 @@ pub fn recursive_type_with_infinite_size_error( for &span in &spans { err.span_label(span, "recursive without indirection"); } - let short_msg = format!("insert some indirection to make `{}` representable", path); let msg = format!( "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable", path, ); - match &spans[..] { - [span] => { - err.multipart_suggestions( - &short_msg, - vec![ + if spans.len() <= 4 { + err.multipart_suggestion( + &msg, + spans + .iter() + .flat_map(|&span| { vec![ (span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string()), - ], - vec![ - (span.shrink_to_lo(), "Rc<".to_string()), - (span.shrink_to_hi(), ">".to_string()), - ], - vec![(span.shrink_to_lo(), "&".to_string())], - ], - Applicability::HasPlaceholders, - ); - } - _ if spans.len() <= 4 => { - err.multipart_suggestion( - &msg, - spans - .iter() - .flat_map(|&span| { - vec![ - (span.shrink_to_lo(), "Box<".to_string()), - (span.shrink_to_hi(), ">".to_string()), - ] - .into_iter() - }) - .collect(), - Applicability::HasPlaceholders, - ); - } - _ => { - err.help(&msg); - } + ] + .into_iter() + }) + .collect(), + Applicability::HasPlaceholders, + ); + } else { + err.help(&msg); } err.emit(); } diff --git a/src/test/ui/infinite/infinite-tag-type-recursion.stderr b/src/test/ui/infinite/infinite-tag-type-recursion.stderr index b6a4d8f4cf563..6d1df4fda2eb0 100644 --- a/src/test/ui/infinite/infinite-tag-type-recursion.stderr +++ b/src/test/ui/infinite/infinite-tag-type-recursion.stderr @@ -6,14 +6,10 @@ LL | enum MList { Cons(isize, MList), Nil } | | | recursive type has infinite size | -help: insert some indirection to make `MList` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `MList` representable | LL | enum MList { Cons(isize, Box), Nil } | ^^^^ ^ -LL | enum MList { Cons(isize, Rc), Nil } - | ^^^ ^ -LL | enum MList { Cons(isize, &MList), Nil } - | ^ error[E0391]: cycle detected when computing drop-check constraints for `MList` --> $DIR/infinite-tag-type-recursion.rs:1:1 diff --git a/src/test/ui/issues/issue-17431-1.stderr b/src/test/ui/issues/issue-17431-1.stderr index 8d44154650e04..58d087ca1998b 100644 --- a/src/test/ui/issues/issue-17431-1.stderr +++ b/src/test/ui/issues/issue-17431-1.stderr @@ -6,14 +6,10 @@ LL | struct Foo { foo: Option> } | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | struct Foo { foo: Box>> } | ^^^^ ^ -LL | struct Foo { foo: Rc>> } - | ^^^ ^ -LL | struct Foo { foo: &Option> } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-2.stderr b/src/test/ui/issues/issue-17431-2.stderr index b06184e84da28..eba4bf6d1d5ea 100644 --- a/src/test/ui/issues/issue-17431-2.stderr +++ b/src/test/ui/issues/issue-17431-2.stderr @@ -6,14 +6,10 @@ LL | struct Baz { q: Option } | | | recursive type has infinite size | -help: insert some indirection to make `Baz` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Baz` representable | LL | struct Baz { q: Box> } | ^^^^ ^ -LL | struct Baz { q: Rc> } - | ^^^ ^ -LL | struct Baz { q: &Option } - | ^ error[E0072]: recursive type `Foo` has infinite size --> $DIR/issue-17431-2.rs:4:1 @@ -23,14 +19,10 @@ LL | struct Foo { q: Option } | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | struct Foo { q: Box> } | ^^^^ ^ -LL | struct Foo { q: Rc> } - | ^^^ ^ -LL | struct Foo { q: &Option } - | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-17431-3.stderr b/src/test/ui/issues/issue-17431-3.stderr index f32bd70fd6d94..f6b15d0528ae8 100644 --- a/src/test/ui/issues/issue-17431-3.stderr +++ b/src/test/ui/issues/issue-17431-3.stderr @@ -6,14 +6,10 @@ LL | struct Foo { foo: Mutex> } | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | struct Foo { foo: Box>> } | ^^^^ ^ -LL | struct Foo { foo: Rc>> } - | ^^^ ^ -LL | struct Foo { foo: &Mutex> } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-4.stderr b/src/test/ui/issues/issue-17431-4.stderr index 372c5e975c844..aa709e1ad5183 100644 --- a/src/test/ui/issues/issue-17431-4.stderr +++ b/src/test/ui/issues/issue-17431-4.stderr @@ -6,14 +6,10 @@ LL | struct Foo { foo: Option>>, marker: marker::PhantomData | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | struct Foo { foo: Box>>>, marker: marker::PhantomData } | ^^^^ ^ -LL | struct Foo { foo: Rc>>>, marker: marker::PhantomData } - | ^^^ ^ -LL | struct Foo { foo: &Option>>, marker: marker::PhantomData } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-5.stderr b/src/test/ui/issues/issue-17431-5.stderr index 01b850ac33694..1558cffb036b3 100644 --- a/src/test/ui/issues/issue-17431-5.stderr +++ b/src/test/ui/issues/issue-17431-5.stderr @@ -6,14 +6,10 @@ LL | struct Bar { x: Bar , marker: marker::PhantomData } | | | recursive type has infinite size | -help: insert some indirection to make `Bar` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Bar` representable | LL | struct Bar { x: Box> , marker: marker::PhantomData } | ^^^^ ^ -LL | struct Bar { x: Rc> , marker: marker::PhantomData } - | ^^^ ^ -LL | struct Bar { x: &Bar , marker: marker::PhantomData } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-6.stderr b/src/test/ui/issues/issue-17431-6.stderr index ce6c2db07fb6d..f2aa2a79c8200 100644 --- a/src/test/ui/issues/issue-17431-6.stderr +++ b/src/test/ui/issues/issue-17431-6.stderr @@ -6,14 +6,10 @@ LL | enum Foo { X(Mutex>) } | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | enum Foo { X(Box>>) } | ^^^^ ^ -LL | enum Foo { X(Rc>>) } - | ^^^ ^ -LL | enum Foo { X(&Mutex>) } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17431-7.stderr b/src/test/ui/issues/issue-17431-7.stderr index 4fb563ba502f2..684c3089e85ec 100644 --- a/src/test/ui/issues/issue-17431-7.stderr +++ b/src/test/ui/issues/issue-17431-7.stderr @@ -6,14 +6,10 @@ LL | enum Foo { Voo(Option>) } | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | enum Foo { Voo(Box>>) } | ^^^^ ^ -LL | enum Foo { Voo(Rc>>) } - | ^^^ ^ -LL | enum Foo { Voo(&Option>) } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2718-a.stderr b/src/test/ui/issues/issue-2718-a.stderr index 48b7a61e059ea..d152ffde4e57d 100644 --- a/src/test/ui/issues/issue-2718-a.stderr +++ b/src/test/ui/issues/issue-2718-a.stderr @@ -7,14 +7,10 @@ LL | pub struct Pong(SendPacket); | | recursive without indirection | recursive type has infinite size | -help: insert some indirection to make `pingpong::Pong` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `pingpong::Pong` representable | LL | pub struct Pong(Box>); | ^^^^ ^ -LL | pub struct Pong(Rc>); - | ^^^ ^ -LL | pub struct Pong(&SendPacket); - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3008-1.stderr b/src/test/ui/issues/issue-3008-1.stderr index d1173a4b3334c..87ee36df21696 100644 --- a/src/test/ui/issues/issue-3008-1.stderr +++ b/src/test/ui/issues/issue-3008-1.stderr @@ -7,14 +7,10 @@ LL | enum Bar { LL | BarSome(Bar) | --- recursive without indirection | -help: insert some indirection to make `Bar` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Bar` representable | LL | BarSome(Box) | ^^^^ ^ -LL | BarSome(Rc) - | ^^^ ^ -LL | BarSome(&Bar) - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3008-2.stderr b/src/test/ui/issues/issue-3008-2.stderr index 4fd60639b21a8..369a19d37e6f6 100644 --- a/src/test/ui/issues/issue-3008-2.stderr +++ b/src/test/ui/issues/issue-3008-2.stderr @@ -6,14 +6,10 @@ LL | struct Bar { x: Bar } | | | recursive type has infinite size | -help: insert some indirection to make `Bar` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Bar` representable | LL | struct Bar { x: Box } | ^^^^ ^ -LL | struct Bar { x: Rc } - | ^^^ ^ -LL | struct Bar { x: &Bar } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3008-3.stderr b/src/test/ui/issues/issue-3008-3.stderr index e6efad9188300..0b162eff94a7c 100644 --- a/src/test/ui/issues/issue-3008-3.stderr +++ b/src/test/ui/issues/issue-3008-3.stderr @@ -6,14 +6,10 @@ LL | enum E2 { V2(E2, marker::PhantomData), } | | | recursive type has infinite size | -help: insert some indirection to make `E2` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `E2` representable | LL | enum E2 { V2(Box>, marker::PhantomData), } | ^^^^ ^ -LL | enum E2 { V2(Rc>, marker::PhantomData), } - | ^^^ ^ -LL | enum E2 { V2(&E2, marker::PhantomData), } - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3779.stderr b/src/test/ui/issues/issue-3779.stderr index 9b50ddec12a44..7b17e91421660 100644 --- a/src/test/ui/issues/issue-3779.stderr +++ b/src/test/ui/issues/issue-3779.stderr @@ -7,14 +7,10 @@ LL | LL | element: Option | --------- recursive without indirection | -help: insert some indirection to make `S` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `S` representable | LL | element: Box> | ^^^^ ^ -LL | element: Rc> - | ^^^ ^ -LL | element: &Option - | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57271.stderr b/src/test/ui/issues/issue-57271.stderr index a6fe83a9b5636..b7c799e163cee 100644 --- a/src/test/ui/issues/issue-57271.stderr +++ b/src/test/ui/issues/issue-57271.stderr @@ -7,14 +7,10 @@ LL | Class(ClassTypeSignature), LL | Array(TypeSignature), | ------------- recursive without indirection | -help: insert some indirection to make `ObjectType` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `ObjectType` representable | LL | Array(Box), | ^^^^ ^ -LL | Array(Rc), - | ^^^ ^ -LL | Array(&TypeSignature), - | ^ error[E0072]: recursive type `TypeSignature` has infinite size --> $DIR/issue-57271.rs:19:1 @@ -25,14 +21,10 @@ LL | Base(BaseType), LL | Object(ObjectType), | ---------- recursive without indirection | -help: insert some indirection to make `TypeSignature` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `TypeSignature` representable | LL | Object(Box), | ^^^^ ^ -LL | Object(Rc), - | ^^^ ^ -LL | Object(&ObjectType), - | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/recursion/recursive-enum.stderr b/src/test/ui/recursion/recursive-enum.stderr index c68badd458bce..ab4709d8e709e 100644 --- a/src/test/ui/recursion/recursive-enum.stderr +++ b/src/test/ui/recursion/recursive-enum.stderr @@ -6,14 +6,10 @@ LL | enum List { Cons(T, List), Nil } | | | recursive type has infinite size | -help: insert some indirection to make `List` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable | LL | enum List { Cons(T, Box>), Nil } | ^^^^ ^ -LL | enum List { Cons(T, Rc>), Nil } - | ^^^ ^ -LL | enum List { Cons(T, &List), Nil } - | ^ error: aborting due to previous error diff --git a/src/test/ui/sized-cycle-note.stderr b/src/test/ui/sized-cycle-note.stderr index 99d8cfd0a05c9..45062c2ea6c72 100644 --- a/src/test/ui/sized-cycle-note.stderr +++ b/src/test/ui/sized-cycle-note.stderr @@ -6,14 +6,10 @@ LL | struct Baz { q: Option } | | | recursive type has infinite size | -help: insert some indirection to make `Baz` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Baz` representable | LL | struct Baz { q: Box> } | ^^^^ ^ -LL | struct Baz { q: Rc> } - | ^^^ ^ -LL | struct Baz { q: &Option } - | ^ error[E0072]: recursive type `Foo` has infinite size --> $DIR/sized-cycle-note.rs:11:1 @@ -23,14 +19,10 @@ LL | struct Foo { q: Option } | | | recursive type has infinite size | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | struct Foo { q: Box> } | ^^^^ ^ -LL | struct Foo { q: Rc> } - | ^^^ ^ -LL | struct Foo { q: &Option } - | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr index 855e4facb7b8c..06493f05142e6 100644 --- a/src/test/ui/span/E0072.stderr +++ b/src/test/ui/span/E0072.stderr @@ -7,14 +7,10 @@ LL | head: u8, LL | tail: Option, | ---------------- recursive without indirection | -help: insert some indirection to make `ListNode` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `ListNode` representable | LL | tail: Box>, | ^^^^ ^ -LL | tail: Rc>, - | ^^^ ^ -LL | tail: &Option, - | ^ error: aborting due to previous error diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr index 260c2157e96b7..55128347f7404 100644 --- a/src/test/ui/span/multiline-span-E0072.stderr +++ b/src/test/ui/span/multiline-span-E0072.stderr @@ -10,14 +10,10 @@ LL | | tail: Option, LL | | } | |_^ recursive type has infinite size | -help: insert some indirection to make `ListNode` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `ListNode` representable | LL | tail: Box>, | ^^^^ ^ -LL | tail: Rc>, - | ^^^ ^ -LL | tail: &Option, - | ^ error: aborting due to previous error diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr index c1a3270d0a567..fb1d98b58dfbe 100644 --- a/src/test/ui/span/recursive-type-field.stderr +++ b/src/test/ui/span/recursive-type-field.stderr @@ -6,14 +6,10 @@ LL | struct Foo<'a> { LL | bar: Bar<'a>, | ------- recursive without indirection | -help: insert some indirection to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable | LL | bar: Box>, | ^^^^ ^ -LL | bar: Rc>, - | ^^^ ^ -LL | bar: &Bar<'a>, - | ^ error[E0072]: recursive type `Bar` has infinite size --> $DIR/recursive-type-field.rs:8:1 diff --git a/src/test/ui/type/type-recursive.stderr b/src/test/ui/type/type-recursive.stderr index b98a6eac49e04..d6d32cc5d6f39 100644 --- a/src/test/ui/type/type-recursive.stderr +++ b/src/test/ui/type/type-recursive.stderr @@ -7,14 +7,10 @@ LL | foo: isize, LL | foolish: T1 | -- recursive without indirection | -help: insert some indirection to make `T1` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T1` representable | LL | foolish: Box | ^^^^ ^ -LL | foolish: Rc - | ^^^ ^ -LL | foolish: &T1 - | ^ error: aborting due to previous error diff --git a/src/test/ui/union/union-nonrepresentable.stderr b/src/test/ui/union/union-nonrepresentable.stderr index 70863a549ad25..c54d04de12c50 100644 --- a/src/test/ui/union/union-nonrepresentable.stderr +++ b/src/test/ui/union/union-nonrepresentable.stderr @@ -7,14 +7,10 @@ LL | a: u8, LL | b: U, | - recursive without indirection | -help: insert some indirection to make `U` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `U` representable | LL | b: Box, | ^^^^ ^ -LL | b: Rc, - | ^^^ ^ -LL | b: &U, - | ^ error: aborting due to previous error From 03552ec3fa4828329874a17d1b8966a0c03809d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 10 Jun 2020 14:54:27 -0700 Subject: [PATCH 24/25] fix rebase --- src/test/ui/issues/issue-72554.stderr | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/ui/issues/issue-72554.stderr b/src/test/ui/issues/issue-72554.stderr index 9db65f4a2ee8f..9de94c393a711 100644 --- a/src/test/ui/issues/issue-72554.stderr +++ b/src/test/ui/issues/issue-72554.stderr @@ -6,7 +6,10 @@ LL | pub enum ElemDerived { LL | A(ElemDerived) | ----------- recursive without indirection | - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ElemDerived` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `ElemDerived` representable + | +LL | A(Box) + | ^^^^ ^ error: aborting due to previous error From 7dc19b0bd5e8ca02f9f924098d9fac928441926b Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 11 Jun 2020 05:21:15 +0100 Subject: [PATCH 25/25] Update src/libcore/num/mod.rs Co-authored-by: lzutao --- src/libcore/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index b43994868dea2..fe131de66f152 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3309,8 +3309,8 @@ Basic usage: ``` ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101); -assert_eq!((", stringify!($SelfT), "::MAX).saturating_add(127), ", stringify!($SelfT), -"::MAX);", $EndFeature, " +assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(127), ", stringify!($SelfT), "::MAX);", +$EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")]