Auto merge of #99964 - matthiaskrgr:rollup-jr836e2, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #99650 (Support `x --keep-stage 0 check`) - #99873 (rustdoc: align invalid-html-tags lint with commonmark spec) - #99889 (Remove `parent_pat` from `TopInfo`) - #99890 (Do not allow bad projection term to leak into the type checker) - #99937 (Reset directory iteration in remove_dir_all) - #99950 (Remove more Clean trait implementations) - #99956 (Also gate AllocatedPointer and AllocAlign definitions by LLVM_VERSION_GE) - #99962 (Discover channel for LLVM download) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0f4bcadb46
16 changed files with 149 additions and 102 deletions
|
@ -87,8 +87,10 @@ enum LLVMRustAttribute {
|
||||||
NoCfCheck = 35,
|
NoCfCheck = 35,
|
||||||
ShadowCallStack = 36,
|
ShadowCallStack = 36,
|
||||||
AllocSize = 37,
|
AllocSize = 37,
|
||||||
|
#if LLVM_VERSION_GE(15, 0)
|
||||||
AllocatedPointer = 38,
|
AllocatedPointer = 38,
|
||||||
AllocAlign = 39,
|
AllocAlign = 39,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct OpaqueRustString *RustStringRef;
|
typedef struct OpaqueRustString *RustStringRef;
|
||||||
|
|
|
@ -1234,7 +1234,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
|
|
||||||
match binding.kind {
|
match binding.kind {
|
||||||
ConvertedBindingKind::Equality(term) => {
|
ConvertedBindingKind::Equality(mut term) => {
|
||||||
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
||||||
// the "projection predicate" for:
|
// the "projection predicate" for:
|
||||||
//
|
//
|
||||||
|
@ -1245,18 +1245,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
(hir::def::DefKind::AssocTy, ty::Term::Ty(_))
|
(hir::def::DefKind::AssocTy, ty::Term::Ty(_))
|
||||||
| (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
|
| (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
let got = if let ty::Term::Ty(_) = term { "type" } else { "const" };
|
let got = if let ty::Term::Ty(_) = term { "type" } else { "constant" };
|
||||||
let expected = def_kind.descr(assoc_item_def_id);
|
let expected = def_kind.descr(assoc_item_def_id);
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
binding.span,
|
binding.span,
|
||||||
&format!("mismatch in bind of {expected}, got {got}"),
|
&format!("expected {expected} bound, found {got}"),
|
||||||
)
|
)
|
||||||
.span_note(
|
.span_note(
|
||||||
tcx.def_span(assoc_item_def_id),
|
tcx.def_span(assoc_item_def_id),
|
||||||
&format!("{expected} defined here does not match {got}"),
|
&format!("{expected} defined here"),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
|
term = match def_kind {
|
||||||
|
hir::def::DefKind::AssocTy => tcx.ty_error().into(),
|
||||||
|
hir::def::DefKind::AssocConst => tcx
|
||||||
|
.const_error(
|
||||||
|
tcx.bound_type_of(assoc_item_def_id)
|
||||||
|
.subst(tcx, projection_ty.skip_binder().substs),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bounds.projection_bounds.push((
|
bounds.projection_bounds.push((
|
||||||
|
|
|
@ -72,22 +72,6 @@ struct TopInfo<'tcx> {
|
||||||
/// found type `std::result::Result<_, _>`
|
/// found type `std::result::Result<_, _>`
|
||||||
/// ```
|
/// ```
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
/// This refers to the parent pattern. Used to provide extra diagnostic information on errors.
|
|
||||||
/// ```text
|
|
||||||
/// error[E0308]: mismatched types
|
|
||||||
/// --> $DIR/const-in-struct-pat.rs:8:17
|
|
||||||
/// |
|
|
||||||
/// L | struct f;
|
|
||||||
/// | --------- unit struct defined here
|
|
||||||
/// ...
|
|
||||||
/// L | let Thing { f } = t;
|
|
||||||
/// | ^
|
|
||||||
/// | |
|
|
||||||
/// | expected struct `std::string::String`, found struct `f`
|
|
||||||
/// | `f` is interpreted as a unit struct, not a new binding
|
|
||||||
/// | help: bind the struct field to a different name instead: `f: other_f`
|
|
||||||
/// ```
|
|
||||||
parent_pat: Option<&'tcx Pat<'tcx>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> FnCtxt<'_, 'tcx> {
|
impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
|
@ -147,7 +131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
origin_expr: bool,
|
origin_expr: bool,
|
||||||
) {
|
) {
|
||||||
let info = TopInfo { expected, origin_expr, span, parent_pat: None };
|
let info = TopInfo { expected, origin_expr, span };
|
||||||
self.check_pat(pat, expected, INITIAL_BM, info);
|
self.check_pat(pat, expected, INITIAL_BM, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,9 +174,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, def_bm, ti)
|
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, def_bm, ti)
|
||||||
}
|
}
|
||||||
PatKind::Or(pats) => {
|
PatKind::Or(pats) => {
|
||||||
let parent_pat = Some(pat);
|
|
||||||
for pat in pats {
|
for pat in pats {
|
||||||
self.check_pat(pat, expected, def_bm, TopInfo { parent_pat, ..ti });
|
self.check_pat(pat, expected, def_bm, ti);
|
||||||
}
|
}
|
||||||
expected
|
expected
|
||||||
}
|
}
|
||||||
|
@ -621,7 +604,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(p) = sub {
|
if let Some(p) = sub {
|
||||||
self.check_pat(p, expected, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
|
self.check_pat(p, expected, def_bm, ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ty
|
local_ty
|
||||||
|
@ -782,7 +765,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
|
let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
|
||||||
let err = self.tcx.ty_error();
|
let err = self.tcx.ty_error();
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let ti = TopInfo { parent_pat: Some(pat), ..ti };
|
let ti = ti;
|
||||||
self.check_pat(field.pat, err, def_bm, ti);
|
self.check_pat(field.pat, err, def_bm, ti);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
@ -799,11 +782,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat_path<'b>(
|
fn check_pat_path(
|
||||||
&self,
|
&self,
|
||||||
pat: &Pat<'_>,
|
pat: &Pat<'tcx>,
|
||||||
qpath: &hir::QPath<'_>,
|
qpath: &hir::QPath<'_>,
|
||||||
path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]),
|
path_resolution: (Res, Option<Ty<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
ti: TopInfo<'tcx>,
|
ti: TopInfo<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
|
@ -837,7 +820,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if let Some(err) =
|
if let Some(err) =
|
||||||
self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
|
self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
|
||||||
{
|
{
|
||||||
self.emit_bad_pat_path(err, pat.span, res, pat_res, pat_ty, segments, ti.parent_pat);
|
self.emit_bad_pat_path(err, pat, res, pat_res, pat_ty, segments);
|
||||||
}
|
}
|
||||||
pat_ty
|
pat_ty
|
||||||
}
|
}
|
||||||
|
@ -876,16 +859,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_bad_pat_path<'b>(
|
fn emit_bad_pat_path(
|
||||||
&self,
|
&self,
|
||||||
mut e: DiagnosticBuilder<'_, ErrorGuaranteed>,
|
mut e: DiagnosticBuilder<'_, ErrorGuaranteed>,
|
||||||
pat_span: Span,
|
pat: &hir::Pat<'tcx>,
|
||||||
res: Res,
|
res: Res,
|
||||||
pat_res: Res,
|
pat_res: Res,
|
||||||
pat_ty: Ty<'tcx>,
|
pat_ty: Ty<'tcx>,
|
||||||
segments: &'b [hir::PathSegment<'b>],
|
segments: &'tcx [hir::PathSegment<'tcx>],
|
||||||
parent_pat: Option<&Pat<'_>>,
|
|
||||||
) {
|
) {
|
||||||
|
let pat_span = pat.span;
|
||||||
if let Some(span) = self.tcx.hir().res_span(pat_res) {
|
if let Some(span) = self.tcx.hir().res_span(pat_res) {
|
||||||
e.span_label(span, &format!("{} defined here", res.descr()));
|
e.span_label(span, &format!("{} defined here", res.descr()));
|
||||||
if let [hir::PathSegment { ident, .. }] = &*segments {
|
if let [hir::PathSegment { ident, .. }] = &*segments {
|
||||||
|
@ -898,8 +881,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
res.descr(),
|
res.descr(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
match parent_pat {
|
match self.tcx.hir().get(self.tcx.hir().get_parent_node(pat.hir_id)) {
|
||||||
Some(Pat { kind: hir::PatKind::Struct(..), .. }) => {
|
hir::Node::Pat(Pat { kind: hir::PatKind::Struct(..), .. }) => {
|
||||||
e.span_suggestion_verbose(
|
e.span_suggestion_verbose(
|
||||||
ident.span.shrink_to_hi(),
|
ident.span.shrink_to_hi(),
|
||||||
"bind the struct field to a different name instead",
|
"bind the struct field to a different name instead",
|
||||||
|
@ -960,9 +943,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let on_error = || {
|
let on_error = || {
|
||||||
let parent_pat = Some(pat);
|
|
||||||
for pat in subpats {
|
for pat in subpats {
|
||||||
self.check_pat(pat, tcx.ty_error(), def_bm, TopInfo { parent_pat, ..ti });
|
self.check_pat(pat, tcx.ty_error(), def_bm, ti);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let report_unexpected_res = |res: Res| {
|
let report_unexpected_res = |res: Res| {
|
||||||
|
@ -1046,7 +1028,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
|
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
|
||||||
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
|
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
|
||||||
self.check_pat(subpat, field_ty, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
|
self.check_pat(subpat, field_ty, def_bm, ti);
|
||||||
|
|
||||||
self.tcx.check_stability(
|
self.tcx.check_stability(
|
||||||
variant.fields[i].did,
|
variant.fields[i].did,
|
||||||
|
@ -1324,7 +1306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.check_pat(field.pat, field_ty, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
|
self.check_pat(field.pat, field_ty, def_bm, ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut unmentioned_fields = variant
|
let mut unmentioned_fields = variant
|
||||||
|
@ -1936,7 +1918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let err = tcx.ty_error();
|
let err = tcx.ty_error();
|
||||||
(err, err)
|
(err, err)
|
||||||
};
|
};
|
||||||
self.check_pat(inner, inner_ty, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
|
self.check_pat(inner, inner_ty, def_bm, ti);
|
||||||
rptr_ty
|
rptr_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1035,11 +1035,13 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
|
||||||
unsafe { mem::ManuallyDrop::new(File::from_raw_handle(f.as_raw_handle())) }
|
unsafe { mem::ManuallyDrop::new(File::from_raw_handle(f.as_raw_handle())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut restart = true;
|
||||||
while let Some(dir) = dirlist.last() {
|
while let Some(dir) = dirlist.last() {
|
||||||
let dir = copy_handle(dir);
|
let dir = copy_handle(dir);
|
||||||
|
|
||||||
// Fill the buffer and iterate the entries.
|
// Fill the buffer and iterate the entries.
|
||||||
let more_data = dir.fill_dir_buff(&mut buffer, false)?;
|
let more_data = dir.fill_dir_buff(&mut buffer, restart)?;
|
||||||
|
restart = false;
|
||||||
for (name, is_directory) in buffer.iter() {
|
for (name, is_directory) in buffer.iter() {
|
||||||
if is_directory {
|
if is_directory {
|
||||||
let child_dir = open_link_no_reparse(
|
let child_dir = open_link_no_reparse(
|
||||||
|
|
|
@ -1312,6 +1312,13 @@ impl Config {
|
||||||
git
|
git
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn artifact_channel(&self, commit: &str) -> String {
|
||||||
|
let mut channel = self.git();
|
||||||
|
channel.arg("show").arg(format!("{}:src/ci/channel", commit));
|
||||||
|
let channel = output(&mut channel);
|
||||||
|
channel.trim().to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to find the relative path of `bindir`, otherwise return it in full.
|
/// Try to find the relative path of `bindir`, otherwise return it in full.
|
||||||
pub fn bindir_relative(&self) -> &Path {
|
pub fn bindir_relative(&self) -> &Path {
|
||||||
let bindir = &self.bindir;
|
let bindir = &self.bindir;
|
||||||
|
@ -1547,8 +1554,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> {
|
||||||
|
|
||||||
fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
|
fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
|
||||||
builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
|
builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
|
||||||
// FIXME: support downloading artifacts from the beta channel
|
let channel = builder.config.artifact_channel(commit);
|
||||||
const CHANNEL: &str = "nightly";
|
|
||||||
let host = builder.config.build.triple;
|
let host = builder.config.build.triple;
|
||||||
let bin_root = builder.out.join(host).join("ci-rustc");
|
let bin_root = builder.out.join(host).join("ci-rustc");
|
||||||
let rustc_stamp = bin_root.join(".rustc-stamp");
|
let rustc_stamp = bin_root.join(".rustc-stamp");
|
||||||
|
@ -1557,13 +1563,13 @@ fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
|
||||||
if bin_root.exists() {
|
if bin_root.exists() {
|
||||||
t!(fs::remove_dir_all(&bin_root));
|
t!(fs::remove_dir_all(&bin_root));
|
||||||
}
|
}
|
||||||
let filename = format!("rust-std-{CHANNEL}-{host}.tar.xz");
|
let filename = format!("rust-std-{channel}-{host}.tar.xz");
|
||||||
let pattern = format!("rust-std-{host}");
|
let pattern = format!("rust-std-{host}");
|
||||||
download_ci_component(builder, filename, &pattern, commit);
|
download_ci_component(builder, filename, &pattern, commit);
|
||||||
let filename = format!("rustc-{CHANNEL}-{host}.tar.xz");
|
let filename = format!("rustc-{channel}-{host}.tar.xz");
|
||||||
download_ci_component(builder, filename, "rustc", commit);
|
download_ci_component(builder, filename, "rustc", commit);
|
||||||
// download-rustc doesn't need its own cargo, it can just use beta's.
|
// download-rustc doesn't need its own cargo, it can just use beta's.
|
||||||
let filename = format!("rustc-dev-{CHANNEL}-{host}.tar.xz");
|
let filename = format!("rustc-dev-{channel}-{host}.tar.xz");
|
||||||
download_ci_component(builder, filename, "rustc-dev", commit);
|
download_ci_component(builder, filename, "rustc-dev", commit);
|
||||||
|
|
||||||
builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
|
builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
|
||||||
|
|
|
@ -623,15 +623,6 @@ Arguments:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Subcommand::Check { .. } = &cmd {
|
|
||||||
if matches.opt_str("keep-stage").is_some()
|
|
||||||
|| matches.opt_str("keep-stage-std").is_some()
|
|
||||||
{
|
|
||||||
eprintln!("--keep-stage not yet supported for x.py check");
|
|
||||||
crate::detail_exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Flags {
|
Flags {
|
||||||
verbose: matches.opt_count("verbose"),
|
verbose: matches.opt_count("verbose"),
|
||||||
stage: matches.opt_str("stage").map(|j| j.parse().expect("`stage` should be a number")),
|
stage: matches.opt_str("stage").map(|j| j.parse().expect("`stage` should be a number")),
|
||||||
|
|
|
@ -189,7 +189,8 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) {
|
||||||
} else {
|
} else {
|
||||||
&builder.config.stage0_metadata.config.artifacts_server
|
&builder.config.stage0_metadata.config.artifacts_server
|
||||||
};
|
};
|
||||||
let filename = format!("rust-dev-nightly-{}.tar.xz", builder.build.build.triple);
|
let channel = builder.config.artifact_channel(llvm_sha);
|
||||||
|
let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple);
|
||||||
let tarball = rustc_cache.join(&filename);
|
let tarball = rustc_cache.join(&filename);
|
||||||
if !tarball.exists() {
|
if !tarball.exists() {
|
||||||
let help_on_error = "error: failed to download llvm from ci
|
let help_on_error = "error: failed to download llvm from ci
|
||||||
|
|
|
@ -17,8 +17,8 @@ use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty, clean_ty,
|
self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty, clean_ty,
|
||||||
clean_ty_generics, clean_visibility, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId,
|
clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
|
||||||
Type, Visibility,
|
Clean, ImplKind, ItemId, Type, Visibility,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::formats::item_type::ItemType;
|
use crate::formats::item_type::ItemType;
|
||||||
|
@ -236,7 +236,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
|
||||||
|
|
||||||
clean::Enum {
|
clean::Enum {
|
||||||
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
|
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
|
||||||
variants: cx.tcx.adt_def(did).variants().iter().map(|v| v.clean(cx)).collect(),
|
variants: cx.tcx.adt_def(did).variants().iter().map(|v| clean_variant_def(v, cx)).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1824,46 +1824,38 @@ pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_variant_data<'tcx>(
|
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
|
||||||
variant: &hir::VariantData<'tcx>,
|
let kind = match variant.ctor_kind {
|
||||||
cx: &mut DocContext<'tcx>,
|
|
||||||
) -> VariantStruct {
|
|
||||||
VariantStruct {
|
|
||||||
struct_type: CtorKind::from_hir(variant),
|
|
||||||
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Item> for ty::VariantDef {
|
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
|
|
||||||
let kind = match self.ctor_kind {
|
|
||||||
CtorKind::Const => Variant::CLike,
|
CtorKind::Const => Variant::CLike,
|
||||||
CtorKind::Fn => Variant::Tuple(
|
CtorKind::Fn => Variant::Tuple(
|
||||||
self.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
|
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
|
||||||
),
|
),
|
||||||
CtorKind::Fictive => Variant::Struct(VariantStruct {
|
CtorKind::Fictive => Variant::Struct(VariantStruct {
|
||||||
struct_type: CtorKind::Fictive,
|
struct_type: CtorKind::Fictive,
|
||||||
fields: self.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
|
fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
let what_rustc_thinks =
|
let what_rustc_thinks =
|
||||||
Item::from_def_id_and_parts(self.def_id, Some(self.name), VariantItem(kind), cx);
|
Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx);
|
||||||
// don't show `pub` for variants, which always inherit visibility
|
// don't show `pub` for variants, which always inherit visibility
|
||||||
Item { visibility: Inherited, ..what_rustc_thinks }
|
Item { visibility: Inherited, ..what_rustc_thinks }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Variant> for hir::VariantData<'tcx> {
|
fn clean_variant_data<'tcx>(
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Variant {
|
variant: &hir::VariantData<'tcx>,
|
||||||
match self {
|
cx: &mut DocContext<'tcx>,
|
||||||
hir::VariantData::Struct(..) => Variant::Struct(clean_variant_data(self, cx)),
|
) -> Variant {
|
||||||
|
match variant {
|
||||||
|
hir::VariantData::Struct(..) => Variant::Struct(VariantStruct {
|
||||||
|
struct_type: CtorKind::from_hir(variant),
|
||||||
|
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
|
||||||
|
}),
|
||||||
hir::VariantData::Tuple(..) => {
|
hir::VariantData::Tuple(..) => {
|
||||||
Variant::Tuple(self.fields().iter().map(|x| clean_field(x, cx)).collect())
|
Variant::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())
|
||||||
}
|
}
|
||||||
hir::VariantData::Unit(..) => Variant::CLike,
|
hir::VariantData::Unit(..) => Variant::CLike,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> {
|
impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Path {
|
fn clean(&self, cx: &mut DocContext<'tcx>) -> Path {
|
||||||
|
@ -2009,7 +2001,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> {
|
impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
|
fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
|
||||||
let kind = VariantItem(self.data.clean(cx));
|
let kind = VariantItem(clean_variant_data(&self.data, cx));
|
||||||
let what_rustc_thinks =
|
let what_rustc_thinks =
|
||||||
Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
|
Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
|
||||||
// don't show `pub` for variants, which are always public
|
// don't show `pub` for variants, which are always public
|
||||||
|
|
|
@ -94,6 +94,14 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option<usize> {
|
||||||
if current_pos == end_pos { None } else { Some(current_pos) }
|
if current_pos == end_pos { None } else { Some(current_pos) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool {
|
||||||
|
// https://spec.commonmark.org/0.30/#raw-html
|
||||||
|
//
|
||||||
|
// > A tag name consists of an ASCII letter followed by zero or more ASCII letters, digits, or
|
||||||
|
// > hyphens (-).
|
||||||
|
c.is_ascii_alphabetic() || !is_empty && (c == '-' || c.is_ascii_digit())
|
||||||
|
}
|
||||||
|
|
||||||
fn extract_html_tag(
|
fn extract_html_tag(
|
||||||
tags: &mut Vec<(String, Range<usize>)>,
|
tags: &mut Vec<(String, Range<usize>)>,
|
||||||
text: &str,
|
text: &str,
|
||||||
|
@ -117,7 +125,7 @@ fn extract_html_tag(
|
||||||
// Checking if this is a closing tag (like `</a>` for `<a>`).
|
// Checking if this is a closing tag (like `</a>` for `<a>`).
|
||||||
if c == '/' && tag_name.is_empty() {
|
if c == '/' && tag_name.is_empty() {
|
||||||
is_closing = true;
|
is_closing = true;
|
||||||
} else if c.is_ascii_alphanumeric() {
|
} else if is_valid_for_html_tag_name(c, tag_name.is_empty()) {
|
||||||
tag_name.push(c);
|
tag_name.push(c);
|
||||||
} else {
|
} else {
|
||||||
if !tag_name.is_empty() {
|
if !tag_name.is_empty() {
|
||||||
|
|
|
@ -108,3 +108,9 @@ pub fn j() {}
|
||||||
/// <Vec<_> shouldn't warn!
|
/// <Vec<_> shouldn't warn!
|
||||||
/// ``````
|
/// ``````
|
||||||
pub fn k() {}
|
pub fn k() {}
|
||||||
|
|
||||||
|
/// Web Components style <dashed-tags>
|
||||||
|
//~^ ERROR unclosed HTML tag `dashed-tags`
|
||||||
|
/// Web Components style </unopened-tag>
|
||||||
|
//~^ ERROR unopened HTML tag `unopened-tag`
|
||||||
|
pub fn m() {}
|
||||||
|
|
|
@ -82,5 +82,17 @@ error: Unclosed HTML comment
|
||||||
LL | /// <!--
|
LL | /// <!--
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error: unopened HTML tag `unopened-tag`
|
||||||
|
--> $DIR/invalid-html-tags.rs:114:26
|
||||||
|
|
|
||||||
|
LL | /// Web Components style </unopened-tag>
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: unclosed HTML tag `dashed-tags`
|
||||||
|
--> $DIR/invalid-html-tags.rs:112:26
|
||||||
|
|
|
||||||
|
LL | /// Web Components style <dashed-tags>
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,9 @@ impl FooTy for Bar {
|
||||||
|
|
||||||
|
|
||||||
fn foo<F: Foo<N=usize>>() {}
|
fn foo<F: Foo<N=usize>>() {}
|
||||||
//~^ ERROR mismatch in
|
//~^ ERROR expected associated constant bound, found type
|
||||||
fn foo2<F: FooTy<T=3usize>>() {}
|
fn foo2<F: FooTy<T=3usize>>() {}
|
||||||
//~^ ERROR mismatch in
|
//~^ ERROR expected associated type bound, found constant
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo::<Bar>();
|
foo::<Bar>();
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
error: mismatch in bind of associated constant, got type
|
error: expected associated constant bound, found type
|
||||||
--> $DIR/assoc-const-ty-mismatch.rs:23:15
|
--> $DIR/assoc-const-ty-mismatch.rs:23:15
|
||||||
|
|
|
|
||||||
LL | fn foo<F: Foo<N=usize>>() {}
|
LL | fn foo<F: Foo<N=usize>>() {}
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
note: associated constant defined here does not match type
|
note: associated constant defined here
|
||||||
--> $DIR/assoc-const-ty-mismatch.rs:5:3
|
--> $DIR/assoc-const-ty-mismatch.rs:5:3
|
||||||
|
|
|
|
||||||
LL | const N: usize;
|
LL | const N: usize;
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: mismatch in bind of associated type, got const
|
error: expected associated type bound, found constant
|
||||||
--> $DIR/assoc-const-ty-mismatch.rs:25:18
|
--> $DIR/assoc-const-ty-mismatch.rs:25:18
|
||||||
|
|
|
|
||||||
LL | fn foo2<F: FooTy<T=3usize>>() {}
|
LL | fn foo2<F: FooTy<T=3usize>>() {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
note: associated type defined here does not match const
|
note: associated type defined here
|
||||||
--> $DIR/assoc-const-ty-mismatch.rs:9:3
|
--> $DIR/assoc-const-ty-mismatch.rs:9:3
|
||||||
|
|
|
|
||||||
LL | type T;
|
LL | type T;
|
||||||
|
|
11
src/test/ui/associated-type-bounds/issue-99828.rs
Normal file
11
src/test/ui/associated-type-bounds/issue-99828.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
|
||||||
|
//~^ ERROR expected associated type bound, found constant
|
||||||
|
//~| ERROR associated const equality is incomplete
|
||||||
|
vec.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let vec = Vec::new();
|
||||||
|
let mut iter = get_iter(&vec);
|
||||||
|
iter.next();
|
||||||
|
}
|
24
src/test/ui/associated-type-bounds/issue-99828.stderr
Normal file
24
src/test/ui/associated-type-bounds/issue-99828.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0658]: associated const equality is incomplete
|
||||||
|
--> $DIR/issue-99828.rs:1:43
|
||||||
|
|
|
||||||
|
LL | fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
|
||||||
|
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: expected associated type bound, found constant
|
||||||
|
--> $DIR/issue-99828.rs:1:43
|
||||||
|
|
|
||||||
|
LL | fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: associated type defined here
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | type Item;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Add table
Reference in a new issue