Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge need_type_info_err(_const) #77093

Merged
merged 8 commits into from
Sep 26, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 173 additions & 102 deletions compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
GenericParamDefKind::Const { .. } => {
let origin = ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstParameterDefinition(param.name),
kind: ConstVariableOriginKind::ConstParameterDefinition(
param.name,
param.def_id,
),
span,
};
let const_var_id =
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_middle/src/infer/unify_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ use rustc_data_structures::undo_log::UndoLogs;
use rustc_data_structures::unify::{
self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue,
};
use rustc_span::def_id::DefId;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use rustc_span::Span;

use std::cmp;
use std::marker::PhantomData;
Expand Down Expand Up @@ -124,8 +125,7 @@ pub struct ConstVariableOrigin {
pub enum ConstVariableOriginKind {
MiscVariable,
ConstInference,
// FIXME(const_generics): Consider storing the `DefId` of the param here.
ConstParameterDefinition(Symbol),
ConstParameterDefinition(Symbol, DefId),
SubstitutionPlaceholder,
}

Expand Down Expand Up @@ -176,17 +176,17 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);

fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
let val = match (value1.val, value2.val) {
let (val, span) = match (value1.val, value2.val) {
(ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
bug!("equating two const variables, both of which have known values")
}

// If one side is known, prefer that one.
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
Ok(value1.val)
(value1.val, value1.origin.span)
}
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
Ok(value2.val)
(value2.val, value2.origin.span)
}

// If both sides are *unknown*, it hardly matters, does it?
Expand All @@ -200,14 +200,14 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
// universe is the minimum of the two universes, because that is
// the one which contains the fewest names in scope.
let universe = cmp::min(universe1, universe2);
Ok(ConstVariableValue::Unknown { universe })
(ConstVariableValue::Unknown { universe }, value1.origin.span)
}
}?;
};

Ok(ConstVarValue {
origin: ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstInference,
span: DUMMY_SP,
span: span,
},
val,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,15 +396,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
) -> Option<RegionNameHighlight> {
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, counter);
let type_name = self.infcx.extract_type_name(&ty, Some(highlight)).0;
let type_name = self.infcx.extract_infer_data(ty.into(), Some(highlight)).name;

debug!(
"highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
type_name, needle_fr
);
if type_name.find(&format!("'{}", counter)).is_some() {
// Only add a label if we can confirm that a region was labelled.

Some(RegionNameHighlight::CannotMatchHirTy(span, type_name))
} else {
None
Expand Down Expand Up @@ -646,7 +645,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {

let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0;
let type_name = self.infcx.extract_infer_data(return_ty.into(), Some(highlight)).name;

let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);

Expand Down Expand Up @@ -698,7 +697,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {

let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0;
let type_name = self.infcx.extract_infer_data(yield_ty.into(), Some(highlight)).name;

let mir_hir_id = tcx.hir().local_def_id_to_hir_id(self.mir_def_id);

Expand Down
23 changes: 7 additions & 16 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use rustc_hir::Node;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{
self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
TypeFoldable, WithConstness,
Expand Down Expand Up @@ -1513,10 +1512,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
// check upstream for type errors and don't add the obligations to
// begin with in those cases.
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
self.need_type_info_err(body_id, span, self_ty.into(), ErrorCode::E0282).emit();
return;
}
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
let mut err =
self.need_type_info_err(body_id, span, self_ty.into(), ErrorCode::E0283);
err.note(&format!("cannot satisfy `{}`", predicate));
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
Expand Down Expand Up @@ -1580,17 +1580,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
return;
}

match arg.unpack() {
GenericArgKind::Lifetime(lt) => {
span_bug!(span, "unexpected well formed predicate: {:?}", lt)
}
GenericArgKind::Type(ty) => {
self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
}
GenericArgKind::Const(ct) => {
self.need_type_info_err_const(body_id, span, ct, ErrorCode::E0282)
}
}
self.need_type_info_err(body_id, span, arg, ErrorCode::E0282)
}

ty::PredicateAtom::Subtype(data) => {
Expand All @@ -1601,7 +1591,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
let SubtypePredicate { a_is_expected: _, a, b } = data;
// both must be type variables, or the other would've been instantiated
assert!(a.is_ty_var() && b.is_ty_var());
self.need_type_info_err(body_id, span, a, ErrorCode::E0282)
self.need_type_info_err(body_id, span, a.into(), ErrorCode::E0282)
}
ty::PredicateAtom::Projection(data) => {
let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
Expand All @@ -1612,7 +1602,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
}
if self_ty.needs_infer() && ty.needs_infer() {
// We do this for the `foo.collect()?` case to produce a suggestion.
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
let mut err =
self.need_type_info_err(body_id, span, self_ty.into(), ErrorCode::E0284);
err.note(&format!("cannot satisfy `{}`", predicate));
err
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2991,7 +2991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
} else {
if !self.is_tainted_by_errors() {
self.need_type_info_err((**self).body_id, sp, ty, E0282)
self.need_type_info_err((**self).body_id, sp, ty.into(), E0282)
.note("type must be known at this point")
.emit();
}
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_typeck/src/check/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,18 +653,23 @@ impl<'cx, 'tcx> Resolver<'cx, '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)
.need_type_info_err(
Some(self.body.id()),
self.span.to_span(self.tcx),
t.into(),
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(
.need_type_info_err(
Some(self.body.id()),
self.span.to_span(self.tcx),
c,
c.into(),
E0282,
)
.emit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/cannot-infer-const-args.rs:12:5
|
LL | foo();
| ^^^
|
= note: cannot infer the value of the const parameter `X`
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/cannot-infer-const-args.rs:12:5
|
LL | foo();
| ^^^
|
= note: cannot infer the value of the const parameter `X`
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`

error: aborting due to previous error

Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/const-generics/infer/issue-77092.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![feature(min_const_generics)]

use std::convert::TryInto;

fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] {
(&mut data[start .. start + N]).try_into().unwrap()
}

fn main() {
let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];

for i in 1 .. 4 {
println!("{:?}", take_array_from_mut(&mut arr, i));
//~^ ERROR type annotations needed
}
}
9 changes: 9 additions & 0 deletions src/test/ui/const-generics/infer/issue-77092.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0282]: type annotations needed
--> $DIR/issue-77092.rs:13:26
|
LL | println!("{:?}", take_array_from_mut(&mut arr, i));
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{_: usize}`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense here to use a similar message to below?
E.g.

cannot infer the value of const parameter `N`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the failed inference variable has a ConstInference origin, as it was created from unifying two uninferred consts vids.

So we don't have the info to emit a better error message in this case. We probably should "just" use one of the ConstParams as the origin in that case. I think the reason we don't do so with types is due to variance.

Not completely sure about all of this though, so I would prefer to look into this in a followup PR


error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
4 changes: 1 addition & 3 deletions src/test/ui/const-generics/infer/method-chain.full.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/method-chain.rs:21:33
|
LL | Foo.bar().bar().bar().bar().baz();
| ^^^
|
= note: cannot infer the value of the const parameter `N`
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`

error: aborting due to previous error

Expand Down
4 changes: 1 addition & 3 deletions src/test/ui/const-generics/infer/method-chain.min.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/method-chain.rs:21:33
|
LL | Foo.bar().bar().bar().bar().baz();
| ^^^
|
= note: cannot infer the value of the const parameter `N`
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:14:9
|
LL | Foo.foo();
| ^^^
|
= note: cannot infer the value of the const parameter `N`
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:14:9
|
LL | Foo.foo();
| ^^^
|
= note: cannot infer the value of the const parameter `N`
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`

error: aborting due to previous error

Expand Down