-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
[DRAFT] Make lang items private #72249
Conversation
CI failed pending changes from #72216 (I'll be rebasing on top of it when it lands) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
src/librustc_hir/lang_items.rs
Outdated
|
||
impl LangItemRecord { | ||
/// Requires that the `LangItem` was bound and returns the corresponding `DefId`. | ||
pub fn require(self) -> Result<DefId, LangItem> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of the reason to move away from Option
is to make it hard for people to call unwrap
. Having a function that returns a Result
sort of defeats the purpose doesn't it? People will just write lang_items().sized().require().unwrap()
.
I think require
should accept a TyCtxt
and an Option<Span>
and return DefId
, emitting an error when it fails. If you want to do more complex things, you can match on LangItemRecord
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay yeah that’s a fair point - I’ll try again that way around although I feel like there may be some places where the code definitely take a hit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, this indicates that this PR should go through the major-change proposal process as @nikomatsakis mentioned on the issue. MCP is relatively new, so I think we're still exploring what magnitude of change qualifies as "major". This PR is a good test of that lower bound.
Would you be interested in opening a proposal that explains the anti-pattern this PR tries to prevent as well as a rough sketch of the API? One positive side-effect of the process is that more people will be informed about the correct use of the new API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A similar question-- is there a rustc-dev-guide entry on lang items? I think there should be, and I suspect that any such entry would be affected by this change (as it would likely have given some examples of how lang items are meant to be used).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think we have a dev guide entry on lang items yet and I agree that we should. I’ve got a couple of exams next week but once they’re done I’ll write up the MCP, rewrite this PR and start drafting some stuff for the dev guide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds great! Thanks for your work on this. =)
I don't think btw that the MCP has to be super detailed, I think sketching out the plan is sufficient, especially given that you can point at this PR. The main idea is to have some standard way to advertise changes people may want to be aware of.
src/librustc_hir/lang_items.rs
Outdated
/// Checks the current `LangItemRecord` against the given `DefId`. | ||
/// Returns true if and only if the language item was found and its `DefId` | ||
/// is equal to the `DefId` provided. | ||
pub fn is(self, other: DefId) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider PartialEq<DefId>
instead of a custom method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I thought about it but decided it seemed a little opaque - do you think PartialEq<DefId>
would be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm mostly indifferent but also lean towards an inherent method. Just wondering if you had a more convincing argument. FWIW, I would have chosen a different name (has_def_id
), but that's just bikeshedding.
src/librustc_middle/ty/context.rs
Outdated
@@ -2731,6 +2731,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { | |||
providers.has_panic_handler = |tcx, cnum| { | |||
assert_eq!(cnum, LOCAL_CRATE); | |||
// We want to check if the panic handler was defined in this crate | |||
tcx.lang_items().panic_impl().map_or(false, |did| did.is_local()) | |||
tcx.lang_items().panic_impl().require().map_or(false, |did| did.is_local()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this could be a method on LangItemRecord
, is_local
or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s a really good point - thanks
src/librustc_traits/chalk/db.rs
Outdated
.map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) | ||
.unwrap(), | ||
CopyTrait => self | ||
.tcx | ||
.lang_items() | ||
.copy_trait() | ||
.require() | ||
.map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) | ||
.unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the require().unwrap()
pattern I was worried about BTW.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I definitely agree - it’s just about trying to find a way to avoid having the whole compiler import the new type (I’m really not sure what the right answer is here)
Some(def_id) => def_id, | ||
None => return None, | ||
}; | ||
let sized_def_id = self.tcx.lang_items().sized_trait().require().ok()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we error in places like this when we don't have the Sized
trait? I'm not sure if we really need to gracefully handle its absence.
☔ The latest upstream changes (presumably #71665) made this pull request unmergeable. Please resolve the merge conflicts. |
I had a go at implementing a new API for dealing with
lang_items
as discussed in #72240.This touches a lot of code. 9/10 I feel like it makes the code more readable, or makes it explicit that you should be
require()
'ing lang items, but there are definitely some exceptions (particularly in some of thelibrustdoc
code). An obvious fix to cut down on the number ofrequire().ok()
s would be to addinto_option()
, but that starts to feel like the old API again.(This completely breaks
clippy
and I haven't run the test bench yet.)r? @oli-obk