about summary refs log tree commit diff
path: root/compiler/rustc_query_impl/src/keys.rs
diff options
context:
space:
mode:
authorAaron Hill <aa1ronham@gmail.com>2021-04-04 16:55:39 -0400
committerAaron Hill <aa1ronham@gmail.com>2021-07-16 16:29:02 -0500
commita7653337380071ebc5b83a8133121b87dc892442 (patch)
tree731dc884e12d998b11796e2dbdf2cb08cbe2dcce /compiler/rustc_query_impl/src/keys.rs
parent59d92bd0173fb0436b93aa56ff2cb288d4717701 (diff)
downloadrust-a7653337380071ebc5b83a8133121b87dc892442.tar.gz
rust-a7653337380071ebc5b83a8133121b87dc892442.zip
Add initial implementation of HIR-based WF checking for diagnostics
During well-formed checking, we walk through all types 'nested' in
generic arguments. For example, WF-checking `Option<MyStruct<u8>>`
will cause us to check `MyStruct<u8>` and `u8`. However, this is done
on a `rustc_middle::ty::Ty`, which has no span information. As a result,
any errors that occur will have a very general span (e.g. the
definintion of an associated item).

This becomes a problem when macros are involved. In general, an
associated type like `type MyType = Option<MyStruct<u8>>;` may
have completely different spans for each nested type in the HIR. Using
the span of the entire associated item might end up pointing to a macro
invocation, even though a user-provided span is available in one of the
nested types.

This PR adds a framework for HIR-based well formed checking. This check
is only run during error reporting, and is used to obtain a more precise
span for an existing error. This is accomplished by individually
checking each 'nested' type in the HIR for the type, allowing us to
find the most-specific type (and span) that produces a given error.

The majority of the changes are to the error-reporting code. However,
some of the general trait code is modified to pass through more
information.

Since this has no soundness implications, I've implemented a minimal
version to begin with, which can be extended over time. In particular,
this only works for HIR items with a corresponding `DefId` (e.g. it will
not work for WF-checking performed within function bodies).
Diffstat (limited to 'compiler/rustc_query_impl/src/keys.rs')
-rw-r--r--compiler/rustc_query_impl/src/keys.rs12
1 files changed, 12 insertions, 0 deletions
diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
index b3cc7de4662..1993e0a602f 100644
--- a/compiler/rustc_query_impl/src/keys.rs
+++ b/compiler/rustc_query_impl/src/keys.rs
@@ -1,6 +1,7 @@
 //! Defines the set of legal keys that can be used in queries.
 
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
+use rustc_hir::HirId;
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::mir;
 use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -395,3 +396,14 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) {
         DUMMY_SP
     }
 }
+
+impl<'tcx> Key for (ty::Predicate<'tcx>, HirId) {
+    #[inline(always)]
+    fn query_crate_is_local(&self) -> bool {
+        true
+    }
+
+    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
+        DUMMY_SP
+    }
+}