mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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:
commit
ad3a6f70ac
@ -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>>,
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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()),
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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`.
|
||||
|
@ -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)];
|
||||
|
@ -2093,7 +2093,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
_ => String::new(),
|
||||
};
|
||||
if !s.is_empty() {
|
||||
s.push_str(" ");
|
||||
s.push(' ');
|
||||
}
|
||||
s
|
||||
};
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
})
|
||||
|
@ -353,7 +353,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
|
||||
if !INCLUDE_COVERAGE_STATEMENTS {
|
||||
continue;
|
||||
}
|
||||
format!("unreachable")
|
||||
String::from("unreachable")
|
||||
}
|
||||
},
|
||||
_ => format!("{:?}", statement),
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -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() };
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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>,
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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":[]}
|
||||
|
@ -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":[]}
|
||||
|
@ -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]);
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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
|
@ -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`.
|
@ -1,4 +1,5 @@
|
||||
// aux-build:const_generic_lib.rs
|
||||
// revisions: full min
|
||||
|
||||
extern crate const_generic_lib;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// run-pass
|
||||
// revisions: full min
|
||||
// aux-build:const_generic_lib.rs
|
||||
|
||||
extern crate const_generic_lib;
|
||||
|
@ -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]);
|
||||
}
|
@ -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
|
||||
|
@ -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]);
|
||||
}
|
@ -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>();
|
||||
}
|
@ -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`.
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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>`
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
@ -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],
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
10
src/test/ui/const-generics/issues/issue-61935.full.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-61935.full.stderr
Normal 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
|
||||
|
10
src/test/ui/const-generics/issues/issue-61935.min.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-61935.min.stderr
Normal 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
|
||||
|
@ -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>{}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
10
src/test/ui/const-generics/issues/issue-62220.min.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-62220.min.stderr
Normal 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
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
10
src/test/ui/const-generics/issues/issue-62456.full.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-62456.full.stderr
Normal 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
|
||||
|
10
src/test/ui/const-generics/issues/issue-62456.min.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-62456.min.stderr
Normal 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
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
| ^^^^^^^^^^
|
10
src/test/ui/const-generics/issues/issue-62504.min.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-62504.min.stderr
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`.
|
18
src/test/ui/const-generics/issues/issue-62878.min.stderr
Normal file
18
src/test/ui/const-generics/issues/issue-62878.min.stderr
Normal 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`.
|
@ -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
|
||||
}
|
||||
|
@ -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`.
|
103
src/test/ui/const-generics/issues/issue-67185-2.min.stderr
Normal file
103
src/test/ui/const-generics/issues/issue-67185-2.min.stderr
Normal 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`.
|
@ -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;
|
||||
|
10
src/test/ui/const-generics/issues/issue-67739.min.stderr
Normal file
10
src/test/ui/const-generics/issues/issue-67739.min.stderr
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
29
src/test/ui/const-generics/issues/issue-68366.min.stderr
Normal file
29
src/test/ui/const-generics/issues/issue-68366.min.stderr
Normal 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`.
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
| ^^^^
|
57
src/test/ui/const-generics/issues/issue-72787.min.stderr
Normal file
57
src/test/ui/const-generics/issues/issue-72787.min.stderr
Normal 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`.
|
@ -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() {
|
||||
|
@ -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,
|
||||
| ^^^^^^
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// revisions: full min
|
||||
// check-pass
|
||||
// aux-build:const_generic_issues_lib.rs
|
||||
extern crate const_generic_issues_lib as lib2;
|
||||
|
18
src/test/ui/issues/issue-76077-1.fixed
Normal file
18
src/test/ui/issues/issue-76077-1.fixed
Normal 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
|
||||
}
|
18
src/test/ui/issues/issue-76077-1.rs
Normal file
18
src/test/ui/issues/issue-76077-1.rs
Normal 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
|
||||
}
|
24
src/test/ui/issues/issue-76077-1.stderr
Normal file
24
src/test/ui/issues/issue-76077-1.stderr
Normal 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
|
||||
|
10
src/test/ui/issues/issue-76077.rs
Normal file
10
src/test/ui/issues/issue-76077.rs
Normal 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
|
||||
}
|
8
src/test/ui/issues/issue-76077.stderr
Normal file
8
src/test/ui/issues/issue-76077.stderr
Normal 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
|
||||
|
9
src/test/ui/parser/unsafe-foreign-mod.rs
Normal file
9
src/test/ui/parser/unsafe-foreign-mod.rs
Normal 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() {}
|
14
src/test/ui/parser/unsafe-foreign-mod.stderr
Normal file
14
src/test/ui/parser/unsafe-foreign-mod.stderr
Normal 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
|
||||
|
9
src/test/ui/parser/unsafe-mod.rs
Normal file
9
src/test/ui/parser/unsafe-mod.rs
Normal 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
Loading…
Reference in New Issue
Block a user