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

[fruitless] equip Res::Err with ErrorGuaranteeed #20

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
26 changes: 15 additions & 11 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::kw;
use rustc_span::Symbol;
use rustc_span::{ErrorGuaranteed, Symbol};

use std::array::IntoIter;
use std::fmt::Debug;
@@ -464,7 +464,7 @@ pub enum Res<Id = hir::HirId> {
/// of the compiler won't crash and can instead report more errors.
///
/// **Not bound to a specific namespace.**
Err,
Err(ErrorGuaranteed),
}

/// The result of resolving a path before lowering to HIR,
@@ -497,7 +497,7 @@ impl PartialRes {

#[inline]
pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
if base_res == Res::Err {
if base_res.is_err() {
unresolved_segments = 0
}
PartialRes { base_res, unresolved_segments }
@@ -678,7 +678,7 @@ impl<Id> Res<Id> {
| Res::SelfCtor(..)
| Res::ToolMod
| Res::NonMacroAttr(..)
| Res::Err => None,
| Res::Err(_) => None,
}
}

@@ -690,6 +690,10 @@ impl<Id> Res<Id> {
}
}

pub fn is_err(&self) -> bool {
matches!(self, Res::Err(_))
}

/// A human readable name for the res kind ("function", "module", etc.).
pub fn descr(&self) -> &'static str {
match *self {
@@ -700,7 +704,7 @@ impl<Id> Res<Id> {
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
Res::ToolMod => "tool module",
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
Res::Err => "unresolved item",
Res::Err(_) => "unresolved item",
}
}

@@ -709,7 +713,7 @@ impl<Id> Res<Id> {
match *self {
Res::Def(kind, _) => kind.article(),
Res::NonMacroAttr(kind) => kind.article(),
Res::Err => "an",
Res::Err(_) => "an",
_ => "a",
}
}
@@ -726,7 +730,7 @@ impl<Id> Res<Id> {
}
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
Res::Err(guar) => Res::Err(guar),
}
}

@@ -742,7 +746,7 @@ impl<Id> Res<Id> {
}
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
Res::Err(guar) => Res::Err(guar),
})
}

@@ -762,7 +766,7 @@ impl<Id> Res<Id> {
}
}

/// Returns `None` if this is `Res::Err`
/// Returns `None` if this is [`Res::Err`].
pub fn ns(&self) -> Option<Namespace> {
match self {
Res::Def(kind, ..) => kind.ns(),
@@ -771,11 +775,11 @@ impl<Id> Res<Id> {
}
Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
Res::Err => None,
Res::Err(_) => None,
}
}

/// Always returns `true` if `self` is `Res::Err`
/// Always returns `true` if `self` is [`Res::Err`].
pub fn matches_ns(&self, ns: Namespace) -> bool {
self.ns().map_or(true, |actual_ns| actual_ns == ns)
}
11 changes: 5 additions & 6 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -214,10 +214,6 @@ impl<'hir> PathSegment<'hir> {
PathSegment { ident, hir_id, res, infer_args: true, args: None }
}

pub fn invalid() -> Self {
Self::new(Ident::empty(), HirId::INVALID, Res::Err)
}

pub fn args(&self) -> &GenericArgs<'hir> {
if let Some(ref args) = self.args {
args
@@ -1703,7 +1699,10 @@ impl Expr<'_> {
pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
match self.kind {
ExprKind::Path(QPath::Resolved(_, ref path)) => {
matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
matches!(
path.res,
Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err(_)
)
}

// Type ascription inherits its place expression kind from its
@@ -3059,7 +3058,7 @@ impl TraitRef<'_> {
pub fn trait_def_id(&self) -> Option<DefId> {
match self.path.res {
Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
Res::Err => None,
Res::Err(_) => None,
res => panic!("{res:?} did not resolve to a trait or trait alias"),
}
}
7 changes: 6 additions & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
@@ -2154,7 +2154,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
span,
def_id,
&[],
&hir::PathSegment::invalid(),
// FIXME: Don't use Res::Err but "Res::Untermined" or "Res::Dummy"
&hir::PathSegment::new(
Ident::empty(),
HirId::INVALID,
Res::Err((|| -> () { todo!() })()),
),
None,
ty::BoundConstness::NotConst,
);
8 changes: 6 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
@@ -1379,8 +1379,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// mutability difference, like calling a method on `Pin<&mut Self>` that is on
// `Pin<&Self>`.
if targs.len() == 1 {
let mut item_segment = hir::PathSegment::invalid();
item_segment.ident = item_name;
// FIXME(fmease): Don't use Res::Err
let item_segment = hir::PathSegment::new(
item_name,
HirId::INVALID,
hir::def::Res::Err((|| -> () { todo!() })()),
);
for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] {
let new_args =
tcx.mk_args_from_iter(targs.iter().map(|arg| match arg.as_type() {
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -929,7 +929,7 @@ impl<'hir> Map<'hir> {

pub fn res_span(self, res: Res) -> Option<Span> {
match res {
Res::Err => None,
Res::Err(_) => None,
Res::Local(id) => Some(self.span(id)),
res => self.span_if_local(res.opt_def_id()?),
}
5 changes: 4 additions & 1 deletion compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
@@ -258,7 +258,10 @@ impl<'tcx> TypeckResults<'tcx> {
hir::QPath::Resolved(_, path) => path.res,
hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.type_dependent_def(id)
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
// FIXME: use Res::Undetermined here (I guess???)
.map_or(Res::Err((|| -> ErrorGuaranteed { todo!() })()), |(kind, def_id)| {
Res::Def(kind, def_id)
}),
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ impl<'tcx> TyCtxt<'tcx> {
| DefKind::Impl { .. },
def_id,
) => Some(def_id),
Res::Err => None,
Res::Err(_) => None,
_ => None,
}
}
19 changes: 9 additions & 10 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -288,16 +288,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.r.record_partial_res(id, PartialRes::new(res));
}
if module.is_normal() {
match res {
Res::Err => Ok(ty::Visibility::Public),
_ => {
let vis = ty::Visibility::Restricted(res.def_id());
if self.r.is_accessible_from(vis, parent_scope.module) {
Ok(vis.expect_local())
} else {
Err(VisResolutionError::AncestorOnly(path.span))
}
if !res.is_err() {
let vis = ty::Visibility::Restricted(res.def_id());
if self.r.is_accessible_from(vis, parent_scope.module) {
Ok(vis.expect_local())
} else {
Err(VisResolutionError::AncestorOnly(path.span))
}
} else {
Ok(ty::Visibility::Public)
}
} else {
expected_found_error(res)
@@ -1011,7 +1010,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..)
| Res::Err => bug!("unexpected resolution: {:?}", res),
| Res::Err(_) => bug!("unexpected resolution: {res:?}"),
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1854,7 +1854,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
while let Some(binding) = next_binding {
let name = next_ident;
next_binding = match binding.kind {
_ if res == Res::Err => None,
_ if res.is_err() => None,
NameBindingKind::Import { binding, import, .. } => match import.kind {
_ if binding.span.is_dummy() => None,
ImportKind::Single { source, .. } => {
23 changes: 13 additions & 10 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
@@ -295,7 +295,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
assert!(ns == TypeNS || ns == ValueNS);
let orig_ident = ident;
if ident.name == kw::Empty {
return Some(LexicalScopeBinding::Res(Res::Err));
// FIXME(fmease): Figure out when this is reached to provide a good message (...).
return Some(LexicalScopeBinding::Res(Res::Err(self.dcx().delayed_bug("xxx"))));
}
let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
// FIXME(jseyfried) improve `Self` hygiene
@@ -1143,8 +1144,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
};
self.report_error(span, res_error);
}
assert_eq!(res, Res::Err);
return Res::Err;
match res {
Res::Err(guar) => return Res::Err(guar),
res => bug!("unexpected resolution: {res:?}"),
}
}

match res {
@@ -1197,7 +1200,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
};
self.report_error(span, resolution_error);
}
return Res::Err;
return Res::Err(todo!()); // FIXME
}
RibKind::ConstParamTy => {
if let Some(span) = finalize {
@@ -1209,19 +1212,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
},
);
}
return Res::Err;
return Res::Err(todo!()); // FIXME
}
RibKind::InlineAsmSym => {
if let Some(span) = finalize {
self.report_error(span, InvalidAsmSym);
}
return Res::Err;
return Res::Err(todo!()); // FIXME
}
}
}
if let Some((span, res_err)) = res_err {
self.report_error(span, res_err);
return Res::Err;
let guar = self.report_error(span, res_err);
return Res::Err(guar);
}
}
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
@@ -1582,8 +1585,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
return PathResult::NonModule(PartialRes::new(res));
} else if res == Res::Err {
return PathResult::NonModule(PartialRes::new(Res::Err));
} else if let Res::Err(guar) = res {
return PathResult::NonModule(PartialRes::new(Res::Err(guar)));
} else if opt_ns.is_some() && (is_last || maybe_assoc) {
self.lint_if_path_starts_with_module(finalize, path, second_binding);
record_segment_res(self, res);
17 changes: 9 additions & 8 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
@@ -319,7 +319,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
self.set_binding_parent_module(binding, module);
self.update_resolution(module, key, warn_ambiguity, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if res == Res::Err && old_binding.res() != Res::Err {
if res.is_err() && !old_binding.res().is_err() {
// Do not override real bindings with `Res::Err`s from error recovery.
return Ok(());
}
@@ -612,7 +612,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(binding) = resolution.binding {
if let NameBindingKind::Import { import, .. } = binding.kind
&& let Some((amb_binding, _)) = binding.ambiguity
&& binding.res() != Res::Err
&& !binding.res().is_err()
&& exported_ambiguities.contains(&binding)
{
self.lint_buffer.buffer_lint(
@@ -639,8 +639,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
NameBindingKind::Import { import, .. } => import.id(),
};

if binding.res() != Res::Err
&& glob_binding.res() != Res::Err
if !binding.res().is_err()
&& !glob_binding.res().is_err()
&& let NameBindingKind::Import { import: glob_import, .. } =
glob_binding.kind
&& let Some(binding_id) = binding_id
@@ -964,7 +964,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
return None;
}
PathResult::NonModule(partial_res) => {
if no_ambiguity && partial_res.full_res() != Some(Res::Err) {
if no_ambiguity && !matches!(partial_res.full_res(), Some(Res::Err(_))) {
// Check if there are no ambiguities and the result is not dummy.
assert!(import.imported_module.get().is_none());
}
@@ -1082,9 +1082,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
initial_binding.res()
});
let res = binding.res();
let has_ambiguity_error =
this.ambiguity_errors.iter().any(|error| !error.warning);
if res == Res::Err || has_ambiguity_error {
if let Res::Err(_guar) = res {
return;
}
if this.ambiguity_errors.iter().any(|error| !error.warning) {
this.dcx()
.span_delayed_bug(import.span, "some error happened for an import");
return;