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

Fix ICE in diagnostic_hir_wf_check #87524

Merged
merged 1 commit into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {

let mut err = match *error {
SelectionError::Unimplemented => {
// If this obligation was generated as a result of well-formed checking, see if we
// can get a better error message by performing HIR-based well formed checking.
// If this obligation was generated as a result of well-formedness checking, see if we
// can get a better error message by performing HIR-based well-formedness checking.
if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
root_obligation.cause.code.peel_derives()
{
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_typeck/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,20 @@ fn diagnostic_hir_wf_check<'tcx>(
// given the type `Option<MyStruct<u8>>`, we will check
// `Option<MyStruct<u8>>`, `MyStruct<u8>`, and `u8`.
// For each type, we perform a well-formed check, and see if we get
// an erorr that matches our expected predicate. We keep save
// an error that matches our expected predicate. We save
// the `ObligationCause` corresponding to the *innermost* type,
// which is the most specific type that we can point to.
// In general, the different components of an `hir::Ty` may have
// completely differentr spans due to macro invocations. Pointing
// completely different spans due to macro invocations. Pointing
// to the most accurate part of the type can be the difference
// between a useless span (e.g. the macro invocation site)
// and a useful span (e.g. a user-provided type passed in to the macro).
// and a useful span (e.g. a user-provided type passed into the macro).
//
// This approach is quite inefficient - we redo a lot of work done
// by the normal WF checker. However, this code is run at most once
// per reported error - it will have no impact when compilation succeeds,
// and should only have an impact if a very large number of errors are
// displaydd to the user.
// and should only have an impact if a very large number of errors is
// displayed to the user.
struct HirWfCheck<'tcx> {
tcx: TyCtxt<'tcx>,
predicate: ty::Predicate<'tcx>,
Expand Down Expand Up @@ -126,10 +126,12 @@ fn diagnostic_hir_wf_check<'tcx>(
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
hir::Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::TyAlias(ty) => Some(ty),
hir::ImplItemKind::Const(ty, _) => Some(ty),
ref item => bug!("Unexpected ImplItem {:?}", item),
},
hir::Node::TraitItem(item) => match item.kind {
hir::TraitItemKind::Type(_, ty) => ty,
hir::TraitItemKind::Const(ty, _) => Some(ty),
ref item => bug!("Unexpected TraitItem {:?}", item),
},
hir::Node::Item(item) => match item.kind {
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/wf/issue-87495.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Regression test for the ICE described in #87495.

trait T {
const CONST: (bool, dyn T);
//~^ ERROR: the trait `T` cannot be made into an object [E0038]
}

fn main() {}
18 changes: 18 additions & 0 deletions src/test/ui/wf/issue-87495.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0038]: the trait `T` cannot be made into an object
--> $DIR/issue-87495.rs:4:25
|
LL | const CONST: (bool, dyn T);
| ^^^^^ `T` cannot be made into an object
|
= help: consider moving `CONST` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-87495.rs:4:11
|
LL | trait T {
| - this trait cannot be made into an object...
LL | const CONST: (bool, dyn T);
| ^^^^^ ...because it contains this associated `const`

error: aborting due to previous error

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