Auto merge of #76582 - tmandry:rollup-lwwc93b, r=tmandry

Rollup of 11 pull requests

Successful merges:

 - #75857 (Syntactically permit unsafety on mods)
 - #76289 (Add docs about crate level documentation support)
 - #76514 (Add revisions to const generic issue UI tests.)
 - #76524 (typeck: don't suggest inaccessible private fields)
 - #76548 (Validate removal of AscribeUserType, FakeRead, and Shallow borrow)
 - #76555 (Reword `trivial_casts` lint in rustc book to better explain what it does.)
 - #76559 (add the `const_evaluatable_checked` feature)
 - #76563 (small typo fix in rustc_parse docs)
 - #76565 (take reference to Place directly instead of taking reference to Box<Place>)
 - #76567 (use push(char) to add chars (single-char &strs) to strings instead of push_str(&str))
 - #76568 (Add missing examples on core traits' method)

Failed merges:

r? `@ghost`
This commit is contained in:
bors 2020-09-10 19:23:11 +00:00
commit ad3a6f70ac
104 changed files with 1320 additions and 301 deletions

View File

@ -2289,12 +2289,15 @@ impl FnRetTy {
/// Module declaration.
///
/// E.g., `mod foo;` or `mod foo { .. }`.
#[derive(Clone, Encodable, Decodable, Debug, Default)]
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
/// to the last token in the external file.
pub inner: Span,
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
/// semantically by Rust.
pub unsafety: Unsafe,
pub items: Vec<P<Item>>,
/// `true` for `mod foo { .. }`; `false` for `mod foo;`.
pub inline: bool,
@ -2302,9 +2305,12 @@ pub struct Mod {
/// Foreign module declaration.
///
/// E.g., `extern { .. }` or `extern C { .. }`.
/// E.g., `extern { .. }` or `extern "C" { .. }`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ForeignMod {
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
/// semantically by Rust.
pub unsafety: Unsafe,
pub abi: Option<StrLit>,
pub items: Vec<P<ForeignItem>>,
}

View File

@ -490,7 +490,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
}
pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) {
let ForeignMod { abi: _, items } = foreign_mod;
let ForeignMod { unsafety: _, abi: _, items } = foreign_mod;
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}
@ -970,7 +970,8 @@ pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
vis.visit_asyncness(asyncness);
}
pub fn noop_visit_mod<T: MutVisitor>(Mod { inner, items, inline: _ }: &mut Mod, vis: &mut T) {
pub fn noop_visit_mod<T: MutVisitor>(module: &mut Mod, vis: &mut T) {
let Mod { inner, unsafety: _, items, inline: _ } = module;
vis.visit_span(inner);
items.flat_map_in_place(|item| vis.flat_map_item(item));
}
@ -990,7 +991,7 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
let len = items.len();
if len == 0 {
let module = Mod { inner: span, items: vec![], inline: true };
let module = Mod { inner: span, unsafety: Unsafe::No, items: vec![], inline: true };
Crate { module, attrs: vec![], span, proc_macros }
} else if len == 1 {
let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner();

View File

@ -990,12 +990,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.error_item_without_body(item.span, "function", msg, " { <body> }");
}
}
ItemKind::ForeignMod(_) => {
ItemKind::ForeignMod(ForeignMod { unsafety, .. }) => {
let old_item = mem::replace(&mut self.extern_mod, Some(item));
self.invalid_visibility(
&item.vis,
Some("place qualifiers on individual foreign items instead"),
);
if let Unsafe::Yes(span) = unsafety {
self.err_handler().span_err(span, "extern block cannot be declared unsafe");
}
visit::walk_item(self, item);
self.extern_mod = old_item;
return; // Avoid visiting again.
@ -1029,7 +1032,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs);
return;
}
ItemKind::Mod(Mod { inline, .. }) => {
ItemKind::Mod(Mod { inline, unsafety, .. }) => {
if let Unsafe::Yes(span) = unsafety {
self.err_handler().span_err(span, "module cannot be declared unsafe");
}
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
if !inline && !self.session.contains_name(&item.attrs, sym::path) {
self.check_mod_file_item_asciionly(item.ident);

View File

@ -1139,7 +1139,11 @@ impl<'a> State<'a> {
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
ast::ItemKind::Mod(ref _mod) => {
self.head(visibility_qualified(&item.vis, "mod"));
self.head(to_string(|s| {
s.print_visibility(&item.vis);
s.print_unsafety(_mod.unsafety);
s.word("mod");
}));
self.print_ident(item.ident);
if _mod.inline || self.is_expanded {
@ -1154,7 +1158,10 @@ impl<'a> State<'a> {
}
}
ast::ItemKind::ForeignMod(ref nmod) => {
self.head("extern");
self.head(to_string(|s| {
s.print_unsafety(nmod.unsafety);
s.word("extern");
}));
if let Some(abi) = nmod.abi {
self.print_literal(&abi.as_lit());
self.nbsp();

View File

@ -166,14 +166,14 @@ pub mod printf {
let cap = self.span.len() + if has_options { 2 } else { 0 };
let mut s = String::with_capacity(cap);
s.push_str("{");
s.push('{');
if let Some(arg) = self.parameter {
write!(s, "{}", arg.checked_sub(1)?).ok()?;
}
if has_options {
s.push_str(":");
s.push(':');
let align = if let Some(fill) = fill {
s.push_str(fill);
@ -191,11 +191,11 @@ pub mod printf {
}
if alt {
s.push_str("#");
s.push('#');
}
if zero_fill {
s.push_str("0");
s.push('0');
}
if let Some(width) = width {
@ -203,7 +203,7 @@ pub mod printf {
}
if let Some(precision) = precision {
s.push_str(".");
s.push('.');
precision.translate(&mut s).ok()?;
}
@ -212,7 +212,7 @@ pub mod printf {
}
}
s.push_str("}");
s.push('}');
Some(s)
}
}

View File

@ -1076,7 +1076,7 @@ fn exec_linker(
}
.to_string(),
);
args.push_str("\n");
args.push('\n');
}
let file = tmpdir.join("linker-arguments");
let bytes = if sess.target.target.options.is_like_msvc {

View File

@ -37,7 +37,7 @@ pub fn push_debuginfo_type_name<'tcx>(
ty::Bool => output.push_str("bool"),
ty::Char => output.push_str("char"),
ty::Str => output.push_str("str"),
ty::Never => output.push_str("!"),
ty::Never => output.push('!'),
ty::Int(int_ty) => output.push_str(int_ty.name_str()),
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
ty::Float(float_ty) => output.push_str(float_ty.name_str()),

View File

@ -399,7 +399,7 @@ impl<'a> StripUnconfigured<'a> {
}
pub fn configure_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
let ast::ForeignMod { abi: _, items } = foreign_mod;
let ast::ForeignMod { unsafety: _, abi: _, items } = foreign_mod;
items.flat_map_in_place(|item| self.configure(item));
}

View File

@ -13,7 +13,7 @@ use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::{self as ast, AttrItem, Block, LitKind, NodeId, PatKind, Path};
use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind};
use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind, Unsafe};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
use rustc_data_structures::map_in_place::MapInPlace;
@ -370,11 +370,21 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
None => {
// Resolution failed so we return an empty expansion
krate.attrs = vec![];
krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
krate.module = ast::Mod {
inner: orig_mod_span,
unsafety: Unsafe::No,
items: vec![],
inline: true,
};
}
Some(ast::Item { span, kind, .. }) => {
krate.attrs = vec![];
krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
krate.module = ast::Mod {
inner: orig_mod_span,
unsafety: Unsafe::No,
items: vec![],
inline: true,
};
self.cx.span_err(
span,
&format!(
@ -1441,8 +1451,15 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
push_directory(&self.cx.sess, ident, &item.attrs, dir)
} else {
// We have an outline `mod foo;` so we need to parse the file.
let (new_mod, dir) =
parse_external_mod(&self.cx.sess, ident, span, dir, &mut attrs, pushed);
let (new_mod, dir) = parse_external_mod(
&self.cx.sess,
ident,
span,
old_mod.unsafety,
dir,
&mut attrs,
pushed,
);
let krate = ast::Crate {
span: new_mod.inner,

View File

@ -1,4 +1,4 @@
use rustc_ast::{token, Attribute, Mod};
use rustc_ast::{token, Attribute, Mod, Unsafe};
use rustc_errors::{struct_span_err, PResult};
use rustc_parse::new_parser_from_file;
use rustc_session::parse::ParseSess;
@ -42,6 +42,7 @@ crate fn parse_external_mod(
sess: &Session,
id: Ident,
span: Span, // The span to blame on errors.
unsafety: Unsafe,
Directory { mut ownership, path }: Directory,
attrs: &mut Vec<Attribute>,
pop_mod_stack: &mut bool,
@ -60,13 +61,16 @@ crate fn parse_external_mod(
drop(included_mod_stack);
// Actually parse the external file as a module.
let mut module =
new_parser_from_file(&sess.parse_sess, &mp.path, Some(span)).parse_mod(&token::Eof)?;
let mut parser = new_parser_from_file(&sess.parse_sess, &mp.path, Some(span));
let mut module = parser.parse_mod(&token::Eof, unsafety)?;
module.0.inline = false;
module
};
// (1) ...instead, we return a dummy module.
let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_default();
let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_else(|_| {
let module = Mod { inner: Span::default(), unsafety, items: Vec::new(), inline: false };
(module, Vec::new())
});
attrs.append(&mut new_attrs);
// Extract the directory path for submodules of `module`.

View File

@ -585,6 +585,9 @@ declare_features! (
/// Allows `if let` guard in match arms.
(active, if_let_guard, "1.47.0", Some(51114), None),
/// Allows non trivial generic constants which have to be manually propageted upwards.
(active, const_evaluatable_checked, "1.48.0", Some(76560), None),
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
@ -600,6 +603,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_generics,
sym::let_chains,
sym::raw_dylib,
sym::const_evaluatable_checked,
sym::const_trait_impl,
sym::const_trait_bound_opt_out,
sym::lazy_normalization_consts,
@ -607,6 +611,6 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
];
/// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error
/// the two are present, produce an error.
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] =
&[(sym::const_generics, sym::min_const_generics)];

View File

@ -2093,7 +2093,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => String::new(),
};
if !s.is_empty() {
s.push_str(" ");
s.push(' ');
}
s
};

View File

@ -50,7 +50,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
ty::Covariant => self.relate(a, b),
// FIXME(#41044) -- not correct, need test
ty::Bivariant => Ok(a.clone()),
ty::Bivariant => Ok(a),
ty::Contravariant => self.fields.glb(self.a_is_expected).relate(a, b),
}
}

View File

@ -150,8 +150,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some(mut descr) => {
// Surround descr with `backticks`.
descr.reserve(2);
descr.insert_str(0, "`");
descr.push_str("`");
descr.insert(0, '`');
descr.push('`');
descr
}
None => "value".to_string(),
@ -222,7 +222,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if self.upvars[var_index].by_ref {
buf.push_str(&name);
} else {
buf.push_str(&format!("*{}", &name));
buf.push('*');
buf.push_str(&name);
}
} else {
if autoderef {
@ -234,7 +235,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&including_downcast,
)?;
} else {
buf.push_str(&"*");
buf.push('*');
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
@ -272,7 +273,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
autoderef,
&including_downcast,
)?;
buf.push_str(&format!(".{}", field_name));
buf.push('.');
buf.push_str(&field_name);
}
}
ProjectionElem::Index(index) => {
@ -284,11 +286,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
autoderef,
&including_downcast,
)?;
buf.push_str("[");
buf.push('[');
if self.append_local_to_string(*index, buf).is_err() {
buf.push_str("_");
buf.push('_');
}
buf.push_str("]");
buf.push(']');
}
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
autoderef = true;
@ -301,7 +303,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
autoderef,
&including_downcast,
)?;
buf.push_str(&"[..]");
buf.push_str("[..]");
}
};
}
@ -648,7 +650,7 @@ impl UseSpans {
" in closure".to_string()
}
}
_ => "".to_string(),
_ => String::new(),
}
}

View File

@ -417,7 +417,7 @@ crate fn location_set_str(
fn region_value_str(elements: impl IntoIterator<Item = RegionElement>) -> String {
let mut result = String::new();
result.push_str("{");
result.push('{');
// Set to Some(l1, l2) when we have observed all the locations
// from l1..=l2 (inclusive) but not yet printed them. This
@ -478,7 +478,7 @@ fn region_value_str(elements: impl IntoIterator<Item = RegionElement>) -> String
push_location_range(&mut result, location1, location2);
}
result.push_str("}");
result.push('}');
return result;

View File

@ -382,7 +382,7 @@ fn collect_and_partition_mono_items<'tcx>(
cgus.sort_by_key(|(name, _)| *name);
cgus.dedup();
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
output.push_str(" ");
output.push(' ');
output.push_str(&cgu_name.as_str());
let linkage_abbrev = match linkage {
@ -399,9 +399,9 @@ fn collect_and_partition_mono_items<'tcx>(
Linkage::Common => "Common",
};
output.push_str("[");
output.push('[');
output.push_str(linkage_abbrev);
output.push_str("]");
output.push(']');
}
output
})

View File

@ -353,7 +353,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
if !INCLUDE_COVERAGE_STATEMENTS {
continue;
}
format!("unreachable")
String::from("unreachable")
}
},
_ => format!("{:?}", statement),

View File

@ -674,7 +674,7 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
y_bb_idx: BasicBlock,
) -> StatementEquality {
let helper = |rhs: &Rvalue<'tcx>,
place: &Box<Place<'tcx>>,
place: &Place<'tcx>,
variant_index: &VariantIdx,
side_to_choose| {
let place_type = place.ty(self.body, self.tcx).ty;

View File

@ -4,8 +4,8 @@ use super::{MirPass, MirSource};
use rustc_middle::mir::visit::Visitor;
use rustc_middle::{
mir::{
AggregateKind, BasicBlock, Body, Location, MirPhase, Operand, Rvalue, Statement,
StatementKind, Terminator, TerminatorKind,
AggregateKind, BasicBlock, Body, BorrowKind, Location, MirPhase, Operand, Rvalue,
Statement, StatementKind, Terminator, TerminatorKind,
},
ty::{
self,
@ -274,9 +274,33 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
)
}
}
Rvalue::Ref(_, BorrowKind::Shallow, _) => {
if self.mir_phase > MirPhase::DropLowering {
self.fail(
location,
"`Assign` statement with a `Shallow` borrow should have been removed after drop lowering phase",
);
}
}
_ => {}
}
}
StatementKind::AscribeUserType(..) => {
if self.mir_phase > MirPhase::DropLowering {
self.fail(
location,
"`AscribeUserType` should have been removed after drop lowering phase",
);
}
}
StatementKind::FakeRead(..) => {
if self.mir_phase > MirPhase::DropLowering {
self.fail(
location,
"`FakeRead` should have been removed after drop lowering phase",
);
}
}
_ => {}
}
}

View File

@ -514,7 +514,7 @@ fn write_scope_tree(
write!(indented_decl, " as {:?}", user_ty).unwrap();
}
}
indented_decl.push_str(";");
indented_decl.push(';');
let local_name =
if local == RETURN_PLACE { " return place".to_string() } else { String::new() };

View File

@ -109,7 +109,7 @@ pub fn maybe_new_parser_from_source_str(
}
/// Creates a new parser, handling errors as appropriate if the file doesn't exist.
/// If a span is given, that is used on an error as the as the source of the problem.
/// If a span is given, that is used on an error as the source of the problem.
pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option<Span>) -> Parser<'a> {
source_file_to_parser(sess, file_to_source_file(sess, path, sp))
}

View File

@ -28,7 +28,7 @@ impl<'a> Parser<'a> {
/// Parses a source module as a crate. This is the main entry point for the parser.
pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> {
let lo = self.token.span;
let (module, attrs) = self.parse_mod(&token::Eof)?;
let (module, attrs) = self.parse_mod(&token::Eof, Unsafe::No)?;
let span = lo.to(self.token.span);
let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`.
Ok(ast::Crate { attrs, module, span, proc_macros })
@ -36,27 +36,38 @@ impl<'a> Parser<'a> {
/// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
let unsafety = self.parse_unsafety();
self.expect_keyword(kw::Mod)?;
let id = self.parse_ident()?;
let (module, mut inner_attrs) = if self.eat(&token::Semi) {
Default::default()
(Mod { inner: Span::default(), unsafety, items: Vec::new(), inline: false }, Vec::new())
} else {
self.expect(&token::OpenDelim(token::Brace))?;
self.parse_mod(&token::CloseDelim(token::Brace))?
self.parse_mod(&token::CloseDelim(token::Brace), unsafety)?
};
attrs.append(&mut inner_attrs);
Ok((id, ItemKind::Mod(module)))
}
/// Parses the contents of a module (inner attributes followed by module items).
pub fn parse_mod(&mut self, term: &TokenKind) -> PResult<'a, (Mod, Vec<Attribute>)> {
pub fn parse_mod(
&mut self,
term: &TokenKind,
unsafety: Unsafe,
) -> PResult<'a, (Mod, Vec<Attribute>)> {
let lo = self.token.span;
let attrs = self.parse_inner_attributes()?;
let module = self.parse_mod_items(term, lo)?;
let module = self.parse_mod_items(term, lo, unsafety)?;
Ok((module, attrs))
}
/// Given a termination token, parses all of the items in a module.
fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> {
fn parse_mod_items(
&mut self,
term: &TokenKind,
inner_lo: Span,
unsafety: Unsafe,
) -> PResult<'a, Mod> {
let mut items = vec![];
while let Some(item) = self.parse_item()? {
items.push(item);
@ -75,7 +86,7 @@ impl<'a> Parser<'a> {
let hi = if self.token.span.is_dummy() { inner_lo } else { self.prev_token.span };
Ok(Mod { inner: inner_lo.to(hi), items, inline: true })
Ok(Mod { inner: inner_lo.to(hi), unsafety, items, inline: true })
}
}
@ -235,8 +246,13 @@ impl<'a> Parser<'a> {
self.parse_item_extern_crate()?
} else {
// EXTERN BLOCK
self.parse_item_foreign_mod(attrs)?
self.parse_item_foreign_mod(attrs, Unsafe::No)?
}
} else if self.is_unsafe_foreign_mod() {
// EXTERN BLOCK
let unsafety = self.parse_unsafety();
self.expect_keyword(kw::Extern)?;
self.parse_item_foreign_mod(attrs, unsafety)?
} else if self.is_static_global() {
// STATIC ITEM
self.bump(); // `static`
@ -256,7 +272,9 @@ impl<'a> Parser<'a> {
{
// IMPL ITEM
self.parse_item_impl(attrs, def())?
} else if self.eat_keyword(kw::Mod) {
} else if self.check_keyword(kw::Mod)
|| self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Mod])
{
// MODULE ITEM
self.parse_item_mod(attrs)?
} else if self.eat_keyword(kw::Type) {
@ -893,10 +911,14 @@ impl<'a> Parser<'a> {
/// extern "C" {}
/// extern {}
/// ```
fn parse_item_foreign_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
fn parse_item_foreign_mod(
&mut self,
attrs: &mut Vec<Attribute>,
unsafety: Unsafe,
) -> PResult<'a, ItemInfo> {
let abi = self.parse_abi(); // ABI?
let items = self.parse_item_list(attrs, |p| p.parse_foreign_item())?;
let module = ast::ForeignMod { abi, items };
let module = ast::ForeignMod { unsafety, abi, items };
Ok((Ident::invalid(), ItemKind::ForeignMod(module)))
}
@ -938,6 +960,15 @@ impl<'a> Parser<'a> {
.emit();
}
fn is_unsafe_foreign_mod(&self) -> bool {
self.token.is_keyword(kw::Unsafe)
&& self.is_keyword_ahead(1, &[kw::Extern])
&& self.look_ahead(
2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize),
|t| t.kind == token::OpenDelim(token::Brace),
)
}
fn is_static_global(&mut self) -> bool {
if self.check_keyword(kw::Static) {
// Check if this could be a closure.
@ -1552,10 +1583,14 @@ impl<'a> Parser<'a> {
// `$qual fn` or `$qual $qual`:
|| QUALS.iter().any(|&kw| self.check_keyword(kw))
&& self.look_ahead(1, |t| {
// ...qualified and then `fn`, e.g. `const fn`.
// `$qual fn`, e.g. `const fn` or `async fn`.
t.is_keyword(kw::Fn)
// Two qualifiers. This is enough. Due `async` we need to check that it's reserved.
|| t.is_non_raw_ident_where(|i| QUALS.contains(&i.name) && i.is_reserved())
// Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
|| t.is_non_raw_ident_where(|i| QUALS.contains(&i.name)
// Rule out 2015 `const async: T = val`.
&& i.is_reserved()
// Rule out unsafe extern block.
&& !self.is_unsafe_foreign_mod())
})
// `extern ABI fn`
|| self.check_keyword(kw::Extern)
@ -1567,9 +1602,9 @@ impl<'a> Parser<'a> {
/// up to and including the `fn` keyword. The formal grammar is:
///
/// ```
/// Extern = "extern" StringLit ;
/// Extern = "extern" StringLit? ;
/// FnQual = "const"? "async"? "unsafe"? Extern? ;
/// FnFrontMatter = FnQual? "fn" ;
/// FnFrontMatter = FnQual "fn" ;
/// ```
pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
let constness = self.parse_constness();

View File

@ -438,7 +438,7 @@ impl<'tcx> SaveContext<'tcx> {
.next()
.map(|item| item.def_id);
}
qualname.push_str(">");
qualname.push('>');
(qualname, trait_id, decl_id, docs, attrs)
}

View File

@ -497,7 +497,7 @@ impl<'hir> Sig for hir::Item<'hir> {
sig.text.push_str(&bounds_to_string(bounds));
}
// FIXME where clause
sig.text.push_str(";");
sig.text.push(';');
Ok(sig)
}

View File

@ -581,9 +581,9 @@ impl OutputFilenames {
if !ext.is_empty() {
if !extension.is_empty() {
extension.push_str(".");
extension.push('.');
extension.push_str(RUST_CGU_EXT);
extension.push_str(".");
extension.push('.');
}
extension.push_str(ext);

View File

@ -348,6 +348,7 @@ symbols! {
const_compare_raw_pointers,
const_constructor,
const_eval_limit,
const_evaluatable_checked,
const_extern_fn,
const_fn,
const_fn_transmute,

View File

@ -14,6 +14,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
param_env: ty::ParamEnv<'tcx>,
span: Span,
) -> Result<(), ErrorHandled> {
debug!("is_const_evaluatable({:?}, {:?})", def, substs);
if infcx.tcx.features().const_evaluatable_checked {
// FIXME(const_evaluatable_checked): Actually look into generic constants to
// implement const equality.
for pred in param_env.caller_bounds() {
match pred.skip_binders() {
ty::PredicateAtom::ConstEvaluatable(b_def, b_substs) => {
debug!("is_const_evaluatable: caller_bound={:?}, {:?}", b_def, b_substs);
if b_def == def && b_substs == substs {
debug!("is_const_evaluatable: caller_bound ~~> ok");
return Ok(());
}
}
_ => {} // don't care
}
}
}
let future_compat_lint = || {
if let Some(local_def_id) = def.did.as_local() {
infcx.tcx.struct_span_lint_hir(
@ -38,24 +56,23 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
// See #74595 for more details about this.
let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
let def_kind = infcx.tcx.def_kind(def.did);
match def_kind {
DefKind::AnonConst => {
let mir_body = if let Some(def) = def.as_const_arg() {
infcx.tcx.optimized_mir_of_const_arg(def)
} else {
infcx.tcx.optimized_mir(def.did)
};
if mir_body.is_polymorphic && concrete.is_ok() {
future_compat_lint();
}
}
_ => {
if substs.has_param_types_or_consts() && concrete.is_ok() {
future_compat_lint();
if concrete.is_ok() && substs.has_param_types_or_consts() {
match infcx.tcx.def_kind(def.did) {
DefKind::AnonConst => {
let mir_body = if let Some(def) = def.as_const_arg() {
infcx.tcx.optimized_mir_of_const_arg(def)
} else {
infcx.tcx.optimized_mir(def.did)
};
if mir_body.is_polymorphic {
future_compat_lint();
}
}
_ => future_compat_lint(),
}
}
debug!(?concrete, "is_const_evaluatable");
concrete.map(drop)
}

View File

@ -1241,42 +1241,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.sess.span_err(span, "union expressions should have exactly one field");
}
} else if check_completeness && !error_happened && !remaining_fields.is_empty() {
let len = remaining_fields.len();
let mut displayable_field_names =
remaining_fields.keys().map(|ident| ident.as_str()).collect::<Vec<_>>();
displayable_field_names.sort();
let truncated_fields_error = if len <= 3 {
String::new()
} else {
format!(" and {} other field{}", (len - 3), if len - 3 == 1 { "" } else { "s" })
};
let remaining_fields_names = displayable_field_names
let no_accessible_remaining_fields = remaining_fields
.iter()
.take(3)
.map(|n| format!("`{}`", n))
.collect::<Vec<_>>()
.join(", ");
.filter(|(_, (_, field))| {
field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
})
.next()
.is_none();
struct_span_err!(
tcx.sess,
span,
E0063,
"missing field{} {}{} in initializer of `{}`",
pluralize!(remaining_fields.len()),
remaining_fields_names,
truncated_fields_error,
adt_ty
)
.span_label(
span,
format!("missing {}{}", remaining_fields_names, truncated_fields_error),
)
.emit();
if no_accessible_remaining_fields {
self.report_no_accessible_fields(adt_ty, span);
} else {
self.report_missing_field(adt_ty, span, remaining_fields);
}
}
error_happened
}
@ -1293,6 +1272,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
/// Report an error for a struct field expression when there are fields which aren't provided.
///
/// ```ignore (diagnostic)
/// error: missing field `you_can_use_this_field` in initializer of `foo::Foo`
/// --> src/main.rs:8:5
/// |
/// 8 | foo::Foo {};
/// | ^^^^^^^^ missing `you_can_use_this_field`
///
/// error: aborting due to previous error
/// ```
fn report_missing_field(
&self,
adt_ty: Ty<'tcx>,
span: Span,
remaining_fields: FxHashMap<Ident, (usize, &ty::FieldDef)>,
) {
let tcx = self.tcx;
let len = remaining_fields.len();
let mut displayable_field_names =
remaining_fields.keys().map(|ident| ident.as_str()).collect::<Vec<_>>();
displayable_field_names.sort();
let truncated_fields_error = if len <= 3 {
String::new()
} else {
format!(" and {} other field{}", (len - 3), if len - 3 == 1 { "" } else { "s" })
};
let remaining_fields_names = displayable_field_names
.iter()
.take(3)
.map(|n| format!("`{}`", n))
.collect::<Vec<_>>()
.join(", ");
struct_span_err!(
tcx.sess,
span,
E0063,
"missing field{} {}{} in initializer of `{}`",
pluralize!(remaining_fields.len()),
remaining_fields_names,
truncated_fields_error,
adt_ty
)
.span_label(span, format!("missing {}{}", remaining_fields_names, truncated_fields_error))
.emit();
}
/// Report an error for a struct field expression when there are no visible fields.
///
/// ```ignore (diagnostic)
/// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
/// --> src/main.rs:8:5
/// |
/// 8 | foo::Foo {};
/// | ^^^^^^^^
///
/// error: aborting due to previous error
/// ```
fn report_no_accessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
self.tcx.sess.span_err(
span,
&format!(
"cannot construct `{}` with struct literal syntax due to inaccessible fields",
adt_ty,
),
);
}
fn report_unknown_field(
&self,
ty: Ty<'tcx>,

View File

@ -1078,8 +1078,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut unmentioned_fields = variant
.fields
.iter()
.map(|field| field.ident.normalize_to_macros_2_0())
.filter(|ident| !used_fields.contains_key(&ident))
.map(|field| (field, field.ident.normalize_to_macros_2_0()))
.filter(|(_, ident)| !used_fields.contains_key(&ident))
.collect::<Vec<_>>();
let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered()) {
@ -1110,7 +1110,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
}
} else if !etc && !unmentioned_fields.is_empty() {
unmentioned_err = Some(self.error_unmentioned_fields(pat, &unmentioned_fields));
let no_accessible_unmentioned_fields = unmentioned_fields
.iter()
.filter(|(field, _)| {
field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
})
.next()
.is_none();
if no_accessible_unmentioned_fields {
unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
} else {
unmentioned_err = Some(self.error_unmentioned_fields(pat, &unmentioned_fields));
}
}
match (inexistent_fields_err, unmentioned_err) {
(Some(mut i), Some(mut u)) => {
@ -1173,7 +1185,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
kind_name: &str,
inexistent_fields: &[Ident],
unmentioned_fields: &mut Vec<Ident>,
unmentioned_fields: &mut Vec<(&ty::FieldDef, Ident)>,
variant: &ty::VariantDef,
) -> DiagnosticBuilder<'tcx> {
let tcx = self.tcx;
@ -1215,7 +1227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
if plural == "" {
let input = unmentioned_fields.iter().map(|field| &field.name);
let input = unmentioned_fields.iter().map(|(_, field)| &field.name);
let suggested_name = find_best_match_for_name(input, ident.name, None);
if let Some(suggested_name) = suggested_name {
err.span_suggestion(
@ -1232,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `smart_resolve_context_dependent_help`.
if suggested_name.to_ident_string().parse::<usize>().is_err() {
// We don't want to throw `E0027` in case we have thrown `E0026` for them.
unmentioned_fields.retain(|&x| x.name != suggested_name);
unmentioned_fields.retain(|&(_, x)| x.name != suggested_name);
}
}
}
@ -1300,17 +1312,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}
/// Returns a diagnostic reporting a struct pattern which is missing an `..` due to
/// inaccessible fields.
///
/// ```ignore (diagnostic)
/// error: pattern requires `..` due to inaccessible fields
/// --> src/main.rs:10:9
/// |
/// LL | let foo::Foo {} = foo::Foo::default();
/// | ^^^^^^^^^^^
/// |
/// help: add a `..`
/// |
/// LL | let foo::Foo { .. } = foo::Foo::default();
/// | ^^^^^^
/// ```
fn error_no_accessible_fields(
&self,
pat: &Pat<'_>,
fields: &'tcx [hir::FieldPat<'tcx>],
) -> DiagnosticBuilder<'tcx> {
let mut err = self
.tcx
.sess
.struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields");
if let Some(field) = fields.last() {
err.span_suggestion_verbose(
field.span.shrink_to_hi(),
"ignore the inaccessible and unused fields",
", ..".to_string(),
Applicability::MachineApplicable,
);
} else {
let qpath_span = if let PatKind::Struct(qpath, ..) = &pat.kind {
qpath.span()
} else {
bug!("`error_no_accessible_fields` called on non-struct pattern");
};
// Shrink the span to exclude the `foo:Foo` in `foo::Foo { }`.
let span = pat.span.with_lo(qpath_span.shrink_to_hi().hi());
err.span_suggestion_verbose(
span,
"ignore the inaccessible and unused fields",
" { .. }".to_string(),
Applicability::MachineApplicable,
);
}
err
}
/// Returns a diagnostic reporting a struct pattern which does not mention some fields.
///
/// ```ignore (diagnostic)
/// error[E0027]: pattern does not mention field `you_cant_use_this_field`
/// --> src/main.rs:15:9
/// |
/// LL | let foo::Foo {} = foo::Foo::new();
/// | ^^^^^^^^^^^ missing field `you_cant_use_this_field`
/// ```
fn error_unmentioned_fields(
&self,
pat: &Pat<'_>,
unmentioned_fields: &[Ident],
unmentioned_fields: &[(&ty::FieldDef, Ident)],
) -> DiagnosticBuilder<'tcx> {
let field_names = if unmentioned_fields.len() == 1 {
format!("field `{}`", unmentioned_fields[0])
format!("field `{}`", unmentioned_fields[0].1)
} else {
let fields = unmentioned_fields
.iter()
.map(|name| format!("`{}`", name))
.map(|(_, name)| format!("`{}`", name))
.collect::<Vec<String>>()
.join(", ");
format!("fields {}", fields)

View File

@ -37,11 +37,12 @@ use rustc_middle::hir::map::Map;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::util::Discr;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
use rustc_middle::ty::{TypeFoldable, TypeVisitor};
use rustc_session::config::SanitizerSet;
use rustc_session::lint;
use rustc_session::parse::feature_err;
@ -50,6 +51,8 @@ use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi;
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
use smallvec::SmallVec;
mod type_of;
struct OnlySelfBounds(bool);
@ -1672,10 +1675,46 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate
.alloc_from_iter(result.predicates.iter().chain(inferred_outlives).copied());
}
}
if tcx.features().const_evaluatable_checked {
let const_evaluatable = const_evaluatable_predicates_of(tcx, def_id, &result);
result.predicates =
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable));
}
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
result
}
pub fn const_evaluatable_predicates_of<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
predicates: &ty::GenericPredicates<'tcx>,
) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> {
#[derive(Default)]
struct ConstCollector<'tcx> {
ct: SmallVec<[(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>); 4]>,
}
impl<'tcx> TypeVisitor<'tcx> for ConstCollector<'tcx> {
fn visit_const(&mut self, ct: &'tcx Const<'tcx>) -> bool {
if let ty::ConstKind::Unevaluated(def, substs, None) = ct.val {
self.ct.push((def, substs));
}
false
}
}
let mut collector = ConstCollector::default();
for (pred, _span) in predicates.predicates.iter() {
pred.visit_with(&mut collector);
}
warn!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.ct);
collector.ct.into_iter().map(move |(def_id, subst)| {
(ty::PredicateAtom::ConstEvaluatable(def_id, subst).to_predicate(tcx), DUMMY_SP)
})
}
/// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
/// `Self: Trait` predicates for traits.

View File

@ -78,6 +78,12 @@ pub trait Add<Rhs = Self> {
type Output;
/// Performs the `+` operation.
///
/// # Example
///
/// ```
/// assert_eq!(12 + 1, 13);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn add(self, rhs: Rhs) -> Self::Output;
@ -178,6 +184,12 @@ pub trait Sub<Rhs = Self> {
type Output;
/// Performs the `-` operation.
///
/// # Example
///
/// ```
/// assert_eq!(12 - 1, 11);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn sub(self, rhs: Rhs) -> Self::Output;
@ -300,6 +312,12 @@ pub trait Mul<Rhs = Self> {
type Output;
/// Performs the `*` operation.
///
/// # Example
///
/// ```
/// assert_eq!(12 * 2, 24);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn mul(self, rhs: Rhs) -> Self::Output;
@ -426,6 +444,12 @@ pub trait Div<Rhs = Self> {
type Output;
/// Performs the `/` operation.
///
/// # Example
///
/// ```
/// assert_eq!(12 / 2, 6);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn div(self, rhs: Rhs) -> Self::Output;
@ -513,6 +537,12 @@ pub trait Rem<Rhs = Self> {
type Output;
/// Performs the `%` operation.
///
/// # Example
///
/// ```
/// assert_eq!(12 % 10, 2);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn rem(self, rhs: Rhs) -> Self::Output;
@ -612,6 +642,13 @@ pub trait Neg {
type Output;
/// Performs the unary `-` operation.
///
/// # Example
///
/// ```
/// let x: i32 = 12;
/// assert_eq!(-x, -12);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn neg(self) -> Self::Output;
@ -673,6 +710,14 @@ neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "+=")]
pub trait AddAssign<Rhs = Self> {
/// Performs the `+=` operation.
///
/// # Example
///
/// ```
/// let mut x: u32 = 12;
/// x += 1;
/// assert_eq!(x, 13);
/// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn add_assign(&mut self, rhs: Rhs);
}
@ -731,6 +776,14 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "-=")]
pub trait SubAssign<Rhs = Self> {
/// Performs the `-=` operation.
///
/// # Example
///
/// ```
/// let mut x: u32 = 12;
/// x -= 1;
/// assert_eq!(x, 11);
/// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn sub_assign(&mut self, rhs: Rhs);
}
@ -780,6 +833,14 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "*=")]
pub trait MulAssign<Rhs = Self> {
/// Performs the `*=` operation.
///
/// # Example
///
/// ```
/// let mut x: u32 = 12;
/// x *= 2;
/// assert_eq!(x, 24);
/// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn mul_assign(&mut self, rhs: Rhs);
}
@ -829,6 +890,14 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "/=")]
pub trait DivAssign<Rhs = Self> {
/// Performs the `/=` operation.
///
/// # Example
///
/// ```
/// let mut x: u32 = 12;
/// x /= 2;
/// assert_eq!(x, 6);
/// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn div_assign(&mut self, rhs: Rhs);
}
@ -881,6 +950,14 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "%=")]
pub trait RemAssign<Rhs = Self> {
/// Performs the `%=` operation.
///
/// # Example
///
/// ```
/// let mut x: u32 = 12;
/// x %= 10;
/// assert_eq!(x, 2);
/// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn rem_assign(&mut self, rhs: Rhs);
}

View File

@ -232,7 +232,8 @@ error: lifetime name `'x` only used once
## trivial-casts
This lint detects trivial casts which could be removed. Some example code
This lint detects trivial casts which could be replaced with coercion, which may require
type ascription or a temporary variable. Some example code
that triggers this lint:
```rust

View File

@ -93,6 +93,29 @@ passes `-L`, a flag that helps rustdoc find the dependencies
your code relies on. If our project used dependencies, we'd get
documentation for them as well!
## Outer and inner documentation
The `///` syntax is used to document the item present after it.
That's why it is called an outer documentation.
There is another syntax: `//!`, which is used to document the
item it is present inside. It is called an inner documentation.
It is often used when documenting the entire crate,
because nothing comes before it: it is the root of the crate.
So in order to document an entire crate, you need to use `//!` syntax.
For example:
``` rust
//! This is my first rust crate
```
When used in the crate root, it documents the item it is inside,
which is the crate itself.
For more information about the `//!` syntax, see [the Book].
[the Book]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#commenting-contained-items
## Using standalone Markdown files
`rustdoc` can also generate HTML from standalone Markdown files. Let's

View File

@ -1 +1 @@
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}

View File

@ -1 +1 @@
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}

View File

@ -1,4 +1,6 @@
#![feature(const_generics)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct Struct<const N: usize>(pub [u8; N]);

View File

@ -1,4 +1,6 @@
#![feature(const_generics)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct Num<const N: usize>;

View File

@ -1,11 +1,11 @@
error[E0308]: mismatched types
--> $DIR/const-argument-cross-crate-mismatch.rs:6:67
--> $DIR/const-argument-cross-crate-mismatch.rs:7:67
|
LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
| ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
error[E0308]: mismatched types
--> $DIR/const-argument-cross-crate-mismatch.rs:8:65
--> $DIR/const-argument-cross-crate-mismatch.rs:9:65
|
LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
| ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements

View File

@ -0,0 +1,15 @@
error[E0308]: mismatched types
--> $DIR/const-argument-cross-crate-mismatch.rs:7:67
|
LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
| ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
error[E0308]: mismatched types
--> $DIR/const-argument-cross-crate-mismatch.rs:9:65
|
LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
| ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,4 +1,5 @@
// aux-build:const_generic_lib.rs
// revisions: full min
extern crate const_generic_lib;

View File

@ -1,4 +1,5 @@
// run-pass
// revisions: full min
// aux-build:const_generic_lib.rs
extern crate const_generic_lib;

View File

@ -0,0 +1,14 @@
#![feature(const_generics)]
#![allow(incomplete_features)]
type Arr<const N: usize> = [u8; N - 1];
fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
//~^ ERROR constant expression depends
Default::default()
}
fn main() {
let x = test::<33>();
assert_eq!(x, [0; 32]);
}

View File

@ -0,0 +1,10 @@
error: constant expression depends on a generic parameter
--> $DIR/feature-gate-const_evaluatable_checked.rs:6:30
|
LL | fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
| ^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
// run-pass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]
type Arr<const N: usize> = [u8; N - 1];
fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
Default::default()
}
fn main() {
let x = test::<33>();
assert_eq!(x, [0; 32]);
}

View File

@ -0,0 +1,12 @@
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]
type Arr<const N: usize> = [u8; N - 1]; //~ ERROR evaluation of constant
fn test<const N: usize>() -> Arr<N> where Arr<N>: Sized {
todo!()
}
fn main() {
test::<0>();
}

View File

@ -0,0 +1,9 @@
error[E0080]: evaluation of constant value failed
--> $DIR/simple_fail.rs:4:33
|
LL | type Arr<const N: usize> = [u8; N - 1];
| ^^^^^ attempt to compute `0_usize - 1_usize` which would overflow
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -0,0 +1,8 @@
error: type parameters must be declared prior to const parameters
--> $DIR/complex-unord-param.rs:9:41
|
LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
| ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a, const N: usize, const M: usize>`
error: aborting due to previous error

View File

@ -1,11 +1,13 @@
// run-pass
// [full] run-pass
// revisions: full min
// Checks a complicated usage of unordered params
#![feature(const_generics)]
#![allow(incomplete_features)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#![allow(dead_code)]
struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
//[min]~^ ERROR type parameters must be declared prior to const parameters
args: &'a [&'a [T; M]; N],
specifier: A,
}

View File

@ -1,11 +1,11 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/intermixed-lifetime.rs:6:28
--> $DIR/intermixed-lifetime.rs:7:28
|
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/intermixed-lifetime.rs:9:37
--> $DIR/intermixed-lifetime.rs:11:37
|
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`

View File

@ -0,0 +1,26 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/intermixed-lifetime.rs:7:28
|
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
| -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
error: type parameters must be declared prior to const parameters
--> $DIR/intermixed-lifetime.rs:7:32
|
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
| ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
error: lifetime parameters must be declared prior to const parameters
--> $DIR/intermixed-lifetime.rs:11:37
|
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
| --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
error: type parameters must be declared prior to const parameters
--> $DIR/intermixed-lifetime.rs:11:28
|
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
| -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
error: aborting due to 4 previous errors

View File

@ -1,12 +1,16 @@
// revisions: full min
// Checks that lifetimes cannot be interspersed between consts and types.
#![feature(const_generics)]
#![allow(incomplete_features)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
//~^ Error lifetime parameters must be declared prior to const parameters
//[min]~^^ Error type parameters must be declared prior to const parameters
struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
//~^ Error lifetime parameters must be declared prior to type parameters
//[full]~^ Error lifetime parameters must be declared prior to type parameters
//[min]~^^ Error type parameters must be declared prior to const parameters
//[min]~| Error lifetime parameters must be declared prior to const parameters
fn main() {}

View File

@ -0,0 +1,8 @@
error: type parameters must be declared prior to const parameters
--> $DIR/simple-defaults.rs:9:40
|
LL | struct FixedOutput<'a, const N: usize, T=u32> {
| ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
error: aborting due to previous error

View File

@ -1,10 +1,13 @@
// run-pass
// [full] run-pass
// revisions: min full
// Checks some basic test cases for defaults.
#![feature(const_generics)]
#![allow(incomplete_features)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#![allow(dead_code)]
struct FixedOutput<'a, const N: usize, T=u32> {
//[min]~^ ERROR type parameters must be declared prior to const parameters
out: &'a [T; N],
}

View File

@ -1,4 +1,6 @@
#![feature(const_generics)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
// All of these three items must be in `lib2` to reproduce the error

View File

@ -0,0 +1,10 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-61935.rs:10:14
|
LL | Self:FooImpl<{N==0}>
| ^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-61935.rs:10:23
|
LL | Self:FooImpl<{N==0}>
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: aborting due to previous error

View File

@ -1,12 +1,15 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
trait Foo {}
impl<const N: usize> Foo for [(); N]
where
Self:FooImpl<{N==0}>
//~^ERROR constant expression depends on a generic parameter
//[full]~^ERROR constant expression depends on a generic parameter
//[min]~^^ERROR generic parameters must not be used inside of non trivial constant values
{}
trait FooImpl<const IS_ZERO: bool>{}

View File

@ -1,19 +0,0 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-61935.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error: constant expression depends on a generic parameter
--> $DIR/issue-61935.rs:8:14
|
LL | Self:FooImpl<{N==0}>
| ^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error; 1 warning emitted

View File

@ -1,7 +1,9 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub trait BitLen: Sized {
const BIT_LEN: usize;
@ -12,5 +14,5 @@ impl<const L: usize> BitLen for [u8; L] {
}
fn main() {
let foo = <[u8; 2]>::BIT_LEN; //~ WARN unused variable
let _foo = <[u8; 2]>::BIT_LEN;
}

View File

@ -1,19 +0,0 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-62187-encountered-polymorphic-const.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
warning: unused variable: `foo`
--> $DIR/issue-62187-encountered-polymorphic-const.rs:15:9
|
LL | let foo = <[u8; 2]>::BIT_LEN;
| ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
|
= note: `#[warn(unused_variables)]` on by default
warning: 2 warnings emitted

View File

@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-62220.rs:10:27
--> $DIR/issue-62220.rs:13:27
|
LL | pub fn trunc(self) -> (TruncatedVector<T, { N }>, T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,10 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-62220.rs:8:59
|
LL | pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: aborting due to previous error

View File

@ -1,14 +1,17 @@
#![allow(incomplete_features)]
#![feature(const_generics)]
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct Vector<T, const N: usize>([T; N]);
pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
impl<T, const N: usize> Vector<T, { N }> {
/// Drop the last component and return the vector with one fewer dimension.
pub fn trunc(self) -> (TruncatedVector<T, { N }>, T) {
//~^ ERROR constant expression depends on a generic parameter
//[full]~^ ERROR constant expression depends on a generic parameter
unimplemented!()
}
}

View File

@ -0,0 +1,10 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-62456.rs:7:20
|
LL | let _ = [0u64; N + 1];
| ^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-62456.rs:7:20
|
LL | let _ = [0u64; N + 1];
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: aborting due to previous error

View File

@ -1,9 +1,12 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn foo<const N: usize>() {
let _ = [0u64; N + 1];
//~^ ERROR constant expression depends on a generic parameter
//[full]~^ ERROR constant expression depends on a generic parameter
//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
}
fn main() {}

View File

@ -1,19 +0,0 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-62456.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error: constant expression depends on a generic parameter
--> $DIR/issue-62456.rs:5:20
|
LL | let _ = [0u64; N + 1];
| ^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error; 1 warning emitted

View File

@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-62504.rs:18:25
--> $DIR/issue-62504.rs:19:25
|
LL | ArrayHolder([0; Self::SIZE])
| ^^^^^^^^^^

View File

@ -0,0 +1,10 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-62504.rs:19:25
|
LL | ArrayHolder([0; Self::SIZE])
| ^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
|
= help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
error: aborting due to previous error

View File

@ -1,7 +1,8 @@
// Regression test for #62504
#![feature(const_generics)]
// revisions: full min
#![allow(incomplete_features)]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
trait HasSize {
const SIZE: usize;
@ -16,7 +17,8 @@ struct ArrayHolder<const X: usize>([u32; X]);
impl<const X: usize> ArrayHolder<X> {
pub const fn new() -> Self {
ArrayHolder([0; Self::SIZE])
//~^ ERROR constant expression depends on a generic parameter
//[full]~^ ERROR constant expression depends on a generic parameter
//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
}
}

View File

@ -0,0 +1,11 @@
error: `NoMatch` is forbidden as the type of a const generic parameter
--> $DIR/issue-62579-no-match.rs:10:17
|
LL | fn foo<const T: NoMatch>() -> bool {
| ^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`
= note: more complex types are supported with `#[feature(const_generics)]`
error: aborting due to previous error

View File

@ -1,12 +1,14 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
// [full] run-pass
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#[derive(PartialEq, Eq)]
struct NoMatch;
fn foo<const T: NoMatch>() -> bool {
//[min]~^ ERROR `NoMatch` is forbidden as the type of a const generic parameter
true
}

View File

@ -1,11 +0,0 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-62579-no-match.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
warning: 1 warning emitted

View File

@ -1,37 +1,28 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-62878.rs:3:38
--> $DIR/issue-62878.rs:6:38
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^ the type must not depend on the parameter `N`
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-62878.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error[E0107]: wrong number of const arguments: expected 2, found 1
--> $DIR/issue-62878.rs:7:5
--> $DIR/issue-62878.rs:11:5
|
LL | foo::<_, {[1]}>();
| ^^^^^^^^^^^^^^^ expected 2 const arguments
error[E0107]: wrong number of type arguments: expected 0, found 1
--> $DIR/issue-62878.rs:7:11
--> $DIR/issue-62878.rs:11:11
|
LL | foo::<_, {[1]}>();
| ^ unexpected type argument
error[E0308]: mismatched types
--> $DIR/issue-62878.rs:7:15
--> $DIR/issue-62878.rs:11:15
|
LL | foo::<_, {[1]}>();
| ^^^ expected `usize`, found array `[{integer}; 1]`
error: aborting due to 4 previous errors; 1 warning emitted
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0107, E0308, E0770.
For more information about an error, try `rustc --explain E0107`.

View File

@ -0,0 +1,18 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-62878.rs:6:38
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^ the type must not depend on the parameter `N`
error: `[u8; _]` is forbidden as the type of a const generic parameter
--> $DIR/issue-62878.rs:6:33
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`
= note: more complex types are supported with `#[feature(const_generics)]`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0770`.

View File

@ -1,11 +1,15 @@
#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn foo<const N: usize, const A: [u8; N]>() {}
//~^ ERROR the type of const parameters must not
//[min]~| ERROR `[u8; _]` is forbidden as the type of a const generic parameter
fn main() {
foo::<_, {[1]}>();
//~^ ERROR wrong number of const arguments
//~| ERROR wrong number of type arguments
//~| ERROR mismatched types
//[full]~^ ERROR wrong number of const arguments
//[full]~| ERROR wrong number of type arguments
//[full]~| ERROR mismatched types
}

View File

@ -1,14 +1,5 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-67185-2.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:15:1
--> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
@ -26,7 +17,7 @@ LL | | }
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:15:1
--> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
@ -44,7 +35,7 @@ LL | | }
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:25:6
--> $DIR/issue-67185-2.rs:27:6
|
LL | trait Foo
| --- required by a bound in this
@ -60,7 +51,7 @@ LL | impl Foo for FooImpl {}
<[u16; 4] as Bar>
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:25:6
--> $DIR/issue-67185-2.rs:27:6
|
LL | trait Foo
| --- required by a bound in this
@ -76,7 +67,7 @@ LL | impl Foo for FooImpl {}
<[u16; 4] as Bar>
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:29:14
--> $DIR/issue-67185-2.rs:31:14
|
LL | trait Foo
| --- required by a bound in this
@ -92,7 +83,7 @@ LL | fn f(_: impl Foo) {}
<[u16; 4] as Bar>
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:29:14
--> $DIR/issue-67185-2.rs:31:14
|
LL | trait Foo
| --- required by a bound in this
@ -107,6 +98,6 @@ LL | fn f(_: impl Foo) {}
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,103 @@
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
LL | | where
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
LL | | <u8 as Baz>::Quaks: Bar,
LL | | {
LL | | }
| |_^ the trait `Bar` is not implemented for `[u16; 3]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
LL | | where
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
LL | | <u8 as Baz>::Quaks: Bar,
LL | | {
LL | | }
| |_^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:27:6
|
LL | trait Foo
| --- required by a bound in this
...
LL | <u8 as Baz>::Quaks: Bar,
| --- required by this bound in `Foo`
...
LL | impl Foo for FooImpl {}
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:27:6
|
LL | trait Foo
| --- required by a bound in this
...
LL | [<u8 as Baz>::Quaks; 2]: Bar,
| --- required by this bound in `Foo`
...
LL | impl Foo for FooImpl {}
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:31:14
|
LL | trait Foo
| --- required by a bound in this
...
LL | [<u8 as Baz>::Quaks; 2]: Bar,
| --- required by this bound in `Foo`
...
LL | fn f(_: impl Foo) {}
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:31:14
|
LL | trait Foo
| --- required by a bound in this
...
LL | <u8 as Baz>::Quaks: Bar,
| --- required by this bound in `Foo`
...
LL | fn f(_: impl Foo) {}
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
|
= help: the following implementations were found:
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,5 +1,7 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
trait Baz {
type Quaks;

View File

@ -0,0 +1,10 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-67739.rs:12:30
|
LL | [0u8; mem::size_of::<Self::Associated>()];
| ^^^^^^^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
|
= help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
error: aborting due to previous error

View File

@ -1,7 +1,7 @@
// Regression test for #67739
#![allow(incomplete_features)]
#![feature(const_generics)]
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
use std::mem;
@ -10,7 +10,8 @@ pub trait Trait {
fn associated_size(&self) -> usize {
[0u8; mem::size_of::<Self::Associated>()];
//~^ ERROR constant expression depends on a generic parameter
//[full]~^ ERROR constant expression depends on a generic parameter
//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
0
}
}

View File

@ -1,5 +1,5 @@
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:10:13
--> $DIR/issue-68366.rs:12:13
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^ unconstrained const parameter
@ -8,7 +8,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
= note: proving the result of expressions other than the parameter are unique is not supported
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:15:12
--> $DIR/issue-68366.rs:18:12
|
LL | impl<const N: usize> Foo {}
| ^ unconstrained const parameter

View File

@ -0,0 +1,29 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-68366.rs:12:37
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:12:13
|
LL | impl <const N: usize> Collatz<{Some(N)}> {}
| ^ unconstrained const parameter
|
= note: expressions using a const parameter must map each value to a distinct output value
= note: proving the result of expressions other than the parameter are unique is not supported
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-68366.rs:18:12
|
LL | impl<const N: usize> Foo {}
| ^ unconstrained const parameter
|
= note: expressions using a const parameter must map each value to a distinct output value
= note: proving the result of expressions other than the parameter are unique is not supported
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0207`.

View File

@ -2,13 +2,16 @@
// The note should relate to the fact that it cannot be shown forall N that it maps 1-1 to a new
// type.
#![feature(const_generics)]
#![allow(incomplete_features)]
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct Collatz<const N: Option<usize>>;
impl <const N: usize> Collatz<{Some(N)}> {}
//~^ ERROR the const parameter
//[min]~^^ generic parameters must not be used inside of non trivial constant values
struct Foo;

View File

@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-72787.rs:9:32
--> $DIR/issue-72787.rs:11:32
|
LL | Condition<{ LHS <= RHS }>: True
| ^^^^
@ -7,7 +7,7 @@ LL | Condition<{ LHS <= RHS }>: True
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
--> $DIR/issue-72787.rs:20:42
--> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
@ -15,7 +15,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
--> $DIR/issue-72787.rs:20:42
--> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
@ -23,7 +23,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
--> $DIR/issue-72787.rs:20:42
--> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
@ -31,7 +31,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
--> $DIR/issue-72787.rs:20:42
--> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^

View File

@ -0,0 +1,57 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-72787.rs:11:17
|
LL | Condition<{ LHS <= RHS }>: True
| ^^^ non-trivial anonymous constants must not depend on the parameter `LHS`
|
= help: it is currently only allowed to use either `LHS` or `{ LHS }` as generic constants
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-72787.rs:11:24
|
LL | Condition<{ LHS <= RHS }>: True
| ^^^ non-trivial anonymous constants must not depend on the parameter `RHS`
|
= help: it is currently only allowed to use either `RHS` or `{ RHS }` as generic constants
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-72787.rs:26:25
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^ non-trivial anonymous constants must not depend on the parameter `I`
|
= help: it is currently only allowed to use either `I` or `{ I }` as generic constants
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-72787.rs:26:36
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^ non-trivial anonymous constants must not depend on the parameter `J`
|
= help: it is currently only allowed to use either `J` or `{ J }` as generic constants
error[E0283]: type annotations needed
--> $DIR/issue-72787.rs:22:26
|
LL | pub trait True {}
| -------------- required by this bound in `True`
...
LL | IsLessOrEqual<I, 8>: True,
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
|
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
error[E0283]: type annotations needed
--> $DIR/issue-72787.rs:22:26
|
LL | pub trait True {}
| -------------- required by this bound in `True`
...
LL | IsLessOrEqual<I, 8>: True,
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
|
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0283`.

View File

@ -1,5 +1,7 @@
#![feature(const_generics)]
#![allow(incomplete_features)]
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct IsLessOrEqual<const LHS: u32, const RHS: u32>;
pub struct Condition<const CONDITION: bool>;
@ -7,7 +9,9 @@ pub trait True {}
impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
Condition<{ LHS <= RHS }>: True
//~^ Error constant expression depends on a generic parameter
//[full]~^ Error constant expression depends on a generic parameter
//[min]~^^ Error generic parameters must not be used inside of non trivial constant values
//[min]~| Error generic parameters must not be used inside of non trivial constant values
{
}
impl True for Condition<true> {}
@ -16,12 +20,16 @@ struct S<const I: u32, const J: u32>;
impl<const I: u32, const J: u32> S<I, J>
where
IsLessOrEqual<I, 8>: True,
//[min]~^ Error type annotations needed [E0283]
//[min]~| Error type annotations needed [E0283]
IsLessOrEqual<J, 8>: True,
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
//~^ Error constant expression depends on a generic parameter
//~| Error constant expression depends on a generic parameter
//~| Error constant expression depends on a generic parameter
//~| Error constant expression depends on a generic parameter
//[full]~^ constant expression depends on a generic parameter
//[full]~| constant expression depends on a generic parameter
//[full]~| constant expression depends on a generic parameter
//[full]~| constant expression depends on a generic parameter
//[min]~^^^^^ Error generic parameters must not be used inside of non trivial constant values
//[min]~| Error generic parameters must not be used inside of non trivial constant values
// Condition<{ 8 - I <= 8 - J }>: True,
{
fn print() {

View File

@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-72819-generic-in-const-eval.rs:7:47
--> $DIR/issue-72819-generic-in-const-eval.rs:9:47
|
LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
| ^^^^^^

View File

@ -0,0 +1,10 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-72819-generic-in-const-eval.rs:9:17
|
LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: aborting due to previous error

View File

@ -1,11 +1,14 @@
// Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type
// bounds.
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#![feature(const_generics)]
#![allow(incomplete_features)]
struct Arr<const N: usize>
where Assert::<{N < usize::max_value() / 2}>: IsTrue,
//~^ ERROR constant expression depends on a generic parameter
//[full]~^ ERROR constant expression depends on a generic parameter
//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
{
}

View File

@ -1,3 +1,4 @@
// revisions: full min
// check-pass
// aux-build:const_generic_issues_lib.rs
extern crate const_generic_issues_lib as lib2;

View File

@ -0,0 +1,18 @@
// run-rustfix
#![allow(dead_code, unused_variables)]
pub mod foo {
#[derive(Default)]
pub struct Foo { invisible: bool, }
#[derive(Default)]
pub struct Bar { pub visible: bool, invisible: bool, }
}
fn main() {
let foo::Foo { .. } = foo::Foo::default();
//~^ ERROR pattern requires `..` due to inaccessible fields
let foo::Bar { visible, .. } = foo::Bar::default();
//~^ ERROR pattern requires `..` due to inaccessible fields
}

View File

@ -0,0 +1,18 @@
// run-rustfix
#![allow(dead_code, unused_variables)]
pub mod foo {
#[derive(Default)]
pub struct Foo { invisible: bool, }
#[derive(Default)]
pub struct Bar { pub visible: bool, invisible: bool, }
}
fn main() {
let foo::Foo {} = foo::Foo::default();
//~^ ERROR pattern requires `..` due to inaccessible fields
let foo::Bar { visible } = foo::Bar::default();
//~^ ERROR pattern requires `..` due to inaccessible fields
}

View File

@ -0,0 +1,24 @@
error: pattern requires `..` due to inaccessible fields
--> $DIR/issue-76077-1.rs:13:9
|
LL | let foo::Foo {} = foo::Foo::default();
| ^^^^^^^^^^^
|
help: ignore the inaccessible and unused fields
|
LL | let foo::Foo { .. } = foo::Foo::default();
| ^^^^^^
error: pattern requires `..` due to inaccessible fields
--> $DIR/issue-76077-1.rs:16:9
|
LL | let foo::Bar { visible } = foo::Bar::default();
| ^^^^^^^^^^^^^^^^^^^^
|
help: ignore the inaccessible and unused fields
|
LL | let foo::Bar { visible, .. } = foo::Bar::default();
| ^^^^
error: aborting due to 2 previous errors

View File

@ -0,0 +1,10 @@
pub mod foo {
pub struct Foo {
you_cant_use_this_field: bool,
}
}
fn main() {
foo::Foo {};
//~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields
}

View File

@ -0,0 +1,8 @@
error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
--> $DIR/issue-76077.rs:8:5
|
LL | foo::Foo {};
| ^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,9 @@
unsafe extern {
//~^ ERROR extern block cannot be declared unsafe
}
unsafe extern "C" {
//~^ ERROR extern block cannot be declared unsafe
}
fn main() {}

View File

@ -0,0 +1,14 @@
error: extern block cannot be declared unsafe
--> $DIR/unsafe-foreign-mod.rs:1:1
|
LL | unsafe extern {
| ^^^^^^
error: extern block cannot be declared unsafe
--> $DIR/unsafe-foreign-mod.rs:5:1
|
LL | unsafe extern "C" {
| ^^^^^^
error: aborting due to 2 previous errors

View File

@ -0,0 +1,9 @@
unsafe mod m {
//~^ ERROR module cannot be declared unsafe
}
unsafe mod n;
//~^ ERROR module cannot be declared unsafe
//~^^ ERROR file not found for module `n`
fn main() {}

Some files were not shown because too many files have changed in this diff Show More