Auto merge of #108620 - Dylan-DPC:rollup-o5c4evy, r=Dylan-DPC

Rollup of 7 pull requests

Successful merges:

 - #108143 (rustdoc: search by macro when query ends with `!`)
 - #108394 (Make `x doc --open` work on every book)
 - #108427 (Recover from for-else and while-else)
 - #108462 (Fix `VecDeque::append` capacity overflow for ZSTs)
 - #108568 (Make associated_item_def_ids for traits use an unstable option to also return associated types for RPITITs)
 - #108604 (Add regression test for #107280)
 - #108605 (Add regression test for #105821)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-03-01 18:51:29 +00:00
commit f77bfb7336
40 changed files with 643 additions and 73 deletions

View File

@ -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> {

View File

@ -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();

View File

@ -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`.
@ -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)
@ -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
@ -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`.
@ -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
@ -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
@ -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.
@ -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.
@ -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> {
@ -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) -> () {
@ -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> {

View File

@ -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))

View File

@ -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

View File

@ -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 {

View File

@ -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).
@ -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),
@ -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),

View File

@ -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],

View File

@ -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 {
@ -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()),
),
@ -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(

View File

@ -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;

View File

@ -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();

View File

@ -62,6 +62,7 @@ macro_rules! book {
target: self.target,
name: INTERNER.intern_str($book_name),
src: INTERNER.intern_path(builder.src.join($path)),
parent: Some(self),
})
}
}
@ -119,18 +120,20 @@ impl Step for UnstableBook {
target: self.target,
name: INTERNER.intern_str("unstable-book"),
src: INTERNER.intern_path(builder.md_doc_out(self.target).join("unstable-book")),
parent: Some(self),
})
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
struct RustbookSrc {
struct RustbookSrc<P: Step> {
target: TargetSelection,
name: Interned<String>,
src: Interned<PathBuf>,
parent: Option<P>,
}
impl Step for RustbookSrc {
impl<P: Step> Step for RustbookSrc<P> {
type Output = ();
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@ -152,13 +155,18 @@ impl Step for RustbookSrc {
let index = out.join("index.html");
let rustbook = builder.tool_exe(Tool::Rustbook);
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
if builder.config.dry_run() || up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
return;
}
builder.info(&format!("Rustbook ({}) - {}", target, name));
let _ = fs::remove_dir_all(&out);
builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(out));
if !builder.config.dry_run() && !(up_to_date(&src, &index) || up_to_date(&rustbook, &index))
{
builder.info(&format!("Rustbook ({}) - {}", target, name));
let _ = fs::remove_dir_all(&out);
builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(out));
}
if self.parent.is_some() {
builder.maybe_open_in_browser::<P>(index)
}
}
}
@ -205,6 +213,7 @@ impl Step for TheBook {
target,
name: INTERNER.intern_str("book"),
src: INTERNER.intern_path(builder.src.join(&relative_path)),
parent: Some(self),
});
// building older edition redirects
@ -213,6 +222,9 @@ impl Step for TheBook {
target,
name: INTERNER.intern_string(format!("book/{}", edition)),
src: INTERNER.intern_path(builder.src.join(&relative_path).join(edition)),
// There should only be one book that is marked as the parent for each target, so
// treat the other editions as not having a parent.
parent: Option::<Self>::None,
});
}
@ -228,10 +240,6 @@ impl Step for TheBook {
invoke_rustdoc(builder, compiler, &shared_assets, target, path);
}
let out = builder.doc_out(target);
let index = out.join("book").join("index.html");
builder.maybe_open_in_browser::<Self>(index);
}
}
@ -1032,10 +1040,7 @@ impl Step for RustcBook {
target: self.target,
name: INTERNER.intern_str("rustc"),
src: INTERNER.intern_path(out_base),
parent: Some(self),
});
let out = builder.doc_out(self.target);
let index = out.join("rustc").join("index.html");
builder.maybe_open_in_browser::<Self>(index);
}
}

View File

@ -84,6 +84,9 @@ When typing in the search bar, you can prefix your search term with a type
followed by a colon (such as `mod:`) to restrict the results to just that
kind of item. (The available items are listed in the help popup.)
Searching for `println!` will search for a macro named `println`, just like
searching for `macro:println` does.
### Changing displayed theme
You can change the displayed theme by opening the settings menu (the gear

View File

@ -300,20 +300,21 @@ function initSearch(rawSearchIndex) {
* @return {integer}
*/
function getIdentEndPosition(parserState) {
const start = parserState.pos;
let end = parserState.pos;
let foundExclamation = false;
let foundExclamation = -1;
while (parserState.pos < parserState.length) {
const c = parserState.userQuery[parserState.pos];
if (!isIdentCharacter(c)) {
if (c === "!") {
if (foundExclamation) {
if (foundExclamation !== -1) {
throw new Error("Cannot have more than one `!` in an ident");
} else if (parserState.pos + 1 < parserState.length &&
isIdentCharacter(parserState.userQuery[parserState.pos + 1])
) {
throw new Error("`!` can only be at the end of an ident");
}
foundExclamation = true;
foundExclamation = parserState.pos;
} else if (isErrorCharacter(c)) {
throw new Error(`Unexpected \`${c}\``);
} else if (
@ -326,9 +327,18 @@ function initSearch(rawSearchIndex) {
if (!isPathStart(parserState)) {
break;
}
if (foundExclamation !== -1) {
if (start <= (end - 2)) {
throw new Error("Cannot have associated items in macros");
} else {
// if start == end - 1, we got the never type
// while the never type has no associated macros, we still
// can parse a path like that
foundExclamation = -1;
}
}
// Skip current ":".
parserState.pos += 1;
foundExclamation = false;
} else {
throw new Error(`Unexpected \`${c}\``);
}
@ -336,6 +346,16 @@ function initSearch(rawSearchIndex) {
parserState.pos += 1;
end = parserState.pos;
}
// if start == end - 1, we got the never type
if (foundExclamation !== -1 && start <= (end - 2)) {
if (parserState.typeFilter === null) {
parserState.typeFilter = "macro";
} else if (parserState.typeFilter !== "macro") {
throw new Error("Invalid search type: macro `!` and " +
`\`${parserState.typeFilter}\` both specified`);
}
end = foundExclamation;
}
return end;
}
@ -589,8 +609,8 @@ function initSearch(rawSearchIndex) {
*
* The supported syntax by this parser is as follow:
*
* ident = *(ALPHA / DIGIT / "_") [!]
* path = ident *(DOUBLE-COLON ident)
* ident = *(ALPHA / DIGIT / "_")
* path = ident *(DOUBLE-COLON ident) [!]
* arg = path [generics]
* arg-without-generic = path
* type-sep = COMMA/WS *(COMMA/WS)

View File

@ -37,6 +37,8 @@ const QUERY = [
"mod : :",
"a!a",
"a!!",
"mod:a!",
"a!::a",
];
const PARSED = [
@ -382,4 +384,22 @@ const PARSED = [
userQuery: "a!!",
error: 'Cannot have more than one `!` in an ident',
},
{
elems: [],
foundElems: 0,
original: "mod:a!",
returned: [],
typeFilter: -1,
userQuery: "mod:a!",
error: 'Invalid search type: macro `!` and `mod` both specified',
},
{
elems: [],
foundElems: 0,
original: "a!::a",
returned: [],
typeFilter: -1,
userQuery: "a!::a",
error: 'Cannot have associated items in macros',
},
];

View File

@ -1,4 +1,4 @@
const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo'];
const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo', 'macro!', 'macro:mac!', 'a::mac!'];
const PARSED = [
{
@ -40,4 +40,49 @@ const PARSED = [
userQuery: "macro<f>:foo",
error: "Unexpected `:`",
},
{
elems: [{
name: "macro",
fullPath: ["macro"],
pathWithoutLast: [],
pathLast: "macro",
generics: [],
}],
foundElems: 1,
original: "macro!",
returned: [],
typeFilter: 14,
userQuery: "macro!",
error: null,
},
{
elems: [{
name: "mac",
fullPath: ["mac"],
pathWithoutLast: [],
pathLast: "mac",
generics: [],
}],
foundElems: 1,
original: "macro:mac!",
returned: [],
typeFilter: 14,
userQuery: "macro:mac!",
error: null,
},
{
elems: [{
name: "a::mac",
fullPath: ["a", "mac"],
pathWithoutLast: ["a"],
pathLast: "mac",
generics: [],
}],
foundElems: 1,
original: "a::mac!",
returned: [],
typeFilter: 14,
userQuery: "a::mac!",
error: null,
},
];

View File

@ -3,6 +3,7 @@ const QUERY = [
"!",
"a!",
"a!::b",
"!::b",
"a!::b!",
];
@ -47,47 +48,50 @@ const PARSED = [
},
{
elems: [{
name: "a!",
fullPath: ["a!"],
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a!",
pathLast: "a",
generics: [],
}],
foundElems: 1,
original: "a!",
returned: [],
typeFilter: -1,
typeFilter: 14,
userQuery: "a!",
error: null,
},
{
elems: [{
name: "a!::b",
fullPath: ["a!", "b"],
pathWithoutLast: ["a!"],
pathLast: "b",
generics: [],
}],
foundElems: 1,
elems: [],
foundElems: 0,
original: "a!::b",
returned: [],
typeFilter: -1,
userQuery: "a!::b",
error: null,
error: "Cannot have associated items in macros",
},
{
elems: [{
name: "a!::b!",
fullPath: ["a!", "b!"],
pathWithoutLast: ["a!"],
pathLast: "b!",
name: "!::b",
fullPath: ["!", "b"],
pathWithoutLast: ["!"],
pathLast: "b",
generics: [],
}],
foundElems: 1,
original: "!::b",
returned: [],
typeFilter: -1,
userQuery: "!::b",
error: null,
},
{
elems: [],
foundElems: 0,
original: "a!::b!",
returned: [],
typeFilter: -1,
userQuery: "a!::b!",
error: null,
error: "Cannot have associated items in macros",
},
];

View File

@ -0,0 +1,10 @@
// exact-check
const QUERY = 'abracadabra!';
const EXPECTED = {
'others': [
{ 'path': 'macro_search', 'name': 'abracadabra' },
{ 'path': 'macro_search', 'name': 'abracadabra_b' },
],
};

View File

@ -0,0 +1,10 @@
#[macro_export]
macro_rules! abracadabra {
() => {}
}
#[macro_export]
macro_rules! abracadabra_b {
() => {}
}
pub fn abracadabra() {}
pub fn abracadabra_c() {}

View File

@ -87,6 +87,7 @@
-Z llvm-plugins=val -- a list LLVM plugins to enable (space separated)
-Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
-Z location-detail=val -- 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`)
-Z lower-impl-trait-in-trait-to-assoc-ty=val -- modify the lowering strategy for `impl Trait` in traits so that they are lowered to generic associated types
-Z ls=val -- list the symbols defined by a library crate (default: no)
-Z macro-backtrace=val -- show macro backtraces (default: no)
-Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)

View File

@ -0,0 +1,15 @@
// edition:2021
async fn foo() {
inner::<false>().await
//~^ ERROR: function takes 2 generic arguments but 1 generic argument was supplied
//~| ERROR: type inside `async fn` body must be known in this context
//~| ERROR: type inside `async fn` body must be known in this context
//~| ERROR: type inside `async fn` body must be known in this context
//~| ERROR: type inside `async fn` body must be known in this context
//~| ERROR: type inside `async fn` body must be known in this context
}
async fn inner<T, const PING: bool>() {}
fn main() {}

View File

@ -0,0 +1,82 @@
error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/issue-107280.rs:4:5
|
LL | inner::<false>().await
| ^^^^^ ----- supplied 1 generic argument
| |
| expected 2 generic arguments
|
note: function defined here, with 2 generic parameters: `T`, `PING`
--> $DIR/issue-107280.rs:13:10
|
LL | async fn inner<T, const PING: bool>() {}
| ^^^^^ - ----------------
help: add missing generic argument
|
LL | inner::<false, PING>().await
| ++++++
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/issue-107280.rs:4:5
|
LL | inner::<false>().await
| ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/issue-107280.rs:4:21
|
LL | inner::<false>().await
| ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/issue-107280.rs:4:5
|
LL | inner::<false>().await
| ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/issue-107280.rs:4:21
|
LL | inner::<false>().await
| ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/issue-107280.rs:4:5
|
LL | inner::<false>().await
| ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/issue-107280.rs:4:21
|
LL | inner::<false>().await
| ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/issue-107280.rs:4:5
|
LL | inner::<false>().await
| ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/issue-107280.rs:4:21
|
LL | inner::<false>().await
| ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/issue-107280.rs:4:5
|
LL | inner::<false>().await
| ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/issue-107280.rs:4:21
|
LL | inner::<false>().await
| ^^^^^^
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0107, E0698.
For more information about an error, try `rustc --explain E0107`.

View File

@ -0,0 +1,23 @@
// check-pass
#![allow(incomplete_features)]
#![feature(adt_const_params, const_ptr_read, generic_const_exprs)]
#![allow(dead_code)]
const fn catone<const M: usize>(_a: &[u8; M]) -> [u8; M + 1]
where
[(); M + 1]:,
{
unimplemented!()
}
struct Catter<const A: &'static [u8]>;
impl<const A: &'static [u8]> Catter<A>
where
[(); A.len() + 1]:,
{
const ZEROS: &'static [u8; A.len()] = &[0_u8; A.len()];
const R: &'static [u8] = &catone(Self::ZEROS);
}
fn main() {}

View File

@ -0,0 +1,8 @@
fn main() {
for _ in 0..1 {
//~^ NOTE `else` is attached to this loop
} else {
//~^ ERROR `for...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
}
}

View File

@ -0,0 +1,17 @@
error: `for...else` loops are not supported
--> $DIR/for-else-err.rs:4:7
|
LL | for _ in 0..1 {
| --- `else` is attached to this loop
LL |
LL | } else {
| _______^
LL | |
LL | |
LL | | }
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
fn main() {
let _ = for _ in 0..1 {
//~^ NOTE `else` is attached to this loop
} else {
//~^ ERROR `for...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
};
}

View File

@ -0,0 +1,17 @@
error: `for...else` loops are not supported
--> $DIR/for-else-let-else-err.rs:4:7
|
LL | let _ = for _ in 0..1 {
| --- `else` is attached to this loop
LL |
LL | } else {
| _______^
LL | |
LL | |
LL | | };
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error

View File

@ -7,10 +7,6 @@ fn main() {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let Some(1) = (loop { break Some(1) }) else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let 2 = 1 + (match 1 { n => n }) else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;

View File

@ -7,10 +7,6 @@ fn main() {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let Some(1) = loop { break Some(1) } else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let 2 = 1 + match 1 { n => n } else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;

View File

@ -10,18 +10,7 @@ LL | let Some(1) = ({ Some(1) }) else {
| + +
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:10:40
|
LL | let Some(1) = loop { break Some(1) } else {
| ^
|
help: wrap the expression in parentheses
|
LL | let Some(1) = (loop { break Some(1) }) else {
| + +
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:14:34
--> $DIR/let-else-brace-before-else.rs:10:34
|
LL | let 2 = 1 + match 1 { n => n } else {
| ^
@ -32,7 +21,7 @@ LL | let 2 = 1 + (match 1 { n => n }) else {
| + +
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:18:40
--> $DIR/let-else-brace-before-else.rs:14:40
|
LL | let Some(1) = unsafe { unsafe_fn() } else {
| ^
@ -42,5 +31,5 @@ help: wrap the expression in parentheses
LL | let Some(1) = (unsafe { unsafe_fn() }) else {
| + +
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View File

@ -0,0 +1,10 @@
fn main() {
let Some(1) = loop {
//~^ NOTE `else` is attached to this loop
break Some(1)
} else {
//~^ ERROR `loop...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
return;
};
}

View File

@ -0,0 +1,18 @@
error: `loop...else` loops are not supported
--> $DIR/loop-else-break-with-value.rs:5:7
|
LL | let Some(1) = loop {
| ---- `else` is attached to this loop
...
LL | } else {
| _______^
LL | |
LL | |
LL | | return;
LL | | };
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
fn main() {
loop {
//~^ NOTE `else` is attached to this loop
} else {
//~^ ERROR `loop...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
}
}

View File

@ -0,0 +1,17 @@
error: `loop...else` loops are not supported
--> $DIR/loop-else-err.rs:4:7
|
LL | loop {
| ---- `else` is attached to this loop
LL |
LL | } else {
| _______^
LL | |
LL | |
LL | | }
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
fn main() {
let _ = loop {
//~^ NOTE `else` is attached to this loop
} else {
//~^ ERROR `loop...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
};
}

View File

@ -0,0 +1,17 @@
error: `loop...else` loops are not supported
--> $DIR/loop-else-let-else-err.rs:4:7
|
LL | let _ = loop {
| ---- `else` is attached to this loop
LL |
LL | } else {
| _______^
LL | |
LL | |
LL | | };
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
fn main() {
while false {
//~^ NOTE `else` is attached to this loop
} else {
//~^ ERROR `while...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
};
}

View File

@ -0,0 +1,17 @@
error: `while...else` loops are not supported
--> $DIR/while-else-err.rs:4:7
|
LL | while false {
| ----- `else` is attached to this loop
LL |
LL | } else {
| _______^
LL | |
LL | |
LL | | };
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error

View File

@ -0,0 +1,8 @@
fn main() {
let _ = while false {
//~^ NOTE `else` is attached to this loop
} else {
//~^ ERROR `while...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
};
}

View File

@ -0,0 +1,17 @@
error: `while...else` loops are not supported
--> $DIR/while-else-let-else-err.rs:4:7
|
LL | let _ = while false {
| ----- `else` is attached to this loop
LL |
LL | } else {
| _______^
LL | |
LL | |
LL | | };
| |_____^
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
error: aborting due to previous error