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

Don't use Res::Err without emitting an error 1/* #72108

Closed
wants to merge 1 commit into from

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented May 11, 2020

We currently use Res::Err both to express "there was an error" and "there is no relevant resolution".

pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
match *qpath {
hir::QPath::Resolved(_, ref path) => path.res,
hir::QPath::TypeRelative(..) => self
.type_dependent_def(id)
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
}
}

Before I work on changing all occurrences of the second meaning to Option<Res> I want to get some
feedback whether this change is actually desired.

cc @nikomatsakis @matthewjasper

@rust-highfive
Copy link
Collaborator

r? @davidtwco

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 11, 2020
@nikomatsakis
Copy link
Contributor

cc @petrochenkov

@petrochenkov petrochenkov self-assigned this May 11, 2020
@nikomatsakis
Copy link
Contributor

I am reading up a bit here to get more context, however my general opinion that we have to be very careful about things that signal "there was an error reported to the user". It's very common to use variants like that to skip downstream errors or avoid bits of work, and it's easy to wind up with unsoundness as a result.

So 👍 to having a clear distinction between "error reported" and "no relevant resolution", presuming at least that 'no relevant resolution' doesn't always imply an error has been reported.

Can you elaborate a bit more on what bits of downstream code want to distinguish between those two cases, though? I know it came up when we were discussing lazy normalization, but I think the context would be helpful.

@lcnr
Copy link
Contributor Author

lcnr commented May 11, 2020

I first noticed this when refactoring query type_of for const generics.

// Try to use the segment resolution if it is valid, otherwise we
// default to the path resolution.
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
let generics = match res {
Res::Def(DefKind::Ctor(..), def_id) => {
tcx.generics_of(tcx.parent(def_id).unwrap())
}
Res::Def(_, def_id) => tcx.generics_of(def_id),
res => {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!(
"unexpected anon const res {:?} in path: {:?}",
res, path,
),
);
return tcx.types.err;
}
};

Some correct qpaths have segments where res is None, for others res is Some(Err) and for others it's Some(actually_correct_res). I think that my current solution is not correct in all cases and something like this may break it. (We have an ICE here atm with seems unrelated though 🤷)

Looking at some other locations where Res::Err is used. I am quite suspicious of the following,
which already depends on this distinction afaict.

if res == Res::Err {
self.set_tainted_by_errors();
on_error();
return self.tcx.types.err;
}

@petrochenkov
Copy link
Contributor

Before I work on changing all occurrences of the second meaning to Option<Res> I want to get some feedback whether this change is actually desired.

I think this is desirable at least after the main resolution pass, but I'd prefer to see this done in stages instead of changing all occurrences in one go. For example

  • everything after AST -> HIR lowering
  • AST -> HIR lowering
  • everything after expansion / early resoluton
  • expansion / early resolution (this may be harder because Res::Err is used in non-trivial ways for import stubs in namespaces where they don't import anything, and maybe other similar cases)

@petrochenkov petrochenkov removed their assignment May 11, 2020
@bors
Copy link
Contributor

bors commented May 19, 2020

☔ The latest upstream changes (presumably #69171) made this pull request unmergeable. Please resolve the merge conflicts.

@lcnr lcnr closed this May 25, 2020
@lcnr lcnr deleted the no-err-no-more branch June 20, 2020 10:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants