Fix ICE in diagnostic_hir_wf_check
This commit is contained in:
parent
70f74719a9
commit
dbd0fd2c2a
4 changed files with 35 additions and 7 deletions
|
@ -240,8 +240,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let mut err = match *error {
|
let mut err = match *error {
|
||||||
SelectionError::Unimplemented => {
|
SelectionError::Unimplemented => {
|
||||||
// If this obligation was generated as a result of well-formed checking, see if we
|
// 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 formed checking.
|
// can get a better error message by performing HIR-based well-formedness checking.
|
||||||
if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
|
if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
|
||||||
root_obligation.cause.code.peel_derives()
|
root_obligation.cause.code.peel_derives()
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,20 +38,20 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||||
// given the type `Option<MyStruct<u8>>`, we will check
|
// given the type `Option<MyStruct<u8>>`, we will check
|
||||||
// `Option<MyStruct<u8>>`, `MyStruct<u8>`, and `u8`.
|
// `Option<MyStruct<u8>>`, `MyStruct<u8>`, and `u8`.
|
||||||
// For each type, we perform a well-formed check, and see if we get
|
// 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,
|
// the `ObligationCause` corresponding to the *innermost* type,
|
||||||
// which is the most specific type that we can point to.
|
// which is the most specific type that we can point to.
|
||||||
// In general, the different components of an `hir::Ty` may have
|
// 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
|
// to the most accurate part of the type can be the difference
|
||||||
// between a useless span (e.g. the macro invocation site)
|
// 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
|
// 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
|
// by the normal WF checker. However, this code is run at most once
|
||||||
// per reported error - it will have no impact when compilation succeeds,
|
// 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
|
// and should only have an impact if a very large number of errors is
|
||||||
// displaydd to the user.
|
// displayed to the user.
|
||||||
struct HirWfCheck<'tcx> {
|
struct HirWfCheck<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicate: ty::Predicate<'tcx>,
|
predicate: ty::Predicate<'tcx>,
|
||||||
|
@ -126,10 +126,12 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||||
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
|
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
|
||||||
hir::Node::ImplItem(item) => match item.kind {
|
hir::Node::ImplItem(item) => match item.kind {
|
||||||
hir::ImplItemKind::TyAlias(ty) => Some(ty),
|
hir::ImplItemKind::TyAlias(ty) => Some(ty),
|
||||||
|
hir::ImplItemKind::Const(ty, _) => Some(ty),
|
||||||
ref item => bug!("Unexpected ImplItem {:?}", item),
|
ref item => bug!("Unexpected ImplItem {:?}", item),
|
||||||
},
|
},
|
||||||
hir::Node::TraitItem(item) => match item.kind {
|
hir::Node::TraitItem(item) => match item.kind {
|
||||||
hir::TraitItemKind::Type(_, ty) => ty,
|
hir::TraitItemKind::Type(_, ty) => ty,
|
||||||
|
hir::TraitItemKind::Const(ty, _) => Some(ty),
|
||||||
ref item => bug!("Unexpected TraitItem {:?}", item),
|
ref item => bug!("Unexpected TraitItem {:?}", item),
|
||||||
},
|
},
|
||||||
hir::Node::Item(item) => match item.kind {
|
hir::Node::Item(item) => match item.kind {
|
||||||
|
|
8
src/test/ui/wf/issue-87495.rs
Normal file
8
src/test/ui/wf/issue-87495.rs
Normal file
|
@ -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
src/test/ui/wf/issue-87495.stderr
Normal file
18
src/test/ui/wf/issue-87495.stderr
Normal file
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue