Skip to content

Rollup of 5 pull requests #133280

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

Merged
merged 22 commits into from
Nov 21, 2024
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b071f64
Emscripten: link with -sWASM_BIGINT
hoodmane Oct 15, 2024
f2f7d32
FieldDef
maxcabrajac Nov 17, 2024
b96758b
Arm
maxcabrajac Nov 17, 2024
e52cef1
Variant
maxcabrajac Nov 17, 2024
f4fbe88
Param
maxcabrajac Nov 17, 2024
8b0284a
GenericParam
maxcabrajac Nov 17, 2024
eb2f1c8
ExprField
maxcabrajac Nov 17, 2024
5c2de73
PatField
maxcabrajac Nov 17, 2024
588c4c4
Rename implied_const_bounds to explicit_implied_const_bounds
compiler-errors Nov 19, 2024
5eeaf2e
Implement ~const opaques
compiler-errors Nov 19, 2024
19b528b
Store resolution for self and crate root module segments
compiler-errors Oct 27, 2024
b33a0d3
we should not be reporting generic error if there is not a segment to…
compiler-errors Oct 26, 2024
1dc1236
Items
maxcabrajac Nov 17, 2024
01b26e6
Use visit_item instead of flat_map_item in test_harness.rs
maxcabrajac Nov 18, 2024
15528b2
Fix `catbat` pager typo.
nnethercote Nov 19, 2024
9116495
Remove redundant `is_terminal` check.
nnethercote Nov 20, 2024
525e191
Rewrite `show_md_content_with_pager`.
nnethercote Nov 20, 2024
61878ec
Rollup merge of #131736 - hoodmane:emscripten-wasm-bigint, r=workingj…
matthiaskrgr Nov 21, 2024
b1008d1
Rollup merge of #132207 - compiler-errors:tweak-res-mod-segment, r=pe…
matthiaskrgr Nov 21, 2024
9d70af5
Rollup merge of #133153 - maxcabrajac:flat_maps, r=petrochenkov
matthiaskrgr Nov 21, 2024
9200925
Rollup merge of #133218 - compiler-errors:const-opaque, r=fee1-dead
matthiaskrgr Nov 21, 2024
c83b6a3
Rollup merge of #133228 - nnethercote:rewrite-show_md_content_with_pa…
matthiaskrgr Nov 21, 2024
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
166 changes: 128 additions & 38 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
@@ -104,8 +104,16 @@ pub trait MutVisitor: Sized {
walk_use_tree(self, use_tree);
}

fn visit_foreign_item(&mut self, ni: &mut P<ForeignItem>) {
walk_item(self, ni);
}

fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
walk_flat_map_item(self, ni)
walk_flat_map_foreign_item(self, ni)
}

fn visit_item(&mut self, i: &mut P<Item>) {
walk_item(self, i);
}

fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
@@ -116,10 +124,18 @@ pub trait MutVisitor: Sized {
walk_fn_header(self, header);
}

fn visit_field_def(&mut self, fd: &mut FieldDef) {
walk_field_def(self, fd);
}

fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> {
walk_flat_map_field_def(self, fd)
}

fn visit_assoc_item(&mut self, i: &mut P<AssocItem>, ctxt: AssocCtxt) {
walk_assoc_item(self, i, ctxt)
}

fn flat_map_assoc_item(
&mut self,
i: P<AssocItem>,
@@ -153,6 +169,10 @@ pub trait MutVisitor: Sized {
walk_flat_map_stmt(self, s)
}

fn visit_arm(&mut self, arm: &mut Arm) {
walk_arm(self, arm);
}

fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
walk_flat_map_arm(self, arm)
}
@@ -199,6 +219,10 @@ pub trait MutVisitor: Sized {
walk_foreign_mod(self, nm);
}

fn visit_variant(&mut self, v: &mut Variant) {
walk_variant(self, v);
}

fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
walk_flat_map_variant(self, v)
}
@@ -251,6 +275,10 @@ pub trait MutVisitor: Sized {
walk_attribute(self, at);
}

fn visit_param(&mut self, param: &mut Param) {
walk_param(self, param);
}

fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
walk_flat_map_param(self, param)
}
@@ -271,6 +299,10 @@ pub trait MutVisitor: Sized {
walk_variant_data(self, vdata);
}

fn visit_generic_param(&mut self, param: &mut GenericParam) {
walk_generic_param(self, param)
}

fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
walk_flat_map_generic_param(self, param)
}
@@ -287,6 +319,10 @@ pub trait MutVisitor: Sized {
walk_mt(self, mt);
}

fn visit_expr_field(&mut self, f: &mut ExprField) {
walk_expr_field(self, f);
}

fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> {
walk_flat_map_expr_field(self, f)
}
@@ -311,6 +347,10 @@ pub trait MutVisitor: Sized {
// Do nothing.
}

fn visit_pat_field(&mut self, fp: &mut PatField) {
walk_pat_field(self, fp)
}

fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
walk_flat_map_pat_field(self, fp)
}
@@ -429,16 +469,20 @@ pub fn visit_delim_span<T: MutVisitor>(vis: &mut T, DelimSpan { open, close }: &
vis.visit_span(close);
}

pub fn walk_flat_map_pat_field<T: MutVisitor>(
vis: &mut T,
mut fp: PatField,
) -> SmallVec<[PatField; 1]> {
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp;
pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
vis.visit_id(id);
visit_attrs(vis, attrs);
vis.visit_ident(ident);
vis.visit_pat(pat);
vis.visit_span(span);
}

pub fn walk_flat_map_pat_field<T: MutVisitor>(
vis: &mut T,
mut fp: PatField,
) -> SmallVec<[PatField; 1]> {
vis.visit_pat_field(&mut fp);
smallvec![fp]
}

@@ -459,14 +503,18 @@ fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
vis.visit_span(span);
}

pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
vis.visit_id(id);
visit_attrs(vis, attrs);
vis.visit_pat(pat);
visit_opt(guard, |guard| vis.visit_expr(guard));
visit_opt(body, |body| vis.visit_expr(body));
vis.visit_span(span);
}

pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
vis.visit_arm(&mut arm);
smallvec![arm]
}

@@ -543,18 +591,22 @@ fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}

pub fn walk_flat_map_variant<T: MutVisitor>(
visitor: &mut T,
mut variant: Variant,
) -> SmallVec<[Variant; 1]> {
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
visitor.visit_id(id);
visit_attrs(visitor, attrs);
visitor.visit_vis(vis);
visitor.visit_ident(ident);
visitor.visit_variant_data(data);
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
visitor.visit_span(span);
}

pub fn walk_flat_map_variant<T: MutVisitor>(
vis: &mut T,
mut variant: Variant,
) -> SmallVec<[Variant; 1]> {
vis.visit_variant(&mut variant);
smallvec![variant]
}

@@ -685,13 +737,17 @@ fn walk_meta_item<T: MutVisitor>(vis: &mut T, mi: &mut MetaItem) {
vis.visit_span(span);
}

pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
pub fn walk_param<T: MutVisitor>(vis: &mut T, param: &mut Param) {
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param;
vis.visit_id(id);
visit_attrs(vis, attrs);
vis.visit_pat(pat);
vis.visit_ty(ty);
vis.visit_span(span);
}

pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
vis.visit_param(&mut param);
smallvec![param]
}

@@ -950,11 +1006,8 @@ fn walk_precise_capturing_arg<T: MutVisitor>(vis: &mut T, arg: &mut PreciseCaptu
}
}

pub fn walk_flat_map_generic_param<T: MutVisitor>(
vis: &mut T,
mut param: GenericParam,
) -> SmallVec<[GenericParam; 1]> {
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param;
pub fn walk_generic_param<T: MutVisitor>(vis: &mut T, param: &mut GenericParam) {
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param;
vis.visit_id(id);
visit_attrs(vis, attrs);
vis.visit_ident(ident);
@@ -972,6 +1025,13 @@ pub fn walk_flat_map_generic_param<T: MutVisitor>(
if let Some(colon_span) = colon_span {
vis.visit_span(colon_span);
}
}

pub fn walk_flat_map_generic_param<T: MutVisitor>(
vis: &mut T,
mut param: GenericParam,
) -> SmallVec<[GenericParam; 1]> {
vis.visit_generic_param(&mut param);
smallvec![param]
}

@@ -1054,30 +1114,38 @@ fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
vis.visit_span(span);
}

pub fn walk_flat_map_field_def<T: MutVisitor>(
visitor: &mut T,
mut fd: FieldDef,
) -> SmallVec<[FieldDef; 1]> {
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd;
pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd;
visitor.visit_id(id);
visit_attrs(visitor, attrs);
visitor.visit_vis(vis);
visit_opt(ident, |ident| visitor.visit_ident(ident));
visitor.visit_ty(ty);
visitor.visit_span(span);
smallvec![fd]
}

pub fn walk_flat_map_expr_field<T: MutVisitor>(
pub fn walk_flat_map_field_def<T: MutVisitor>(
vis: &mut T,
mut f: ExprField,
) -> SmallVec<[ExprField; 1]> {
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f;
mut fd: FieldDef,
) -> SmallVec<[FieldDef; 1]> {
vis.visit_field_def(&mut fd);
smallvec![fd]
}

pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
vis.visit_id(id);
visit_attrs(vis, attrs);
vis.visit_ident(ident);
vis.visit_expr(expr);
vis.visit_span(span);
}

pub fn walk_flat_map_expr_field<T: MutVisitor>(
vis: &mut T,
mut f: ExprField,
) -> SmallVec<[ExprField; 1]> {
vis.visit_expr_field(&mut f);
smallvec![f]
}

@@ -1331,18 +1399,19 @@ pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
vis.visit_span(inject_use_span);
}

pub fn walk_flat_map_item<K: WalkItemKind<Ctxt = ()>>(
visitor: &mut impl MutVisitor,
item: P<Item<K>>,
) -> SmallVec<[P<Item<K>>; 1]> {
walk_flat_map_assoc_item(visitor, item, ())
pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P<Item<impl WalkItemKind<Ctxt = ()>>>) {
walk_item_ctxt(visitor, item, ())
}

pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, ctxt: AssocCtxt) {
walk_item_ctxt(visitor, item, ctxt)
}

pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
fn walk_item_ctxt<K: WalkItemKind>(
visitor: &mut impl MutVisitor,
mut item: P<Item<K>>,
item: &mut P<Item<K>>,
ctxt: K::Ctxt,
) -> SmallVec<[P<Item<K>>; 1]> {
) {
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
visitor.visit_id(id);
visit_attrs(visitor, attrs);
@@ -1351,6 +1420,27 @@ pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
kind.walk(*span, *id, ident, vis, ctxt, visitor);
visit_lazy_tts(visitor, tokens);
visitor.visit_span(span);
}

pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
vis.visit_item(&mut item);
smallvec![item]
}

pub fn walk_flat_map_foreign_item(
vis: &mut impl MutVisitor,
mut item: P<ForeignItem>,
) -> SmallVec<[P<ForeignItem>; 1]> {
vis.visit_foreign_item(&mut item);
smallvec![item]
}

pub fn walk_flat_map_assoc_item(
vis: &mut impl MutVisitor,
mut item: P<AssocItem>,
ctxt: AssocCtxt,
) -> SmallVec<[P<AssocItem>; 1]> {
vis.visit_assoc_item(&mut item, ctxt);
smallvec![item]
}

24 changes: 16 additions & 8 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
@@ -463,13 +463,6 @@ impl WalkItemKind for ItemKind {
}
}

pub fn walk_item<'a, V: Visitor<'a>>(
visitor: &mut V,
item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
) -> V::Result {
walk_assoc_item(visitor, item, ())
}

pub fn walk_enum_def<'a, V: Visitor<'a>>(
visitor: &mut V,
EnumDef { variants }: &'a EnumDef,
@@ -931,7 +924,22 @@ impl WalkItemKind for AssocItemKind {
}
}

pub fn walk_assoc_item<'a, V: Visitor<'a>, K: WalkItemKind>(
pub fn walk_item<'a, V: Visitor<'a>>(
visitor: &mut V,
item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
) -> V::Result {
walk_item_ctxt(visitor, item, ())
}

pub fn walk_assoc_item<'a, V: Visitor<'a>>(
visitor: &mut V,
item: &'a AssocItem,
ctxt: AssocCtxt,
) -> V::Result {
walk_item_ctxt(visitor, item, ctxt)
}

fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
visitor: &mut V,
item: &'a Item<K>,
ctxt: K::Ctxt,
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/cfg_eval.rs
Original file line number Diff line number Diff line change
@@ -215,7 +215,7 @@ impl MutVisitor for CfgEval<'_> {
foreign_item: P<ast::ForeignItem>,
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
let foreign_item = configure!(self, foreign_item);
mut_visit::walk_flat_map_item(self, foreign_item)
mut_visit::walk_flat_map_foreign_item(self, foreign_item)
}

fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
52 changes: 21 additions & 31 deletions compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Code that generates a test runner to run all the tests in a crate

use std::{iter, mem};
use std::mem;

use rustc_ast as ast;
use rustc_ast::entry::EntryPointType;
@@ -19,7 +19,7 @@ use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency};
use rustc_span::symbol::{Ident, Symbol, sym};
use rustc_span::{DUMMY_SP, Span};
use rustc_target::spec::PanicStrategy;
use smallvec::{SmallVec, smallvec};
use smallvec::smallvec;
use thin_vec::{ThinVec, thin_vec};
use tracing::debug;

@@ -129,8 +129,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
c.items.push(mk_main(&mut self.cx));
}

fn flat_map_item(&mut self, mut i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
let item = &mut *i;
fn visit_item(&mut self, item: &mut P<ast::Item>) {
let item = &mut **item;

if let Some(name) = get_test_name(&item) {
debug!("this is a test item");

@@ -158,7 +159,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
// But in those cases, we emit a lint to warn the user of these missing tests.
walk_item(&mut InnerItemLinter { sess: self.cx.ext_cx.sess }, &item);
}
smallvec![i]
}
}

@@ -198,40 +198,30 @@ struct EntryPointCleaner<'a> {
}

impl<'a> MutVisitor for EntryPointCleaner<'a> {
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
fn visit_item(&mut self, item: &mut P<ast::Item>) {
self.depth += 1;
let item = walk_flat_map_item(self, i).expect_one("noop did something");
ast::mut_visit::walk_item(self, item);
self.depth -= 1;

// Remove any #[rustc_main] or #[start] from the AST so it doesn't
// clash with the one we're going to add, but mark it as
// #[allow(dead_code)] to avoid printing warnings.
let item = match entry_point_type(&item, self.depth == 0) {
match entry_point_type(&item, self.depth == 0) {
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| {
let allow_dead_code = attr::mk_attr_nested_word(
&self.sess.psess.attr_id_generator,
ast::AttrStyle::Outer,
ast::Safety::Default,
sym::allow,
sym::dead_code,
self.def_site,
);
let attrs = attrs
.into_iter()
.filter(|attr| {
!attr.has_name(sym::rustc_main) && !attr.has_name(sym::start)
})
.chain(iter::once(allow_dead_code))
.collect();

ast::Item { id, ident, attrs, kind, vis, span, tokens }
})
let allow_dead_code = attr::mk_attr_nested_word(
&self.sess.psess.attr_id_generator,
ast::AttrStyle::Outer,
ast::Safety::Default,
sym::allow,
sym::dead_code,
self.def_site,
);
item.attrs
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
item.attrs.push(allow_dead_code);
}
EntryPointType::None | EntryPointType::OtherMain => item,
EntryPointType::None | EntryPointType::OtherMain => {}
};

smallvec![item]
}
}

@@ -292,7 +282,7 @@ fn generate_test_harness(
/// Most of the Ident have the usual def-site hygiene for the AST pass. The
/// exception is the `test_const`s. These have a syntax context that has two
/// opaque marks: one from the expansion of `test` or `test_case`, and one
/// generated in `TestHarnessGenerator::flat_map_item`. When resolving this
/// generated in `TestHarnessGenerator::visit_item`. When resolving this
/// identifier after failing to find a matching identifier in the root module
/// we remove the outer mark, and try resolving at its def-site, which will
/// then resolve to `test_const`.
93 changes: 43 additions & 50 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
#![feature(panic_update_hook)]
#![feature(result_flattening)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

@@ -564,71 +565,63 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
}
}

/// If color is always or auto, print formatted & colorized markdown. If color is never or
/// if formatted printing fails, print the raw text.
/// If `color` is `always` or `auto`, try to print pretty (formatted & colorized) markdown. If
/// that fails or `color` is `never`, print the raw markdown.
///
/// Prefers a pager, falls back standard print
/// Uses a pager if possible, falls back to stdout.
fn show_md_content_with_pager(content: &str, color: ColorConfig) {
let mut fallback_to_println = false;
let pager_name = env::var_os("PAGER").unwrap_or_else(|| {
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
});

let mut cmd = Command::new(&pager_name);
// FIXME: find if other pagers accept color options
let mut print_formatted = if pager_name == "less" {
cmd.arg("-R");
true
} else {
["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
};

if color == ColorConfig::Never {
print_formatted = false;
} else if color == ColorConfig::Always {
print_formatted = true;
if pager_name == "less" {
cmd.arg("-R"); // allows color escape sequences
}

let mdstream = markdown::MdStream::parse_str(content);
let bufwtr = markdown::create_stdout_bufwtr();
let mut mdbuf = bufwtr.buffer();
if mdstream.write_termcolor_buf(&mut mdbuf).is_err() {
print_formatted = false;
}

if let Ok(mut pager) = cmd.stdin(Stdio::piped()).spawn() {
if let Some(pipe) = pager.stdin.as_mut() {
let res = if print_formatted {
pipe.write_all(mdbuf.as_slice())
} else {
pipe.write_all(content.as_bytes())
};

if res.is_err() {
fallback_to_println = true;
}
let pretty_on_pager = match color {
ColorConfig::Auto => {
// Add other pagers that accept color escape sequences here.
["less", "bat", "batcat", "delta"].iter().any(|v| *v == pager_name)
}
ColorConfig::Always => true,
ColorConfig::Never => false,
};

if pager.wait().is_err() {
fallback_to_println = true;
}
} else {
fallback_to_println = true;
}
// Try to prettify the raw markdown text. The result can be used by the pager or on stdout.
let pretty_data = {
let mdstream = markdown::MdStream::parse_str(content);
let bufwtr = markdown::create_stdout_bufwtr();
let mut mdbuf = bufwtr.buffer();
if mdstream.write_termcolor_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None }
};

// If pager fails for whatever reason, we should still print the content
// to standard output
if fallback_to_println {
let fmt_success = match color {
ColorConfig::Auto => io::stdout().is_terminal() && bufwtr.print(&mdbuf).is_ok(),
ColorConfig::Always => bufwtr.print(&mdbuf).is_ok(),
ColorConfig::Never => false,
// Try to print via the pager, pretty output if possible.
let pager_res: Option<()> = try {
let mut pager = cmd.stdin(Stdio::piped()).spawn().ok()?;

let pager_stdin = pager.stdin.as_mut()?;
if pretty_on_pager && let Some((_, mdbuf)) = &pretty_data {
pager_stdin.write_all(mdbuf.as_slice()).ok()?;
} else {
pager_stdin.write_all(content.as_bytes()).ok()?;
};

if !fmt_success {
safe_print!("{content}");
}
pager.wait().ok()?;
};
if pager_res.is_some() {
return;
}

// The pager failed. Try to print pretty output to stdout.
if let Some((bufwtr, mdbuf)) = &pretty_data
&& bufwtr.print(&mdbuf).is_ok()
{
return;
}

// Everything failed. Print the raw markdown text.
safe_print!("{content}");
}

fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
@@ -1382,7 +1382,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
fragment.make_foreign_items()
}
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
walk_flat_map_item(visitor, self)
walk_flat_map_foreign_item(visitor, self)
}
fn is_mac_call(&self) -> bool {
matches!(self.kind, ForeignItemKind::MacCall(..))
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/placeholders.rs
Original file line number Diff line number Diff line change
@@ -296,7 +296,7 @@ impl MutVisitor for PlaceholderExpander {
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
match item.kind {
ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(),
_ => walk_flat_map_item(self, item),
_ => walk_flat_map_foreign_item(self, item),
}
}

2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
@@ -339,6 +339,8 @@ fn check_opaque_meets_bounds<'tcx>(

let misc_cause = ObligationCause::misc(span, def_id);
// FIXME: We should just register the item bounds here, rather than equating.
// FIXME(const_trait_impl): When we do that, please make sure to also register
// the `~const` bounds.
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
Ok(()) => {}
Err(ty_err) => {
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
@@ -2083,7 +2083,7 @@ pub(super) fn check_type_bounds<'tcx>(
// Only in a const implementation do we need to check that the `~const` item bounds hold.
if tcx.is_conditionally_const(impl_ty_def_id) {
obligations.extend(
tcx.implied_const_bounds(trait_ty.def_id)
tcx.explicit_implied_const_bounds(trait_ty.def_id)
.iter_instantiated_copied(tcx, rebased_args)
.map(|(c, span)| {
traits::Obligation::new(
10 changes: 9 additions & 1 deletion compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ pub fn provide(providers: &mut Providers) {
predicates_of::explicit_supertraits_containing_assoc_item,
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
const_conditions: predicates_of::const_conditions,
implied_const_bounds: predicates_of::implied_const_bounds,
explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds,
type_param_predicates: predicates_of::type_param_predicates,
trait_def,
adt_def,
@@ -340,6 +340,10 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
self.tcx.ensure().explicit_item_super_predicates(def_id);
self.tcx.ensure().item_bounds(def_id);
self.tcx.ensure().item_super_predicates(def_id);
if self.tcx.is_conditionally_const(def_id) {
self.tcx.ensure().explicit_implied_const_bounds(def_id);
self.tcx.ensure().const_conditions(def_id);
}
intravisit::walk_opaque_ty(self, opaque);
}

@@ -682,6 +686,10 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
tcx.ensure().generics_of(item.owner_id);
tcx.ensure().type_of(item.owner_id);
tcx.ensure().predicates_of(item.owner_id);
if tcx.is_conditionally_const(def_id) {
tcx.ensure().explicit_implied_const_bounds(def_id);
tcx.ensure().const_conditions(def_id);
}
match item.kind {
hir::ForeignItemKind::Fn(..) => {
tcx.ensure().codegen_fn_attrs(item.owner_id);
13 changes: 10 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
@@ -959,6 +959,12 @@ pub(super) fn const_conditions<'tcx>(
hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
},
Node::OpaqueTy(opaque) => match opaque.origin {
hir::OpaqueTyOrigin::FnReturn { parent, .. } => return tcx.const_conditions(parent),
hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => {
unreachable!()
}
},
// N.B. Tuple ctors are unconditionally constant.
Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
@@ -1018,7 +1024,7 @@ pub(super) fn const_conditions<'tcx>(
}
}

pub(super) fn implied_const_bounds<'tcx>(
pub(super) fn explicit_implied_const_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
@@ -1034,10 +1040,11 @@ pub(super) fn implied_const_bounds<'tcx>(
PredicateFilter::SelfConstIfConst,
)
}
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => {
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
| Node::OpaqueTy(_) => {
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
}
_ => bug!("implied_const_bounds called on wrong item: {def_id:?}"),
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
};

bounds.map_bound(|bounds| {
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
@@ -1106,7 +1106,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.collect::<String>()
),
[(only, _)] => only.to_string(),
[] => "this type".to_string(),
[] => bug!("expected one segment to deny"),
};

let arg_spans: Vec<Span> = segments
@@ -1136,7 +1136,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
"s",
),
[only] => (only.to_string(), ""),
[] => unreachable!("expected at least one generic to prohibit"),
[] => bug!("expected at least one generic to prohibit"),
};
let last_span = *arg_spans.last().unwrap();
let span: MultiSpan = arg_spans.into();
27 changes: 23 additions & 4 deletions compiler/rustc_infer/src/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
@@ -574,9 +574,8 @@ impl<'tcx> InferCtxt<'tcx> {
// unexpected region errors.
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));

let item_bounds = tcx.explicit_item_bounds(def_id);
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
let predicate = predicate.fold_with(&mut BottomUpFolder {
let replace_opaques_in = |clause: ty::Clause<'tcx>, goals: &mut Vec<_>| {
clause.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| match *ty.kind() {
// We can't normalize associated types from `rustc_infer`,
@@ -612,11 +611,31 @@ impl<'tcx> InferCtxt<'tcx> {
},
lt_op: |lt| lt,
ct_op: |ct| ct,
});
})
};

let item_bounds = tcx.explicit_item_bounds(def_id);
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
let predicate = replace_opaques_in(predicate, goals);

// Require that the predicate holds for the concrete type.
debug!(?predicate);
goals.push(Goal::new(self.tcx, param_env, predicate));
}

// If this opaque is being defined and it's conditionally const,
if self.tcx.is_conditionally_const(def_id) {
let item_bounds = tcx.explicit_implied_const_bounds(def_id);
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
let predicate = replace_opaques_in(
predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe),
goals,
);

// Require that the predicate holds for the concrete type.
debug!(?predicate);
goals.push(Goal::new(self.tcx, param_env, predicate));
}
}
}
}
17 changes: 9 additions & 8 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
@@ -230,15 +230,16 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
}

fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
self.with_lint_attrs(item.id, &item.attrs, |cx| match ctxt {
ast_visit::AssocCtxt::Trait => {
lint_callback!(cx, check_trait_item, item);
ast_visit::walk_assoc_item(cx, item, ctxt);
}
ast_visit::AssocCtxt::Impl => {
lint_callback!(cx, check_impl_item, item);
ast_visit::walk_assoc_item(cx, item, ctxt);
self.with_lint_attrs(item.id, &item.attrs, |cx| {
match ctxt {
ast_visit::AssocCtxt::Trait => {
lint_callback!(cx, check_trait_item, item);
}
ast_visit::AssocCtxt::Impl => {
lint_callback!(cx, check_impl_item, item);
}
}
ast_visit::walk_assoc_item(cx, item, ctxt);
});
}

2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
@@ -275,7 +275,7 @@ provide! { tcx, def_id, other, cdata,
defaultness => { table_direct }
constness => { table_direct }
const_conditions => { table }
implied_const_bounds => { table_defaulted_array }
explicit_implied_const_bounds => { table_defaulted_array }
coerce_unsized_info => {
Ok(cdata
.root
12 changes: 8 additions & 4 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -1463,8 +1463,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record_array!(self.tables.module_children_non_reexports[def_id] <-
module_children.iter().map(|child| child.res.def_id().index));
if self.tcx.is_const_trait(def_id) {
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
<- self.tcx.implied_const_bounds(def_id).skip_binder());
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
}
}
if let DefKind::TraitAlias = def_kind {
@@ -1532,6 +1532,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.encode_explicit_item_super_predicates(def_id);
record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id));
self.encode_precise_capturing_args(def_id);
if tcx.is_conditionally_const(def_id) {
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
<- tcx.explicit_implied_const_bounds(def_id).skip_binder());
}
}
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
@@ -1654,8 +1658,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.encode_explicit_item_bounds(def_id);
self.encode_explicit_item_super_predicates(def_id);
if tcx.is_conditionally_const(def_id) {
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
<- self.tcx.implied_const_bounds(def_id).skip_binder());
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
@@ -391,7 +391,7 @@ define_tables! {
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -697,7 +697,7 @@ rustc_queries! {
separate_provide_extern
}

query implied_const_bounds(
query explicit_implied_const_bounds(
key: DefId
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
desc { |tcx| "computing the implied `~const` bounds for `{}`",
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
@@ -393,12 +393,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
)
}

fn implied_const_bounds(
fn explicit_implied_const_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
ty::EarlyBinder::bind(
self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
)
}

8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -2110,7 +2110,13 @@ impl<'tcx> TyCtxt<'tcx> {
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
}
}
DefKind::Closure | DefKind::OpaqueTy => {
DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent),
hir::OpaqueTyOrigin::AsyncFn { .. } => false,
// FIXME(const_trait_impl): ATPITs could be conditionally const?
hir::OpaqueTyOrigin::TyAlias { .. } => false,
},
DefKind::Closure => {
// Closures and RPITs will eventually have const conditions
// for `~const` bounds.
false
2 changes: 1 addition & 1 deletion compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ where

/// Assemble additional assumptions for an alias that are not included
/// in the item bounds of the alias. For now, this is limited to the
/// `implied_const_bounds` for an associated type.
/// `explicit_implied_const_bounds` for an associated type.
fn consider_additional_alias_assumptions(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
5 changes: 1 addition & 4 deletions compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
@@ -84,12 +84,9 @@ where
let cx = ecx.cx();
let mut candidates = vec![];

// FIXME(const_trait_impl): We elaborate here because the implied const bounds
// aren't necessarily elaborated. We probably should prefix this query
// with `explicit_`...
for clause in elaborate::elaborate(
cx,
cx.implied_const_bounds(alias_ty.def_id)
cx.explicit_implied_const_bounds(alias_ty.def_id)
.iter_instantiated(cx, alias_ty.args)
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
) {
14 changes: 10 additions & 4 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
@@ -1478,9 +1478,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if segment_idx == 0 {
if name == kw::SelfLower {
let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, parent_scope.module),
));
let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
if let Some(res) = self_mod.res() {
record_segment_res(self, res);
}
module = Some(ModuleOrUniformRoot::Module(self_mod));
continue;
}
if name == kw::PathRoot && ident.span.at_least_rust_2018() {
@@ -1497,7 +1499,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
// `::a::b`, `crate::a::b` or `$crate::a::b`
module = Some(ModuleOrUniformRoot::Module(self.resolve_crate_root(ident)));
let crate_root = self.resolve_crate_root(ident);
if let Some(res) = crate_root.res() {
record_segment_res(self, res);
}
module = Some(ModuleOrUniformRoot::Module(crate_root));
continue;
}
}
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@ use crate::spec::{
pub(crate) fn target() -> Target {
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
let pre_link_args = LinkArgs::new();
let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]);
let post_link_args =
TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0", "-sWASM_BIGINT"]);

let opts = TargetOptions {
os: "emscripten".into(),
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/elaborate.rs
Original file line number Diff line number Diff line change
@@ -157,7 +157,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
}
// `T: ~const Trait` implies `T: ~const Supertrait`.
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
elaboratable.child(
trait_ref
.to_host_effect_clause(cx, data.constness)
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
@@ -229,7 +229,7 @@ pub trait Interner:
self,
def_id: Self::DefId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
fn implied_const_bounds(
fn explicit_implied_const_bounds(
self,
def_id: Self::DefId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
4 changes: 2 additions & 2 deletions library/Cargo.lock
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
addr2line = { version = "0.22.0", optional = true, default-features = false }

[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
libc = { version = "0.2.161", default-features = false, features = [
libc = { version = "0.2.162", default-features = false, features = [
'rustc-dep-of-std',
], public = true }

18 changes: 18 additions & 0 deletions tests/ui/generics/generics-on-self-mod-segment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
struct Ty;

fn self_(_: self::<i32>::Ty) {}
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`

fn crate_(_: crate::<i32>::Ty) {}
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`

macro_rules! dollar_crate {
() => {
fn dollar_crate_(_: $crate::<i32>::Ty) {}
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
}
}

dollar_crate!();

fn main() {}
32 changes: 32 additions & 0 deletions tests/ui/generics/generics-on-self-mod-segment.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
--> $DIR/generics-on-self-mod-segment.rs:3:20
|
LL | fn self_(_: self::<i32>::Ty) {}
| ---- ^^^ type argument not allowed
| |
| not allowed on module `generics_on_self_mod_segment`

error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
--> $DIR/generics-on-self-mod-segment.rs:6:22
|
LL | fn crate_(_: crate::<i32>::Ty) {}
| ----- ^^^ type argument not allowed
| |
| not allowed on module `generics_on_self_mod_segment`

error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
--> $DIR/generics-on-self-mod-segment.rs:11:38
|
LL | fn dollar_crate_(_: $crate::<i32>::Ty) {}
| ------ ^^^ type argument not allowed
| |
| not allowed on module `generics_on_self_mod_segment`
...
LL | dollar_crate!();
| --------------- in this macro invocation
|
= note: this error originates in the macro `dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0109`.
2 changes: 1 addition & 1 deletion tests/ui/trait-bounds/maybe-bound-has-path-args.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
trait Trait {}

fn test<T: ?self::<i32>::Trait>() {}
//~^ ERROR type arguments are not allowed on this type
//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args`
//~| WARN relaxing a default bound only does something for `?Sized`

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/trait-bounds/maybe-bound-has-path-args.stderr
Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
LL | fn test<T: ?self::<i32>::Trait>() {}
| ^^^^^^^^^^^^^^^^^^^

error[E0109]: type arguments are not allowed on this type
error[E0109]: type arguments are not allowed on module `maybe_bound_has_path_args`
--> $DIR/maybe-bound-has-path-args.rs:3:20
|
LL | fn test<T: ?self::<i32>::Trait>() {}
| ---- ^^^ type argument not allowed
| |
| not allowed on this type
| not allowed on module `maybe_bound_has_path_args`

error: aborting due to 1 previous error; 1 warning emitted

Original file line number Diff line number Diff line change
@@ -12,5 +12,13 @@ LL | const fn test() -> impl ~const Fn() {
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 2 previous errors
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-closure-parse-not-item.rs:7:25
|
LL | const fn test() -> impl ~const Fn() {
| ^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 3 previous errors

15 changes: 15 additions & 0 deletions tests/ui/traits/const-traits/const-opaque.no.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0277]: the trait bound `(): const Foo` is not satisfied
--> $DIR/const-opaque.rs:31:18
|
LL | let opaque = bar(());
| ^^^^^^^

error[E0277]: the trait bound `(): const Foo` is not satisfied
--> $DIR/const-opaque.rs:33:5
|
LL | opaque.method();
| ^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
38 changes: 38 additions & 0 deletions tests/ui/traits/const-traits/const-opaque.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//@ revisions: yes no
//@ compile-flags: -Znext-solver
//@[yes] check-pass

#![feature(const_trait_impl)]

#[const_trait]
trait Foo {
fn method(&self);
}

impl<T: ~const Foo> const Foo for (T,) {
fn method(&self) {}
}

#[cfg(yes)]
impl const Foo for () {
fn method(&self) {}
}

#[cfg(no)]
impl Foo for () {
fn method(&self) {}
}

const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
(t,)
}

const _: () = {
let opaque = bar(());
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
opaque.method();
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
std::mem::forget(opaque);
};

fn main() {}
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
const fn test() -> impl ~const Fn() {
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
const move || { //~ ERROR const closures are experimental
let sl: &[u8] = b"foo";

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0658]: const closures are experimental
--> $DIR/ice-112822-expected-type-for-param.rs:6:5
--> $DIR/ice-112822-expected-type-for-param.rs:7:5
|
LL | const move || {
| ^^^^^
@@ -22,8 +22,16 @@ LL | const fn test() -> impl ~const Fn() {
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
LL | const fn test() -> impl ~const Fn() {
| ^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0015]: cannot call non-const operator in constant functions
--> $DIR/ice-112822-expected-type-for-param.rs:11:17
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
LL | assert_eq!(first, &b'f');
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,15 +40,15 @@ LL | assert_eq!(first, &b'f');
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0015]: cannot call non-const fn `core::panicking::assert_failed::<&u8, &u8>` in constant functions
--> $DIR/ice-112822-expected-type-for-param.rs:11:17
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
LL | assert_eq!(first, &b'f');
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 5 previous errors
error: aborting due to 6 previous errors

Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.