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

Rollup of 7 pull requests #108620

Merged
merged 22 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4de9c6d
rustdoc: search by macro when query ends with `!`
notriddle Feb 16, 2023
d963318
Correct eslint warning
notriddle Feb 17, 2023
07cf219
Update how-to-read-rustdoc.md
notriddle Feb 22, 2023
317be61
make --open work on all books
pietroalbini Feb 23, 2023
96e6fb6
Update search eBNF with `!` moved
notriddle Feb 25, 2023
379b18b
Use checked_add in VecDeque::append for ZSTs to avoid overflow
pommicket Feb 25, 2023
12f959b
Add test for VecDeque::append ZST capacity overflow
pommicket Feb 25, 2023
0758c05
recover from for-else and while-else
y21 Feb 23, 2023
9642346
Add regression test for #107280
JohnTitor Mar 1, 2023
50d35c1
Add regression test for #105821
JohnTitor Mar 1, 2023
5295de1
Add opt_rpitit_info query
spastorino Feb 28, 2023
e74f50e
Add unstable option new_rpitit to be used for new RPITIT lowering system
spastorino Feb 28, 2023
be72bec
Fix typo in docs
spastorino Feb 28, 2023
811a1ca
Make associated_item_def_ids for traits use an unstable option to als…
spastorino Feb 28, 2023
73e2fe0
Properly implement should_encode_fn_impl_trait_in_trait using new uns…
spastorino Feb 28, 2023
f03e534
Rollup merge of #108143 - notriddle:notriddle/filter-exclamation-macr…
Dylan-DPC Mar 1, 2023
38461f8
Rollup merge of #108394 - ferrocene:pa-open, r=ozkanonur
Dylan-DPC Mar 1, 2023
27fa7b5
Rollup merge of #108427 - y21:for-else-diagnostic, r=compiler-errors
Dylan-DPC Mar 1, 2023
093a53f
Rollup merge of #108462 - pommicket:fix-vecdeque-zst-overflow, r=Amanieu
Dylan-DPC Mar 1, 2023
9d132f7
Rollup merge of #108568 - spastorino:new-rpitit-flag, r=compiler-errors
Dylan-DPC Mar 1, 2023
0ed76b4
Rollup merge of #108604 - JohnTitor:issue-107280, r=compiler-errors
Dylan-DPC Mar 1, 2023
02e4eef
Rollup merge of #108605 - JohnTitor:issue-105821, r=compiler-errors
Dylan-DPC Mar 1, 2023
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
15 changes: 12 additions & 3 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,9 +1101,18 @@ fn should_encode_const(def_kind: DefKind) -> bool {
}
}

// Return `false` to avoid encoding impl trait in trait, while we don't use the query.
fn should_encode_fn_impl_trait_in_trait<'tcx>(_tcx: TyCtxt<'tcx>, _def_id: DefId) -> bool {
false
// We only encode impl trait in trait when using `lower-impl-trait-in-trait-to-assoc-ty` unstable
// option.
fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
if tcx.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty
&& let Some(assoc_item) = tcx.opt_associated_item(def_id)
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
&& assoc_item.kind == ty::AssocKind::Fn
{
true
} else {
false
}
}

impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ pub fn provide(providers: &mut Providers) {
}
};
providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local());
providers.opt_rpitit_info = |_, _| None;
providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
providers.expn_that_defined = |tcx, id| {
let id = id.expect_local();
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ rustc_queries! {
/// Definitions that were generated with no HIR, would be feeded to return `None`.
query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{
desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
feedable
}

/// Gives access to the HIR node's parent for the HIR owner `key`.
Expand Down Expand Up @@ -166,6 +167,7 @@ rustc_queries! {
}
cache_on_disk_if { key.is_local() }
separate_provide_extern
feedable
}

query collect_return_position_impl_trait_in_trait_tys(key: DefId)
Expand Down Expand Up @@ -222,6 +224,7 @@ rustc_queries! {
arena_cache
cache_on_disk_if { key.is_local() }
separate_provide_extern
feedable
}

/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
Expand Down Expand Up @@ -264,6 +267,7 @@ rustc_queries! {
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
feedable
}

/// Elaborated version of the predicates from `explicit_item_bounds`.
Expand Down Expand Up @@ -588,6 +592,7 @@ rustc_queries! {
desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
feedable
}

/// Returns the inferred outlives predicates (e.g., for `struct
Expand All @@ -596,6 +601,7 @@ rustc_queries! {
desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
feedable
}

/// Maps from the `DefId` of a trait to the list of
Expand Down Expand Up @@ -728,6 +734,7 @@ rustc_queries! {
desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
feedable
}

/// Collects the associated items defined on a trait or impl.
Expand Down Expand Up @@ -1142,6 +1149,15 @@ rustc_queries! {
desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
feedable
}

/// The `opt_rpitit_info` query returns the pair of the def id of the function where the RPIT
/// is defined and the opaque def id if any.
query opt_rpitit_info(def_id: DefId) -> Option<ty::ImplTraitInTraitData> {
desc { |tcx| "opt_rpitit_info `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
feedable
}

/// Gets the span for the definition.
Expand All @@ -1157,6 +1173,7 @@ rustc_queries! {
desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
feedable
}

query lookup_stability(def_id: DefId) -> Option<attr::Stability> {
Expand Down Expand Up @@ -1498,6 +1515,7 @@ rustc_queries! {
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
feedable
}

query check_well_formed(key: hir::OwnerId) -> () {
Expand Down Expand Up @@ -1695,6 +1713,7 @@ rustc_queries! {
query visibility(def_id: DefId) -> ty::Visibility<DefId> {
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
feedable
}

query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,12 @@ pub enum ImplOverlapKind {
Issue33140,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
pub enum ImplTraitInTraitData {
Trait { fn_def_id: DefId, opaque_def_id: DefId },
Impl { fn_def_id: DefId },
}

impl<'tcx> TyCtxt<'tcx> {
pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> {
self.typeck(self.hir().body_owner_def_id(body))
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_parse/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ parse_missing_in_in_for_loop = missing `in` in `for` loop
parse_missing_expression_in_for_loop = missing expression to iterate on in `for` loop
.suggestion = try adding an expression to the `for` loop

parse_loop_else = `{$loop_kind}...else` loops are not supported
.note = consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
.loop_keyword = `else` is attached to this loop

parse_missing_comma_after_match_arm = expected `,` following `match` arm
.suggestion = missing a comma here to end this `match` arm

Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,17 @@ pub(crate) struct MissingExpressionInForLoop {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_loop_else)]
#[note]
pub(crate) struct LoopElseNotSupported {
#[primary_span]
pub span: Span,
pub loop_kind: &'static str,
#[label(parse_loop_keyword)]
pub loop_kw: Span,
}

#[derive(Diagnostic)]
#[diag(parse_missing_comma_after_match_arm)]
pub(crate) struct MissingCommaAfterMatchArm {
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2503,9 +2503,27 @@ impl<'a> Parser<'a> {
let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;

let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);

self.recover_loop_else("for", lo)?;

Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
}

/// Recovers from an `else` clause after a loop (`for...else`, `while...else`)
fn recover_loop_else(&mut self, loop_kind: &'static str, loop_kw: Span) -> PResult<'a, ()> {
if self.token.is_keyword(kw::Else) && self.may_recover() {
let else_span = self.token.span;
self.bump();
let else_clause = self.parse_expr_else()?;
self.sess.emit_err(errors::LoopElseNotSupported {
span: else_span.to(else_clause.span),
loop_kind,
loop_kw,
});
}
Ok(())
}

fn error_missing_in_for_loop(&mut self) {
let (span, sub): (_, fn(_) -> _) = if self.token.is_ident_named(sym::of) {
// Possibly using JS syntax (#75311).
Expand All @@ -2530,6 +2548,9 @@ impl<'a> Parser<'a> {
err.span_label(cond.span, "this `while` condition successfully parsed");
err
})?;

self.recover_loop_else("while", lo)?;

Ok(self.mk_expr_with_attrs(
lo.to(self.prev_token.span),
ExprKind::While(cond, body, opt_label),
Expand All @@ -2541,6 +2562,7 @@ impl<'a> Parser<'a> {
fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
let loop_span = self.prev_token.span;
let (attrs, body) = self.parse_inner_attrs_and_block()?;
self.recover_loop_else("loop", lo)?;
Ok(self.mk_expr_with_attrs(
lo.to(self.prev_token.span),
ExprKind::Loop(body, opt_label, loop_span),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,9 @@ options! {
"what location details should be tracked when using caller_location, either \
`none`, or a comma separated list of location details, for which \
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
lower_impl_trait_in_trait_to_assoc_ty: bool = (false, parse_bool, [TRACKED],
"modify the lowering strategy for `impl Trait` in traits so that they are lowered to \
generic associated types"),
ls: bool = (false, parse_bool, [UNTRACKED],
"list the symbols defined by a library crate (default: no)"),
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
Expand Down
96 changes: 90 additions & 6 deletions compiler/rustc_ty_utils/src/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_middle::ty::{self, DefIdTree, ImplTraitInTraitData, InternalSubsts, TyCtxt};
use rustc_span::symbol::kw;

pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers {
Expand All @@ -21,9 +22,37 @@ pub fn provide(providers: &mut ty::query::Providers) {
fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
let item = tcx.hir().expect_item(def_id.expect_local());
match item.kind {
hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter(
trait_item_refs.iter().map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
),
hir::ItemKind::Trait(.., ref trait_item_refs) => {
if tcx.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty {
// We collect RPITITs for each trait method's return type and create a
// corresponding associated item using associated_items_for_impl_trait_in_trait
// query.
tcx.arena.alloc_from_iter(
trait_item_refs
.iter()
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
.chain(
trait_item_refs
.iter()
.filter(|trait_item_ref| {
matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
})
.flat_map(|trait_item_ref| {
let trait_fn_def_id =
trait_item_ref.id.owner_id.def_id.to_def_id();
tcx.associated_items_for_impl_trait_in_trait(trait_fn_def_id)
})
.map(|def_id| *def_id),
),
)
} else {
tcx.arena.alloc_from_iter(
trait_item_refs
.iter()
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
)
}
}
hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
),
Expand Down Expand Up @@ -193,10 +222,65 @@ fn associated_item_for_impl_trait_in_trait(
let span = tcx.def_span(opaque_ty_def_id);
let trait_assoc_ty =
tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
trait_assoc_ty.def_id()

let local_def_id = trait_assoc_ty.def_id();
let def_id = local_def_id.to_def_id();

trait_assoc_ty.opt_def_kind(Some(DefKind::AssocTy));

// There's no HIR associated with this new synthesized `def_id`, so feed
// `opt_local_def_id_to_hir_id` with `None`.
trait_assoc_ty.opt_local_def_id_to_hir_id(None);

// Copy span of the opaque.
trait_assoc_ty.def_ident_span(Some(span));

// Add the def_id of the function and opaque that generated this synthesized associated type.
trait_assoc_ty.opt_rpitit_info(Some(ImplTraitInTraitData::Trait {
fn_def_id,
opaque_def_id: opaque_ty_def_id.to_def_id(),
}));

trait_assoc_ty.associated_item(ty::AssocItem {
name: kw::Empty,
kind: ty::AssocKind::Type,
def_id,
trait_item_def_id: None,
container: ty::TraitContainer,
fn_has_self_parameter: false,
});

// Copy visility of the containing function.
trait_assoc_ty.visibility(tcx.visibility(fn_def_id));

// Copy impl_defaultness of the containing function.
trait_assoc_ty.impl_defaultness(tcx.impl_defaultness(fn_def_id));

// Copy type_of of the opaque.
trait_assoc_ty.type_of(ty::EarlyBinder(tcx.mk_opaque(
opaque_ty_def_id.to_def_id(),
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id.to_def_id()),
)));

// Copy generics_of of the opaque.
trait_assoc_ty.generics_of(tcx.generics_of(opaque_ty_def_id).clone());

// There are no predicates for the synthesized associated type.
trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
parent: Some(trait_def_id),
predicates: &[],
});

// There are no inferred outlives for the synthesized associated type.
trait_assoc_ty.inferred_outlives_of(&[]);

// FIXME implement this.
trait_assoc_ty.explicit_item_bounds(&[]);

local_def_id
}

/// Given an `trait_assoc_def_id` that corresponds to a previously synthethized impl trait in trait
/// Given an `trait_assoc_def_id` that corresponds to a previously synthesized impl trait in trait
/// into an associated type and an `impl_def_id` corresponding to an impl block, create and return
/// the corresponding associated item inside the impl block.
fn impl_associated_item_for_impl_trait_in_trait(
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1924,7 +1924,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
#[stable(feature = "append", since = "1.4.0")]
pub fn append(&mut self, other: &mut Self) {
if T::IS_ZST {
self.len += other.len;
self.len = self.len.checked_add(other.len).expect("capacity overflow");
other.len = 0;
other.head = 0;
return;
Expand Down
14 changes: 14 additions & 0 deletions library/alloc/tests/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,20 @@ fn test_append_double_drop() {
assert_eq!(count_b, 1);
}

#[test]
#[should_panic]
fn test_append_zst_capacity_overflow() {
let mut v = Vec::with_capacity(usize::MAX);
// note: using resize instead of set_len here would
// be *extremely* slow in unoptimized builds.
// SAFETY: `v` has capacity `usize::MAX`, and no initialization
// is needed for empty tuples.
unsafe { v.set_len(usize::MAX) };
let mut v = VecDeque::from(v);
let mut w = vec![()].into();
v.append(&mut w);
}

#[test]
fn test_retain() {
let mut buf = VecDeque::new();
Expand Down
Loading