Skip to content

Commit

Permalink
Auto merge of rust-lang#72346 - Dylan-DPC:rollup-vp418xs, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - rust-lang#71886 (Stabilize saturating_abs and saturating_neg)
 - rust-lang#72066 (correctly handle uninferred consts)
 - rust-lang#72068 (Ignore arguments when looking for `IndexMut` for subsequent `mut` obligation)
 - rust-lang#72338 (Fix ICE in -Zsave-analysis)
 - rust-lang#72344 (Assert doc wording)

Failed merges:

r? @ghost
  • Loading branch information
bors committed May 19, 2020
2 parents 914adf0 + 745ca2a commit 42acd90
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/libcore/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ pub(crate) mod builtin {
/// be disabled. See [`debug_assert!`] for assertions that are not enabled in
/// release builds by default.
///
/// Unsafe code relies on `assert!` to enforce run-time invariants that, if
/// Unsafe code may rely on `assert!` to enforce run-time invariants that, if
/// violated could lead to unsafety.
///
/// Other use-cases of `assert!` include testing and enforcing run-time
Expand Down
10 changes: 4 additions & 6 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,8 +1165,7 @@ instead of overflowing.
Basic usage:
```
", $Feature, "#![feature(saturating_neg)]
assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);
assert_eq!(", stringify!($SelfT), "::MIN.saturating_neg(), ", stringify!($SelfT),
"::MAX);
Expand All @@ -1175,7 +1174,7 @@ assert_eq!(", stringify!($SelfT), "::MAX.saturating_neg(), ", stringify!($SelfT)
$EndFeature, "
```"),

#[unstable(feature = "saturating_neg", issue = "59983")]
#[stable(feature = "saturating_neg", since = "1.45.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")]
#[inline]
pub const fn saturating_neg(self) -> Self {
Expand All @@ -1192,8 +1191,7 @@ MIN` instead of overflowing.
Basic usage:
```
", $Feature, "#![feature(saturating_neg)]
assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);
assert_eq!(", stringify!($SelfT), "::MIN.saturating_abs(), ", stringify!($SelfT),
"::MAX);
Expand All @@ -1202,7 +1200,7 @@ assert_eq!((", stringify!($SelfT), "::MIN + 1).saturating_abs(), ", stringify!($
$EndFeature, "
```"),

#[unstable(feature = "saturating_neg", issue = "59983")]
#[stable(feature = "saturating_neg", since = "1.45.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")]
#[inline]
pub const fn saturating_abs(self) -> Self {
Expand Down
1 change: 0 additions & 1 deletion src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#![feature(pattern)]
#![feature(range_is_empty)]
#![feature(raw)]
#![feature(saturating_neg)]
#![feature(sort_internals)]
#![feature(slice_partition_at_index)]
#![feature(specialization)]
Expand Down
43 changes: 42 additions & 1 deletion src/librustc_infer/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,19 @@ fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String {
}

pub enum TypeAnnotationNeeded {
/// ```compile_fail,E0282
/// let x = "hello".chars().rev().collect();
/// ```
E0282,
/// An implementation cannot be chosen unambiguously because of lack of information.
/// ```compile_fail,E0283
/// let _ = Default::default();
/// ```
E0283,
/// ```compile_fail,E0284
/// let mut d: u64 = 2;
/// d = d % 1u32.into();
/// ```
E0284,
}

Expand Down Expand Up @@ -261,7 +272,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
printer.name_resolver = Some(Box::new(&getter));
let _ = if let ty::FnDef(..) = ty.kind {
// We don't want the regular output for `fn`s because it includes its path in
// invalid pseduo-syntax, we want the `fn`-pointer output instead.
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
ty.fn_sig(self.tcx).print(printer)
} else {
ty.print(printer)
Expand Down Expand Up @@ -518,6 +529,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err
}

// FIXME(const_generics): We should either try and merge this with `need_type_info_err`
// or improve the errors created here.
//
// Unlike for type inference variables, we don't yet store the origin of const inference variables.
// This is needed for to get a more relevant error span.
pub fn need_type_info_err_const(
&self,
body_id: Option<hir::BodyId>,
span: Span,
ct: &'tcx ty::Const<'tcx>,
error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx> {
let mut local_visitor = FindHirNodeVisitor::new(&self, ct.into(), span);
if let Some(body_id) = body_id {
let expr = self.tcx.hir().expect_expr(body_id.hir_id);
local_visitor.visit_expr(expr);
}

let error_code = error_code.into();
let mut err = self.tcx.sess.struct_span_err_with_code(
local_visitor.target_span,
&format!("type annotations needed"),
error_code,
);

err.note("unable to infer the value of a const parameter");

err
}

/// If the `FnSig` for the method call can be found and type arguments are identified as
/// needed, suggest annotating the call, otherwise point out the resulting type of the call.
fn annotate_method_call(
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,11 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
}

pub fn get_path_res(&self, id: NodeId) -> Res {
let hir_id = self.tcx.hir().node_id_to_hir_id(id);
// FIXME(#71104)
let hir_id = match self.tcx.hir().opt_node_id_to_hir_id(id) {
Some(id) => id,
None => return Res::Err,
};
match self.tcx.hir().get(hir_id) {
Node::TraitRef(tr) => tr.path.res,

Expand Down
4 changes: 3 additions & 1 deletion src/librustc_typeck/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {

match expr.kind {
hir::ExprKind::Index(ref base_expr, ref index_expr) => {
let index_expr_ty = self.node_ty(index_expr.hir_id);
// We need to get the final type in case dereferences were needed for the trait
// to apply (#72002).
let index_expr_ty = self.tables.borrow().expr_ty_adjusted(index_expr);
self.convert_place_op_to_mutable(
PlaceOp::Index,
expr,
Expand Down
20 changes: 16 additions & 4 deletions src/librustc_typeck/check/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,13 +647,26 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
}

fn report_error(&self, t: Ty<'tcx>) {
fn report_type_error(&self, t: Ty<'tcx>) {
if !self.tcx.sess.has_errors() {
self.infcx
.need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, E0282)
.emit();
}
}

fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
if !self.tcx.sess.has_errors() {
self.infcx
.need_type_info_err_const(
Some(self.body.id()),
self.span.to_span(self.tcx),
c,
E0282,
)
.emit();
}
}
}

impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
Expand All @@ -666,7 +679,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
Ok(t) => self.infcx.tcx.erase_regions(&t),
Err(_) => {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
self.report_error(t);
self.report_type_error(t);
self.replaced_with_error = true;
self.tcx().types.err
}
Expand All @@ -683,8 +696,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
Ok(ct) => self.infcx.tcx.erase_regions(&ct),
Err(_) => {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
// FIXME: we'd like to use `self.report_error`, but it doesn't yet
// accept a &'tcx ty::Const.
self.report_const_error(ct);
self.replaced_with_error = true;
self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty })
}
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/const-generics/uninferred-consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete

// taken from https://github.com/rust-lang/rust/issues/70507#issuecomment-615268893
struct Foo;
impl Foo {
fn foo<const N: usize>(self) {}
}
fn main() {
Foo.foo();
//~^ ERROR type annotations needed
}
20 changes: 20 additions & 0 deletions src/test/ui/const-generics/uninferred-consts.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/uninferred-consts.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information

error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:10:5
|
LL | Foo.foo();
| ^^^^^^^^^
|
= note: unable to infer the value of a const parameter

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0282`.
1 change: 0 additions & 1 deletion src/test/ui/consts/const-int-arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// run-pass

#![feature(saturating_neg)]
#![feature(const_checked_int_methods)]
#![feature(const_euclidean_int_methods)]
#![feature(const_overflowing_int_methods)]
Expand Down
29 changes: 29 additions & 0 deletions src/test/ui/issues/issue-72002.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// check-pass
struct Indexable;

impl Indexable {
fn boo(&mut self) {}
}

impl std::ops::Index<&str> for Indexable {
type Output = Indexable;

fn index(&self, field: &str) -> &Indexable {
self
}
}

impl std::ops::IndexMut<&str> for Indexable {
fn index_mut(&mut self, field: &str) -> &mut Indexable {
self
}
}

fn main() {
let mut v = Indexable;
let field = "hello".to_string();

v[field.as_str()].boo();

v[&field].boo(); // < This should work
}
7 changes: 7 additions & 0 deletions src/test/ui/save-analysis/issue-72267.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// compile-flags: -Z save-analysis

fn main() {
let _: Box<(dyn ?Sized)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR at least one trait is required for an object type
}
15 changes: 15 additions & 0 deletions src/test/ui/save-analysis/issue-72267.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: `?Trait` is not permitted in trait object types
--> $DIR/issue-72267.rs:4:21
|
LL | let _: Box<(dyn ?Sized)>;
| ^^^^^^

error[E0224]: at least one trait is required for an object type
--> $DIR/issue-72267.rs:4:17
|
LL | let _: Box<(dyn ?Sized)>;
| ^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0224`.

0 comments on commit 42acd90

Please sign in to comment.